Merge "Remove unused shortcut title to improve the boot time performance"
diff --git a/Android.bp b/Android.bp
index 72e519c..07e6b36 100644
--- a/Android.bp
+++ b/Android.bp
@@ -585,7 +585,6 @@
"--hide RequiresPermission " +
"--hide SdkConstant " +
"--hide Todo " +
- "--hide Typo " +
"--hide UnavailableSymbol " +
"--manifest $(location :frameworks-base-core-AndroidManifest.xml) "
diff --git a/apex/blobstore/service/java/com/android/server/blob/BlobMetadata.java b/apex/blobstore/service/java/com/android/server/blob/BlobMetadata.java
index d5315da..8494326 100644
--- a/apex/blobstore/service/java/com/android/server/blob/BlobMetadata.java
+++ b/apex/blobstore/service/java/com/android/server/blob/BlobMetadata.java
@@ -52,9 +52,9 @@
import android.content.res.Resources;
import android.os.Binder;
import android.os.ParcelFileDescriptor;
+import android.os.Process;
import android.os.RevocableFileDescriptor;
import android.os.UserHandle;
-import android.permission.PermissionManager;
import android.system.ErrnoException;
import android.system.Os;
import android.util.ArrayMap;
@@ -298,8 +298,8 @@
}
}
- final boolean canCallerAccessBlobsAcrossUsers = checkCallerCanAccessBlobsAcrossUsers(
- callingPackage, callingUserId);
+ final boolean canCallerAccessBlobsAcrossUsers =
+ checkCallerCanAccessBlobsAcrossUsers(callingUid);
if (!canCallerAccessBlobsAcrossUsers) {
return false;
}
@@ -325,12 +325,11 @@
return false;
}
- private static boolean checkCallerCanAccessBlobsAcrossUsers(
- String callingPackage, int callingUserId) {
+ private boolean checkCallerCanAccessBlobsAcrossUsers(int callingUid) {
final long token = Binder.clearCallingIdentity();
try {
- return PermissionManager.checkPackageNamePermission(ACCESS_BLOBS_ACROSS_USERS,
- callingPackage, callingUserId) == PackageManager.PERMISSION_GRANTED;
+ return mContext.checkPermission(ACCESS_BLOBS_ACROSS_USERS,
+ Process.INVALID_PID, callingUid) == PackageManager.PERMISSION_GRANTED;
} finally {
Binder.restoreCallingIdentity(token);
}
diff --git a/apex/jobscheduler/framework/java/android/app/job/JobInfo.java b/apex/jobscheduler/framework/java/android/app/job/JobInfo.java
index 526e63c..3a05323 100644
--- a/apex/jobscheduler/framework/java/android/app/job/JobInfo.java
+++ b/apex/jobscheduler/framework/java/android/app/job/JobInfo.java
@@ -1817,6 +1817,8 @@
/**
* Specify that this job should recur with the provided interval and flex. The job can
* execute at any time in a window of flex length at the end of the period.
+ * If the constraints are not satisfied within the window,
+ * the job will wait until the constraints are satisfied.
* @param intervalMillis Millisecond interval for which this job will repeat. A minimum
* value of {@link #getMinPeriodMillis()} is enforced.
* @param flexMillis Millisecond flex for this job. Flex is clamped to be at least
diff --git a/apex/jobscheduler/framework/java/android/app/job/JobParameters.java b/apex/jobscheduler/framework/java/android/app/job/JobParameters.java
index bf4f9a8..f1403bd5 100644
--- a/apex/jobscheduler/framework/java/android/app/job/JobParameters.java
+++ b/apex/jobscheduler/framework/java/android/app/job/JobParameters.java
@@ -438,7 +438,10 @@
* For jobs with {@link android.app.job.JobInfo.Builder#setOverrideDeadline(long)} set, this
* provides an easy way to tell whether the job is being executed due to the deadline
* expiring. Note: If the job is running because its deadline expired, it implies that its
- * constraints will not be met.
+ * constraints will not be met. However,
+ * {@link android.app.job.JobInfo.Builder#setPeriodic(boolean) periodic jobs} will only ever
+ * run when their constraints are satisfied, therefore, the constraints will still be satisfied
+ * for a periodic job even if the deadline has expired.
*/
public boolean isOverrideDeadlineExpired() {
return overrideDeadlineExpired;
diff --git a/apex/jobscheduler/service/java/com/android/server/tare/Ledger.java b/apex/jobscheduler/service/java/com/android/server/tare/Ledger.java
index a68170c..92b21e1 100644
--- a/apex/jobscheduler/service/java/com/android/server/tare/Ledger.java
+++ b/apex/jobscheduler/service/java/com/android/server/tare/Ledger.java
@@ -25,7 +25,9 @@
import android.annotation.CurrentTimeMillisLong;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.os.Build;
import android.util.IndentingPrintWriter;
+import android.util.Log;
import android.util.SparseLongArray;
import android.util.TimeUtils;
@@ -38,6 +40,10 @@
* Ledger to track the last recorded balance and recent activities of an app.
*/
class Ledger {
+ private static final String TAG = "TARE-" + Ledger.class.getSimpleName();
+ private static final boolean DEBUG = InternalResourceService.DEBUG
+ || Log.isLoggable(TAG, Log.DEBUG);
+
/** The window size within which rewards will be counted and used towards reward limiting. */
private static final long TOTAL_REWARD_WINDOW_MS = 24 * HOUR_IN_MILLIS;
/** The number of buckets to split {@link #TOTAL_REWARD_WINDOW_MS} into. */
@@ -51,7 +57,7 @@
TOTAL_REWARD_WINDOW_MS / NUM_REWARD_BUCKET_WINDOWS;
/** The maximum number of transactions to retain in memory at any one time. */
@VisibleForTesting
- static final int MAX_TRANSACTION_COUNT = 50;
+ static final int MAX_TRANSACTION_COUNT = Build.IS_ENG || Build.IS_USERDEBUG || DEBUG ? 32 : 4;
static class Transaction {
public final long startTimeMs;
@@ -67,7 +73,7 @@
this.startTimeMs = startTimeMs;
this.endTimeMs = endTimeMs;
this.eventId = eventId;
- this.tag = tag;
+ this.tag = tag == null ? null : tag.intern();
this.delta = delta;
this.ctp = ctp;
}
diff --git a/core/api/current.txt b/core/api/current.txt
index d0e32a7..00e3eff 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -4458,6 +4458,7 @@
method public void onProvideAssistData(android.os.Bundle);
method public android.net.Uri onProvideReferrer();
method public void onRequestPermissionsResult(int, @NonNull String[], @NonNull int[]);
+ method public void onRequestPermissionsResult(int, @NonNull String[], @NonNull int[], int);
method @CallSuper protected void onRestart();
method protected void onRestoreInstanceState(@NonNull android.os.Bundle);
method public void onRestoreInstanceState(@Nullable android.os.Bundle, @Nullable android.os.PersistableBundle);
@@ -4499,6 +4500,7 @@
method public android.view.DragAndDropPermissions requestDragAndDropPermissions(android.view.DragEvent);
method public void requestFullscreenMode(int, @Nullable android.os.OutcomeReceiver<java.lang.Void,java.lang.Throwable>);
method public final void requestPermissions(@NonNull String[], int);
+ method public final void requestPermissions(@NonNull String[], int, int);
method public final void requestShowKeyboardShortcuts();
method @Deprecated public boolean requestVisibleBehind(boolean);
method public final boolean requestWindowFeature(int);
@@ -4546,6 +4548,7 @@
method public void setVrModeEnabled(boolean, @NonNull android.content.ComponentName) throws android.content.pm.PackageManager.NameNotFoundException;
method public boolean shouldDockBigOverlays();
method public boolean shouldShowRequestPermissionRationale(@NonNull String);
+ method public boolean shouldShowRequestPermissionRationale(@NonNull String, int);
method public boolean shouldUpRecreateTask(android.content.Intent);
method public boolean showAssist(android.os.Bundle);
method @Deprecated public final void showDialog(int);
@@ -14205,46 +14208,6 @@
ctor public SQLiteAccessPermException(String);
}
- public interface SQLiteAuthorizer {
- method public int onAuthorize(int, @Nullable String, @Nullable String, @Nullable String, @Nullable String);
- field public static final int SQLITE_ACTION_ALTER_TABLE = 26; // 0x1a
- field public static final int SQLITE_ACTION_ANALYZE = 28; // 0x1c
- field public static final int SQLITE_ACTION_ATTACH = 24; // 0x18
- field public static final int SQLITE_ACTION_CREATE_INDEX = 1; // 0x1
- field public static final int SQLITE_ACTION_CREATE_TABLE = 2; // 0x2
- field public static final int SQLITE_ACTION_CREATE_TEMP_INDEX = 3; // 0x3
- field public static final int SQLITE_ACTION_CREATE_TEMP_TABLE = 4; // 0x4
- field public static final int SQLITE_ACTION_CREATE_TEMP_TRIGGER = 5; // 0x5
- field public static final int SQLITE_ACTION_CREATE_TEMP_VIEW = 6; // 0x6
- field public static final int SQLITE_ACTION_CREATE_TRIGGER = 7; // 0x7
- field public static final int SQLITE_ACTION_CREATE_VIEW = 8; // 0x8
- field public static final int SQLITE_ACTION_CREATE_VTABLE = 29; // 0x1d
- field public static final int SQLITE_ACTION_DELETE = 9; // 0x9
- field public static final int SQLITE_ACTION_DETACH = 25; // 0x19
- field public static final int SQLITE_ACTION_DROP_INDEX = 10; // 0xa
- field public static final int SQLITE_ACTION_DROP_TABLE = 11; // 0xb
- field public static final int SQLITE_ACTION_DROP_TEMP_INDEX = 12; // 0xc
- field public static final int SQLITE_ACTION_DROP_TEMP_TABLE = 13; // 0xd
- field public static final int SQLITE_ACTION_DROP_TEMP_TRIGGER = 14; // 0xe
- field public static final int SQLITE_ACTION_DROP_TEMP_VIEW = 15; // 0xf
- field public static final int SQLITE_ACTION_DROP_TRIGGER = 16; // 0x10
- field public static final int SQLITE_ACTION_DROP_VIEW = 17; // 0x11
- field public static final int SQLITE_ACTION_DROP_VTABLE = 30; // 0x1e
- field public static final int SQLITE_ACTION_FUNCTION = 31; // 0x1f
- field public static final int SQLITE_ACTION_INSERT = 18; // 0x12
- field public static final int SQLITE_ACTION_PRAGMA = 19; // 0x13
- field public static final int SQLITE_ACTION_READ = 20; // 0x14
- field public static final int SQLITE_ACTION_RECURSIVE = 33; // 0x21
- field public static final int SQLITE_ACTION_REINDEX = 27; // 0x1b
- field public static final int SQLITE_ACTION_SAVEPOINT = 32; // 0x20
- field public static final int SQLITE_ACTION_SELECT = 21; // 0x15
- field public static final int SQLITE_ACTION_TRANSACTION = 22; // 0x16
- field public static final int SQLITE_ACTION_UPDATE = 23; // 0x17
- field public static final int SQLITE_AUTHORIZER_RESULT_DENY = 1; // 0x1
- field public static final int SQLITE_AUTHORIZER_RESULT_IGNORE = 2; // 0x2
- field public static final int SQLITE_AUTHORIZER_RESULT_OK = 0; // 0x0
- }
-
public class SQLiteBindOrColumnIndexOutOfRangeException extends android.database.sqlite.SQLiteException {
ctor public SQLiteBindOrColumnIndexOutOfRangeException();
ctor public SQLiteBindOrColumnIndexOutOfRangeException(String);
@@ -14301,7 +14264,6 @@
method public void beginTransactionWithListenerNonExclusive(@Nullable android.database.sqlite.SQLiteTransactionListener);
method public void beginTransactionWithListenerReadOnly(@Nullable android.database.sqlite.SQLiteTransactionListener);
method public android.database.sqlite.SQLiteStatement compileStatement(String) throws android.database.SQLException;
- method @NonNull public android.database.sqlite.SQLiteStatement compileStatement(@NonNull String, @NonNull android.database.sqlite.SQLiteAuthorizer) throws android.database.SQLException;
method @NonNull public static android.database.sqlite.SQLiteDatabase create(@Nullable android.database.sqlite.SQLiteDatabase.CursorFactory);
method @NonNull public static android.database.sqlite.SQLiteDatabase createInMemory(@NonNull android.database.sqlite.SQLiteDatabase.OpenParams);
method public int delete(String, String, String[]);
@@ -14312,7 +14274,6 @@
method public void execPerConnectionSQL(@NonNull String, @Nullable Object[]) throws android.database.SQLException;
method public void execSQL(String) throws android.database.SQLException;
method public void execSQL(String, Object[]) throws android.database.SQLException;
- method public void execSQL(@NonNull String, @Nullable Object[], @NonNull android.database.sqlite.SQLiteAuthorizer) throws android.database.SQLException;
method public static String findEditTable(String);
method public java.util.List<android.util.Pair<java.lang.String,java.lang.String>> getAttachedDbs();
method public long getMaximumSize();
@@ -14324,7 +14285,6 @@
method public long insert(String, String, android.content.ContentValues);
method public long insertOrThrow(String, String, android.content.ContentValues) throws android.database.SQLException;
method public long insertWithOnConflict(String, String, android.content.ContentValues, int);
- method public boolean isAuthorizerSupportEnabled();
method public boolean isDatabaseIntegrityOk();
method public boolean isDbLockedByCurrentThread();
method @Deprecated public boolean isDbLockedByOtherThreads();
@@ -14351,7 +14311,6 @@
method public android.database.Cursor rawQuery(String, String[], android.os.CancellationSignal);
method public android.database.Cursor rawQueryWithFactory(android.database.sqlite.SQLiteDatabase.CursorFactory, String, String[], String);
method public android.database.Cursor rawQueryWithFactory(android.database.sqlite.SQLiteDatabase.CursorFactory, String, String[], String, android.os.CancellationSignal);
- method @NonNull public android.database.Cursor rawQueryWithFactory(@Nullable android.database.sqlite.SQLiteDatabase.CursorFactory, @NonNull String, @Nullable String[], @Nullable String, @Nullable android.os.CancellationSignal, @NonNull android.database.sqlite.SQLiteAuthorizer);
method public static int releaseMemory();
method public long replace(String, String, android.content.ContentValues);
method public long replaceOrThrow(String, String, android.content.ContentValues) throws android.database.SQLException;
@@ -14368,7 +14327,6 @@
method public int update(String, android.content.ContentValues, String, String[]);
method public int updateWithOnConflict(String, android.content.ContentValues, String, String[], int);
method public void validateSql(@NonNull String, @Nullable android.os.CancellationSignal);
- method public void validateSql(@NonNull String, @Nullable android.os.CancellationSignal, @NonNull android.database.sqlite.SQLiteAuthorizer);
method @Deprecated public boolean yieldIfContended();
method public boolean yieldIfContendedSafely();
method public boolean yieldIfContendedSafely(long);
@@ -14417,9 +14375,7 @@
ctor public SQLiteDatabase.OpenParams.Builder(android.database.sqlite.SQLiteDatabase.OpenParams);
method @NonNull public android.database.sqlite.SQLiteDatabase.OpenParams.Builder addOpenFlags(int);
method @NonNull public android.database.sqlite.SQLiteDatabase.OpenParams build();
- method public boolean isAuthorizerSupportEnabled();
method @NonNull public android.database.sqlite.SQLiteDatabase.OpenParams.Builder removeOpenFlags(int);
- method @NonNull public android.database.sqlite.SQLiteDatabase.OpenParams.Builder setAuthorizerSupportEnabled(boolean);
method @NonNull public android.database.sqlite.SQLiteDatabase.OpenParams.Builder setCursorFactory(@Nullable android.database.sqlite.SQLiteDatabase.CursorFactory);
method @NonNull public android.database.sqlite.SQLiteDatabase.OpenParams.Builder setErrorHandler(@Nullable android.database.DatabaseErrorHandler);
method @Deprecated @NonNull public android.database.sqlite.SQLiteDatabase.OpenParams.Builder setIdleConnectionTimeout(@IntRange(from=0) long);
@@ -24384,6 +24340,7 @@
field public static final int TYPE_REMOTE_CAR = 1008; // 0x3f0
field public static final int TYPE_REMOTE_COMPUTER = 1006; // 0x3ee
field public static final int TYPE_REMOTE_GAME_CONSOLE = 1007; // 0x3ef
+ field public static final int TYPE_REMOTE_SMARTPHONE = 1010; // 0x3f2
field public static final int TYPE_REMOTE_SMARTWATCH = 1009; // 0x3f1
field public static final int TYPE_REMOTE_SPEAKER = 1002; // 0x3ea
field public static final int TYPE_REMOTE_TABLET = 1004; // 0x3ec
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 928e41d..6ea9c24 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -3924,6 +3924,7 @@
field public static final int DELETE_FAILED_OWNER_BLOCKED = -4; // 0xfffffffc
field public static final int DELETE_KEEP_DATA = 1; // 0x1
field public static final int DELETE_SUCCEEDED = 1; // 0x1
+ field public static final String EXTRA_REQUEST_PERMISSIONS_DEVICE_ID = "android.content.pm.extra.REQUEST_PERMISSIONS_DEVICE_ID";
field public static final String EXTRA_REQUEST_PERMISSIONS_LEGACY_ACCESS_PERMISSION_NAMES = "android.content.pm.extra.REQUEST_PERMISSIONS_LEGACY_ACCESS_PERMISSION_NAMES";
field public static final String EXTRA_REQUEST_PERMISSIONS_NAMES = "android.content.pm.extra.REQUEST_PERMISSIONS_NAMES";
field public static final String EXTRA_REQUEST_PERMISSIONS_RESULTS = "android.content.pm.extra.REQUEST_PERMISSIONS_RESULTS";
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index 255b45e..1dfd4f9 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -1303,7 +1303,6 @@
public final class SQLiteDirectCursorDriver implements android.database.sqlite.SQLiteCursorDriver {
ctor public SQLiteDirectCursorDriver(android.database.sqlite.SQLiteDatabase, String, String, android.os.CancellationSignal);
- ctor public SQLiteDirectCursorDriver(@NonNull android.database.sqlite.SQLiteDatabase, @Nullable android.database.sqlite.SQLiteAuthorizer, @NonNull String, @Nullable String, @Nullable android.os.CancellationSignal);
method public void cursorClosed();
method public void cursorDeactivated();
method public void cursorRequeried(android.database.Cursor);
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index b229806..0bdf0a0 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -5445,14 +5445,14 @@
* the signature of the app declaring the permissions.
* </p>
* <p>
- * Call {@link #shouldShowRequestPermissionRationale(String)} before calling this API to
+ * Call {@link #shouldShowRequestPermissionRationale} before calling this API to
* check if the system recommends to show a rationale UI before asking for a permission.
* </p>
* <p>
* If your app does not have the requested permissions the user will be presented
* with UI for accepting them. After the user has accepted or rejected the
* requested permissions you will receive a callback on {@link
- * #onRequestPermissionsResult(int, String[], int[])} reporting whether the
+ * #onRequestPermissionsResult} reporting whether the
* permissions were granted or not.
* </p>
* <p>
@@ -5464,8 +5464,7 @@
* to grant and which to reject. Hence, you should be prepared that your activity
* may be paused and resumed. Further, granting some permissions may require
* a restart of you application. In such a case, the system will recreate the
- * activity stack before delivering the result to {@link
- * #onRequestPermissionsResult(int, String[], int[])}.
+ * activity stack before delivering the result to {@link #onRequestPermissionsResult}.
* </p>
* <p>
* When checking whether you have a permission you should use {@link
@@ -5475,7 +5474,7 @@
* You cannot request a permission if your activity sets {@link
* android.R.styleable#AndroidManifestActivity_noHistory noHistory} to
* <code>true</code> because in this case the activity would not receive
- * result callbacks including {@link #onRequestPermissionsResult(int, String[], int[])}.
+ * result callbacks including {@link #onRequestPermissionsResult}.
* </p>
* <p>
* The <a href="https://github.com/android/platform-samples/tree/main/samples/privacy/permissions">
@@ -5483,18 +5482,89 @@
* request permissions at run time.
* </p>
*
- * @param permissions The requested permissions. Must me non-null and not empty.
+ * @param permissions The requested permissions. Must be non-null and not empty.
* @param requestCode Application specific request code to match with a result
- * reported to {@link #onRequestPermissionsResult(int, String[], int[])}.
- * Should be >= 0.
+ * reported to {@link #onRequestPermissionsResult}.
+ * Should be >= 0.
*
* @throws IllegalArgumentException if requestCode is negative.
*
- * @see #onRequestPermissionsResult(int, String[], int[])
- * @see #checkSelfPermission(String)
- * @see #shouldShowRequestPermissionRationale(String)
+ * @see #onRequestPermissionsResult
+ * @see #checkSelfPermission
+ * @see #shouldShowRequestPermissionRationale
*/
public final void requestPermissions(@NonNull String[] permissions, int requestCode) {
+ requestPermissions(permissions, requestCode, getDeviceId());
+ }
+
+ /**
+ * Requests permissions to be granted to this application. These permissions
+ * must be requested in your manifest, they should not be granted to your app,
+ * and they should have protection level {@link
+ * android.content.pm.PermissionInfo#PROTECTION_DANGEROUS dangerous}, regardless
+ * whether they are declared by the platform or a third-party app.
+ * <p>
+ * Normal permissions {@link android.content.pm.PermissionInfo#PROTECTION_NORMAL}
+ * are granted at install time if requested in the manifest. Signature permissions
+ * {@link android.content.pm.PermissionInfo#PROTECTION_SIGNATURE} are granted at
+ * install time if requested in the manifest and the signature of your app matches
+ * the signature of the app declaring the permissions.
+ * </p>
+ * <p>
+ * Call {@link #shouldShowRequestPermissionRationale} before calling this API to
+ * check if the system recommends to show a rationale UI before asking for a permission.
+ * </p>
+ * <p>
+ * If your app does not have the requested permissions the user will be presented
+ * with UI for accepting them. After the user has accepted or rejected the
+ * requested permissions you will receive a callback on {@link #onRequestPermissionsResult}
+ * reporting whether the permissions were granted or not.
+ * </p>
+ * <p>
+ * Note that requesting a permission does not guarantee it will be granted and
+ * your app should be able to run without having this permission.
+ * </p>
+ * <p>
+ * This method may start an activity allowing the user to choose which permissions
+ * to grant and which to reject. Hence, you should be prepared that your activity
+ * may be paused and resumed. Further, granting some permissions may require
+ * a restart of you application. In such a case, the system will recreate the
+ * activity stack before delivering the result to {@link #onRequestPermissionsResult}.
+ * </p>
+ * <p>
+ * When checking whether you have a permission you should use {@link
+ * #checkSelfPermission(String)}.
+ * </p>
+ * <p>
+ * You cannot request a permission if your activity sets {@link
+ * android.R.styleable#AndroidManifestActivity_noHistory noHistory} to
+ * <code>true</code> because in this case the activity would not receive
+ * result callbacks including {@link #onRequestPermissionsResult}.
+ * </p>
+ * <p>
+ * The <a href="https://github.com/android/platform-samples/tree/main/samples/privacy/permissions">
+ * permissions samples</a> repo demonstrates how to use this method to
+ * request permissions at run time.
+ * </p>
+ *
+ * @param permissions The requested permissions. Must be non-null and not empty.
+ * @param requestCode Application specific request code to match with a result
+ * reported to {@link #onRequestPermissionsResult}.
+ * Should be >= 0.
+ * @param deviceId The app is requesting permissions for this device. The primary/physical
+ * device is assigned {@link Context#DEVICE_ID_DEFAULT}, and {@link
+ * android.companion.virtual.VirtualDeviceManager.VirtualDevice virtual devices}
+ * are assigned unique device Ids.
+ *
+ * @throws IllegalArgumentException if requestCode is negative.
+ *
+ * @see #onRequestPermissionsResult
+ * @see #checkSelfPermission
+ * @see #shouldShowRequestPermissionRationale
+ * @see Context#DEVICE_ID_DEFAULT
+ */
+ public final void requestPermissions(@NonNull String[] permissions, int requestCode,
+ int deviceId) {
if (requestCode < 0) {
throw new IllegalArgumentException("requestCode should be >= 0");
}
@@ -5502,7 +5572,7 @@
if (mHasCurrentPermissionsRequest) {
Log.w(TAG, "Can request only one set of permissions at a time");
// Dispatch the callback with empty arrays which means a cancellation.
- onRequestPermissionsResult(requestCode, new String[0], new int[0]);
+ onRequestPermissionsResult(requestCode, new String[0], new int[0], deviceId);
return;
}
@@ -5516,27 +5586,29 @@
}
}
- final Intent intent = getPackageManager().buildRequestPermissionsIntent(permissions);
+ PackageManager packageManager = getDeviceId() == deviceId ? getPackageManager()
+ : createDeviceContext(deviceId).getPackageManager();
+ final Intent intent = packageManager.buildRequestPermissionsIntent(permissions);
startActivityForResult(REQUEST_PERMISSIONS_WHO_PREFIX, intent, requestCode, null);
mHasCurrentPermissionsRequest = true;
}
/**
* Callback for the result from requesting permissions. This method
- * is invoked for every call on {@link #requestPermissions(String[], int)}.
+ * is invoked for every call on {@link #requestPermissions}
* <p>
* <strong>Note:</strong> It is possible that the permissions request interaction
* with the user is interrupted. In this case you will receive empty permissions
* and results arrays which should be treated as a cancellation.
* </p>
*
- * @param requestCode The request code passed in {@link #requestPermissions(String[], int)}.
+ * @param requestCode The request code passed in {@link #requestPermissions}.
* @param permissions The requested permissions. Never null.
- * @param grantResults The grant results for the corresponding permissions
- * which is either {@link android.content.pm.PackageManager#PERMISSION_GRANTED}
- * or {@link android.content.pm.PackageManager#PERMISSION_DENIED}. Never null.
+ * @param grantResults The grant results for the corresponding permissions which is either
+ * {@link android.content.pm.PackageManager#PERMISSION_GRANTED} or
+ * {@link android.content.pm.PackageManager#PERMISSION_DENIED}. Never null.
*
- * @see #requestPermissions(String[], int)
+ * @see #requestPermissions
*/
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults) {
@@ -5544,20 +5616,66 @@
}
/**
+ * Callback for the result from requesting permissions. This method
+ * is invoked for every call on {@link #requestPermissions}.
+ * <p>
+ * <strong>Note:</strong> It is possible that the permissions request interaction
+ * with the user is interrupted. In this case you will receive empty permissions
+ * and results arrays which should be treated as a cancellation.
+ * </p>
+ *
+ * @param requestCode The request code passed in {@link #requestPermissions}.
+ * @param permissions The requested permissions. Never null.
+ * @param grantResults The grant results for the corresponding permissions which is either
+ * {@link android.content.pm.PackageManager#PERMISSION_GRANTED} or
+ * {@link android.content.pm.PackageManager#PERMISSION_DENIED}. Never null.
+ * @param deviceId The deviceId for which permissions were requested. The primary/physical
+ * device is assigned {@link Context#DEVICE_ID_DEFAULT}, and {@link
+ * android.companion.virtual.VirtualDeviceManager.VirtualDevice virtual devices}
+ * are assigned unique device Ids.
+ *
+ * @see #requestPermissions
+ */
+ public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
+ @NonNull int[] grantResults, int deviceId) {
+ onRequestPermissionsResult(requestCode, permissions, grantResults);
+ }
+
+ /**
* Gets whether you should show UI with rationale before requesting a permission.
*
* @param permission A permission your app wants to request.
* @return Whether you should show permission rationale UI.
*
- * @see #checkSelfPermission(String)
- * @see #requestPermissions(String[], int)
- * @see #onRequestPermissionsResult(int, String[], int[])
+ * @see #checkSelfPermission
+ * @see #requestPermissions
+ * @see #onRequestPermissionsResult
*/
public boolean shouldShowRequestPermissionRationale(@NonNull String permission) {
return getPackageManager().shouldShowRequestPermissionRationale(permission);
}
/**
+ * Gets whether you should show UI with rationale before requesting a permission.
+ *
+ * @param permission A permission your app wants to request.
+ * @param deviceId The app is requesting permissions for this device. The primary/physical
+ * device is assigned {@link Context#DEVICE_ID_DEFAULT}, and {@link
+ * android.companion.virtual.VirtualDeviceManager.VirtualDevice virtual devices}
+ * are assigned unique device Ids.
+ * @return Whether you should show permission rationale UI.
+ *
+ * @see #checkSelfPermission
+ * @see #requestPermissions
+ * @see #onRequestPermissionsResult
+ */
+ public boolean shouldShowRequestPermissionRationale(@NonNull String permission, int deviceId) {
+ final PackageManager packageManager = getDeviceId() == deviceId ? getPackageManager()
+ : createDeviceContext(deviceId).getPackageManager();
+ return packageManager.shouldShowRequestPermissionRationale(permission);
+ }
+
+ /**
* Same as calling {@link #startActivityForResult(Intent, int, Bundle)}
* with no options.
*
@@ -9107,12 +9225,15 @@
private void dispatchRequestPermissionsResult(int requestCode, Intent data) {
mHasCurrentPermissionsRequest = false;
- // If the package installer crashed we may have not data - best effort.
+ // If the package installer crashed we may have no data - best effort.
String[] permissions = (data != null) ? data.getStringArrayExtra(
PackageManager.EXTRA_REQUEST_PERMISSIONS_NAMES) : new String[0];
final int[] grantResults = (data != null) ? data.getIntArrayExtra(
PackageManager.EXTRA_REQUEST_PERMISSIONS_RESULTS) : new int[0];
- onRequestPermissionsResult(requestCode, permissions, grantResults);
+ final int deviceId = (data != null) ? data.getIntExtra(
+ PackageManager.EXTRA_REQUEST_PERMISSIONS_DEVICE_ID, Context.DEVICE_ID_DEFAULT
+ ) : Context.DEVICE_ID_DEFAULT;
+ onRequestPermissionsResult(requestCode, permissions, grantResults, deviceId);
}
private void dispatchRequestPermissionsResultToFragment(int requestCode, Intent data,
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 0ba56b9..f4a29ed 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -942,6 +942,13 @@
}
@Override
+ public Intent buildRequestPermissionsIntent(@NonNull String[] permissions) {
+ Intent intent = super.buildRequestPermissionsIntent(permissions);
+ intent.putExtra(EXTRA_REQUEST_PERMISSIONS_DEVICE_ID, mContext.getDeviceId());
+ return intent;
+ }
+
+ @Override
public CharSequence getBackgroundPermissionOptionLabel() {
try {
diff --git a/core/java/android/app/WallpaperColors.java b/core/java/android/app/WallpaperColors.java
index b710644..5f5a7df 100644
--- a/core/java/android/app/WallpaperColors.java
+++ b/core/java/android/app/WallpaperColors.java
@@ -28,6 +28,7 @@
import android.os.Parcel;
import android.os.Parcelable;
import android.os.SystemProperties;
+import android.os.Trace;
import android.util.Log;
import android.util.MathUtils;
import android.util.Size;
@@ -144,6 +145,7 @@
throw new IllegalArgumentException("Drawable cannot be null");
}
+ Trace.beginSection("WallpaperColors#fromDrawable");
Rect initialBounds = drawable.copyBounds();
int width = drawable.getIntrinsicWidth();
int height = drawable.getIntrinsicHeight();
@@ -165,6 +167,7 @@
bitmap.recycle();
drawable.setBounds(initialBounds);
+ Trace.endSection();
return colors;
}
@@ -195,7 +198,7 @@
public static WallpaperColors fromBitmap(@NonNull Bitmap bitmap,
@FloatRange (from = 0f, to = 1f) float dimAmount) {
Objects.requireNonNull(bitmap, "Bitmap can't be null");
-
+ Trace.beginSection("WallpaperColors#fromBitmap");
final int bitmapArea = bitmap.getWidth() * bitmap.getHeight();
boolean shouldRecycle = false;
if (bitmapArea > MAX_WALLPAPER_EXTRACTION_AREA) {
@@ -247,6 +250,7 @@
bitmap.recycle();
}
+ Trace.endSection();
return new WallpaperColors(populationByColor, HINT_FROM_BITMAP | hints);
}
@@ -462,7 +466,7 @@
* Gets the most visually representative color of the wallpaper.
* "Visually representative" means easily noticeable in the image,
* probably happening at high frequency.
- *
+ *fromBitmap
* @return A color.
*/
public @NonNull Color getPrimaryColor() {
@@ -545,6 +549,7 @@
return 0;
}
+ Trace.beginSection("WallpaperColors#calculateDarkHints");
dimAmount = MathUtils.saturate(dimAmount);
int[] pixels = new int[source.getWidth() * source.getHeight()];
double totalLuminance = 0;
@@ -607,6 +612,7 @@
" maxD: " + maxDarkPixels + " numPixels: " + pixels.length);
}
+ Trace.endSection();
return hints;
}
diff --git a/core/java/android/app/smartspace/SmartspaceAction.java b/core/java/android/app/smartspace/SmartspaceAction.java
index f17b044..4475fc5 100644
--- a/core/java/android/app/smartspace/SmartspaceAction.java
+++ b/core/java/android/app/smartspace/SmartspaceAction.java
@@ -348,6 +348,10 @@
*/
@NonNull
public SmartspaceAction build() {
+ if (mIcon != null) {
+ mIcon.convertToAshmem();
+ }
+
return new SmartspaceAction(mId, mIcon, mTitle, mSubtitle, mContentDescription,
mPendingIntent, mIntent, mUserHandle, mExtras);
}
diff --git a/core/java/android/app/smartspace/uitemplatedata/Icon.java b/core/java/android/app/smartspace/uitemplatedata/Icon.java
index 6bdc926..b9d90bf 100644
--- a/core/java/android/app/smartspace/uitemplatedata/Icon.java
+++ b/core/java/android/app/smartspace/uitemplatedata/Icon.java
@@ -171,6 +171,7 @@
*/
@NonNull
public Icon build() {
+ mIcon.convertToAshmem();
return new Icon(mIcon, mContentDescription, mShouldTint);
}
}
diff --git a/core/java/android/companion/CompanionDeviceManager.java b/core/java/android/companion/CompanionDeviceManager.java
index 2e67225..4dea4a7 100644
--- a/core/java/android/companion/CompanionDeviceManager.java
+++ b/core/java/android/companion/CompanionDeviceManager.java
@@ -36,7 +36,6 @@
import android.app.PendingIntent;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
-import android.companion.utils.FeatureUtils;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -1227,11 +1226,6 @@
@Nullable
public IntentSender buildPermissionTransferUserConsentIntent(int associationId)
throws DeviceNotAssociatedException {
- if (!FeatureUtils.isPermSyncEnabled()) {
- throw new UnsupportedOperationException("Calling"
- + " buildPermissionTransferUserConsentIntent, but this API is disabled by the"
- + " system.");
- }
try {
PendingIntent pendingIntent = mService.buildPermissionTransferUserConsentIntent(
mContext.getOpPackageName(),
@@ -1264,10 +1258,6 @@
@Deprecated
@UserHandleAware
public void startSystemDataTransfer(int associationId) throws DeviceNotAssociatedException {
- if (!FeatureUtils.isPermSyncEnabled()) {
- throw new UnsupportedOperationException("Calling startSystemDataTransfer, but this API"
- + " is disabled by the system.");
- }
try {
mService.startSystemDataTransfer(mContext.getOpPackageName(), mContext.getUserId(),
associationId, null);
@@ -1300,10 +1290,6 @@
@NonNull Executor executor,
@NonNull OutcomeReceiver<Void, CompanionException> result)
throws DeviceNotAssociatedException {
- if (!FeatureUtils.isPermSyncEnabled()) {
- throw new UnsupportedOperationException("Calling startSystemDataTransfer, but this API"
- + " is disabled by the system.");
- }
try {
mService.startSystemDataTransfer(mContext.getOpPackageName(), mContext.getUserId(),
associationId, new SystemDataTransferCallbackProxy(executor, result));
diff --git a/core/java/android/companion/OWNERS b/core/java/android/companion/OWNERS
index 0348fe2..54d9c24 100644
--- a/core/java/android/companion/OWNERS
+++ b/core/java/android/companion/OWNERS
@@ -1,3 +1,5 @@
evanxinchen@google.com
guojing@google.com
-raphk@google.com
\ No newline at end of file
+jeremyns@google.com
+raphk@google.com
+yukl@google.com
\ No newline at end of file
diff --git a/core/java/android/companion/utils/FeatureUtils.java b/core/java/android/companion/utils/FeatureUtils.java
index 157eef8..a382e09 100644
--- a/core/java/android/companion/utils/FeatureUtils.java
+++ b/core/java/android/companion/utils/FeatureUtils.java
@@ -16,6 +16,7 @@
package android.companion.utils;
+import android.os.Binder;
import android.os.Build;
import android.provider.DeviceConfig;
@@ -31,8 +32,19 @@
private static final String PROPERTY_PERM_SYNC_ENABLED = "perm_sync_enabled";
public static boolean isPermSyncEnabled() {
- return Build.isDebuggable() || DeviceConfig.getBoolean(NAMESPACE_COMPANION,
- PROPERTY_PERM_SYNC_ENABLED, false);
+ // Permissions sync is always enabled in debuggable mode.
+ if (Build.isDebuggable()) {
+ return true;
+ }
+
+ // Clear app identity to read the device config for feature flag.
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ return DeviceConfig.getBoolean(NAMESPACE_COMPANION,
+ PROPERTY_PERM_SYNC_ENABLED, false);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
}
private FeatureUtils() {
diff --git a/core/java/android/companion/virtual/VirtualDeviceManager.java b/core/java/android/companion/virtual/VirtualDeviceManager.java
index 060a5c8..c10e898 100644
--- a/core/java/android/companion/virtual/VirtualDeviceManager.java
+++ b/core/java/android/companion/virtual/VirtualDeviceManager.java
@@ -102,6 +102,13 @@
public static final String EXTRA_VIRTUAL_DEVICE_ID =
"android.companion.virtual.extra.VIRTUAL_DEVICE_ID";
+ /**
+ * A representation of an invalid CDM association ID. Association IDs must be positive.
+ *
+ * @hide
+ */
+ public static final int ASSOCIATION_ID_INVALID = -1;
+
/** @hide */
@Retention(RetentionPolicy.SOURCE)
@IntDef(
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index c221d72..06635ee 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -481,7 +481,7 @@
* If binding from a top app and its target SDK version is at or above
* {@link android.os.Build.VERSION_CODES#R}, the app needs to
* explicitly use BIND_INCLUDE_CAPABILITIES flag to pass all capabilities to the service so the
- * other app can have while-use-use access such as location, camera, microphone from background.
+ * other app can have while-in-use access such as location, camera, microphone from background.
* If binding from a top app and its target SDK version is below
* {@link android.os.Build.VERSION_CODES#R}, BIND_INCLUDE_CAPABILITIES is implicit.
*/
@@ -678,7 +678,7 @@
* </p>
*
* <em>This flag is NOT compatible with {@link BindServiceFlags}. If you need to use
- * {@link BindServiceFlags}, you must use {@link #BIND_EXTERNAL_SERVICE_LONG} instead.
+ * {@link BindServiceFlags}, you must use {@link #BIND_EXTERNAL_SERVICE_LONG} instead.</em>
*/
public static final int BIND_EXTERNAL_SERVICE = 0x80000000;
diff --git a/core/java/android/content/pm/AppSearchShortcutInfo.java b/core/java/android/content/pm/AppSearchShortcutInfo.java
index fb41b89..225b3d3 100644
--- a/core/java/android/content/pm/AppSearchShortcutInfo.java
+++ b/core/java/android/content/pm/AppSearchShortcutInfo.java
@@ -445,7 +445,7 @@
@VisibleForTesting
public static class Builder extends GenericDocument.Builder<Builder> {
- private List<String> mFlags = new ArrayList<>(1);
+ private final List<String> mFlags = new ArrayList<>(1);
public Builder(String packageName, String id) {
super(/*namespace=*/ packageName, id, SCHEMA_TYPE);
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index 3487e0b..f0b99f1 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -67,7 +67,7 @@
* <application> tag.
*/
public class ApplicationInfo extends PackageItemInfo implements Parcelable {
- private static ForBoolean sForBoolean = Parcelling.Cache.getOrCreate(ForBoolean.class);
+ private static final ForBoolean sForBoolean = Parcelling.Cache.getOrCreate(ForBoolean.class);
private static final Parcelling.BuiltIn.ForStringSet sForStringSet =
Parcelling.Cache.getOrCreate(Parcelling.BuiltIn.ForStringSet.class);
@@ -1892,7 +1892,7 @@
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
private final Collator sCollator = Collator.getInstance();
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
- private PackageManager mPM;
+ private final PackageManager mPM;
}
public ApplicationInfo() {
diff --git a/core/java/android/content/pm/Attribution.java b/core/java/android/content/pm/Attribution.java
index 989a5b9..3649249 100644
--- a/core/java/android/content/pm/Attribution.java
+++ b/core/java/android/content/pm/Attribution.java
@@ -33,7 +33,7 @@
/**
* The tag of this attribution. From the <manifest> tag's "tag" attribute
*/
- private @NonNull String mTag;
+ private final @NonNull String mTag;
/**
* The resource ID of the label of the attribution From the <manifest> tag's "label"
@@ -43,7 +43,7 @@
- // Code below generated by codegen v1.0.22.
+ // Code below generated by codegen v1.0.23.
//
// DO NOT MODIFY!
// CHECKSTYLE:OFF Generated code
@@ -146,10 +146,10 @@
};
@DataClass.Generated(
- time = 1608139558081L,
- codegenVersion = "1.0.22",
+ time = 1683311736586L,
+ codegenVersion = "1.0.23",
sourceFile = "frameworks/base/core/java/android/content/pm/Attribution.java",
- inputSignatures = "private @android.annotation.NonNull java.lang.String mTag\nprivate final @android.annotation.IdRes int mLabel\nclass Attribution extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genHiddenConstructor=true)")
+ inputSignatures = "private final @android.annotation.NonNull java.lang.String mTag\nprivate final @android.annotation.IdRes int mLabel\nclass Attribution extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genHiddenConstructor=true)")
@Deprecated
private void __metadata() {}
diff --git a/core/java/android/content/pm/BaseParceledListSlice.java b/core/java/android/content/pm/BaseParceledListSlice.java
index 37b1778..cc4e9c8 100644
--- a/core/java/android/content/pm/BaseParceledListSlice.java
+++ b/core/java/android/content/pm/BaseParceledListSlice.java
@@ -42,8 +42,8 @@
* @hide
*/
abstract class BaseParceledListSlice<T> implements Parcelable {
- private static String TAG = "ParceledListSlice";
- private static boolean DEBUG = false;
+ private static final String TAG = "ParceledListSlice";
+ private static final boolean DEBUG = false;
/*
* TODO get this number from somewhere else. For now set it to a quarter of
diff --git a/core/java/android/content/pm/CapabilityParams.java b/core/java/android/content/pm/CapabilityParams.java
index 7239bac..60e8123 100644
--- a/core/java/android/content/pm/CapabilityParams.java
+++ b/core/java/android/content/pm/CapabilityParams.java
@@ -172,7 +172,7 @@
@NonNull
private final String mKey;
@NonNull
- private String mPrimaryValue;
+ private final String mPrimaryValue;
@NonNull
private Set<String> mAliases;
diff --git a/core/java/android/content/pm/IncrementalStatesInfo.java b/core/java/android/content/pm/IncrementalStatesInfo.java
index f15afdf..7098249 100644
--- a/core/java/android/content/pm/IncrementalStatesInfo.java
+++ b/core/java/android/content/pm/IncrementalStatesInfo.java
@@ -24,8 +24,8 @@
* @hide
*/
public class IncrementalStatesInfo implements Parcelable {
- private boolean mIsLoading;
- private float mProgress;
+ private final boolean mIsLoading;
+ private final float mProgress;
private long mLoadingCompletedTime;
diff --git a/core/java/android/content/pm/KeySet.java b/core/java/android/content/pm/KeySet.java
index fd459e6..3da5bff 100644
--- a/core/java/android/content/pm/KeySet.java
+++ b/core/java/android/content/pm/KeySet.java
@@ -29,7 +29,7 @@
*/
public class KeySet implements Parcelable {
- private IBinder token;
+ private final IBinder token;
/** @hide */
public KeySet(IBinder token) {
diff --git a/core/java/android/content/pm/LauncherApps.java b/core/java/android/content/pm/LauncherApps.java
index d6592d5..3165e29 100644
--- a/core/java/android/content/pm/LauncherApps.java
+++ b/core/java/android/content/pm/LauncherApps.java
@@ -1737,7 +1737,8 @@
mCallbacks.add(toAdd);
}
- private IOnAppsChangedListener.Stub mAppsChangedListener = new IOnAppsChangedListener.Stub() {
+ private final IOnAppsChangedListener.Stub mAppsChangedListener =
+ new IOnAppsChangedListener.Stub() {
@Override
public void onPackageRemoved(UserHandle user, String packageName)
@@ -1872,7 +1873,7 @@
private static final int MSG_SHORTCUT_CHANGED = 8;
private static final int MSG_LOADING_PROGRESS_CHANGED = 9;
- private LauncherApps.Callback mCallback;
+ private final LauncherApps.Callback mCallback;
private static class CallbackInfo {
String[] packageNames;
diff --git a/core/java/android/content/pm/PackageItemInfo.java b/core/java/android/content/pm/PackageItemInfo.java
index 2bac066..bb978e0 100644
--- a/core/java/android/content/pm/PackageItemInfo.java
+++ b/core/java/android/content/pm/PackageItemInfo.java
@@ -502,6 +502,6 @@
}
private final Collator sCollator = Collator.getInstance();
- private PackageManager mPM;
+ private final PackageManager mPM;
}
}
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index dca4544..292f51bf 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -4612,6 +4612,19 @@
"android.content.pm.extra.REQUEST_PERMISSIONS_NAMES";
/**
+ * The deviceId for which the permissions are requested, {@link Context#DEVICE_ID_DEFAULT}
+ * is the default device ID.
+ * <p>
+ * <strong>Type:</strong> int
+ * </p>
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final String EXTRA_REQUEST_PERMISSIONS_DEVICE_ID =
+ "android.content.pm.extra.REQUEST_PERMISSIONS_DEVICE_ID";
+
+ /**
* The results from the permissions request.
* <p>
* <strong>Type:</strong> int[] of #PermissionResult
@@ -6592,7 +6605,7 @@
@UnsupportedAppUsage
public Intent buildRequestPermissionsIntent(@NonNull String[] permissions) {
if (ArrayUtils.isEmpty(permissions)) {
- throw new IllegalArgumentException("permission cannot be null or empty");
+ throw new IllegalArgumentException("permission cannot be null or empty");
}
Intent intent = new Intent(ACTION_REQUEST_PERMISSIONS);
intent.putExtra(EXTRA_REQUEST_PERMISSIONS_NAMES, permissions);
diff --git a/core/java/android/content/pm/PermissionInfo.java b/core/java/android/content/pm/PermissionInfo.java
index 9114ea3..cdda12e 100644
--- a/core/java/android/content/pm/PermissionInfo.java
+++ b/core/java/android/content/pm/PermissionInfo.java
@@ -489,7 +489,8 @@
*/
public @Nullable CharSequence nonLocalizedDescription;
- private static ForStringSet sForStringSet = Parcelling.Cache.getOrCreate(ForStringSet.class);
+ private static final ForStringSet sForStringSet =
+ Parcelling.Cache.getOrCreate(ForStringSet.class);
/**
* A {@link Set} of trusted signing certificate digests. If this permission has the {@link
diff --git a/core/java/android/content/pm/ResolveInfo.java b/core/java/android/content/pm/ResolveInfo.java
index 02a4980..36c03fd 100644
--- a/core/java/android/content/pm/ResolveInfo.java
+++ b/core/java/android/content/pm/ResolveInfo.java
@@ -586,6 +586,6 @@
}
private final Collator mCollator = Collator.getInstance();
- private PackageManager mPM;
+ private final PackageManager mPM;
}
}
diff --git a/core/java/android/content/pm/parsing/result/ParseTypeImpl.java b/core/java/android/content/pm/parsing/result/ParseTypeImpl.java
index c323704..8343c92 100644
--- a/core/java/android/content/pm/parsing/result/ParseTypeImpl.java
+++ b/core/java/android/content/pm/parsing/result/ParseTypeImpl.java
@@ -41,7 +41,7 @@
public static final boolean DEBUG_THROW_ALL_ERRORS = false;
@NonNull
- private Callback mCallback;
+ private final Callback mCallback;
private Object mResult;
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index 885060f..c3d5b71 100644
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -2003,13 +2003,25 @@
private int mHashCode = 0;
- private boolean containsValue(int resId, boolean force) {
+ private int findValue(int resId, boolean force) {
for (int i = 0; i < mCount; ++i) {
if (mResId[i] == resId && mForce[i] == force) {
- return true;
+ return i;
}
}
- return false;
+ return -1;
+ }
+
+ private void moveToLast(int index) {
+ if (index < 0 || index >= mCount - 1) {
+ return;
+ }
+ final int id = mResId[index];
+ final boolean force = mForce[index];
+ System.arraycopy(mResId, index + 1, mResId, index, mCount - index - 1);
+ mResId[mCount - 1] = id;
+ System.arraycopy(mForce, index + 1, mForce, index, mCount - index - 1);
+ mForce[mCount - 1] = force;
}
public void append(int resId, boolean force) {
@@ -2022,15 +2034,17 @@
}
// Some apps tend to keep adding same resources over and over, let's protect from it.
- if (containsValue(resId, force)) {
- return;
+ // Note: the order still matters, as the values that come later override the earlier
+ // ones.
+ final int index = findValue(resId, force);
+ if (index >= 0) {
+ moveToLast(index);
+ } else {
+ mResId = GrowingArrayUtils.append(mResId, mCount, resId);
+ mForce = GrowingArrayUtils.append(mForce, mCount, force);
+ mCount++;
+ mHashCode = 31 * (31 * mHashCode + resId) + (force ? 1 : 0);
}
-
- mResId = GrowingArrayUtils.append(mResId, mCount, resId);
- mForce = GrowingArrayUtils.append(mForce, mCount, force);
- mCount++;
-
- mHashCode = 31 * (31 * mHashCode + resId) + (force ? 1 : 0);
}
/**
diff --git a/core/java/android/database/sqlite/SQLiteAuthorizer.java b/core/java/android/database/sqlite/SQLiteAuthorizer.java
deleted file mode 100644
index a2bf898..0000000
--- a/core/java/android/database/sqlite/SQLiteAuthorizer.java
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.database.sqlite;
-
-import android.annotation.IntDef;
-import android.annotation.Nullable;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Authorizer which is consulted during compilation of a SQL statement.
- * <p>
- * During compilation, this callback will be invoked to determine if each action
- * requested by the SQL statement is allowed.
- * <p>
- * This can be useful to dynamically block interaction with private, internal,
- * or otherwise sensitive columns or tables inside a database, such as when
- * compiling an untrusted SQL statement.
- */
-public interface SQLiteAuthorizer {
- /** @hide */
- @IntDef(prefix = { "SQLITE_AUTHORIZER_RESULT_" }, value = {
- SQLITE_AUTHORIZER_RESULT_OK,
- SQLITE_AUTHORIZER_RESULT_DENY,
- SQLITE_AUTHORIZER_RESULT_IGNORE,
- })
- @Retention(RetentionPolicy.SOURCE)
- @interface AuthorizerResult {}
-
- /** @hide */
- @IntDef(prefix = { "SQLITE_ACTION_" }, value = {
- SQLITE_ACTION_CREATE_INDEX,
- SQLITE_ACTION_CREATE_TABLE,
- SQLITE_ACTION_CREATE_TEMP_INDEX,
- SQLITE_ACTION_CREATE_TEMP_TABLE,
- SQLITE_ACTION_CREATE_TEMP_TRIGGER,
- SQLITE_ACTION_CREATE_TEMP_VIEW,
- SQLITE_ACTION_CREATE_TRIGGER,
- SQLITE_ACTION_CREATE_VIEW,
- SQLITE_ACTION_DELETE,
- SQLITE_ACTION_DROP_INDEX,
- SQLITE_ACTION_DROP_TABLE,
- SQLITE_ACTION_DROP_TEMP_INDEX,
- SQLITE_ACTION_DROP_TEMP_TABLE,
- SQLITE_ACTION_DROP_TEMP_TRIGGER,
- SQLITE_ACTION_DROP_TEMP_VIEW,
- SQLITE_ACTION_DROP_TRIGGER,
- SQLITE_ACTION_DROP_VIEW,
- SQLITE_ACTION_INSERT,
- SQLITE_ACTION_PRAGMA,
- SQLITE_ACTION_READ,
- SQLITE_ACTION_SELECT,
- SQLITE_ACTION_TRANSACTION,
- SQLITE_ACTION_UPDATE,
- SQLITE_ACTION_ATTACH,
- SQLITE_ACTION_DETACH,
- SQLITE_ACTION_ALTER_TABLE,
- SQLITE_ACTION_REINDEX,
- SQLITE_ACTION_ANALYZE,
- SQLITE_ACTION_CREATE_VTABLE,
- SQLITE_ACTION_DROP_VTABLE,
- SQLITE_ACTION_FUNCTION,
- SQLITE_ACTION_SAVEPOINT,
- SQLITE_ACTION_RECURSIVE,
- })
- @Retention(RetentionPolicy.SOURCE)
- @interface AuthorizerAction {}
-
- /** Successful result */
- int SQLITE_AUTHORIZER_RESULT_OK = 0;
- /** Abort the SQL statement with an error */
- int SQLITE_AUTHORIZER_RESULT_DENY = 1;
- /** Don't allow access, but don't generate an error */
- int SQLITE_AUTHORIZER_RESULT_IGNORE = 2;
-
- /** Authorizer action for {@code CREATE INDEX} */
- int SQLITE_ACTION_CREATE_INDEX = 1;
- /** Authorizer action for {@code CREATE TABLE} */
- int SQLITE_ACTION_CREATE_TABLE = 2;
- /** Authorizer action for {@code CREATE TEMP INDEX} */
- int SQLITE_ACTION_CREATE_TEMP_INDEX = 3;
- /** Authorizer action for {@code CREATE TEMP TABLE} */
- int SQLITE_ACTION_CREATE_TEMP_TABLE = 4;
- /** Authorizer action for {@code CREATE TEMP TRIGGER} */
- int SQLITE_ACTION_CREATE_TEMP_TRIGGER = 5;
- /** Authorizer action for {@code CREATE TEMP VIEW} */
- int SQLITE_ACTION_CREATE_TEMP_VIEW = 6;
- /** Authorizer action for {@code CREATE TRIGGER} */
- int SQLITE_ACTION_CREATE_TRIGGER = 7;
- /** Authorizer action for {@code CREATE VIEW} */
- int SQLITE_ACTION_CREATE_VIEW = 8;
- /** Authorizer action for {@code DELETE} */
- int SQLITE_ACTION_DELETE = 9;
- /** Authorizer action for {@code DROP INDEX} */
- int SQLITE_ACTION_DROP_INDEX = 10;
- /** Authorizer action for {@code DROP TABLE} */
- int SQLITE_ACTION_DROP_TABLE = 11;
- /** Authorizer action for {@code DROP TEMP INDEX} */
- int SQLITE_ACTION_DROP_TEMP_INDEX = 12;
- /** Authorizer action for {@code DROP TEMP TABLE} */
- int SQLITE_ACTION_DROP_TEMP_TABLE = 13;
- /** Authorizer action for {@code DROP TEMP TRIGGER} */
- int SQLITE_ACTION_DROP_TEMP_TRIGGER = 14;
- /** Authorizer action for {@code DROP TEMP VIEW} */
- int SQLITE_ACTION_DROP_TEMP_VIEW = 15;
- /** Authorizer action for {@code DROP TRIGGER} */
- int SQLITE_ACTION_DROP_TRIGGER = 16;
- /** Authorizer action for {@code DROP VIEW} */
- int SQLITE_ACTION_DROP_VIEW = 17;
- /** Authorizer action for {@code INSERT} */
- int SQLITE_ACTION_INSERT = 18;
- /** Authorizer action for {@code PRAGMA} */
- int SQLITE_ACTION_PRAGMA = 19;
- /** Authorizer action for read access on a specific table and column */
- int SQLITE_ACTION_READ = 20;
- /** Authorizer action for {@code SELECT} */
- int SQLITE_ACTION_SELECT = 21;
- /** Authorizer action for transaction operations */
- int SQLITE_ACTION_TRANSACTION = 22;
- /** Authorizer action for {@code UPDATE} */
- int SQLITE_ACTION_UPDATE = 23;
- /** Authorizer action for {@code ATTACH} */
- int SQLITE_ACTION_ATTACH = 24;
- /** Authorizer action for {@code DETACH} */
- int SQLITE_ACTION_DETACH = 25;
- /** Authorizer action for {@code ALTER TABLE} */
- int SQLITE_ACTION_ALTER_TABLE = 26;
- /** Authorizer action for {@code REINDEX} */
- int SQLITE_ACTION_REINDEX = 27;
- /** Authorizer action for {@code ANALYZE} */
- int SQLITE_ACTION_ANALYZE = 28;
- /** Authorizer action for {@code CREATE VIRTUAL TABLE} */
- int SQLITE_ACTION_CREATE_VTABLE = 29;
- /** Authorizer action for {@code DROP VIRTUAL TABLE} */
- int SQLITE_ACTION_DROP_VTABLE = 30;
- /** Authorizer action for invocation of a function */
- int SQLITE_ACTION_FUNCTION = 31;
- /** Authorizer action for savepoint operations */
- int SQLITE_ACTION_SAVEPOINT = 32;
- /** Authorizer action for recursive operations */
- int SQLITE_ACTION_RECURSIVE = 33;
-
- /**
- * Test if the given action should be allowed.
- *
- * @param action The action requested by the SQL statement currently being
- * compiled.
- * @param arg3 Optional argument relevant to the given action.
- * @param arg4 Optional argument relevant to the given action.
- * @param arg5 Optional argument relevant to the given action.
- * @param arg6 Optional argument relevant to the given action.
- * @return {@link SQLiteConstants#SQLITE_AUTHORIZER_RESULT_OK} to allow the action,
- * {@link SQLiteConstants#SQLITE_AUTHORIZER_RESULT_IGNORE} to disallow the specific
- * action but allow the SQL statement to continue to be compiled, or
- * {@link SQLiteConstants#SQLITE_AUTHORIZER_RESULT_DENY} to cause the entire SQL
- * statement to be rejected with an error.
- * @see <a href="https://www.sqlite.org/c3ref/c_alter_table.html">Upstream
- * SQLite documentation</a> that describes possible actions and their
- * arguments.
- */
- @AuthorizerResult int onAuthorize(@AuthorizerAction int action, @Nullable String arg3,
- @Nullable String arg4, @Nullable String arg5, @Nullable String arg6);
-}
diff --git a/core/java/android/database/sqlite/SQLiteConnection.java b/core/java/android/database/sqlite/SQLiteConnection.java
index b757cd9..8323f7c 100644
--- a/core/java/android/database/sqlite/SQLiteConnection.java
+++ b/core/java/android/database/sqlite/SQLiteConnection.java
@@ -17,7 +17,7 @@
package android.database.sqlite;
import android.annotation.NonNull;
-import android.annotation.Nullable;
+
import android.database.Cursor;
import android.database.CursorWindow;
import android.database.DatabaseUtils;
@@ -33,10 +33,8 @@
import android.util.LruCache;
import android.util.Pair;
import android.util.Printer;
-
import dalvik.system.BlockGuard;
import dalvik.system.CloseGuard;
-
import java.io.File;
import java.io.IOException;
import java.lang.ref.Reference;
@@ -130,10 +128,9 @@
private int mCancellationSignalAttachCount;
private static native long nativeOpen(String path, int openFlags, String label,
- int lookasideSlotSize, int lookasideSlotCount);
+ boolean enableTrace, boolean enableProfile, int lookasideSlotSize,
+ int lookasideSlotCount);
private static native void nativeClose(long connectionPtr);
- private static native void nativeSetAuthorizer(long connectionPtr,
- SQLiteAuthorizer authorizer);
private static native void nativeRegisterCustomScalarFunction(long connectionPtr,
String name, UnaryOperator<String> function);
private static native void nativeRegisterCustomAggregateFunction(long connectionPtr,
@@ -228,7 +225,9 @@
final String file = mConfiguration.path;
final int cookie = mRecentOperations.beginOperation("open", null, null);
try {
- mConnectionPtr = nativeOpen(file, mConfiguration.openFlags, mConfiguration.label,
+ mConnectionPtr = nativeOpen(file, mConfiguration.openFlags,
+ mConfiguration.label,
+ NoPreloadHolder.DEBUG_SQL_STATEMENTS, NoPreloadHolder.DEBUG_SQL_TIME,
mConfiguration.lookasideSlotSize, mConfiguration.lookasideSlotCount);
} catch (SQLiteCantOpenDatabaseException e) {
final StringBuilder message = new StringBuilder("Cannot open database '")
@@ -302,9 +301,9 @@
private void setPageSize() {
if (!mConfiguration.isInMemoryDb() && !mIsReadOnlyConnection) {
final long newValue = SQLiteGlobal.getDefaultPageSize();
- long value = executeForLong(null, "PRAGMA page_size", null, null);
+ long value = executeForLong("PRAGMA page_size", null, null);
if (value != newValue) {
- execute(null, "PRAGMA page_size=" + newValue, null, null);
+ execute("PRAGMA page_size=" + newValue, null, null);
}
}
}
@@ -312,9 +311,9 @@
private void setAutoCheckpointInterval() {
if (!mConfiguration.isInMemoryDb() && !mIsReadOnlyConnection) {
final long newValue = SQLiteGlobal.getWALAutoCheckpoint();
- long value = executeForLong(null, "PRAGMA wal_autocheckpoint", null, null);
+ long value = executeForLong("PRAGMA wal_autocheckpoint", null, null);
if (value != newValue) {
- executeForLong(null, "PRAGMA wal_autocheckpoint=" + newValue, null, null);
+ executeForLong("PRAGMA wal_autocheckpoint=" + newValue, null, null);
}
}
}
@@ -322,9 +321,9 @@
private void setJournalSizeLimit() {
if (!mConfiguration.isInMemoryDb() && !mIsReadOnlyConnection) {
final long newValue = SQLiteGlobal.getJournalSizeLimit();
- long value = executeForLong(null, "PRAGMA journal_size_limit", null, null);
+ long value = executeForLong("PRAGMA journal_size_limit", null, null);
if (value != newValue) {
- executeForLong(null, "PRAGMA journal_size_limit=" + newValue, null, null);
+ executeForLong("PRAGMA journal_size_limit=" + newValue, null, null);
}
}
}
@@ -332,9 +331,9 @@
private void setForeignKeyModeFromConfiguration() {
if (!mIsReadOnlyConnection) {
final long newValue = mConfiguration.foreignKeyConstraintsEnabled ? 1 : 0;
- long value = executeForLong(null, "PRAGMA foreign_keys", null, null);
+ long value = executeForLong("PRAGMA foreign_keys", null, null);
if (value != newValue) {
- execute(null, "PRAGMA foreign_keys=" + newValue, null, null);
+ execute("PRAGMA foreign_keys=" + newValue, null, null);
}
}
}
@@ -387,7 +386,7 @@
Log.i(TAG, walFile.getAbsolutePath() + " " + size + " bytes: Bigger than "
+ threshold + "; truncating");
try {
- executeForString(null, "PRAGMA wal_checkpoint(TRUNCATE)", null, null);
+ executeForString("PRAGMA wal_checkpoint(TRUNCATE)", null, null);
mConfiguration.shouldTruncateWalFile = false;
} catch (SQLiteException e) {
Log.w(TAG, "Failed to truncate the -wal file", e);
@@ -399,10 +398,10 @@
// No change to the sync mode is intended
return;
}
- String value = executeForString(null, "PRAGMA synchronous", null, null);
+ String value = executeForString("PRAGMA synchronous", null, null);
if (!canonicalizeSyncMode(value).equalsIgnoreCase(
canonicalizeSyncMode(newValue))) {
- execute(null, "PRAGMA synchronous=" + newValue, null, null);
+ execute("PRAGMA synchronous=" + newValue, null, null);
}
}
@@ -421,11 +420,10 @@
// No change to the journal mode is intended
return;
}
- String value = executeForString(null, "PRAGMA journal_mode", null, null);
+ String value = executeForString("PRAGMA journal_mode", null, null);
if (!value.equalsIgnoreCase(newValue)) {
try {
- String result = executeForString(null, "PRAGMA journal_mode=" + newValue,
- null, null);
+ String result = executeForString("PRAGMA journal_mode=" + newValue, null, null);
if (result.equalsIgnoreCase(newValue)) {
return;
}
@@ -477,26 +475,26 @@
try {
// Ensure the android metadata table exists.
- execute(null, "CREATE TABLE IF NOT EXISTS android_metadata (locale TEXT)", null, null);
+ execute("CREATE TABLE IF NOT EXISTS android_metadata (locale TEXT)", null, null);
// Check whether the locale was actually changed.
- final String oldLocale = executeForString(null, "SELECT locale FROM android_metadata "
+ final String oldLocale = executeForString("SELECT locale FROM android_metadata "
+ "UNION SELECT NULL ORDER BY locale DESC LIMIT 1", null, null);
if (oldLocale != null && oldLocale.equals(newLocale)) {
return;
}
// Go ahead and update the indexes using the new locale.
- execute(null, "BEGIN", null, null);
+ execute("BEGIN", null, null);
boolean success = false;
try {
- execute(null, "DELETE FROM android_metadata", null, null);
- execute(null, "INSERT INTO android_metadata (locale) VALUES(?)",
+ execute("DELETE FROM android_metadata", null, null);
+ execute("INSERT INTO android_metadata (locale) VALUES(?)",
new Object[] { newLocale }, null);
- execute(null, "REINDEX LOCALIZED", null, null);
+ execute("REINDEX LOCALIZED", null, null);
success = true;
} finally {
- execute(null, success ? "COMMIT" : "ROLLBACK", null, null);
+ execute(success ? "COMMIT" : "ROLLBACK", null, null);
}
} catch (SQLiteException ex) {
throw ex;
@@ -525,10 +523,10 @@
final int type = DatabaseUtils.getSqlStatementType(statement.first);
switch (type) {
case DatabaseUtils.STATEMENT_SELECT:
- executeForString(null, statement.first, statement.second, null);
+ executeForString(statement.first, statement.second, null);
break;
case DatabaseUtils.STATEMENT_PRAGMA:
- execute(null, statement.first, statement.second, null);
+ execute(statement.first, statement.second, null);
break;
default:
throw new IllegalArgumentException(
@@ -545,10 +543,9 @@
final File checkFile = new File(mConfiguration.path
+ SQLiteGlobal.WIPE_CHECK_FILE_SUFFIX);
- final boolean hasMetadataTable = executeForLong(null,
+ final boolean hasMetadataTable = executeForLong(
"SELECT count(*) FROM sqlite_master"
- + " WHERE type='table' AND name='android_metadata'",
- null, null) > 0;
+ + " WHERE type='table' AND name='android_metadata'", null, null) > 0;
final boolean hasCheckFile = checkFile.exists();
if (!mIsReadOnlyConnection && !hasCheckFile) {
@@ -670,15 +667,14 @@
*
* @throws SQLiteException if an error occurs, such as a syntax error.
*/
- public void prepare(@Nullable SQLiteAuthorizer authorizer, @NonNull String sql,
- @Nullable SQLiteStatementInfo outStatementInfo) {
+ public void prepare(String sql, SQLiteStatementInfo outStatementInfo) {
if (sql == null) {
throw new IllegalArgumentException("sql must not be null.");
}
final int cookie = mRecentOperations.beginOperation("prepare", sql, null);
try {
- final PreparedStatement statement = acquirePreparedStatement(authorizer, sql);
+ final PreparedStatement statement = acquirePreparedStatement(sql);
try {
if (outStatementInfo != null) {
outStatementInfo.numParameters = statement.mNumParameters;
@@ -718,9 +714,8 @@
* or invalid number of bind arguments.
* @throws OperationCanceledException if the operation was canceled.
*/
- public void execute(@Nullable SQLiteAuthorizer authorizer,
- @NonNull String sql, @Nullable Object[] bindArgs,
- @Nullable CancellationSignal cancellationSignal) {
+ public void execute(String sql, Object[] bindArgs,
+ CancellationSignal cancellationSignal) {
if (sql == null) {
throw new IllegalArgumentException("sql must not be null.");
}
@@ -729,7 +724,7 @@
try {
final boolean isPragmaStmt =
DatabaseUtils.getSqlStatementType(sql) == DatabaseUtils.STATEMENT_PRAGMA;
- final PreparedStatement statement = acquirePreparedStatement(authorizer, sql);
+ final PreparedStatement statement = acquirePreparedStatement(sql);
try {
throwIfStatementForbidden(statement);
bindArguments(statement, bindArgs);
@@ -764,15 +759,15 @@
* or invalid number of bind arguments.
* @throws OperationCanceledException if the operation was canceled.
*/
- public long executeForLong(@Nullable SQLiteAuthorizer authorizer, @NonNull String sql,
- @Nullable Object[] bindArgs, @Nullable CancellationSignal cancellationSignal) {
+ public long executeForLong(String sql, Object[] bindArgs,
+ CancellationSignal cancellationSignal) {
if (sql == null) {
throw new IllegalArgumentException("sql must not be null.");
}
final int cookie = mRecentOperations.beginOperation("executeForLong", sql, bindArgs);
try {
- final PreparedStatement statement = acquirePreparedStatement(authorizer, sql);
+ final PreparedStatement statement = acquirePreparedStatement(sql);
try {
throwIfStatementForbidden(statement);
bindArguments(statement, bindArgs);
@@ -809,15 +804,15 @@
* or invalid number of bind arguments.
* @throws OperationCanceledException if the operation was canceled.
*/
- public String executeForString(@Nullable SQLiteAuthorizer authorizer, @NonNull String sql,
- @Nullable Object[] bindArgs, @Nullable CancellationSignal cancellationSignal) {
+ public String executeForString(String sql, Object[] bindArgs,
+ CancellationSignal cancellationSignal) {
if (sql == null) {
throw new IllegalArgumentException("sql must not be null.");
}
final int cookie = mRecentOperations.beginOperation("executeForString", sql, bindArgs);
try {
- final PreparedStatement statement = acquirePreparedStatement(authorizer, sql);
+ final PreparedStatement statement = acquirePreparedStatement(sql);
try {
throwIfStatementForbidden(statement);
bindArguments(statement, bindArgs);
@@ -856,9 +851,8 @@
* or invalid number of bind arguments.
* @throws OperationCanceledException if the operation was canceled.
*/
- public ParcelFileDescriptor executeForBlobFileDescriptor(@Nullable SQLiteAuthorizer authorizer,
- @NonNull String sql, @Nullable Object[] bindArgs,
- @Nullable CancellationSignal cancellationSignal) {
+ public ParcelFileDescriptor executeForBlobFileDescriptor(String sql, Object[] bindArgs,
+ CancellationSignal cancellationSignal) {
if (sql == null) {
throw new IllegalArgumentException("sql must not be null.");
}
@@ -866,7 +860,7 @@
final int cookie = mRecentOperations.beginOperation("executeForBlobFileDescriptor",
sql, bindArgs);
try {
- final PreparedStatement statement = acquirePreparedStatement(authorizer, sql);
+ final PreparedStatement statement = acquirePreparedStatement(sql);
try {
throwIfStatementForbidden(statement);
bindArguments(statement, bindArgs);
@@ -903,9 +897,8 @@
* or invalid number of bind arguments.
* @throws OperationCanceledException if the operation was canceled.
*/
- public int executeForChangedRowCount(@Nullable SQLiteAuthorizer authorizer,
- @NonNull String sql, @Nullable Object[] bindArgs,
- @Nullable CancellationSignal cancellationSignal) {
+ public int executeForChangedRowCount(String sql, Object[] bindArgs,
+ CancellationSignal cancellationSignal) {
if (sql == null) {
throw new IllegalArgumentException("sql must not be null.");
}
@@ -914,7 +907,7 @@
final int cookie = mRecentOperations.beginOperation("executeForChangedRowCount",
sql, bindArgs);
try {
- final PreparedStatement statement = acquirePreparedStatement(authorizer, sql);
+ final PreparedStatement statement = acquirePreparedStatement(sql);
try {
throwIfStatementForbidden(statement);
bindArguments(statement, bindArgs);
@@ -953,9 +946,8 @@
* or invalid number of bind arguments.
* @throws OperationCanceledException if the operation was canceled.
*/
- public long executeForLastInsertedRowId(@Nullable SQLiteAuthorizer authorizer,
- @NonNull String sql, @Nullable Object[] bindArgs,
- @Nullable CancellationSignal cancellationSignal) {
+ public long executeForLastInsertedRowId(String sql, Object[] bindArgs,
+ CancellationSignal cancellationSignal) {
if (sql == null) {
throw new IllegalArgumentException("sql must not be null.");
}
@@ -963,7 +955,7 @@
final int cookie = mRecentOperations.beginOperation("executeForLastInsertedRowId",
sql, bindArgs);
try {
- final PreparedStatement statement = acquirePreparedStatement(authorizer, sql);
+ final PreparedStatement statement = acquirePreparedStatement(sql);
try {
throwIfStatementForbidden(statement);
bindArguments(statement, bindArgs);
@@ -1008,10 +1000,9 @@
* or invalid number of bind arguments.
* @throws OperationCanceledException if the operation was canceled.
*/
- public int executeForCursorWindow(@Nullable SQLiteAuthorizer authorizer, @NonNull String sql,
- @Nullable Object[] bindArgs, @NonNull CursorWindow window,
- int startPos, int requiredPos, boolean countAllRows,
- @Nullable CancellationSignal cancellationSignal) {
+ public int executeForCursorWindow(String sql, Object[] bindArgs,
+ CursorWindow window, int startPos, int requiredPos, boolean countAllRows,
+ CancellationSignal cancellationSignal) {
if (sql == null) {
throw new IllegalArgumentException("sql must not be null.");
}
@@ -1027,7 +1018,7 @@
final int cookie = mRecentOperations.beginOperation("executeForCursorWindow",
sql, bindArgs);
try {
- final PreparedStatement statement = acquirePreparedStatement(authorizer, sql);
+ final PreparedStatement statement = acquirePreparedStatement(sql);
try {
throwIfStatementForbidden(statement);
bindArguments(statement, bindArgs);
@@ -1065,19 +1056,13 @@
}
}
-
/**
* Return a {@link #PreparedStatement}, possibly from the cache.
*/
- private PreparedStatement acquirePreparedStatement(@Nullable SQLiteAuthorizer authorizer,
- @NonNull String sql) {
+ PreparedStatement acquirePreparedStatement(String sql) {
++mPool.mTotalPrepareStatements;
- // Custom per-statement authorizers are typically used for incoming
- // untrusted custom SQL, which is likely to have low cache hit ratios,
- // so we compile them every time. This leaves the prepared statement
- // cache for statements using the default authorizer.
- boolean skipCache = (authorizer != null);
- PreparedStatement statement = skipCache ? null : mPreparedStatementCache.get(sql);
+ PreparedStatement statement = mPreparedStatementCache.get(sql);
+ boolean skipCache = false;
if (statement != null) {
if (!statement.mInUse) {
return statement;
@@ -1088,12 +1073,8 @@
skipCache = true;
}
++mPool.mTotalPrepareStatementCacheMiss;
- if (authorizer != null) {
- nativeSetAuthorizer(mConnectionPtr, authorizer);
- }
- long statementPtr = 0;
+ final long statementPtr = nativePrepareStatement(mConnectionPtr, sql);
try {
- statementPtr = nativePrepareStatement(mConnectionPtr, sql);
final int numParameters = nativeGetParameterCount(mConnectionPtr, statementPtr);
final int type = DatabaseUtils.getSqlStatementType(sql);
final boolean readOnly = nativeIsReadOnly(mConnectionPtr, statementPtr);
@@ -1105,15 +1086,10 @@
} catch (RuntimeException ex) {
// Finalize the statement if an exception occurred and we did not add
// it to the cache. If it is already in the cache, then leave it there.
- // It is safe to call finalize on a NULL, if nativePrepare failed.
if (statement == null || !statement.mInCache) {
nativeFinalizeStatement(mConnectionPtr, statementPtr);
}
throw ex;
- } finally {
- if (authorizer != null) {
- nativeSetAuthorizer(mConnectionPtr, null);
- }
}
statement.mInUse = true;
return statement;
@@ -1154,11 +1130,10 @@
* Return a prepared statement for use by {@link SQLiteRawStatement}. This throws if the
* prepared statement is incompatible with this connection.
*/
- PreparedStatement acquirePersistentStatement(@Nullable SQLiteAuthorizer authorizer,
- @NonNull String sql) {
+ PreparedStatement acquirePersistentStatement(@NonNull String sql) {
final int cookie = mRecentOperations.beginOperation("prepare", sql, null);
try {
- final PreparedStatement statement = acquirePreparedStatement(authorizer, sql);
+ final PreparedStatement statement = acquirePreparedStatement(sql);
throwIfStatementForbidden(statement);
return statement;
} catch (RuntimeException e) {
@@ -1353,8 +1328,8 @@
long pageCount = 0;
long pageSize = 0;
try {
- pageCount = executeForLong(null, "PRAGMA page_count;", null, null);
- pageSize = executeForLong(null, "PRAGMA page_size;", null, null);
+ pageCount = executeForLong("PRAGMA page_count;", null, null);
+ pageSize = executeForLong("PRAGMA page_size;", null, null);
} catch (SQLiteException ex) {
// Ignore.
}
@@ -1365,15 +1340,15 @@
// the main database which we have already described.
CursorWindow window = new CursorWindow("collectDbStats");
try {
- executeForCursorWindow(null, "PRAGMA database_list;", null, window, 0, 0, false, null);
+ executeForCursorWindow("PRAGMA database_list;", null, window, 0, 0, false, null);
for (int i = 1; i < window.getNumRows(); i++) {
String name = window.getString(i, 1);
String path = window.getString(i, 2);
pageCount = 0;
pageSize = 0;
try {
- pageCount = executeForLong(null, "PRAGMA " + name + ".page_count;", null, null);
- pageSize = executeForLong(null, "PRAGMA " + name + ".page_size;", null, null);
+ pageCount = executeForLong("PRAGMA " + name + ".page_count;", null, null);
+ pageSize = executeForLong("PRAGMA " + name + ".page_size;", null, null);
} catch (SQLiteException ex) {
// Ignore.
}
diff --git a/core/java/android/database/sqlite/SQLiteDatabase.java b/core/java/android/database/sqlite/SQLiteDatabase.java
index 06d4f28..8391865 100644
--- a/core/java/android/database/sqlite/SQLiteDatabase.java
+++ b/core/java/android/database/sqlite/SQLiteDatabase.java
@@ -44,12 +44,10 @@
import android.util.Log;
import android.util.Pair;
import android.util.Printer;
-
import com.android.internal.util.Preconditions;
import dalvik.annotation.optimization.NeverCompile;
import dalvik.system.CloseGuard;
-
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
@@ -255,13 +253,6 @@
*/
public static final int NO_LOCALIZED_COLLATORS = 0x00000010; // update native code if changing
- /** @hide */
- public static final int ENABLE_TRACE = 0x00000100;
- /** @hide */
- public static final int ENABLE_PROFILE = 0x00000200;
- /** @hide */
- public static final int ENABLE_AUTHORIZER = 0x00000400;
-
/**
* Open flag: Flag for {@link #openDatabase} to create the database file if it does not
* already exist.
@@ -1462,38 +1453,9 @@
* {@link SQLiteStatement}s are not synchronized, see the documentation for more details.
*/
public SQLiteStatement compileStatement(String sql) throws SQLException {
- return compileStatementInternal(sql, null);
- }
-
- /**
- * Compiles an SQL statement into a reusable pre-compiled statement object.
- * The parameters are identical to {@link #execSQL(String)}. You may put ?s in the
- * statement and fill in those values with {@link SQLiteProgram#bindString}
- * and {@link SQLiteProgram#bindLong} each time you want to run the
- * statement. Statements may not return result sets larger than 1x1.
- *<p>
- * No two threads should be using the same {@link SQLiteStatement} at the same time.
- * Must configure: {@link OpenParams.Builder#setAuthorizerSupportEnabled(boolean)}.
- *
- * @param sql The raw SQL statement, may contain ? for unknown values to be
- * bound later.
- * @param authorizer The sql authorizer attached to the statement.
- * @return A pre-compiled {@link SQLiteStatement} object. Note that
- * {@link SQLiteStatement}s are not synchronized, see the documentation for more details.
- */
- public @NonNull SQLiteStatement compileStatement(@NonNull String sql,
- @NonNull SQLiteAuthorizer authorizer) throws SQLException {
- return compileStatementInternal(sql, authorizer);
- }
-
- private @NonNull SQLiteStatement compileStatementInternal(@NonNull String sql,
- @Nullable SQLiteAuthorizer authorizer) throws SQLException {
- if (authorizer != null) {
- throwIfNotAuthorizerEnabled();
- }
acquireReference();
try {
- return new SQLiteStatement(this, authorizer, sql, null);
+ return new SQLiteStatement(this, sql, null);
} finally {
releaseReference();
}
@@ -1790,8 +1752,7 @@
public Cursor rawQueryWithFactory(
CursorFactory cursorFactory, String sql, String[] selectionArgs,
String editTable) {
- return rawQueryWithFactoryInternal(cursorFactory, sql, selectionArgs,
- editTable, null, null);
+ return rawQueryWithFactory(cursorFactory, sql, selectionArgs, editTable, null);
}
/**
@@ -1812,52 +1773,17 @@
public Cursor rawQueryWithFactory(
CursorFactory cursorFactory, String sql, String[] selectionArgs,
String editTable, CancellationSignal cancellationSignal) {
- return rawQueryWithFactoryInternal(cursorFactory, sql, selectionArgs, editTable,
- cancellationSignal, null);
- }
-
- /**
- * Runs the provided SQL and returns a cursor over the result set.
- * Must configure: {@link OpenParams.Builder#setAuthorizerSupportEnabled(boolean)}.
- *
- * @param cursorFactory the cursor factory to use, or null for the default factory
- * @param sql the SQL query. The SQL string must not be ; terminated
- * @param selectionArgs You may include ?s in where clause in the query,
- * which will be replaced by the values from selectionArgs. The
- * values will be bound as Strings.
- * @param editTable the name of the first table, which is editable
- * @param cancellationSignal A signal to cancel the operation in progress, or null if none.
- * If the operation is canceled, then {@link OperationCanceledException} will be thrown
- * when the query is executed.
- * @param authorizer The sql authorizer attached to the query.
- * @return A {@link Cursor} object, which is positioned before the first entry. Note that
- * {@link Cursor}s are not synchronized, see the documentation for more details.
- */
- public @NonNull Cursor rawQueryWithFactory(@Nullable CursorFactory cursorFactory,
- @NonNull String sql, @SuppressLint("ArrayReturn") @Nullable String[] selectionArgs,
- @Nullable String editTable, @Nullable CancellationSignal cancellationSignal,
- @NonNull SQLiteAuthorizer authorizer) {
- return rawQueryWithFactoryInternal(cursorFactory, sql, selectionArgs, editTable,
- cancellationSignal, authorizer);
- }
-
- private @NonNull Cursor rawQueryWithFactoryInternal(@Nullable CursorFactory cursorFactory,
- @NonNull String sql, @SuppressLint("ArrayReturn") @Nullable String[] selectionArgs,
- @Nullable String editTable, @Nullable CancellationSignal cancellationSignal,
- @Nullable SQLiteAuthorizer authorizer) {
- if (authorizer != null) {
- throwIfNotAuthorizerEnabled();
- }
acquireReference();
try {
- SQLiteCursorDriver driver = new SQLiteDirectCursorDriver(this, authorizer, sql,
- editTable, cancellationSignal);
+ SQLiteCursorDriver driver = new SQLiteDirectCursorDriver(this, sql, editTable,
+ cancellationSignal);
return driver.query(cursorFactory != null ? cursorFactory : mCursorFactory,
selectionArgs);
} finally {
releaseReference();
}
}
+
/**
* Convenience method for inserting a row into the database.
*
@@ -2005,8 +1931,7 @@
}
sql.append(')');
- // Custom authorizers can be applied through SQLiteQueryBuilder
- SQLiteStatement statement = new SQLiteStatement(this, null, sql.toString(), bindArgs);
+ SQLiteStatement statement = new SQLiteStatement(this, sql.toString(), bindArgs);
try {
return statement.executeInsert();
} finally {
@@ -2033,9 +1958,8 @@
public int delete(String table, String whereClause, String[] whereArgs) {
acquireReference();
try {
- // Custom authorizers can be applied through SQLiteQueryBuilder
- SQLiteStatement statement = new SQLiteStatement(this, null, "DELETE FROM " + table
- + (!TextUtils.isEmpty(whereClause) ? " WHERE " + whereClause : ""), whereArgs);
+ SQLiteStatement statement = new SQLiteStatement(this, "DELETE FROM " + table +
+ (!TextUtils.isEmpty(whereClause) ? " WHERE " + whereClause : ""), whereArgs);
try {
return statement.executeUpdateDelete();
} finally {
@@ -2112,8 +2036,7 @@
sql.append(whereClause);
}
- // Custom authorizers can be applied through SQLiteQueryBuilder
- SQLiteStatement statement = new SQLiteStatement(this, null, sql.toString(), bindArgs);
+ SQLiteStatement statement = new SQLiteStatement(this, sql.toString(), bindArgs);
try {
return statement.executeUpdateDelete();
} finally {
@@ -2150,7 +2073,7 @@
* @throws SQLException if the SQL string is invalid
*/
public void execSQL(String sql) throws SQLException {
- executeSql(null, sql, null);
+ executeSql(sql, null);
}
/**
@@ -2203,72 +2126,14 @@
* @throws SQLException if the SQL string is invalid
*/
public void execSQL(String sql, Object[] bindArgs) throws SQLException {
- executeSql(null, sql, bindArgs);
- }
-
- /**
- * Execute a single SQL statement that is NOT a SELECT/INSERT/UPDATE/DELETE.
- * Must configure: {@link OpenParams.Builder#setAuthorizerSupportEnabled(boolean)}.
- * <p>
- * For INSERT statements, use any of the following instead.
- * <ul>
- * <li>{@link #insert(String, String, ContentValues)}</li>
- * <li>{@link #insertOrThrow(String, String, ContentValues)}</li>
- * <li>{@link #insertWithOnConflict(String, String, ContentValues, int)}</li>
- * </ul>
- * <p>
- * For UPDATE statements, use any of the following instead.
- * <ul>
- * <li>{@link #update(String, ContentValues, String, String[])}</li>
- * <li>{@link #updateWithOnConflict(String, ContentValues, String, String[], int)}</li>
- * </ul>
- * <p>
- * For DELETE statements, use any of the following instead.
- * <ul>
- * <li>{@link #delete(String, String, String[])}</li>
- * </ul>
- * <p>
- * For example, the following are good candidates for using this method:
- * <ul>
- * <li>ALTER TABLE</li>
- * <li>CREATE or DROP table / trigger / view / index / virtual table</li>
- * <li>REINDEX</li>
- * <li>RELEASE</li>
- * <li>SAVEPOINT</li>
- * <li>PRAGMA that returns no data</li>
- * </ul>
- * </p>
- * <p>
- * When using {@link #enableWriteAheadLogging()}, journal_mode is
- * automatically managed by this class. So, do not set journal_mode
- * using "PRAGMA journal_mode'<value>" statement if your app is using
- * {@link #enableWriteAheadLogging()}
- * </p>
- * <p>
- * Note that {@code PRAGMA} values which apply on a per-connection basis
- * should <em>not</em> be configured using this method; you should instead
- * use {@link #execPerConnectionSQL} to ensure that they are uniformly
- * applied to all current and future connections.
- * </p>
- *
- * @param sql the SQL statement to be executed. Multiple statements separated by semicolons are
- * not supported.
- * @param bindArgs only byte[], String, Long and Double are supported in bindArgs.
- * @param authorizer The sql authorizer attached to the query.
- * @throws SQLException if the SQL string is invalid
- */
- public void execSQL(@NonNull String sql,
- @SuppressLint("ArrayReturn") @Nullable Object[] bindArgs,
- @NonNull SQLiteAuthorizer authorizer) throws SQLException {
- if (authorizer != null) {
- throwIfNotAuthorizerEnabled();
+ if (bindArgs == null) {
+ throw new IllegalArgumentException("Empty bindArgs");
}
- executeSql(authorizer, sql, bindArgs);
+ executeSql(sql, bindArgs);
}
/** {@hide} */
- public int executeSql(@Nullable SQLiteAuthorizer authorizer, @NonNull String sql,
- @Nullable Object[] bindArgs) throws SQLException {
+ public int executeSql(String sql, Object[] bindArgs) throws SQLException {
acquireReference();
try {
final int statementType = DatabaseUtils.getSqlStatementType(sql);
@@ -2286,7 +2151,7 @@
}
}
- try (SQLiteStatement statement = new SQLiteStatement(this, authorizer, sql, bindArgs)) {
+ try (SQLiteStatement statement = new SQLiteStatement(this, sql, bindArgs)) {
return statement.executeUpdateDelete();
} finally {
// If schema was updated, close non-primary connections, otherwise they might
@@ -2304,25 +2169,6 @@
* Return a {@link SQLiteRawStatement} connected to the database. A transaction must be in
* progress or an exception will be thrown. The resulting object will be closed automatically
* when the current transaction closes.
- * Must configure: {@link OpenParams.Builder#setAuthorizerSupportEnabled(boolean)}.
- * @param sql The SQL string to be compiled into a prepared statement.
- * @param authorizer The sql authorizer attached to the statement.
- * @return A {@link SQLiteRawStatement} holding the compiled SQL.
- * @throws IllegalStateException if a transaction is not in progress.
- * @throws SQLiteException if the SQL cannot be compiled.
- * @hide
- */
- @NonNull
- public SQLiteRawStatement createRawStatement(@NonNull String sql,
- @NonNull SQLiteAuthorizer authorizer) {
- Objects.requireNonNull(sql);
- return new SQLiteRawStatement(this, sql, authorizer);
- }
-
- /**
- * Return a {@link SQLiteRawStatement} connected to the database. A transaction must be in
- * progress or an exception will be thrown. The resulting object will be closed automatically
- * when the current transaction closes.
* @param sql The SQL string to be compiled into a prepared statement.
* @return A {@link SQLiteRawStatement} holding the compiled SQL.
* @throws IllegalStateException if a transaction is not in progress.
@@ -2332,8 +2178,9 @@
@NonNull
public SQLiteRawStatement createRawStatement(@NonNull String sql) {
Objects.requireNonNull(sql);
- return createRawStatement(sql, null);
+ return new SQLiteRawStatement(this, sql);
}
+
/**
* Return the "rowid" of the last row to be inserted on the current connection. See the
* SQLite documentation for the specific details. This method must only be called when inside
@@ -2359,33 +2206,7 @@
* @throws SQLiteException if {@code sql} is invalid
*/
public void validateSql(@NonNull String sql, @Nullable CancellationSignal cancellationSignal) {
- validateSqlInternal(sql, cancellationSignal, null);
- }
-
- /**
- * Verifies that a SQL SELECT statement is valid by compiling it.
- * If the SQL statement is not valid, this method will throw a {@link SQLiteException}.
- * Must configure: {@link OpenParams.Builder#setAuthorizerSupportEnabled(boolean)}.
- *
- * @param sql SQL to be validated
- * @param cancellationSignal A signal to cancel the operation in progress, or null if none.
- * If the operation is canceled, then {@link OperationCanceledException} will be thrown
- * when the query is executed.
- * @param authorizer The sql authorizer attached to the query.
- * @throws SQLiteException if {@code sql} is invalid
- */
- public void validateSql(@NonNull String sql, @Nullable CancellationSignal cancellationSignal,
- @NonNull SQLiteAuthorizer authorizer) {
- validateSqlInternal(sql, cancellationSignal, authorizer);
- }
-
- private void validateSqlInternal(@NonNull String sql,
- @Nullable CancellationSignal cancellationSignal,
- @Nullable SQLiteAuthorizer authorizer) {
- if (authorizer != null) {
- throwIfNotAuthorizerEnabled();
- }
- getThreadSession().prepare(authorizer, sql,
+ getThreadSession().prepare(sql,
getThreadDefaultConnectionFlags(/* readOnly =*/ true), cancellationSignal, null);
}
@@ -2405,21 +2226,6 @@
}
/**
- * Returns true if the database is opened with authorizer support enabled.
- *
- * @return True if authorizer support is enabled.
- */
- public boolean isAuthorizerSupportEnabled() {
- synchronized (mLock) {
- return isAuthorizerSupportEnabledLocked();
- }
- }
-
- private boolean isAuthorizerSupportEnabledLocked() {
- return (mConfigurationLocked.openFlags & ENABLE_AUTHORIZER) != 0;
- }
-
- /**
* Returns true if the database is in-memory db.
*
* @return True if the database is in-memory.
@@ -3004,13 +2810,6 @@
return "SQLiteDatabase: " + getPath();
}
- private void throwIfNotAuthorizerEnabled() {
- if ((mConfigurationLocked.openFlags & ENABLE_AUTHORIZER) == 0) {
- throw new IllegalStateException("The database '" + mConfigurationLocked.label
- + "' does not have authorizer support enabled.");
- }
- }
-
private void throwIfNotOpenLocked() {
if (mConnectionPoolLocked == null) {
throw new IllegalStateException("The database '" + mConfigurationLocked.label
@@ -3275,39 +3074,6 @@
}
/**
- * Returns if support for {@link SQLiteAuthorizer} is enabled.
- *
- * @see SQLiteDatabase#compileStatement(String, SQLiteAuthorizer)
- * @see SQLiteDatabase#execSQL(String, Object[], SQLiteAuthorizer)
- * @see SQLiteDatabase#validateSql(String, CancellationSignal,
- * SQLiteAuthorizer)
- * @see SQLiteDatabase#rawQueryWithFactory(CursorFactory, String,
- * String[], String, CancellationSignal, SQLiteAuthorizer)
- */
- public boolean isAuthorizerSupportEnabled() {
- return (mOpenFlags & ENABLE_AUTHORIZER) != 0;
- }
-
- /**
- * Enables or disables support for {@link SQLiteAuthorizer}.
- *
- * @see SQLiteDatabase#compileStatement(String, SQLiteAuthorizer)
- * @see SQLiteDatabase#execSQL(String, Object[], SQLiteAuthorizer)
- * @see SQLiteDatabase#validateSql(String, CancellationSignal,
- * SQLiteAuthorizer)
- * @see SQLiteDatabase#rawQueryWithFactory(CursorFactory, String,
- * String[], String, CancellationSignal, SQLiteAuthorizer)
- */
- public @NonNull Builder setAuthorizerSupportEnabled(boolean enabled) {
- if (enabled) {
- addOpenFlags(SQLiteDatabase.ENABLE_AUTHORIZER);
- } else {
- removeOpenFlags(SQLiteDatabase.ENABLE_AUTHORIZER);
- }
- return this;
- }
-
- /**
* Set an optional factory class that is called to instantiate a cursor when query
* is called.
*
@@ -3408,8 +3174,7 @@
OPEN_READONLY,
CREATE_IF_NECESSARY,
NO_LOCALIZED_COLLATORS,
- ENABLE_WRITE_AHEAD_LOGGING,
- ENABLE_AUTHORIZER
+ ENABLE_WRITE_AHEAD_LOGGING
})
@Retention(RetentionPolicy.SOURCE)
public @interface DatabaseOpenFlags {}
diff --git a/core/java/android/database/sqlite/SQLiteDatabaseConfiguration.java b/core/java/android/database/sqlite/SQLiteDatabaseConfiguration.java
index 63b59f7..bc63686 100644
--- a/core/java/android/database/sqlite/SQLiteDatabaseConfiguration.java
+++ b/core/java/android/database/sqlite/SQLiteDatabaseConfiguration.java
@@ -17,11 +17,9 @@
package android.database.sqlite;
import android.compat.annotation.UnsupportedAppUsage;
-import android.database.sqlite.SQLiteDebug.NoPreloadHolder;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.Pair;
-
import java.util.ArrayList;
import java.util.Locale;
import java.util.function.BinaryOperator;
@@ -157,13 +155,6 @@
throw new IllegalArgumentException("path must not be null.");
}
- if (NoPreloadHolder.DEBUG_SQL_STATEMENTS) {
- openFlags |= SQLiteDatabase.ENABLE_PROFILE;
- }
- if (NoPreloadHolder.DEBUG_SQL_TIME) {
- openFlags |= SQLiteDatabase.ENABLE_TRACE;
- }
-
this.path = path;
label = stripPathForLogs(path);
this.openFlags = openFlags;
diff --git a/core/java/android/database/sqlite/SQLiteDirectCursorDriver.java b/core/java/android/database/sqlite/SQLiteDirectCursorDriver.java
index 8be11d0..1721e0c 100644
--- a/core/java/android/database/sqlite/SQLiteDirectCursorDriver.java
+++ b/core/java/android/database/sqlite/SQLiteDirectCursorDriver.java
@@ -16,8 +16,6 @@
package android.database.sqlite;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
import android.annotation.TestApi;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
@@ -31,7 +29,6 @@
@TestApi
public final class SQLiteDirectCursorDriver implements SQLiteCursorDriver {
private final SQLiteDatabase mDatabase;
- private final SQLiteAuthorizer mAuthorizer;
private final String mEditTable;
private final String mSql;
private final CancellationSignal mCancellationSignal;
@@ -39,22 +36,14 @@
public SQLiteDirectCursorDriver(SQLiteDatabase db, String sql, String editTable,
CancellationSignal cancellationSignal) {
- this(db, null, sql, editTable, cancellationSignal);
- }
-
- public SQLiteDirectCursorDriver(@NonNull SQLiteDatabase db,
- @Nullable SQLiteAuthorizer authorizer, @NonNull String sql,
- @Nullable String editTable, @Nullable CancellationSignal cancellationSignal) {
mDatabase = db;
- mAuthorizer = authorizer;
mEditTable = editTable;
mSql = sql;
mCancellationSignal = cancellationSignal;
}
public Cursor query(CursorFactory factory, String[] selectionArgs) {
- final SQLiteQuery query = new SQLiteQuery(mDatabase,
- mAuthorizer, mSql, mCancellationSignal);
+ final SQLiteQuery query = new SQLiteQuery(mDatabase, mSql, mCancellationSignal);
final Cursor cursor;
try {
query.bindAllArgsAsStrings(selectionArgs);
diff --git a/core/java/android/database/sqlite/SQLiteProgram.java b/core/java/android/database/sqlite/SQLiteProgram.java
index 84b2a8a..cd4131c 100644
--- a/core/java/android/database/sqlite/SQLiteProgram.java
+++ b/core/java/android/database/sqlite/SQLiteProgram.java
@@ -16,8 +16,6 @@
package android.database.sqlite;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
import android.compat.annotation.UnsupportedAppUsage;
import android.database.DatabaseUtils;
import android.os.Build;
@@ -35,7 +33,6 @@
private static final String[] EMPTY_STRING_ARRAY = new String[0];
private final SQLiteDatabase mDatabase;
- private final SQLiteAuthorizer mAuthorizer;
@UnsupportedAppUsage
private final String mSql;
private final boolean mReadOnly;
@@ -44,11 +41,9 @@
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
private final Object[] mBindArgs;
- SQLiteProgram(@NonNull SQLiteDatabase db, @Nullable SQLiteAuthorizer authorizer,
- @NonNull String sql, @Nullable Object[] bindArgs,
- @Nullable CancellationSignal cancellationSignalForPrepare) {
+ SQLiteProgram(SQLiteDatabase db, String sql, Object[] bindArgs,
+ CancellationSignal cancellationSignalForPrepare) {
mDatabase = db;
- mAuthorizer = authorizer;
mSql = sql.trim();
int n = DatabaseUtils.getSqlStatementType(mSql);
@@ -64,7 +59,7 @@
default:
boolean assumeReadOnly = (n == DatabaseUtils.STATEMENT_SELECT);
SQLiteStatementInfo info = new SQLiteStatementInfo();
- db.getThreadSession().prepare(mAuthorizer, mSql,
+ db.getThreadSession().prepare(mSql,
db.getThreadDefaultConnectionFlags(assumeReadOnly),
cancellationSignalForPrepare, info);
mReadOnly = info.readOnly;
@@ -93,10 +88,6 @@
return mDatabase;
}
- final SQLiteAuthorizer getAuthorizer() {
- return mAuthorizer;
- }
-
final String getSql() {
return mSql;
}
diff --git a/core/java/android/database/sqlite/SQLiteQuery.java b/core/java/android/database/sqlite/SQLiteQuery.java
index 1d23193..62bcc20 100644
--- a/core/java/android/database/sqlite/SQLiteQuery.java
+++ b/core/java/android/database/sqlite/SQLiteQuery.java
@@ -16,8 +16,6 @@
package android.database.sqlite;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
import android.database.CursorWindow;
import android.os.CancellationSignal;
import android.os.OperationCanceledException;
@@ -35,9 +33,8 @@
private final CancellationSignal mCancellationSignal;
- SQLiteQuery(@NonNull SQLiteDatabase db, @Nullable SQLiteAuthorizer authorizer,
- @NonNull String query, @Nullable CancellationSignal cancellationSignal) {
- super(db, authorizer, query, null, cancellationSignal);
+ SQLiteQuery(SQLiteDatabase db, String query, CancellationSignal cancellationSignal) {
+ super(db, query, null, cancellationSignal);
mCancellationSignal = cancellationSignal;
}
@@ -62,9 +59,9 @@
try {
window.acquireReference();
try {
- int numRows = getSession().executeForCursorWindow(getAuthorizer(), getSql(),
- getBindArgs(), window, startPos, requiredPos, countAllRows,
- getConnectionFlags(), mCancellationSignal);
+ int numRows = getSession().executeForCursorWindow(getSql(), getBindArgs(),
+ window, startPos, requiredPos, countAllRows, getConnectionFlags(),
+ mCancellationSignal);
return numRows;
} catch (SQLiteDatabaseCorruptException ex) {
onCorruption();
diff --git a/core/java/android/database/sqlite/SQLiteRawStatement.java b/core/java/android/database/sqlite/SQLiteRawStatement.java
index 6c1ec39..6b43788 100644
--- a/core/java/android/database/sqlite/SQLiteRawStatement.java
+++ b/core/java/android/database/sqlite/SQLiteRawStatement.java
@@ -20,6 +20,8 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import com.android.internal.annotations.VisibleForTesting;
+
import dalvik.annotation.optimization.FastNative;
import java.io.Closeable;
@@ -136,15 +138,14 @@
* {@link IllegalStateException} if a transaction is not in progress. Clients should call
* {@link SQLiteDatabase.createRawStatement} to create a new instance.
*/
- SQLiteRawStatement(@NonNull SQLiteDatabase db, @NonNull String sql,
- @Nullable SQLiteAuthorizer authorizer) throws SQLiteException {
+ SQLiteRawStatement(@NonNull SQLiteDatabase db, @NonNull String sql) throws SQLiteException {
mThread = Thread.currentThread();
mDatabase = db;
mSession = mDatabase.getThreadSession();
mSession.throwIfNoTransaction();
mSql = sql;
// Acquire a connection and prepare the statement.
- mPreparedStatement = mSession.acquirePersistentStatement(authorizer, mSql, this);
+ mPreparedStatement = mSession.acquirePersistentStatement(mSql, this);
mStatement = mPreparedStatement.mStatementPtr;
}
diff --git a/core/java/android/database/sqlite/SQLiteSession.java b/core/java/android/database/sqlite/SQLiteSession.java
index 936ff34..2379c84 100644
--- a/core/java/android/database/sqlite/SQLiteSession.java
+++ b/core/java/android/database/sqlite/SQLiteSession.java
@@ -17,7 +17,7 @@
package android.database.sqlite;
import android.annotation.NonNull;
-import android.annotation.Nullable;
+
import android.compat.annotation.UnsupportedAppUsage;
import android.database.CursorWindow;
import android.database.DatabaseUtils;
@@ -80,7 +80,7 @@
* specifying the desired transaction mode. Once an explicit transaction has begun,
* all subsequent database operations will be performed as part of that transaction.
* To end an explicit transaction, first call {@link #setTransactionSuccessful} if the
- * transaction was successful, then call {@link #endTransaction}. If the transaction was
+ * transaction was successful, then call {@link #end}. If the transaction was
* marked successful, its changes will be committed, otherwise they will be rolled back.
* </p><p>
* Explicit transactions can also be nested. A nested explicit transaction is
@@ -309,12 +309,12 @@
CancellationSignal cancellationSignal) {
throwIfTransactionMarkedSuccessful();
beginTransactionUnchecked(transactionMode, transactionListener, connectionFlags,
- cancellationSignal);
+ cancellationSignal);
}
private void beginTransactionUnchecked(int transactionMode,
SQLiteTransactionListener transactionListener, int connectionFlags,
- @Nullable CancellationSignal cancellationSignal) {
+ CancellationSignal cancellationSignal) {
if (cancellationSignal != null) {
cancellationSignal.throwIfCanceled();
}
@@ -329,21 +329,20 @@
// Execute SQL might throw a runtime exception.
switch (transactionMode) {
case TRANSACTION_MODE_IMMEDIATE:
- mConnection.execute(null, "BEGIN IMMEDIATE;", null,
+ mConnection.execute("BEGIN IMMEDIATE;", null,
cancellationSignal); // might throw
break;
case TRANSACTION_MODE_EXCLUSIVE:
- mConnection.execute(null, "BEGIN EXCLUSIVE;", null,
+ mConnection.execute("BEGIN EXCLUSIVE;", null,
cancellationSignal); // might throw
break;
case TRANSACTION_MODE_DEFERRED:
- mConnection.execute(null, "BEGIN DEFERRED;", null,
+ mConnection.execute("BEGIN DEFERRED;", null,
cancellationSignal); // might throw
break;
default:
// Per SQLite documentation, this executes in DEFERRED mode.
- mConnection.execute(null, "BEGIN;",
- null, cancellationSignal); // might throw
+ mConnection.execute("BEGIN;", null, cancellationSignal); // might throw
break;
}
}
@@ -354,8 +353,7 @@
transactionListener.onBegin(); // might throw
} catch (RuntimeException ex) {
if (mTransactionStack == null) {
- mConnection.execute(null, "ROLLBACK;", null,
- cancellationSignal); // might throw
+ mConnection.execute("ROLLBACK;", null, cancellationSignal); // might throw
}
throw ex;
}
@@ -417,14 +415,14 @@
* @see #setTransactionSuccessful
* @see #yieldTransaction
*/
- public void endTransaction(@Nullable CancellationSignal cancellationSignal) {
+ public void endTransaction(CancellationSignal cancellationSignal) {
throwIfNoTransaction();
assert mConnection != null;
+
endTransactionUnchecked(cancellationSignal, false);
}
- private void endTransactionUnchecked(@Nullable CancellationSignal cancellationSignal,
- boolean yielding) {
+ private void endTransactionUnchecked(CancellationSignal cancellationSignal, boolean yielding) {
if (cancellationSignal != null) {
cancellationSignal.throwIfCanceled();
}
@@ -462,11 +460,9 @@
try {
if (successful) {
- mConnection.execute(null, "COMMIT;", null,
- cancellationSignal); // might throw
+ mConnection.execute("COMMIT;", null, cancellationSignal); // might throw
} else {
- mConnection.execute(null, "ROLLBACK;", null,
- cancellationSignal); // might throw
+ mConnection.execute("ROLLBACK;", null, cancellationSignal); // might throw
}
} finally {
releaseConnection(); // might throw
@@ -603,9 +599,8 @@
* @throws SQLiteException if an error occurs, such as a syntax error.
* @throws OperationCanceledException if the operation was canceled.
*/
- public void prepare(@Nullable SQLiteAuthorizer authorizer, @NonNull String sql,
- int connectionFlags, @Nullable CancellationSignal cancellationSignal,
- @Nullable SQLiteStatementInfo outStatementInfo) {
+ public void prepare(String sql, int connectionFlags, CancellationSignal cancellationSignal,
+ SQLiteStatementInfo outStatementInfo) {
if (sql == null) {
throw new IllegalArgumentException("sql must not be null.");
}
@@ -616,7 +611,7 @@
acquireConnection(sql, connectionFlags, cancellationSignal); // might throw
try {
- mConnection.prepare(authorizer, sql, outStatementInfo); // might throw
+ mConnection.prepare(sql, outStatementInfo); // might throw
} finally {
releaseConnection(); // might throw
}
@@ -635,20 +630,19 @@
* or invalid number of bind arguments.
* @throws OperationCanceledException if the operation was canceled.
*/
- public void execute(@Nullable SQLiteAuthorizer authorizer,
- @NonNull String sql, @Nullable Object[] bindArgs, int connectionFlags,
- @Nullable CancellationSignal cancellationSignal) {
+ public void execute(String sql, Object[] bindArgs, int connectionFlags,
+ CancellationSignal cancellationSignal) {
if (sql == null) {
throw new IllegalArgumentException("sql must not be null.");
}
- if (executeSpecial(sql, connectionFlags, cancellationSignal)) {
+ if (executeSpecial(sql, bindArgs, connectionFlags, cancellationSignal)) {
return;
}
acquireConnection(sql, connectionFlags, cancellationSignal); // might throw
try {
- mConnection.execute(authorizer, sql, bindArgs, cancellationSignal); // might throw
+ mConnection.execute(sql, bindArgs, cancellationSignal); // might throw
} finally {
releaseConnection(); // might throw
}
@@ -669,21 +663,19 @@
* or invalid number of bind arguments.
* @throws OperationCanceledException if the operation was canceled.
*/
- public long executeForLong(@Nullable SQLiteAuthorizer authorizer,
- @NonNull String sql, @Nullable Object[] bindArgs, int connectionFlags,
- @Nullable CancellationSignal cancellationSignal) {
+ public long executeForLong(String sql, Object[] bindArgs, int connectionFlags,
+ CancellationSignal cancellationSignal) {
if (sql == null) {
throw new IllegalArgumentException("sql must not be null.");
}
- if (executeSpecial(sql, connectionFlags, cancellationSignal)) {
+ if (executeSpecial(sql, bindArgs, connectionFlags, cancellationSignal)) {
return 0;
}
acquireConnection(sql, connectionFlags, cancellationSignal); // might throw
try {
- return mConnection.executeForLong(authorizer, sql, bindArgs,
- cancellationSignal); // might throw
+ return mConnection.executeForLong(sql, bindArgs, cancellationSignal); // might throw
} finally {
releaseConnection(); // might throw
}
@@ -704,21 +696,19 @@
* or invalid number of bind arguments.
* @throws OperationCanceledException if the operation was canceled.
*/
- public String executeForString(@Nullable SQLiteAuthorizer authorizer,
- @NonNull String sql, @Nullable Object[] bindArgs, int connectionFlags,
- @Nullable CancellationSignal cancellationSignal) {
+ public String executeForString(String sql, Object[] bindArgs, int connectionFlags,
+ CancellationSignal cancellationSignal) {
if (sql == null) {
throw new IllegalArgumentException("sql must not be null.");
}
- if (executeSpecial(sql, connectionFlags, cancellationSignal)) {
+ if (executeSpecial(sql, bindArgs, connectionFlags, cancellationSignal)) {
return null;
}
acquireConnection(sql, connectionFlags, cancellationSignal); // might throw
try {
- return mConnection.executeForString(authorizer, sql, bindArgs,
- cancellationSignal); // might throw
+ return mConnection.executeForString(sql, bindArgs, cancellationSignal); // might throw
} finally {
releaseConnection(); // might throw
}
@@ -741,20 +731,19 @@
* or invalid number of bind arguments.
* @throws OperationCanceledException if the operation was canceled.
*/
- public ParcelFileDescriptor executeForBlobFileDescriptor(@Nullable SQLiteAuthorizer authorizer,
- @NonNull String sql, @Nullable Object[] bindArgs, int connectionFlags,
- @Nullable CancellationSignal cancellationSignal) {
+ public ParcelFileDescriptor executeForBlobFileDescriptor(String sql, Object[] bindArgs,
+ int connectionFlags, CancellationSignal cancellationSignal) {
if (sql == null) {
throw new IllegalArgumentException("sql must not be null.");
}
- if (executeSpecial(sql, connectionFlags, cancellationSignal)) {
+ if (executeSpecial(sql, bindArgs, connectionFlags, cancellationSignal)) {
return null;
}
acquireConnection(sql, connectionFlags, cancellationSignal); // might throw
try {
- return mConnection.executeForBlobFileDescriptor(authorizer, sql, bindArgs,
+ return mConnection.executeForBlobFileDescriptor(sql, bindArgs,
cancellationSignal); // might throw
} finally {
releaseConnection(); // might throw
@@ -776,20 +765,19 @@
* or invalid number of bind arguments.
* @throws OperationCanceledException if the operation was canceled.
*/
- public int executeForChangedRowCount(@Nullable SQLiteAuthorizer authorizer,
- @NonNull String sql, @Nullable Object[] bindArgs, int connectionFlags,
- @Nullable CancellationSignal cancellationSignal) {
+ public int executeForChangedRowCount(String sql, Object[] bindArgs, int connectionFlags,
+ CancellationSignal cancellationSignal) {
if (sql == null) {
throw new IllegalArgumentException("sql must not be null.");
}
- if (executeSpecial(sql, connectionFlags, cancellationSignal)) {
+ if (executeSpecial(sql, bindArgs, connectionFlags, cancellationSignal)) {
return 0;
}
acquireConnection(sql, connectionFlags, cancellationSignal); // might throw
try {
- return mConnection.executeForChangedRowCount(authorizer, sql, bindArgs,
+ return mConnection.executeForChangedRowCount(sql, bindArgs,
cancellationSignal); // might throw
} finally {
releaseConnection(); // might throw
@@ -811,20 +799,19 @@
* or invalid number of bind arguments.
* @throws OperationCanceledException if the operation was canceled.
*/
- public long executeForLastInsertedRowId(@Nullable SQLiteAuthorizer authorizer,
- @NonNull String sql, @Nullable Object[] bindArgs, int connectionFlags,
- @Nullable CancellationSignal cancellationSignal) {
+ public long executeForLastInsertedRowId(String sql, Object[] bindArgs, int connectionFlags,
+ CancellationSignal cancellationSignal) {
if (sql == null) {
throw new IllegalArgumentException("sql must not be null.");
}
- if (executeSpecial(sql, connectionFlags, cancellationSignal)) {
+ if (executeSpecial(sql, bindArgs, connectionFlags, cancellationSignal)) {
return 0;
}
acquireConnection(sql, connectionFlags, cancellationSignal); // might throw
try {
- return mConnection.executeForLastInsertedRowId(authorizer, sql, bindArgs,
+ return mConnection.executeForLastInsertedRowId(sql, bindArgs,
cancellationSignal); // might throw
} finally {
releaseConnection(); // might throw
@@ -855,10 +842,9 @@
* or invalid number of bind arguments.
* @throws OperationCanceledException if the operation was canceled.
*/
- public int executeForCursorWindow(@Nullable SQLiteAuthorizer authorizer, @NonNull String sql,
- @Nullable Object[] bindArgs, @NonNull CursorWindow window, int startPos,
- int requiredPos, boolean countAllRows, int connectionFlags,
- @Nullable CancellationSignal cancellationSignal) {
+ public int executeForCursorWindow(String sql, Object[] bindArgs,
+ CursorWindow window, int startPos, int requiredPos, boolean countAllRows,
+ int connectionFlags, CancellationSignal cancellationSignal) {
if (sql == null) {
throw new IllegalArgumentException("sql must not be null.");
}
@@ -866,14 +852,14 @@
throw new IllegalArgumentException("window must not be null.");
}
- if (executeSpecial(sql, connectionFlags, cancellationSignal)) {
+ if (executeSpecial(sql, bindArgs, connectionFlags, cancellationSignal)) {
window.clear();
return 0;
}
acquireConnection(sql, connectionFlags, cancellationSignal); // might throw
try {
- return mConnection.executeForCursorWindow(authorizer, sql, bindArgs,
+ return mConnection.executeForCursorWindow(sql, bindArgs,
window, startPos, requiredPos, countAllRows,
cancellationSignal); // might throw
} finally {
@@ -902,8 +888,8 @@
* or invalid number of bind arguments.
* @throws OperationCanceledException if the operation was canceled.
*/
- private boolean executeSpecial(@NonNull String sql, int connectionFlags,
- @Nullable CancellationSignal cancellationSignal) {
+ private boolean executeSpecial(String sql, Object[] bindArgs, int connectionFlags,
+ CancellationSignal cancellationSignal) {
if (cancellationSignal != null) {
cancellationSignal.throwIfCanceled();
}
@@ -956,14 +942,13 @@
* method is called when the transaction is closed.
*/
@NonNull
- SQLiteConnection.PreparedStatement acquirePersistentStatement(
- @Nullable SQLiteAuthorizer authorizer,
- @NonNull String query, @NonNull Closeable dependent) {
+ SQLiteConnection.PreparedStatement acquirePersistentStatement(@NonNull String query,
+ @NonNull Closeable dependent) {
throwIfNoTransaction();
throwIfTransactionMarkedSuccessful();
mOpenDependents.addFirst(dependent);
try {
- return mConnection.acquirePersistentStatement(authorizer, query);
+ return mConnection.acquirePersistentStatement(query);
} catch (Throwable e) {
mOpenDependents.remove(dependent);
throw e;
diff --git a/core/java/android/database/sqlite/SQLiteStatement.java b/core/java/android/database/sqlite/SQLiteStatement.java
index 82023c7..acdc0fa 100644
--- a/core/java/android/database/sqlite/SQLiteStatement.java
+++ b/core/java/android/database/sqlite/SQLiteStatement.java
@@ -16,8 +16,6 @@
package android.database.sqlite;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
import android.compat.annotation.UnsupportedAppUsage;
import android.os.Build;
import android.os.ParcelFileDescriptor;
@@ -34,12 +32,7 @@
public final class SQLiteStatement extends SQLiteProgram {
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
SQLiteStatement(SQLiteDatabase db, String sql, Object[] bindArgs) {
- super(db, null, sql, bindArgs, null);
- }
-
- SQLiteStatement(@NonNull SQLiteDatabase db, @Nullable SQLiteAuthorizer authorizer,
- @NonNull String sql, @Nullable Object[] bindArgs) {
- super(db, authorizer, sql, bindArgs, null);
+ super(db, sql, bindArgs, null);
}
/**
@@ -52,8 +45,7 @@
public void execute() {
acquireReference();
try {
- getSession().execute(
- getAuthorizer(), getSql(), getBindArgs(), getConnectionFlags(), null);
+ getSession().execute(getSql(), getBindArgs(), getConnectionFlags(), null);
} catch (SQLiteDatabaseCorruptException ex) {
onCorruption();
throw ex;
@@ -74,7 +66,7 @@
acquireReference();
try {
return getSession().executeForChangedRowCount(
- getAuthorizer(), getSql(), getBindArgs(), getConnectionFlags(), null);
+ getSql(), getBindArgs(), getConnectionFlags(), null);
} catch (SQLiteDatabaseCorruptException ex) {
onCorruption();
throw ex;
@@ -96,7 +88,7 @@
acquireReference();
try {
return getSession().executeForLastInsertedRowId(
- getAuthorizer(), getSql(), getBindArgs(), getConnectionFlags(), null);
+ getSql(), getBindArgs(), getConnectionFlags(), null);
} catch (SQLiteDatabaseCorruptException ex) {
onCorruption();
throw ex;
@@ -117,7 +109,7 @@
acquireReference();
try {
return getSession().executeForLong(
- getAuthorizer(), getSql(), getBindArgs(), getConnectionFlags(), null);
+ getSql(), getBindArgs(), getConnectionFlags(), null);
} catch (SQLiteDatabaseCorruptException ex) {
onCorruption();
throw ex;
@@ -138,7 +130,7 @@
acquireReference();
try {
return getSession().executeForString(
- getAuthorizer(), getSql(), getBindArgs(), getConnectionFlags(), null);
+ getSql(), getBindArgs(), getConnectionFlags(), null);
} catch (SQLiteDatabaseCorruptException ex) {
onCorruption();
throw ex;
@@ -159,7 +151,7 @@
acquireReference();
try {
return getSession().executeForBlobFileDescriptor(
- getAuthorizer(), getSql(), getBindArgs(), getConnectionFlags(), null);
+ getSql(), getBindArgs(), getConnectionFlags(), null);
} catch (SQLiteDatabaseCorruptException ex) {
onCorruption();
throw ex;
diff --git a/core/java/android/hardware/camera2/TotalCaptureResult.java b/core/java/android/hardware/camera2/TotalCaptureResult.java
index ac7f2ca..7e42f43 100644
--- a/core/java/android/hardware/camera2/TotalCaptureResult.java
+++ b/core/java/android/hardware/camera2/TotalCaptureResult.java
@@ -179,7 +179,7 @@
* @return unmodifiable map between physical camera ids and their capture result metadata
*
* @deprecated
- * <p>Please use {@link #getPhysicalCameraTotalResults() instead to get the
+ * <p>Please use {@link #getPhysicalCameraTotalResults()} instead to get the
* physical cameras' {@code TotalCaptureResult}.</p>
*/
public Map<String, CaptureResult> getPhysicalCameraResults() {
diff --git a/core/java/android/nfc/NfcAdapter.java b/core/java/android/nfc/NfcAdapter.java
index cacde7f..9e97216 100644
--- a/core/java/android/nfc/NfcAdapter.java
+++ b/core/java/android/nfc/NfcAdapter.java
@@ -711,6 +711,7 @@
/* Stale sService pointer */
if (sIsInitialized) sIsInitialized = false;
}
+ return null;
}
/* Try to initialize the service */
NfcManager manager = (NfcManager) context.getSystemService(Context.NFC_SERVICE);
diff --git a/core/java/android/os/GraphicsEnvironment.java b/core/java/android/os/GraphicsEnvironment.java
index 92be4c0..c9073fa 100644
--- a/core/java/android/os/GraphicsEnvironment.java
+++ b/core/java/android/os/GraphicsEnvironment.java
@@ -123,6 +123,7 @@
private int mAngleOptInIndex = -1;
private boolean mEnabledByGameMode = false;
+ private boolean mShouldUseAngle = false;
/**
* Set up GraphicsEnvironment
@@ -141,19 +142,16 @@
// Setup ANGLE and pass down ANGLE details to the C++ code
Trace.traceBegin(Trace.TRACE_TAG_GRAPHICS, "setupAngle");
- boolean useAngle = false;
if (setupAngle(context, coreSettings, pm, packageName)) {
- if (shouldUseAngle(context, coreSettings, packageName)) {
- useAngle = true;
- setGpuStats(ANGLE_DRIVER_NAME, ANGLE_DRIVER_VERSION_NAME, ANGLE_DRIVER_VERSION_CODE,
- 0, packageName, getVulkanVersion(pm));
- }
+ mShouldUseAngle = true;
+ setGpuStats(ANGLE_DRIVER_NAME, ANGLE_DRIVER_VERSION_NAME, ANGLE_DRIVER_VERSION_CODE,
+ 0, packageName, getVulkanVersion(pm));
}
Trace.traceEnd(Trace.TRACE_TAG_GRAPHICS);
Trace.traceBegin(Trace.TRACE_TAG_GRAPHICS, "chooseDriver");
if (!chooseDriver(context, coreSettings, pm, packageName, appInfoWithMetaData)) {
- if (!useAngle) {
+ if (!mShouldUseAngle) {
setGpuStats(SYSTEM_DRIVER_NAME, SYSTEM_DRIVER_VERSION_NAME,
SYSTEM_DRIVER_VERSION_CODE,
SystemProperties.getLong(PROPERTY_GFX_DRIVER_BUILD_TIME, 0),
@@ -636,7 +634,10 @@
}
/**
- * Show the ANGLE in Use Dialog Box
+ * Show the ANGLE in use dialog box.
+ * The ANGLE in use dialog box will show up as long as the application
+ * should use ANGLE. It does not mean the application has successfully
+ * loaded ANGLE because this check happens before the loading completes.
* @param context
*/
public void showAngleInUseDialogBox(Context context) {
@@ -644,8 +645,7 @@
return;
}
- final String packageName = context.getPackageName();
- if (!getShouldUseAngle(packageName)) {
+ if (!mShouldUseAngle) {
return;
}
@@ -890,9 +890,8 @@
private static native void setDriverPathAndSphalLibraries(String path, String sphalLibraries);
private static native void setGpuStats(String driverPackageName, String driverVersionName,
long driverVersionCode, long driverBuildTime, String appPackageName, int vulkanVersion);
- private static native void setAngleInfo(String path, String appPackage,
+ private static native void setAngleInfo(String path, String packageName,
String devOptIn, String[] features);
- private static native boolean getShouldUseAngle(String packageName);
private static native boolean setInjectLayersPrSetDumpable();
private static native void nativeToggleAngleAsSystemDriver(boolean enabled);
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 0144d22..84dc79b 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -1770,10 +1770,19 @@
/**
* Specifies if a user is not allowed to use 2g networks.
*
+ * <p> This is a security feature. 2g has no mutual authentication between a device and
+ * cellular base station and downgrading a device's connection to 2g is a common tactic for
+ * several types of privacy and security compromising attacks that could allow an adversary
+ * to intercept, inject, or modify cellular communications.
+ *
* <p>This restriction can only be set by a device owner or a profile owner of an
* organization-owned managed profile on the parent profile.
- * In all cases, the setting applies globally on the device and will prevent the device from
- * scanning for or connecting to 2g networks, except in the case of an emergency.
+ * In all cases, the setting applies globally on the device.
+ *
+ * <p> Cellular connectivity loss (where a device would have otherwise successfully
+ * connected to a 2g network) occurs if the device is in an area where only 2g networks are
+ * available. Emergency calls are an exception and are never impacted. The device will still
+ * scan for and connect to a 2g network for emergency calls.
*
* <p>Holders of the permission
* {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_MOBILE_NETWORK}
diff --git a/core/java/android/permission/PermissionControllerManager.java b/core/java/android/permission/PermissionControllerManager.java
index 319a0ea..84a197a 100644
--- a/core/java/android/permission/PermissionControllerManager.java
+++ b/core/java/android/permission/PermissionControllerManager.java
@@ -40,6 +40,7 @@
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Binder;
+import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Process;
@@ -81,8 +82,8 @@
public final class PermissionControllerManager {
private static final String TAG = PermissionControllerManager.class.getSimpleName();
- private static final long REQUEST_TIMEOUT_MILLIS = 60000;
- private static final long UNBIND_TIMEOUT_MILLIS = 10000;
+ private static final long REQUEST_TIMEOUT_MILLIS = 60000L * Build.HW_TIMEOUT_MULTIPLIER;
+ private static final long UNBIND_TIMEOUT_MILLIS = 10000L * Build.HW_TIMEOUT_MULTIPLIER;
private static final int CHUNK_SIZE = 4 * 1024;
private static final Object sLock = new Object();
diff --git a/core/java/android/service/dreams/DreamService.java b/core/java/android/service/dreams/DreamService.java
index cd57de5..5e7f5d6 100644
--- a/core/java/android/service/dreams/DreamService.java
+++ b/core/java/android/service/dreams/DreamService.java
@@ -16,6 +16,8 @@
package android.service.dreams;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+
import android.annotation.IdRes;
import android.annotation.LayoutRes;
import android.annotation.NonNull;
@@ -630,7 +632,7 @@
}
/**
- * Marks this dream as windowless. Only available to doze dreams.
+ * Marks this dream as windowless. It should be called in {@link #onCreate} method.
*
* @hide
*
@@ -640,7 +642,7 @@
}
/**
- * Returns whether this dream is windowless. Only available to doze dreams.
+ * Returns whether this dream is windowless.
*
* @hide
*/
@@ -1230,8 +1232,10 @@
mDreamToken = dreamToken;
mCanDoze = canDoze;
- if (mWindowless && !mCanDoze) {
- throw new IllegalStateException("Only doze dreams can be windowless");
+ // This is not a security check to prevent malicious dreams but a guard rail to stop
+ // third-party dreams from being windowless and not working well as a result.
+ if (mWindowless && !mCanDoze && !isCallerSystemUi()) {
+ throw new IllegalStateException("Only doze or SystemUI dreams can be windowless.");
}
mDispatchAfterOnAttachedToWindow = () -> {
@@ -1366,6 +1370,11 @@
}
}
+ private boolean isCallerSystemUi() {
+ return checkCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR_SERVICE)
+ == PERMISSION_GRANTED;
+ }
+
private int applyFlags(int oldFlags, int flags, int mask) {
return (oldFlags&~mask) | (flags&mask);
}
diff --git a/core/java/android/util/apk/SourceStampVerifier.java b/core/java/android/util/apk/SourceStampVerifier.java
index f9e3121..11d7a00 100644
--- a/core/java/android/util/apk/SourceStampVerifier.java
+++ b/core/java/android/util/apk/SourceStampVerifier.java
@@ -142,16 +142,21 @@
private static SourceStampVerificationResult verify(
RandomAccessFile apk, byte[] sourceStampCertificateDigest, byte[] manifestBytes) {
+ SignatureInfo signatureInfo;
try {
- SignatureInfo signatureInfo =
+ signatureInfo =
ApkSigningBlockUtils.findSignature(apk, SOURCE_STAMP_BLOCK_ID);
+ } catch (IOException | SignatureNotFoundException | RuntimeException e) {
+ return SourceStampVerificationResult.notPresent();
+ }
+ try {
Map<Integer, Map<Integer, byte[]>> signatureSchemeApkContentDigests =
getSignatureSchemeApkContentDigests(apk, manifestBytes);
return verify(
signatureInfo,
getSignatureSchemeDigests(signatureSchemeApkContentDigests),
sourceStampCertificateDigest);
- } catch (IOException | SignatureNotFoundException | RuntimeException e) {
+ } catch (IOException | RuntimeException e) {
return SourceStampVerificationResult.notVerified();
}
}
diff --git a/core/java/android/view/AttachedSurfaceControl.java b/core/java/android/view/AttachedSurfaceControl.java
index dc06671..1ed5d3f 100644
--- a/core/java/android/view/AttachedSurfaceControl.java
+++ b/core/java/android/view/AttachedSurfaceControl.java
@@ -23,6 +23,9 @@
import android.hardware.HardwareBuffer;
import android.window.SurfaceSyncGroup;
+import java.util.concurrent.Executor;
+import java.util.function.Consumer;
+
/**
* Provides an interface to the root-Surface of a View Hierarchy or Window. This
* is used in combination with the {@link android.view.SurfaceControl} API to enable
@@ -167,4 +170,40 @@
*/
default void setChildBoundingInsets(@NonNull Rect insets) {
}
+
+ /**
+ * Add a trusted presentation listener on the SurfaceControl associated with this window.
+ *
+ * @param t Transaction that the trusted presentation listener is added on. This should
+ * be applied by the caller.
+ * @param thresholds The {@link SurfaceControl.TrustedPresentationThresholds} that will specify
+ * when the to invoke the callback.
+ * @param executor The {@link Executor} where the callback will be invoked on.
+ * @param listener The {@link Consumer} that will receive the callbacks when entered or
+ * exited the threshold.
+ *
+ * @see SurfaceControl.Transaction#setTrustedPresentationCallback(SurfaceControl,
+ * SurfaceControl.TrustedPresentationThresholds, Executor, Consumer)
+ *
+ * @hide b/287076178 un-hide with API bump
+ */
+ default void addTrustedPresentationCallback(@NonNull SurfaceControl.Transaction t,
+ @NonNull SurfaceControl.TrustedPresentationThresholds thresholds,
+ @NonNull Executor executor, @NonNull Consumer<Boolean> listener) {
+ }
+
+ /**
+ * Remove a trusted presentation listener on the SurfaceControl associated with this window.
+ *
+ * @param t Transaction that the trusted presentation listener removed on. This should
+ * be applied by the caller.
+ * @param listener The {@link Consumer} that was previously registered with
+ * addTrustedPresentationCallback that should be removed.
+ *
+ * @see SurfaceControl.Transaction#clearTrustedPresentationCallback(SurfaceControl)
+ * @hide b/287076178 un-hide with API bump
+ */
+ default void removeTrustedPresentationCallback(@NonNull SurfaceControl.Transaction t,
+ @NonNull Consumer<Boolean> listener) {
+ }
}
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index d0ab8a7..71e9052 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -22467,6 +22467,22 @@
}
/**
+ * Configure the {@link android.graphics.RenderEffect} to apply to the backdrop contents of this
+ * View. This will apply a visual effect to the result of the backdrop contents of this View
+ * before it is drawn. For example if
+ * {@link RenderEffect#createBlurEffect(float, float, RenderEffect, Shader.TileMode)}
+ * is provided, the previous content behind this View will be blurred before this View is drawn.
+ * @param renderEffect to be applied to the View. Passing null clears the previously configured
+ * {@link RenderEffect}
+ * @hide
+ */
+ public void setBackdropRenderEffect(@Nullable RenderEffect renderEffect) {
+ if (mRenderNode.setBackdropRenderEffect(renderEffect)) {
+ invalidateViewProperty(true, true);
+ }
+ }
+
+ /**
* Updates the {@link Paint} object used with the current layer (used only if the current
* layer type is not set to {@link #LAYER_TYPE_NONE}). Changed properties of the Paint
* provided to {@link #setLayerType(int, android.graphics.Paint)} will be used the next time
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index f21851f..5eaf089 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -3824,7 +3824,7 @@
}
mPendingTransitions.clear();
}
- if (!performDraw() && mActiveSurfaceSyncGroup != null) {
+ if (!performDraw(mActiveSurfaceSyncGroup) && mActiveSurfaceSyncGroup != null) {
mActiveSurfaceSyncGroup.markSyncReady();
}
}
@@ -4590,6 +4590,10 @@
});
}
+ /**
+ * These callbacks check if the draw failed for any reason and apply
+ * those transactions directly so they don't get stuck forever.
+ */
private void registerCallbackForPendingTransactions() {
Transaction t = new Transaction();
t.merge(mPendingTransaction);
@@ -4618,7 +4622,7 @@
});
}
- private boolean performDraw() {
+ private boolean performDraw(@Nullable SurfaceSyncGroup surfaceSyncGroup) {
mLastPerformDrawSkippedReason = null;
if (mAttachInfo.mDisplayState == Display.STATE_OFF && !mReportNextDraw) {
mLastPerformDrawSkippedReason = "screen_off";
@@ -4628,7 +4632,7 @@
return false;
}
- final boolean fullRedrawNeeded = mFullRedrawNeeded || mActiveSurfaceSyncGroup != null;
+ final boolean fullRedrawNeeded = mFullRedrawNeeded || surfaceSyncGroup != null;
mFullRedrawNeeded = false;
mIsDrawing = true;
@@ -4636,22 +4640,12 @@
addFrameCommitCallbackIfNeeded();
- boolean usingAsyncReport = isHardwareEnabled() && mActiveSurfaceSyncGroup != null;
- if (usingAsyncReport) {
- registerCallbacksForSync(mSyncBuffer, mActiveSurfaceSyncGroup);
- } else if (mHasPendingTransactions) {
- // These callbacks are only needed if there's no sync involved and there were calls to
- // applyTransactionOnDraw. These callbacks check if the draw failed for any reason and
- // apply those transactions directly so they don't get stuck forever.
- registerCallbackForPendingTransactions();
- }
- mHasPendingTransactions = false;
+ boolean usingAsyncReport;
try {
- boolean canUseAsync = draw(fullRedrawNeeded, usingAsyncReport && mSyncBuffer);
- if (usingAsyncReport && !canUseAsync) {
+ usingAsyncReport = draw(fullRedrawNeeded, surfaceSyncGroup, mSyncBuffer);
+ if (mAttachInfo.mThreadedRenderer != null && !usingAsyncReport) {
mAttachInfo.mThreadedRenderer.setFrameCallback(null);
- usingAsyncReport = false;
}
} finally {
mIsDrawing = false;
@@ -4689,10 +4683,12 @@
}
if (mSurfaceHolder != null && mSurface.isValid()) {
- final SurfaceSyncGroup surfaceSyncGroup = mActiveSurfaceSyncGroup;
- SurfaceCallbackHelper sch = new SurfaceCallbackHelper(() ->
- mHandler.post(() -> surfaceSyncGroup.markSyncReady()));
- mActiveSurfaceSyncGroup = null;
+ usingAsyncReport = true;
+ SurfaceCallbackHelper sch = new SurfaceCallbackHelper(() -> {
+ if (surfaceSyncGroup != null) {
+ surfaceSyncGroup.markSyncReady();
+ }
+ });
SurfaceHolder.Callback callbacks[] = mSurfaceHolder.getCallbacks();
@@ -4703,8 +4699,9 @@
}
}
}
- if (mActiveSurfaceSyncGroup != null && !usingAsyncReport) {
- mActiveSurfaceSyncGroup.markSyncReady();
+
+ if (surfaceSyncGroup != null && !usingAsyncReport) {
+ surfaceSyncGroup.markSyncReady();
}
if (mPerformContentCapture) {
performContentCaptureInitialReport();
@@ -4797,7 +4794,8 @@
}
}
- private boolean draw(boolean fullRedrawNeeded, boolean forceDraw) {
+ private boolean draw(boolean fullRedrawNeeded,
+ @Nullable SurfaceSyncGroup activeSyncGroup, boolean syncBuffer) {
Surface surface = mSurface;
if (!surface.isValid()) {
return false;
@@ -4935,9 +4933,19 @@
mAttachInfo.mThreadedRenderer.setTargetHdrSdrRatio(mRenderHdrSdrRatio);
}
- if (forceDraw) {
- mAttachInfo.mThreadedRenderer.forceDrawNextFrame();
+ if (activeSyncGroup != null) {
+ registerCallbacksForSync(syncBuffer, activeSyncGroup);
+ if (syncBuffer) {
+ mAttachInfo.mThreadedRenderer.forceDrawNextFrame();
+ }
+ } else if (mHasPendingTransactions) {
+ // Register a calback if there's no sync involved but there were calls to
+ // applyTransactionOnDraw. If there is a sync involved, the sync callback will
+ // handle merging the pending transaction.
+ registerCallbackForPendingTransactions();
}
+ mHasPendingTransactions = false;
+
mAttachInfo.mThreadedRenderer.draw(mView, mAttachInfo, this);
} else {
// If we get here with a disabled & requested hardware renderer, something went
@@ -11593,4 +11601,17 @@
mChildBoundingInsetsChanged = true;
scheduleTraversals();
}
+
+ @Override
+ public void addTrustedPresentationCallback(@NonNull SurfaceControl.Transaction t,
+ @NonNull SurfaceControl.TrustedPresentationThresholds thresholds,
+ @NonNull Executor executor, @NonNull Consumer<Boolean> listener) {
+ t.setTrustedPresentationCallback(getSurfaceControl(), thresholds, executor, listener);
+ }
+
+ @Override
+ public void removeTrustedPresentationCallback(@NonNull SurfaceControl.Transaction t,
+ @NonNull Consumer<Boolean> listener) {
+ t.clearTrustedPresentationCallback(getSurfaceControl());
+ }
}
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
index c5af28e..12a5a7f 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
@@ -290,6 +290,7 @@
/**
* Action that selects the node.
+ * @see AccessibilityAction#ACTION_SELECT
*/
public static final int ACTION_SELECT = 1 << 2;
@@ -446,19 +447,8 @@
/**
* Action to set the selection. Performing this action with no arguments
* clears the selection.
- * <p>
- * <strong>Arguments:</strong>
- * {@link #ACTION_ARGUMENT_SELECTION_START_INT},
- * {@link #ACTION_ARGUMENT_SELECTION_END_INT}<br>
- * <strong>Example:</strong>
- * <code><pre><p>
- * Bundle arguments = new Bundle();
- * arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_START_INT, 1);
- * arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_END_INT, 2);
- * info.performAction(AccessibilityNodeInfo.ACTION_SET_SELECTION, arguments);
- * </code></pre></p>
- * </p>
*
+ * @see AccessibilityAction#ACTION_SET_SELECTION
* @see #ACTION_ARGUMENT_SELECTION_START_INT
* @see #ACTION_ARGUMENT_SELECTION_END_INT
*/
@@ -483,16 +473,7 @@
* Action that sets the text of the node. Performing the action without argument, using <code>
* null</code> or empty {@link CharSequence} will clear the text. This action will also put the
* cursor at the end of text.
- * <p>
- * <strong>Arguments:</strong>
- * {@link #ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE}<br>
- * <strong>Example:</strong>
- * <code><pre><p>
- * Bundle arguments = new Bundle();
- * arguments.putCharSequence(AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE,
- * "android");
- * info.performAction(AccessibilityNodeInfo.ACTION_SET_TEXT, arguments);
- * </code></pre></p>
+ * @see AccessibilityAction#ACTION_SET_TEXT
*/
public static final int ACTION_SET_TEXT = 1 << 21;
@@ -5188,12 +5169,16 @@
/**
* Action that selects the node.
+ * The view the implements this should send a
+ * {@link AccessibilityEvent#TYPE_VIEW_SELECTED} event.
+ * @see AccessibilityAction#ACTION_CLEAR_SELECTION
*/
public static final AccessibilityAction ACTION_SELECT =
new AccessibilityAction(AccessibilityNodeInfo.ACTION_SELECT);
/**
* Action that deselects the node.
+ * @see AccessibilityAction#ACTION_SELECT
*/
public static final AccessibilityAction ACTION_CLEAR_SELECTION =
new AccessibilityAction(AccessibilityNodeInfo.ACTION_CLEAR_SELECTION);
@@ -5427,7 +5412,10 @@
* info.performAction(AccessibilityAction.ACTION_SET_SELECTION.getId(), arguments);
* </code></pre></p>
* </p>
- *
+ * <p> If this is a text selection, the UI element that implements this should send a
+ * {@link AccessibilityEvent#TYPE_VIEW_TEXT_SELECTION_CHANGED} event if its selection is
+ * updated. This element should also return {@code true} for
+ * {@link AccessibilityNodeInfo#isTextSelectable()}.
* @see AccessibilityNodeInfo#ACTION_ARGUMENT_SELECTION_START_INT
* AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_START_INT
* @see AccessibilityNodeInfo#ACTION_ARGUMENT_SELECTION_END_INT
@@ -5469,6 +5457,10 @@
* "android");
* info.performAction(AccessibilityAction.ACTION_SET_TEXT.getId(), arguments);
* </code></pre></p>
+ * <p> The UI element that implements this should send a
+ * {@link AccessibilityEvent#TYPE_VIEW_TEXT_CHANGED} event if its text is updated.
+ * This element should also return {@code true} for
+ * {@link AccessibilityNodeInfo#isEditable()}.
*/
public static final AccessibilityAction ACTION_SET_TEXT =
new AccessibilityAction(AccessibilityNodeInfo.ACTION_SET_TEXT);
diff --git a/core/java/android/view/animation/AnimationUtils.java b/core/java/android/view/animation/AnimationUtils.java
index 11a80eb..f31a43f 100644
--- a/core/java/android/view/animation/AnimationUtils.java
+++ b/core/java/android/view/animation/AnimationUtils.java
@@ -19,6 +19,9 @@
import android.annotation.AnimRes;
import android.annotation.InterpolatorRes;
import android.annotation.TestApi;
+import android.compat.annotation.ChangeId;
+import android.compat.annotation.EnabledSince;
+import android.compat.annotation.Overridable;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.content.res.Resources;
@@ -47,6 +50,18 @@
private static final int TOGETHER = 0;
private static final int SEQUENTIALLY = 1;
+ /**
+ * For apps targeting {@link Build.VERSION_CODES#VANILLA_ICE_CREAM} and above,
+ * this change ID enables to use expectedPresentationTime instead of the frameTime
+ * for the frame start time .
+ *
+ * @hide
+ */
+ @ChangeId
+ @EnabledSince(targetSdkVersion = android.os.Build.VERSION_CODES.VANILLA_ICE_CREAM)
+ @Overridable
+ public static final long OVERRIDE_ENABLE_EXPECTED_PRSENTATION_TIME = 278730197L;
+
private static class AnimationState {
boolean animationClockLocked;
long currentVsyncTimeMillis;
diff --git a/core/java/android/window/WindowInfosListenerForTest.java b/core/java/android/window/WindowInfosListenerForTest.java
index 25bf85c..7fc55a7 100644
--- a/core/java/android/window/WindowInfosListenerForTest.java
+++ b/core/java/android/window/WindowInfosListenerForTest.java
@@ -87,6 +87,14 @@
this.isTrustedOverlay = (inputConfig & InputConfig.TRUSTED_OVERLAY) != 0;
this.isVisible = (inputConfig & InputConfig.NOT_VISIBLE) == 0;
}
+
+ @Override
+ public String toString() {
+ return name + ", frame=" + bounds
+ + ", isVisible=" + isVisible
+ + ", isTrustedOverlay=" + isTrustedOverlay
+ + ", token=" + windowToken;
+ }
}
private static final String TAG = "WindowInfosListenerForTest";
diff --git a/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java b/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
index 9ffccb3..385612d 100644
--- a/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
+++ b/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
@@ -552,12 +552,6 @@
"task_manager_inform_job_scheduler_of_pending_app_stop";
/**
- * (boolean) Whether widget provider info would be saved to / loaded from system persistence
- * layer as opposed to individual manifests in respective apps.
- */
- public static final String PERSISTS_WIDGET_PROVIDER_INFO = "persists_widget_provider_info";
-
- /**
* (boolean) Whether to show smart chips (based on TextClassifier) in the clipboard overlay.
*/
public static final String CLIPBOARD_OVERLAY_SHOW_ACTIONS = "clipboard_overlay_show_actions";
diff --git a/core/java/com/android/internal/jank/InteractionJankMonitor.java b/core/java/com/android/internal/jank/InteractionJankMonitor.java
index 869b696..92427ec 100644
--- a/core/java/com/android/internal/jank/InteractionJankMonitor.java
+++ b/core/java/com/android/internal/jank/InteractionJankMonitor.java
@@ -69,6 +69,7 @@
import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_APP_LAUNCH_FROM_SETTINGS_BUTTON;
import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_CLEAR_ALL;
import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_DIALOG_OPEN;
+import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_EXPAND_FROM_STATUS_BAR;
import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_HEADS_UP_APPEAR;
import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_HEADS_UP_DISAPPEAR;
import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_NOTIFICATION_ADD;
@@ -267,8 +268,9 @@
* eg: Exit the app using back gesture.
*/
public static final int CUJ_LAUNCHER_APP_CLOSE_TO_HOME_FALLBACK = 78;
+ public static final int CUJ_SHADE_EXPAND_FROM_STATUS_BAR = 79;
- private static final int LAST_CUJ = CUJ_LAUNCHER_APP_CLOSE_TO_HOME_FALLBACK;
+ private static final int LAST_CUJ = CUJ_SHADE_EXPAND_FROM_STATUS_BAR;
private static final int NO_STATSD_LOGGING = -1;
// Used to convert CujType to InteractionType enum value for statsd logging.
@@ -357,6 +359,7 @@
CUJ_TO_STATSD_INTERACTION_TYPE[76] = NO_STATSD_LOGGING;
CUJ_TO_STATSD_INTERACTION_TYPE[77] = NO_STATSD_LOGGING;
CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LAUNCHER_APP_CLOSE_TO_HOME_FALLBACK] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_APP_CLOSE_TO_HOME_FALLBACK;
+ CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_SHADE_EXPAND_FROM_STATUS_BAR] = UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_EXPAND_FROM_STATUS_BAR;
}
private static class InstanceHolder {
@@ -457,6 +460,7 @@
CUJ_LOCKSCREEN_CLOCK_MOVE_ANIMATION,
CUJ_LAUNCHER_OPEN_SEARCH_RESULT,
CUJ_LAUNCHER_APP_CLOSE_TO_HOME_FALLBACK,
+ CUJ_SHADE_EXPAND_FROM_STATUS_BAR,
})
@Retention(RetentionPolicy.SOURCE)
public @interface CujType {
@@ -1070,6 +1074,8 @@
return "LAUNCHER_OPEN_SEARCH_RESULT";
case CUJ_LAUNCHER_APP_CLOSE_TO_HOME_FALLBACK:
return "LAUNCHER_APP_CLOSE_TO_HOME_FALLBACK";
+ case CUJ_SHADE_EXPAND_FROM_STATUS_BAR:
+ return "SHADE_EXPAND_FROM_STATUS_BAR";
}
return "UNKNOWN";
}
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index a95ce64..7f53cb4 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -771,7 +771,7 @@
Zygote.applyInvokeWithSystemProperty(parsedArgs);
if (Zygote.nativeSupportsMemoryTagging()) {
- String mode = SystemProperties.get("arm64.memtag.process.system_server", "");
+ String mode = SystemProperties.get("persist.arm64.memtag.system_server", "");
if (mode.isEmpty()) {
/* The system server has ASYNC MTE by default, in order to allow
* system services to specify their own MTE level later, as you
diff --git a/core/jni/android_database_SQLiteConnection.cpp b/core/jni/android_database_SQLiteConnection.cpp
index 729c1c4..7e827a8 100644
--- a/core/jni/android_database_SQLiteConnection.cpp
+++ b/core/jni/android_database_SQLiteConnection.cpp
@@ -59,10 +59,6 @@
static const int BUSY_TIMEOUT_MS = 2500;
static struct {
- jmethodID onAuthorize;
-} gAuthorizer;
-
-static struct {
jmethodID apply;
} gUnaryOperator;
@@ -74,14 +70,11 @@
// Open flags.
// Must be kept in sync with the constants defined in SQLiteDatabase.java.
enum {
- OPEN_READWRITE = 0x00000000,
- OPEN_READONLY = 0x00000001,
- OPEN_READ_MASK = 0x00000001,
- NO_LOCALIZED_COLLATORS = 0x00000010,
- ENABLE_TRACE = 0x00000100,
- ENABLE_PROFILE = 0x00000200,
- ENABLE_AUTHORIZER = 0x00000400,
- CREATE_IF_NECESSARY = 0x10000000,
+ OPEN_READWRITE = 0x00000000,
+ OPEN_READONLY = 0x00000001,
+ OPEN_READ_MASK = 0x00000001,
+ NO_LOCALIZED_COLLATORS = 0x00000010,
+ CREATE_IF_NECESSARY = 0x10000000,
};
sqlite3* const db;
@@ -90,15 +83,9 @@
const String8 label;
volatile bool canceled;
- volatile jobject authorizer;
- SQLiteConnection(sqlite3* db, int openFlags, const String8& path, const String8& label)
- : db(db),
- openFlags(openFlags),
- path(path),
- label(label),
- canceled(false),
- authorizer(NULL) {}
+ SQLiteConnection(sqlite3* db, int openFlags, const String8& path, const String8& label) :
+ db(db), openFlags(openFlags), path(path), label(label), canceled(false) { }
};
// Called each time a statement begins execution, when tracing is enabled.
@@ -121,34 +108,10 @@
return connection->canceled;
}
-static int sqliteAuthorizerCallback(void* data, int action, const char* arg3, const char* arg4,
- const char* arg5, const char* arg6) {
- SQLiteConnection* connection = static_cast<SQLiteConnection*>(data);
- if (connection->authorizer) {
- JNIEnv* env = AndroidRuntime::getJNIEnv();
- ScopedLocalRef<jobject> authorizerObj(env, env->NewLocalRef(connection->authorizer));
- ScopedLocalRef<jstring> arg3String(env, env->NewStringUTF(arg3));
- ScopedLocalRef<jstring> arg4String(env, env->NewStringUTF(arg4));
- ScopedLocalRef<jstring> arg5String(env, env->NewStringUTF(arg5));
- ScopedLocalRef<jstring> arg6String(env, env->NewStringUTF(arg6));
- int res = env->CallIntMethod(authorizerObj.get(), gAuthorizer.onAuthorize, action,
- arg3String.get(), arg4String.get(), arg5String.get(),
- arg6String.get());
- if (env->ExceptionCheck()) {
- ALOGE("Exception thrown by authorizer");
- env->ExceptionDescribe();
- env->ExceptionClear();
- return SQLITE_DENY;
- } else {
- return res;
- }
- } else {
- return SQLITE_OK;
- }
-}
static jlong nativeOpen(JNIEnv* env, jclass clazz, jstring pathStr, jint openFlags,
- jstring labelStr, jint lookasideSz, jint lookasideCnt) {
+ jstring labelStr, jboolean enableTrace, jboolean enableProfile, jint lookasideSz,
+ jint lookasideCnt) {
int sqliteFlags;
if (openFlags & SQLiteConnection::CREATE_IF_NECESSARY) {
sqliteFlags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
@@ -209,16 +172,13 @@
// Create wrapper object.
SQLiteConnection* connection = new SQLiteConnection(db, openFlags, path, label);
- // Enable optional features if requested.
- if (openFlags & SQLiteConnection::ENABLE_TRACE) {
+ // Enable tracing and profiling if requested.
+ if (enableTrace) {
sqlite3_trace(db, &sqliteTraceCallback, connection);
}
- if (openFlags & SQLiteConnection::ENABLE_PROFILE) {
+ if (enableProfile) {
sqlite3_profile(db, &sqliteProfileCallback, connection);
}
- if (openFlags & SQLiteConnection::ENABLE_AUTHORIZER) {
- sqlite3_set_authorizer(db, &sqliteAuthorizerCallback, connection);
- }
ALOGV("Opened connection %p with label '%s'", db, label.string());
return reinterpret_cast<jlong>(connection);
@@ -228,11 +188,6 @@
SQLiteConnection* connection = reinterpret_cast<SQLiteConnection*>(connectionPtr);
if (connection) {
- if (connection->authorizer) {
- env->DeleteGlobalRef(connection->authorizer);
- connection->authorizer = NULL;
- }
-
ALOGV("Closing connection %p", connection->db);
int err = sqlite3_close(connection->db);
if (err != SQLITE_OK) {
@@ -246,20 +201,6 @@
}
}
-static void nativeSetAuthorizer(JNIEnv* env, jclass clazz, jlong connectionPtr,
- jobject authorizerObj) {
- SQLiteConnection* connection = reinterpret_cast<SQLiteConnection*>(connectionPtr);
-
- if (connection->authorizer) {
- env->DeleteGlobalRef(connection->authorizer);
- connection->authorizer = NULL;
- }
- if (authorizerObj) {
- jobject authorizerObjGlobal = env->NewGlobalRef(authorizerObj);
- connection->authorizer = authorizerObjGlobal;
- }
-}
-
static void sqliteCustomScalarFunctionCallback(sqlite3_context *context,
int argc, sqlite3_value **argv) {
JNIEnv* env = AndroidRuntime::getJNIEnv();
@@ -944,53 +885,69 @@
return sqlite3_last_insert_rowid(connection->db);
}
-static const JNINativeMethod sMethods[] = {
- /* name, signature, funcPtr */
- {"nativeOpen", "(Ljava/lang/String;ILjava/lang/String;II)J", (void*)nativeOpen},
- {"nativeClose", "(J)V", (void*)nativeClose},
- {"nativeSetAuthorizer", "(JLandroid/database/sqlite/SQLiteAuthorizer;)V",
- (void*)nativeSetAuthorizer},
- {"nativeRegisterCustomScalarFunction",
- "(JLjava/lang/String;Ljava/util/function/UnaryOperator;)V",
- (void*)nativeRegisterCustomScalarFunction},
- {"nativeRegisterCustomAggregateFunction",
- "(JLjava/lang/String;Ljava/util/function/BinaryOperator;)V",
- (void*)nativeRegisterCustomAggregateFunction},
- {"nativeRegisterLocalizedCollators", "(JLjava/lang/String;)V",
- (void*)nativeRegisterLocalizedCollators},
- {"nativePrepareStatement", "(JLjava/lang/String;)J", (void*)nativePrepareStatement},
- {"nativeFinalizeStatement", "(JJ)V", (void*)nativeFinalizeStatement},
- {"nativeGetParameterCount", "(JJ)I", (void*)nativeGetParameterCount},
- {"nativeIsReadOnly", "(JJ)Z", (void*)nativeIsReadOnly},
- {"nativeGetColumnCount", "(JJ)I", (void*)nativeGetColumnCount},
- {"nativeGetColumnName", "(JJI)Ljava/lang/String;", (void*)nativeGetColumnName},
- {"nativeBindNull", "(JJI)V", (void*)nativeBindNull},
- {"nativeBindLong", "(JJIJ)V", (void*)nativeBindLong},
- {"nativeBindDouble", "(JJID)V", (void*)nativeBindDouble},
- {"nativeBindString", "(JJILjava/lang/String;)V", (void*)nativeBindString},
- {"nativeBindBlob", "(JJI[B)V", (void*)nativeBindBlob},
- {"nativeResetStatementAndClearBindings", "(JJ)V",
- (void*)nativeResetStatementAndClearBindings},
- {"nativeExecute", "(JJZ)V", (void*)nativeExecute},
- {"nativeExecuteForLong", "(JJ)J", (void*)nativeExecuteForLong},
- {"nativeExecuteForString", "(JJ)Ljava/lang/String;", (void*)nativeExecuteForString},
- {"nativeExecuteForBlobFileDescriptor", "(JJ)I", (void*)nativeExecuteForBlobFileDescriptor},
- {"nativeExecuteForChangedRowCount", "(JJ)I", (void*)nativeExecuteForChangedRowCount},
- {"nativeExecuteForLastInsertedRowId", "(JJ)J", (void*)nativeExecuteForLastInsertedRowId},
- {"nativeExecuteForCursorWindow", "(JJJIIZ)J", (void*)nativeExecuteForCursorWindow},
- {"nativeGetDbLookaside", "(J)I", (void*)nativeGetDbLookaside},
- {"nativeCancel", "(J)V", (void*)nativeCancel},
- {"nativeResetCancel", "(JZ)V", (void*)nativeResetCancel},
+static const JNINativeMethod sMethods[] =
+{
+ /* name, signature, funcPtr */
+ { "nativeOpen", "(Ljava/lang/String;ILjava/lang/String;ZZII)J",
+ (void*)nativeOpen },
+ { "nativeClose", "(J)V",
+ (void*)nativeClose },
+ { "nativeRegisterCustomScalarFunction", "(JLjava/lang/String;Ljava/util/function/UnaryOperator;)V",
+ (void*)nativeRegisterCustomScalarFunction },
+ { "nativeRegisterCustomAggregateFunction", "(JLjava/lang/String;Ljava/util/function/BinaryOperator;)V",
+ (void*)nativeRegisterCustomAggregateFunction },
+ { "nativeRegisterLocalizedCollators", "(JLjava/lang/String;)V",
+ (void*)nativeRegisterLocalizedCollators },
+ { "nativePrepareStatement", "(JLjava/lang/String;)J",
+ (void*)nativePrepareStatement },
+ { "nativeFinalizeStatement", "(JJ)V",
+ (void*)nativeFinalizeStatement },
+ { "nativeGetParameterCount", "(JJ)I",
+ (void*)nativeGetParameterCount },
+ { "nativeIsReadOnly", "(JJ)Z",
+ (void*)nativeIsReadOnly },
+ { "nativeGetColumnCount", "(JJ)I",
+ (void*)nativeGetColumnCount },
+ { "nativeGetColumnName", "(JJI)Ljava/lang/String;",
+ (void*)nativeGetColumnName },
+ { "nativeBindNull", "(JJI)V",
+ (void*)nativeBindNull },
+ { "nativeBindLong", "(JJIJ)V",
+ (void*)nativeBindLong },
+ { "nativeBindDouble", "(JJID)V",
+ (void*)nativeBindDouble },
+ { "nativeBindString", "(JJILjava/lang/String;)V",
+ (void*)nativeBindString },
+ { "nativeBindBlob", "(JJI[B)V",
+ (void*)nativeBindBlob },
+ { "nativeResetStatementAndClearBindings", "(JJ)V",
+ (void*)nativeResetStatementAndClearBindings },
+ { "nativeExecute", "(JJZ)V",
+ (void*)nativeExecute },
+ { "nativeExecuteForLong", "(JJ)J",
+ (void*)nativeExecuteForLong },
+ { "nativeExecuteForString", "(JJ)Ljava/lang/String;",
+ (void*)nativeExecuteForString },
+ { "nativeExecuteForBlobFileDescriptor", "(JJ)I",
+ (void*)nativeExecuteForBlobFileDescriptor },
+ { "nativeExecuteForChangedRowCount", "(JJ)I",
+ (void*)nativeExecuteForChangedRowCount },
+ { "nativeExecuteForLastInsertedRowId", "(JJ)J",
+ (void*)nativeExecuteForLastInsertedRowId },
+ { "nativeExecuteForCursorWindow", "(JJJIIZ)J",
+ (void*)nativeExecuteForCursorWindow },
+ { "nativeGetDbLookaside", "(J)I",
+ (void*)nativeGetDbLookaside },
+ { "nativeCancel", "(J)V",
+ (void*)nativeCancel },
+ { "nativeResetCancel", "(JZ)V",
+ (void*)nativeResetCancel },
- {"nativeLastInsertRowId", "(J)I", (void*)nativeLastInsertRowId}};
+ { "nativeLastInsertRowId", "(J)I", (void*) nativeLastInsertRowId }
+};
int register_android_database_SQLiteConnection(JNIEnv *env)
{
- jclass authorizerClazz = FindClassOrDie(env, "android/database/sqlite/SQLiteAuthorizer");
- gAuthorizer.onAuthorize = GetMethodIDOrDie(env, authorizerClazz, "onAuthorize",
- "(ILjava/lang/String;Ljava/lang/String;Ljava/lang/"
- "String;Ljava/lang/String;)I");
-
jclass unaryClazz = FindClassOrDie(env, "java/util/function/UnaryOperator");
gUnaryOperator.apply = GetMethodIDOrDie(env, unaryClazz,
"apply", "(Ljava/lang/Object;)Ljava/lang/Object;");
diff --git a/core/jni/android_hardware_input_InputWindowHandle.cpp b/core/jni/android_hardware_input_InputWindowHandle.cpp
index 416d991..eb5f297 100644
--- a/core/jni/android_hardware_input_InputWindowHandle.cpp
+++ b/core/jni/android_hardware_input_InputWindowHandle.cpp
@@ -163,10 +163,9 @@
mInfo.touchOcclusionMode = static_cast<TouchOcclusionMode>(
env->GetIntField(obj, gInputWindowHandleClassInfo.touchOcclusionMode));
- mInfo.ownerPid = env->GetIntField(obj,
- gInputWindowHandleClassInfo.ownerPid);
- mInfo.ownerUid = env->GetIntField(obj,
- gInputWindowHandleClassInfo.ownerUid);
+ mInfo.ownerPid = gui::Pid{env->GetIntField(obj, gInputWindowHandleClassInfo.ownerPid)};
+ mInfo.ownerUid = gui::Uid{
+ static_cast<uid_t>(env->GetIntField(obj, gInputWindowHandleClassInfo.ownerUid))};
mInfo.packageName = getStringField(env, obj, gInputWindowHandleClassInfo.packageName, "<null>");
mInfo.displayId = env->GetIntField(obj,
gInputWindowHandleClassInfo.displayId);
@@ -308,8 +307,10 @@
env->SetIntField(inputWindowHandle, gInputWindowHandleClassInfo.touchOcclusionMode,
static_cast<int32_t>(windowInfo.touchOcclusionMode));
- env->SetIntField(inputWindowHandle, gInputWindowHandleClassInfo.ownerPid, windowInfo.ownerPid);
- env->SetIntField(inputWindowHandle, gInputWindowHandleClassInfo.ownerUid, windowInfo.ownerUid);
+ env->SetIntField(inputWindowHandle, gInputWindowHandleClassInfo.ownerPid,
+ windowInfo.ownerPid.val());
+ env->SetIntField(inputWindowHandle, gInputWindowHandleClassInfo.ownerUid,
+ windowInfo.ownerUid.val());
ScopedLocalRef<jstring> packageName(env, env->NewStringUTF(windowInfo.packageName.data()));
env->SetObjectField(inputWindowHandle, gInputWindowHandleClassInfo.packageName,
packageName.get());
diff --git a/core/jni/android_os_GraphicsEnvironment.cpp b/core/jni/android_os_GraphicsEnvironment.cpp
index 01dbceb..d94b982 100644
--- a/core/jni/android_os_GraphicsEnvironment.cpp
+++ b/core/jni/android_os_GraphicsEnvironment.cpp
@@ -49,10 +49,10 @@
appPackageNameChars.c_str(), vulkanVersion);
}
-void setAngleInfo_native(JNIEnv* env, jobject clazz, jstring path, jstring appName,
+void setAngleInfo_native(JNIEnv* env, jobject clazz, jstring path, jstring packageName,
jstring devOptIn, jobjectArray featuresObj) {
ScopedUtfChars pathChars(env, path);
- ScopedUtfChars appNameChars(env, appName);
+ ScopedUtfChars packageNameChars(env, packageName);
ScopedUtfChars devOptInChars(env, devOptIn);
std::vector<std::string> features;
@@ -73,15 +73,10 @@
}
}
- android::GraphicsEnv::getInstance().setAngleInfo(pathChars.c_str(), appNameChars.c_str(),
+ android::GraphicsEnv::getInstance().setAngleInfo(pathChars.c_str(), packageNameChars.c_str(),
devOptInChars.c_str(), features);
}
-bool shouldUseAngle_native(JNIEnv* env, jobject clazz, jstring appName) {
- ScopedUtfChars appNameChars(env, appName);
- return android::GraphicsEnv::getInstance().shouldUseAngle(appNameChars.c_str());
-}
-
void setLayerPaths_native(JNIEnv* env, jobject clazz, jobject classLoader, jstring layerPaths) {
android::NativeLoaderNamespace* appNamespace = android::FindNativeLoaderNamespaceByClassLoader(
env, classLoader);
@@ -126,8 +121,6 @@
{"setAngleInfo",
"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;)V",
reinterpret_cast<void*>(setAngleInfo_native)},
- {"getShouldUseAngle", "(Ljava/lang/String;)Z",
- reinterpret_cast<void*>(shouldUseAngle_native)},
{"setLayerPaths", "(Ljava/lang/ClassLoader;Ljava/lang/String;)V",
reinterpret_cast<void*>(setLayerPaths_native)},
{"setDebugLayers", "(Ljava/lang/String;)V", reinterpret_cast<void*>(setDebugLayers_native)},
diff --git a/core/proto/android/companion/telecom.proto b/core/proto/android/companion/telecom.proto
index 7fe24670..73dd8dd 100644
--- a/core/proto/android/companion/telecom.proto
+++ b/core/proto/android/companion/telecom.proto
@@ -88,6 +88,8 @@
string name = 1;
// Unique identifier for this facilitator, such as a package name.
string identifier = 2;
+ // Extended identifier for this facilitator.
+ string extended_identifier = 3;
}
enum Control {
diff --git a/core/res/res/drawable/ic_bluetooth_share_icon.xml b/core/res/res/drawable/ic_bluetooth_share_icon.xml
deleted file mode 100644
index 6acfd57..0000000
--- a/core/res/res/drawable/ic_bluetooth_share_icon.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<!--
- Copyright (C) 2019 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.
--->
-<!-- This drawable should only be used by the Bluetooth application for its share target icon. -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24dp"
- android:height="24dp"
- android:viewportWidth="24"
- android:viewportHeight="24"
- android:tint="@*android:color/accent_device_default_light">
-
- <path
- android:fillColor="@android:color/white"
- android:pathData="M17.71,7.71L12,2h-1v7.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L11,14.41V22h1l5.71-5.71L13.41,12L17.71,7.71z M13,5.83 l1.88,1.88L13,9.59V5.83z M14.88,16.29L13,18.17v-3.76L14.88,16.29z" />
-</vector>
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 7319425..910e1da 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -1959,7 +1959,8 @@
<string name="app_blocked_title" msgid="7353262160455028160">"Program is nie beskikbaar nie"</string>
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> is nie op die oomblik beskikbaar nie."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> is nie beskikbaar nie"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Toestemming word benodig"</string>
+ <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (3805704317624448487) -->
+ <skip />
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"Kamera is nie beskikbaar nie"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"Gaan voort op foon"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"Mikrofoon is nie beskikbaar nie"</string>
@@ -1970,6 +1971,12 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Jy kan nie nou toegang hiertoe op jou <xliff:g id="DEVICE">%1$s</xliff:g> kry nie. Probeer eerder op jou Android TV-toestel."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Jy kan nie nou toegang hiertoe op jou <xliff:g id="DEVICE">%1$s</xliff:g> kry nie. Probeer eerder op jou tablet."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Jy kan nie nou toegang hiertoe op jou <xliff:g id="DEVICE">%1$s</xliff:g> kry nie. Probeer eerder op jou foon."</string>
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (4706276040125072077) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (1824604581465771629) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (7755223160363292105) -->
+ <skip />
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"Hierdie program versoek tans bykomende sekuriteit. Probeer eerder op jou Android TV-toestel."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"Hierdie program versoek tans bykomende sekuriteit. Probeer eerder op jou tablet."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Hierdie program versoek tans bykomende sekuriteit. Probeer eerder op jou foon."</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 6643a07..40df279 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -1959,7 +1959,8 @@
<string name="app_blocked_title" msgid="7353262160455028160">"መተግበሪያ አይገኝም"</string>
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> አሁን አይገኝም።"</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> አይገኝም"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"ፈቃድ ያስፈልጋል"</string>
+ <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (3805704317624448487) -->
+ <skip />
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"ካሜራ አይገኝም"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"በስልክ ላይ ይቀጥሉ"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"ማይክሮፎን አይገኝም"</string>
@@ -1970,6 +1971,12 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"ይህ በዚህ ጊዜ በእርስዎ <xliff:g id="DEVICE">%1$s</xliff:g> ላይ ሊደረስበት አይችልም። በምትኩ በAndroid TV መሣሪያዎ ላይ ይሞክሩ።"</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"ይህ በዚህ ጊዜ በእርስዎ <xliff:g id="DEVICE">%1$s</xliff:g> ላይ ሊደረስበት አይችልም። በምትኩ በጡባዊዎ ላይ ይሞክሩ።"</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"ይህ በዚህ ጊዜ በእርስዎ <xliff:g id="DEVICE">%1$s</xliff:g> ላይ ሊደረስበት አይችልም። በምትኩ በስልክዎ ላይ ይሞክሩ።"</string>
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (4706276040125072077) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (1824604581465771629) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (7755223160363292105) -->
+ <skip />
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"ይህ መተግበሪያ ተጨማሪ ደህንነትን እየጠየቀ ነው። በምትኩ በAndroid TV መሣሪያዎ ላይ ይሞክሩ።"</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"ይህ መተግበሪያ ተጨማሪ ደህንነትን እየጠየቀ ነው። በምትኩ በጡባዊዎ ላይ ይሞክሩ።"</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"ይህ መተግበሪያ ተጨማሪ ደህንነትን እየጠየቀ ነው። በምትኩ በስልክዎ ላይ ይሞክሩ።"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 33209eb..0df3ec4 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -1223,7 +1223,7 @@
<string name="aerr_application_repeated" msgid="7804378743218496566">"يستمر التطبيق <xliff:g id="APPLICATION">%1$s</xliff:g> في التوقف."</string>
<string name="aerr_process_repeated" msgid="1153152413537954974">"تستمر عملية <xliff:g id="PROCESS">%1$s</xliff:g> في التوقف."</string>
<string name="aerr_restart" msgid="2789618625210505419">"فتح التطبيق مرة أخرى"</string>
- <string name="aerr_report" msgid="3095644466849299308">"إرسال تعليقات"</string>
+ <string name="aerr_report" msgid="3095644466849299308">"إرسال ملاحظات"</string>
<string name="aerr_close" msgid="3398336821267021852">"إغلاق"</string>
<string name="aerr_mute" msgid="2304972923480211376">"كتم الصوت حتى إعادة تشغيل الجهاز"</string>
<string name="aerr_wait" msgid="3198677780474548217">"انتظار"</string>
@@ -1963,7 +1963,8 @@
<string name="app_blocked_title" msgid="7353262160455028160">"التطبيق غير متاح"</string>
<string name="app_blocked_message" msgid="542972921087873023">"تطبيق <xliff:g id="APP_NAME">%1$s</xliff:g> غير متاح الآن."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"تطبيق <xliff:g id="ACTIVITY">%1$s</xliff:g> غير متاح"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"مطلوب منح الإذن"</string>
+ <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (3805704317624448487) -->
+ <skip />
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"الكاميرا غير متاحة"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"الاستمرار على الهاتف"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"الميكروفون غير متاح"</string>
@@ -1974,6 +1975,12 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"لا يمكن الوصول إلى هذا التطبيق على <xliff:g id="DEVICE">%1$s</xliff:g> في الوقت الحالي. حاوِل الوصول إليه على جهاز Android TV بدلاً من ذلك."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"لا يمكن الوصول إلى هذا التطبيق على <xliff:g id="DEVICE">%1$s</xliff:g> في الوقت الحالي. حاوِل الوصول إليه على جهازك اللوحي بدلاً من ذلك."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"لا يمكن الوصول إلى هذا التطبيق على <xliff:g id="DEVICE">%1$s</xliff:g> في الوقت الحالي. حاوِل الوصول إليه على هاتفك بدلاً من ذلك."</string>
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (4706276040125072077) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (1824604581465771629) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (7755223160363292105) -->
+ <skip />
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"يطلب هذا التطبيق الحصول على ميزات أمان إضافية. بدلاً من ذلك، جرِّب استخدام Android TV."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"يطلب هذا التطبيق الحصول على ميزات أمان إضافية. بدلاً من ذلك، جرِّب استخدام جهازك اللوحي."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"يطلب هذا التطبيق الحصول على ميزات أمان إضافية. بدلاً من ذلك، جرِّب استخدام هاتفك."</string>
diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml
index 838586f..f172511 100644
--- a/core/res/res/values-as/strings.xml
+++ b/core/res/res/values-as/strings.xml
@@ -705,7 +705,7 @@
<skip />
<string name="face_acquired_recalibrate_alt" msgid="5702674220280332115">"মুখাৱয়বৰ মডেল সৃষ্টি কৰিব নোৱাৰি। পুনৰ চেষ্টা কৰক।"</string>
<string name="face_acquired_dark_glasses_detected_alt" msgid="4052123776406041972">"ডাঠ ৰঙৰ চশমা চিনাক্ত কৰা হৈছে। আপোনাৰ মুখাৱয়ব সম্পূৰ্ণৰূপে দেখা পোৱা হৈ থাকিবই লাগিব।"</string>
- <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"মুখাৱয়বত আৱৰণ চিনাক্ত কৰা হৈছে। আপোনাৰ মুখাৱয়ব সম্পূৰ্ণৰূপে দেখা পোৱা হৈ থাকিবই লাগিব।"</string>
+ <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"মুখাৱয়ব ঢাক খাই আছে। সম্পূৰ্ণ মুখাৱয়ব দেখা পাব লাগিব।"</string>
<string-array name="face_acquired_vendor">
</string-array>
<string name="face_error_hw_not_available" msgid="5085202213036026288">"মুখমণ্ডল সত্যাপন কৰিব পৰা নগ’ল। হাৰ্ডৱেৰ নাই।"</string>
@@ -1959,7 +1959,8 @@
<string name="app_blocked_title" msgid="7353262160455028160">"এপ্টো উপলব্ধ নহয়"</string>
<string name="app_blocked_message" msgid="542972921087873023">"এই মুহূৰ্তত <xliff:g id="APP_NAME">%1$s</xliff:g> উপলব্ধ নহয়।"</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> উপলব্ধ নহয়"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"অনুমতিৰ প্ৰয়োজন"</string>
+ <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (3805704317624448487) -->
+ <skip />
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"কেমেৰা উপলব্ধ নহয়"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"ফ’নতে অব্যাহত ৰাখক"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"মাইক্ৰ’ফ’ন উপলব্ধ নহয়"</string>
@@ -1970,6 +1971,12 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"এইটো এতিয়া আপোনাৰ <xliff:g id="DEVICE">%1$s</xliff:g>ত এক্সেছ কৰিব পৰা নাযায়। তাৰ পৰিৱৰ্তে আপোনাৰ Android TVত চেষ্টা কৰি চাওক।"</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"এইটো এতিয়া আপোনাৰ <xliff:g id="DEVICE">%1$s</xliff:g>ত এক্সেছ কৰিব পৰা নাযায়। তাৰ পৰিৱৰ্তে আপোনাৰ টেবলেটটোত চেষ্টা কৰি চাওক।"</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"এইটো এতিয়া আপোনাৰ <xliff:g id="DEVICE">%1$s</xliff:g>ত এক্সেছ কৰিব পৰা নাযায়। তাৰ পৰিৱৰ্তে আপোনাৰ ফ’নত চেষ্টা কৰি চাওক।"</string>
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (4706276040125072077) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (1824604581465771629) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (7755223160363292105) -->
+ <skip />
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"এই এপ্টোৱে অতিৰিক্ত সুৰক্ষাৰ বাবে অনুৰোধ কৰিছে। তাৰ পৰিৱৰ্তে আপোনাৰ Android TV ডিভাইচত চেষ্টা কৰি চাওক।"</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"এই এপ্টোৱে অতিৰিক্ত সুৰক্ষাৰ বাবে অনুৰোধ কৰিছে। তাৰ পৰিৱৰ্তে আপোনাৰ টেবলেটত চেষ্টা কৰি চাওক।"</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"এই এপ্টোৱে অতিৰিক্ত সুৰক্ষাৰ বাবে অনুৰোধ কৰিছে। তাৰ পৰিৱৰ্তে আপোনাৰ ফ’নত চেষ্টা কৰি চাওক।"</string>
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index bf0b3b4..cf06e90 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -1959,7 +1959,8 @@
<string name="app_blocked_title" msgid="7353262160455028160">"Tətbiq əlçatan deyil"</string>
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> hazırda əlçatan deyil."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> əlçatan deyil"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"İcazə tələb olunur"</string>
+ <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (3805704317624448487) -->
+ <skip />
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"Kamera əlçatan deyil"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"Telefonda davam edin"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"Mikrofon əlçatan deyil"</string>
@@ -1970,6 +1971,12 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Hazırda <xliff:g id="DEVICE">%1$s</xliff:g> cihazınızda buna giriş mümkün deyil. Android TV cihazınızda sınayın."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Hazırda <xliff:g id="DEVICE">%1$s</xliff:g> cihazınızda buna giriş mümkün deyil. Planşetinizdə sınayın."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Hazırda <xliff:g id="DEVICE">%1$s</xliff:g> cihazınızda buna giriş mümkün deyil. Telefonunuzda sınayın."</string>
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (4706276040125072077) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (1824604581465771629) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (7755223160363292105) -->
+ <skip />
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"Bu tətbiq əlavə təhlükəsizlik tələb edir. Android TV cihazınızda sınayın."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"Bu tətbiq əlavə təhlükəsizlik tələb edir. Planşetinizdə sınayın."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Bu tətbiq əlavə təhlükəsizlik tələb edir. Telefonunuzda sınayı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 1d96814e..d6eb21c 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -1367,7 +1367,7 @@
<string name="usb_ptp_notification_title" msgid="5043437571863443281">"Režim PTP preko USB-a je uključen"</string>
<string name="usb_tether_notification_title" msgid="8828527870612663771">"USB privezivanje je uključeno"</string>
<string name="usb_midi_notification_title" msgid="7404506788950595557">"Režim MIDI preko USB-a je uključen"</string>
- <string name="usb_uvc_notification_title" msgid="2030032862673400008">"Uređaj povezan sa veb-kamerom"</string>
+ <string name="usb_uvc_notification_title" msgid="2030032862673400008">"Uređaj povezan kao veb-kamera"</string>
<string name="usb_accessory_notification_title" msgid="1385394660861956980">"USB dodatak je povezan"</string>
<string name="usb_notification_message" msgid="4715163067192110676">"Dodirnite za još opcija."</string>
<string name="usb_power_notification_message" msgid="7284765627437897702">"Povezani uređaj se puni. Dodirnite za još opcija."</string>
@@ -1960,7 +1960,8 @@
<string name="app_blocked_title" msgid="7353262160455028160">"Aplikacija nije dostupna"</string>
<string name="app_blocked_message" msgid="542972921087873023">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> trenutno nije dostupna."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> – nije dostupno"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Potrebna je dozvola"</string>
+ <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (3805704317624448487) -->
+ <skip />
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"Kamera nije dostupna"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"Nastavite na telefonu"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"Mikrofon je nedostupan"</string>
@@ -1971,6 +1972,12 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Ovoj aplikaciji trenutno ne može da se pristupi sa uređaja <xliff:g id="DEVICE">%1$s</xliff:g>. Probajte na Android TV uređaju."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Ovoj aplikaciji trenutno ne može da se pristupi sa uređaja <xliff:g id="DEVICE">%1$s</xliff:g>. Probajte na tabletu."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Ovoj aplikaciji trenutno ne može da se pristupi sa uređaja <xliff:g id="DEVICE">%1$s</xliff:g>. Probajte na telefonu."</string>
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (4706276040125072077) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (1824604581465771629) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (7755223160363292105) -->
+ <skip />
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"Ova aplikacija zahteva dodatnu bezbednost. Probajte na Android TV uređaju."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"Ova aplikacija zahteva dodatnu bezbednost. Probajte na tabletu."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Ova aplikacija zahteva dodatnu bezbednost. Probajte na telefonu."</string>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index a0ba0a9..9e234e1 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -1961,7 +1961,8 @@
<string name="app_blocked_title" msgid="7353262160455028160">"Праграма недаступная"</string>
<string name="app_blocked_message" msgid="542972921087873023">"Праграма \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" цяпер недаступная."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"Недаступна: <xliff:g id="ACTIVITY">%1$s</xliff:g>"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Патрабуецца дазвол"</string>
+ <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (3805704317624448487) -->
+ <skip />
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"Камера недаступная"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"Працягніце на тэлефоне"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"Мікрафон недаступны"</string>
@@ -1972,6 +1973,12 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Не ўдаецца атрымаць доступ з вашай прылады \"<xliff:g id="DEVICE">%1$s</xliff:g>\". Паспрабуйце скарыстаць прыладу Android TV."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Не ўдаецца атрымаць доступ з вашай прылады \"<xliff:g id="DEVICE">%1$s</xliff:g>\". Паспрабуйце скарыстаць планшэт."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Не ўдаецца атрымаць доступ з вашай прылады \"<xliff:g id="DEVICE">%1$s</xliff:g>\". Паспрабуйце скарыстаць тэлефон."</string>
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (4706276040125072077) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (1824604581465771629) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (7755223160363292105) -->
+ <skip />
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"Гэтай праграме патрабуецца дадатковая бяспека. Паспрабуйце скарыстаць прыладу Android TV."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"Гэтай праграме патрабуецца дадатковая бяспека. Паспрабуйце скарыстаць планшэт."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Гэтай праграме патрабуецца дадатковая бяспека. Паспрабуйце скарыстаць тэлефон."</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 6f7ed4a..ce02cd5 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -705,7 +705,7 @@
<skip />
<string name="face_acquired_recalibrate_alt" msgid="5702674220280332115">"Моделът на лицето ви не бе създаден. Опитайте отново."</string>
<string name="face_acquired_dark_glasses_detected_alt" msgid="4052123776406041972">"Изглежда, че носите тъмни очила. То трябва да е напълно видимо."</string>
- <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"Изглежда, че лицето ви е покрито. То трябва да е напълно видимо."</string>
+ <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"Лицето ви е покрито. То трябва да е напълно видимо."</string>
<string-array name="face_acquired_vendor">
</string-array>
<string name="face_error_hw_not_available" msgid="5085202213036026288">"Лицето не може да се потвърди. Хардуерът не е налице."</string>
@@ -1259,7 +1259,7 @@
<string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Приложенията се стартират."</string>
<string name="android_upgrading_complete" msgid="409800058018374746">"Зареждането завършва."</string>
<string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"Натиснахте бутона за включване/изключване – това обикновено изключва екрана.\n\nОпитайте да докоснете леко, докато настройвате отпечатъка си."</string>
- <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"Изключете екрана за изход от настройката"</string>
+ <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"За изход изключете екрана"</string>
<string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"Изключване"</string>
<string name="fp_power_button_bp_title" msgid="5585506104526820067">"Напред с потвърждаването на отпечатъка?"</string>
<string name="fp_power_button_bp_message" msgid="2983163038168903393">"Натиснахте бутона за включване/изключване – това обикновено изключва екрана.\n\nОпитайте да докоснете леко, за да потвърдите отпечатъка си."</string>
@@ -1959,7 +1959,8 @@
<string name="app_blocked_title" msgid="7353262160455028160">"Приложението не е достъпно"</string>
<string name="app_blocked_message" msgid="542972921087873023">"В момента няма достъп до <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> не е налице"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Необходимо е разрешение"</string>
+ <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (3805704317624448487) -->
+ <skip />
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"Няма достъп до камерата"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"Продължете на телефона"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"Микрофонът не е достъпен"</string>
@@ -1970,6 +1971,12 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Понастоящем не може да се осъществи достъп от устройството ви <xliff:g id="DEVICE">%1$s</xliff:g>. Вместо това опитайте от устройството си с Android TV."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Понастоящем не може да се осъществи достъп от устройството ви <xliff:g id="DEVICE">%1$s</xliff:g>. Вместо това опитайте от таблета си."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Понастоящем не може да се осъществи достъп от устройството ви <xliff:g id="DEVICE">%1$s</xliff:g>. Вместо това опитайте от телефона си."</string>
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (4706276040125072077) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (1824604581465771629) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (7755223160363292105) -->
+ <skip />
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"Това приложение изисква допълнителна стъпка за сигурност. Вместо това опитайте от устройството си с Android TV."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"Това приложение изисква допълнителна стъпка за сигурност. Вместо това опитайте от таблета си."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Това приложение изисква допълнителна стъпка за сигурност. Вместо това опитайте от телефона си."</string>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index 7c3b25aa..2a1808c 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -628,11 +628,11 @@
<string name="biometric_error_generic" msgid="6784371929985434439">"যাচাইকরণে সমস্যা হয়েছে"</string>
<string name="screen_lock_app_setting_name" msgid="6054944352976789228">"স্ক্রিন লক ব্যবহার করুন"</string>
<string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"চালিয়ে যেতে আপনার স্ক্রিন লক ব্যবহার করুন"</string>
- <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"সেন্সর জোরে প্রেস করুন"</string>
+ <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"সেন্সরে জোরে প্রেস করুন"</string>
<string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"ফিঙ্গারপ্রিন্ট শনাক্ত করা যায়নি। আবার চেষ্টা করুন।"</string>
<string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"আঙ্গুলের ছাপের সেন্সর পরিষ্কার করে আবার চেষ্টা করুন"</string>
<string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"সেন্সর পরিষ্কার করে আবার চেষ্টা করুন"</string>
- <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"সেন্সর জোরে প্রেস করুন"</string>
+ <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"সেন্সরে জোরে প্রেস করুন"</string>
<string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"আঙ্গুল খুব ধীরে সরানো হয়েছে৷ অনুগ্রহ করে আবার চেষ্টা করুন৷"</string>
<string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"অন্য আঙ্গুলের ছাপ দিয়ে চেষ্টা করুন"</string>
<string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"অত্যন্ত উজ্জ্বল"</string>
@@ -641,7 +641,7 @@
<string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"প্রতিবার আপনার আঙুলের অবস্থান সামান্য পরিবর্তন করুন"</string>
<string-array name="fingerprint_acquired_vendor">
</string-array>
- <string name="fingerprint_error_not_match" msgid="4599441812893438961">"আঙ্গুলের ছাপ শনাক্ত করা যায়নি"</string>
+ <string name="fingerprint_error_not_match" msgid="4599441812893438961">"ফিঙ্গারপ্রিন্ট শনাক্ত করা যায়নি"</string>
<string name="fingerprint_udfps_error_not_match" msgid="8236930793223158856">"ফিঙ্গারপ্রিন্ট শনাক্ত করা যায়নি"</string>
<string name="fingerprint_authenticated" msgid="2024862866860283100">"আঙ্গুলের ছাপ যাচাই করা হয়েছে"</string>
<string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"ফেস যাচাই করা হয়েছে"</string>
@@ -1368,7 +1368,7 @@
<string name="usb_midi_notification_title" msgid="7404506788950595557">"USB এর মাধ্যমে MIDI চালু করা হয়েছে"</string>
<string name="usb_uvc_notification_title" msgid="2030032862673400008">"ওয়েবক্যাম হিসেবে কানেক্ট করা আছে"</string>
<string name="usb_accessory_notification_title" msgid="1385394660861956980">"ইউএসবি অ্যাক্সেসরি কানেক্ট করা হয়েছে"</string>
- <string name="usb_notification_message" msgid="4715163067192110676">"আরও বিকল্পের জন্য আলতো চাপুন৷"</string>
+ <string name="usb_notification_message" msgid="4715163067192110676">"আরও বিকল্পের জন্য ট্যাপ করুন।"</string>
<string name="usb_power_notification_message" msgid="7284765627437897702">"সংযুক্ত ডিভাইস চার্জ করা হচ্ছে। আরও বিকল্প দেখতে ট্যাপ করুন।"</string>
<string name="usb_unsupported_audio_accessory_title" msgid="2335775548086533065">"অ্যানালগ অডিও অ্যাক্সেসরি শনাক্ত করা হয়েছে"</string>
<string name="usb_unsupported_audio_accessory_message" msgid="1300168007129796621">"সংযুক্ত ডিভাইসটি এই ফোনের সাথে ব্যবহার করা যাবে না। আরও জানতে ট্যাপ করুন।"</string>
@@ -1959,7 +1959,8 @@
<string name="app_blocked_title" msgid="7353262160455028160">"অ্যাপ পাওয়া যাচ্ছে না"</string>
<string name="app_blocked_message" msgid="542972921087873023">"এই মুহূর্তে <xliff:g id="APP_NAME">%1$s</xliff:g> অ্যাপ পাওয়া যাচ্ছে না।"</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> উপলভ্য নেই"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"অনুমতি প্রয়োজন"</string>
+ <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (3805704317624448487) -->
+ <skip />
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"ক্যামেরা উপলভ্য নেই"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"ফোনে চালিয়ে যান"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"মাইক্রোফোন উপলভ্য নেই"</string>
@@ -1970,6 +1971,12 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"এই সময়ে আপনার <xliff:g id="DEVICE">%1$s</xliff:g>-এ এটি অ্যাক্সেস করা যাবে না। পরিবর্তে আপনার Android TV ডিভাইস ব্যবহার করে দেখুন।"</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"এই সময়ে আপনার <xliff:g id="DEVICE">%1$s</xliff:g>-এ এটি অ্যাক্সেস করা যাবে না। পরিবর্তে আপনার ট্যাবলেটে ব্যবহার করে দেখুন।"</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"এই সময়ে আপনার <xliff:g id="DEVICE">%1$s</xliff:g>-এ এটি অ্যাক্সেস করা যাবে না। পরিবর্তে আপনার ফোনে ব্যবহার করে দেখুন।"</string>
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (4706276040125072077) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (1824604581465771629) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (7755223160363292105) -->
+ <skip />
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"এই অ্যাপ অতিরিক্ত নিরাপত্তার জন্য অনুরোধ করছে। পরিবর্তে আপনার Android TV ডিভাইস ব্যবহার করে দেখুন।"</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"এই অ্যাপ অতিরিক্ত নিরাপত্তার জন্য অনুরোধ করছে। পরিবর্তে আপনার ট্যাবলেটে ব্যবহার করে দেখুন।"</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"এই অ্যাপ অতিরিক্ত নিরাপত্তার জন্য অনুরোধ করছে। পরিবর্তে আপনার ফোনে ব্যবহার করে দেখুন।"</string>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index de566ab..e10fe6a 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -685,8 +685,8 @@
<string name="face_acquired_too_dark" msgid="8539853432479385326">"Nema dovoljno svjetlosti"</string>
<string name="face_acquired_too_close" msgid="4453646176196302462">"Odmaknite telefon"</string>
<string name="face_acquired_too_far" msgid="2922278214231064859">"Primaknite telefon"</string>
- <string name="face_acquired_too_high" msgid="8278815780046368576">"Pomjerite telefon naviše"</string>
- <string name="face_acquired_too_low" msgid="4075391872960840081">"Pomjerite telefon naniže"</string>
+ <string name="face_acquired_too_high" msgid="8278815780046368576">"Pomjerite telefon nagore"</string>
+ <string name="face_acquired_too_low" msgid="4075391872960840081">"Pomjerite telefon nadolje"</string>
<string name="face_acquired_too_right" msgid="6245286514593540859">"Pomjerite telefon ulijevo"</string>
<string name="face_acquired_too_left" msgid="9201762240918405486">"Pomjerite telefon udesno"</string>
<string name="face_acquired_poor_gaze" msgid="4427153558773628020">"Gledajte direktno u uređaj."</string>
@@ -1960,7 +1960,8 @@
<string name="app_blocked_title" msgid="7353262160455028160">"Aplikacija nije dostupna"</string>
<string name="app_blocked_message" msgid="542972921087873023">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> trenutno nije dostupna."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"Nedostupno: <xliff:g id="ACTIVITY">%1$s</xliff:g>"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Potrebno je odobrenje"</string>
+ <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (3805704317624448487) -->
+ <skip />
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"Kamera nije dostupna"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"Nastavite na telefonu"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"Mikrofon nije dostupan"</string>
@@ -1971,6 +1972,12 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Trenutno ne možete pristupiti ovoj aplikaciji na uređaju <xliff:g id="DEVICE">%1$s</xliff:g>. Umjesto toga pokušajte na uređaju Android TV."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Trenutno ne možete pristupiti ovoj aplikaciji na uređaju <xliff:g id="DEVICE">%1$s</xliff:g>. Umjesto toga pokušajte na tabletu."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Trenutno ne možete pristupiti ovoj aplikaciji na uređaju <xliff:g id="DEVICE">%1$s</xliff:g>. Umjesto toga pokušajte na telefonu."</string>
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (4706276040125072077) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (1824604581465771629) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (7755223160363292105) -->
+ <skip />
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"Ova aplikacija zahtijeva dodatnu sigurnost. Umjesto toga pokušajte na uređaju Android TV."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"Ova aplikacija zahtijeva dodatnu sigurnost. Umjesto toga pokušajte na tabletu."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Ova aplikacija zahtijeva dodatnu sigurnost. Umjesto toga pokušajte na telefonu."</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 2902d53..d86d9de 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -706,7 +706,7 @@
<skip />
<string name="face_acquired_recalibrate_alt" msgid="5702674220280332115">"No es pot crear el model facial. Torna-ho a provar."</string>
<string name="face_acquired_dark_glasses_detected_alt" msgid="4052123776406041972">"S\'han detectat ulleres fosques. La cara ha de veure\'s sencera."</string>
- <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"S\'ha detectat una mascareta. La cara ha de veure\'s sencera."</string>
+ <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"Tens la cara tapada. La cara ha de veure\'s sencera."</string>
<string-array name="face_acquired_vendor">
</string-array>
<string name="face_error_hw_not_available" msgid="5085202213036026288">"No es pot verificar la cara. Maquinari no disponible."</string>
@@ -1960,7 +1960,8 @@
<string name="app_blocked_title" msgid="7353262160455028160">"L\'aplicació no està disponible"</string>
<string name="app_blocked_message" msgid="542972921087873023">"Ara mateix, <xliff:g id="APP_NAME">%1$s</xliff:g> no està disponible."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> no està disponible"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Permís necessari"</string>
+ <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (3805704317624448487) -->
+ <skip />
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"La càmera no està disponible"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"Continua al telèfon"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"El micròfon no està disponible"</string>
@@ -1971,6 +1972,12 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"En aquests moments, No s\'hi pot accedir des del teu <xliff:g id="DEVICE">%1$s</xliff:g>. Prova-ho al dispositiu Android TV."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"En aquests moments, No s\'hi pot accedir des del teu <xliff:g id="DEVICE">%1$s</xliff:g>. Prova-ho a la tauleta."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"No s\'hi pot accedir des del teu <xliff:g id="DEVICE">%1$s</xliff:g>. Prova-ho al telèfon."</string>
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (4706276040125072077) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (1824604581465771629) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (7755223160363292105) -->
+ <skip />
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"Aquesta aplicació sol·licita seguretat addicional. Prova-ho al dispositiu Android TV."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"Aquesta aplicació sol·licita seguretat addicional. Prova-ho a la tauleta."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Aquesta aplicació sol·licita seguretat addicional. Prova-ho al telèfon."</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 718bc05..02d7309 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -634,7 +634,7 @@
<string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"Otisk prstu se nepodařilo rozpoznat. Zkuste to znovu."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Vyčistěte snímač otisků prstů a zkuste to znovu"</string>
<string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Vyčistěte senzor a zkuste to znovu"</string>
- <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Pevně přitiskněte na snímač"</string>
+ <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Pevně přitiskněte prst na snímač"</string>
<string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Pohyb prstem byl příliš pomalý. Zkuste to znovu."</string>
<string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Zkuste jiný otisk prstu"</string>
<string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Je příliš světlo"</string>
@@ -1961,7 +1961,7 @@
<string name="app_blocked_title" msgid="7353262160455028160">"Aplikace není k dispozici"</string>
<string name="app_blocked_message" msgid="542972921087873023">"Aplikace <xliff:g id="APP_NAME">%1$s</xliff:g> v tuto chvíli není k dispozici."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> není k dispozici"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Je vyžadováno oprávnění"</string>
+ <string name="app_streaming_blocked_title_for_permission_dialog" msgid="3805704317624448487">"Žádost o oprávnění byla potlačena"</string>
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"Kamera není k dispozici"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"Pokračujte na telefonu"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"Mikrofon není k dispozici"</string>
@@ -1972,6 +1972,9 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Tato položka na vašem zařízení <xliff:g id="DEVICE">%1$s</xliff:g> v tuto chvíli není k dispozici. Zkuste to na zařízení Android TV."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Tato položka na vašem zařízení <xliff:g id="DEVICE">%1$s</xliff:g> v tuto chvíli není k dispozici. Zkuste to na tabletu."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Tato položka na vašem zařízení <xliff:g id="DEVICE">%1$s</xliff:g> v tuto chvíli není k dispozici. Zkuste to na telefonu."</string>
+ <string name="app_streaming_blocked_message_for_permission_request" product="tv" msgid="4706276040125072077">"Tato aplikace požaduje další oprávnění, která ale nelze udělit během relace streamování. Oprávnění udělte nejprve na zařízení Android TV."</string>
+ <string name="app_streaming_blocked_message_for_permission_request" product="tablet" msgid="1824604581465771629">"Tato aplikace požaduje další oprávnění, která ale nelze udělit během relace streamování. Oprávnění udělte nejprve na tabletu."</string>
+ <string name="app_streaming_blocked_message_for_permission_request" product="default" msgid="7755223160363292105">"Tato aplikace požaduje další oprávnění, která ale nelze udělit během relace streamování. Oprávnění udělte nejprve na telefonu."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"Tato aplikace požaduje další zabezpečení. Zkuste to na zařízení Android TV."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"Tato aplikace požaduje další zabezpečení. Zkuste to na tabletu."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Tato aplikace požaduje další zabezpečení. Zkuste to na telefonu."</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index e605287..83edf27 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -697,7 +697,7 @@
<string name="face_acquired_pan_too_extreme" msgid="5417928604710621088">"Kig mere direkte på din telefon"</string>
<string name="face_acquired_tilt_too_extreme" msgid="5715715666540716620">"Kig mere direkte på din telefon"</string>
<string name="face_acquired_roll_too_extreme" msgid="8261939882838881194">"Kig mere direkte på din telefon"</string>
- <string name="face_acquired_obscured" msgid="4917643294953326639">"Hvis noget skjuler dit ansigt, skal du fjerne det."</string>
+ <string name="face_acquired_obscured" msgid="4917643294953326639">"Hvis noget skjuler dit ansigt, skal du fjerne det"</string>
<string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"Rengør toppen af din skærm, inkl. den sorte bjælke"</string>
<!-- no translation found for face_acquired_dark_glasses_detected (5643703296620631986) -->
<skip />
@@ -1959,7 +1959,8 @@
<string name="app_blocked_title" msgid="7353262160455028160">"Appen er ikke tilgængelig"</string>
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> er ikke tilgængelig lige nu."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> er ikke understøttet"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Der kræves tilladelse"</string>
+ <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (3805704317624448487) -->
+ <skip />
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"Kameraet er ikke tilgængeligt"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"Fortsæt på telefonen"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"Mikrofonen er ikke tilgængelig"</string>
@@ -1970,6 +1971,12 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Dette er ikke tilgængeligt på din <xliff:g id="DEVICE">%1$s</xliff:g> på nuværende tidspunkt. Prøv på din Android TV-enhed i stedet."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Dette er ikke tilgængeligt på din <xliff:g id="DEVICE">%1$s</xliff:g> på nuværende tidspunkt. Prøv på din tablet i stedet."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Dette er ikke tilgængeligt på din <xliff:g id="DEVICE">%1$s</xliff:g> på nuværende tidspunkt. Prøv på din telefon i stedet."</string>
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (4706276040125072077) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (1824604581465771629) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (7755223160363292105) -->
+ <skip />
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"Denne app anmoder om yderligere sikkerhed. Prøv på din Android TV-enhed i stedet."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"Denne app anmoder om yderligere sikkerhed. Prøv på din tablet i stedet."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Denne app anmoder om yderligere sikkerhed. Prøv på din telefon i stedet."</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 7ae7ff9..381fe71 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -1959,7 +1959,8 @@
<string name="app_blocked_title" msgid="7353262160455028160">"App ist nicht verfügbar"</string>
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> ist derzeit nicht verfügbar."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> nicht verfügbar"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Berechtigung erforderlich"</string>
+ <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (3805704317624448487) -->
+ <skip />
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"Kamera nicht verfügbar"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"Weiter auf Smartphone"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"Mikrofon nicht verfügbar"</string>
@@ -1970,6 +1971,12 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Auf deinem <xliff:g id="DEVICE">%1$s</xliff:g> ist derzeit kein Zugriff möglich. Versuche es stattdessen auf deinem Android TV-Gerät."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Auf deinem <xliff:g id="DEVICE">%1$s</xliff:g> ist derzeit kein Zugriff möglich. Versuche es stattdessen auf deinem Tablet."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Auf deinem <xliff:g id="DEVICE">%1$s</xliff:g> ist derzeit kein Zugriff möglich. Versuche es stattdessen auf deinem Smartphone."</string>
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (4706276040125072077) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (1824604581465771629) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (7755223160363292105) -->
+ <skip />
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"Diese App fordert zusätzliche Sicherheit an. Versuch es stattdessen auf deinem Android TV-Gerät."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"Diese App fordert zusätzliche Sicherheit an. Versuch es stattdessen auf deinem Tablet."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Diese App fordert zusätzliche Sicherheit an. Versuch es stattdessen auf deinem Smartphone."</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 0eb6aa6..90fb787 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -705,7 +705,7 @@
<skip />
<string name="face_acquired_recalibrate_alt" msgid="5702674220280332115">"Αδύνατη η δημιουργία του μοντέλου προσώπου. Δοκιμάστε ξανά."</string>
<string name="face_acquired_dark_glasses_detected_alt" msgid="4052123776406041972">"Ανιχνεύτηκαν σκούρα γυαλιά. Το πρόσωπό σας πρέπει να φαίνεται πλήρως."</string>
- <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"Ανιχνεύτηκε κάλυμμα προσώπου. Το πρόσωπό σας πρέπει να φαίνεται πλήρως."</string>
+ <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"Ανιχνεύτηκε κάλυμμα προσώπου. Δεν φαίνεται όλο το πρόσωπο."</string>
<string-array name="face_acquired_vendor">
</string-array>
<string name="face_error_hw_not_available" msgid="5085202213036026288">"Αδύν. επαλήθ. προσώπου. Μη διαθέσιμος εξοπλισμός."</string>
@@ -1372,8 +1372,8 @@
<string name="usb_power_notification_message" msgid="7284765627437897702">"Φόρτιση συνδεδεμένης συσκευής. Πατήστε για περισσότερες επιλογές."</string>
<string name="usb_unsupported_audio_accessory_title" msgid="2335775548086533065">"Εντοπίστηκε αναλογικό αξεσουάρ ήχου"</string>
<string name="usb_unsupported_audio_accessory_message" msgid="1300168007129796621">"Η συνδεδεμένη συσκευή δεν είναι συμβατή με αυτό το τηλέφωνο. Πατήστε για να μάθετε περισσότερα."</string>
- <string name="adb_active_notification_title" msgid="408390247354560331">"Συνδέθηκε ο εντοπισμός σφαλμάτων USB"</string>
- <string name="adb_active_notification_message" msgid="5617264033476778211">"Πατήστε για απενεργοποίηση εντοπισμού/διόρθ. σφαλμάτων USB"</string>
+ <string name="adb_active_notification_title" msgid="408390247354560331">"Συνδέθηκε ο εντοπ. σφαλμ. USB"</string>
+ <string name="adb_active_notification_message" msgid="5617264033476778211">"Πατήστε για απενεργ. εντοπ./διόρθ. σφαλμ. USB"</string>
<string name="adb_active_notification_message" product="tv" msgid="6624498401272780855">"Επιλογή για απενεργοποίηση του εντοπισμού σφαλμάτων USB."</string>
<string name="adbwifi_active_notification_title" msgid="6147343659168302473">"Συνδέθηκε ο ασύρματος εντοπισμός σφαλμάτων"</string>
<string name="adbwifi_active_notification_message" msgid="930987922852867972">"Πατήστε, για να απενεργοποιήσετε τον ασύρματο εντοπισμό σφαλμάτων"</string>
@@ -1959,7 +1959,8 @@
<string name="app_blocked_title" msgid="7353262160455028160">"Η εφαρμογή δεν είναι διαθέσιμη"</string>
<string name="app_blocked_message" msgid="542972921087873023">"Η εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> δεν είναι διαθέσιμη αυτήν τη στιγμή."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> δεν διατίθεται"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Απαιτείται άδεια"</string>
+ <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (3805704317624448487) -->
+ <skip />
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"Η κάμερα δεν είναι διαθέσιμη"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"Συνέχεια στο τηλέφωνο"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"Το μικρόφωνο δεν είναι διαθέσιμο"</string>
@@ -1970,6 +1971,12 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Δεν είναι δυνατή η πρόσβαση στη συγκεκριμένη εφαρμογή από τη συσκευή <xliff:g id="DEVICE">%1$s</xliff:g> αυτήν τη στιγμή. Δοκιμάστε στη συσκευή Android TV."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Δεν είναι δυνατή η πρόσβαση στη συγκεκριμένη εφαρμογή από τη συσκευή <xliff:g id="DEVICE">%1$s</xliff:g> αυτήν τη στιγμή. Δοκιμάστε στο tablet σας."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Δεν είναι δυνατή η πρόσβαση στη συγκεκριμένη εφαρμογή από τη συσκευή <xliff:g id="DEVICE">%1$s</xliff:g> αυτήν τη στιγμή. Δοκιμάστε στο τηλέφωνό σας."</string>
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (4706276040125072077) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (1824604581465771629) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (7755223160363292105) -->
+ <skip />
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"Αυτή η εφαρμογή ζητά πρόσθετη ασφάλεια. Δοκιμάστε στη συσκευή Android TV."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"Αυτή η εφαρμογή ζητά πρόσθετη ασφάλεια. Δοκιμάστε στο tablet σας."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Αυτή η εφαρμογή ζητά πρόσθετη ασφάλεια. Δοκιμάστε στο τηλέφωνό σας."</string>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index cdb20d0..0caebde 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -1959,7 +1959,8 @@
<string name="app_blocked_title" msgid="7353262160455028160">"App is not available"</string>
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> is not available right now."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> unavailable"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Permission needed"</string>
+ <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (3805704317624448487) -->
+ <skip />
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"Camera unavailable"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"Continue on phone"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"Microphone unavailable"</string>
@@ -1970,6 +1971,12 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"This can’t be accessed on your <xliff:g id="DEVICE">%1$s</xliff:g> at this time. Try on your Android TV device instead."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"This can’t be accessed on your <xliff:g id="DEVICE">%1$s</xliff:g> at this time. Try on your tablet instead."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"This can’t be accessed on your <xliff:g id="DEVICE">%1$s</xliff:g> at this time. Try on your phone instead."</string>
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (4706276040125072077) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (1824604581465771629) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (7755223160363292105) -->
+ <skip />
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"This app is requesting additional security. Try on your Android TV device instead."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"This app is requesting additional security. Try on your tablet instead."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"This app is requesting additional security. Try on your phone instead."</string>
diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml
index b0648e9..44741f5 100644
--- a/core/res/res/values-en-rCA/strings.xml
+++ b/core/res/res/values-en-rCA/strings.xml
@@ -1959,7 +1959,7 @@
<string name="app_blocked_title" msgid="7353262160455028160">"App is not available"</string>
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> is not available right now."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> unavailable"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Permission needed"</string>
+ <string name="app_streaming_blocked_title_for_permission_dialog" msgid="3805704317624448487">"Permission request suppressed"</string>
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"Camera unavailable"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"Continue on phone"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"Microphone unavailable"</string>
@@ -1970,6 +1970,9 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"This can’t be accessed on your <xliff:g id="DEVICE">%1$s</xliff:g> at this time. Try on your Android TV device instead."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"This can’t be accessed on your <xliff:g id="DEVICE">%1$s</xliff:g> at this time. Try on your tablet instead."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"This can’t be accessed on your <xliff:g id="DEVICE">%1$s</xliff:g> at this time. Try on your phone instead."</string>
+ <string name="app_streaming_blocked_message_for_permission_request" product="tv" msgid="4706276040125072077">"This app is requesting additional permissions, but permissions can’t be granted in a streaming session. Grant the permission on your Android TV device first."</string>
+ <string name="app_streaming_blocked_message_for_permission_request" product="tablet" msgid="1824604581465771629">"This app is requesting additional permissions, but permissions can’t be granted in a streaming session. Grant the permission on your tablet first."</string>
+ <string name="app_streaming_blocked_message_for_permission_request" product="default" msgid="7755223160363292105">"This app is requesting additional permissions, but permissions can’t be granted in a streaming session. Grant the permission on your phone first."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"This app is requesting additional security. Try on your Android TV device instead."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"This app is requesting additional security. Try on your tablet instead."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"This app is requesting additional security. Try on your phone instead."</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index d5374e1..278422f 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -1959,7 +1959,8 @@
<string name="app_blocked_title" msgid="7353262160455028160">"App is not available"</string>
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> is not available right now."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> unavailable"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Permission needed"</string>
+ <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (3805704317624448487) -->
+ <skip />
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"Camera unavailable"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"Continue on phone"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"Microphone unavailable"</string>
@@ -1970,6 +1971,12 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"This can’t be accessed on your <xliff:g id="DEVICE">%1$s</xliff:g> at this time. Try on your Android TV device instead."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"This can’t be accessed on your <xliff:g id="DEVICE">%1$s</xliff:g> at this time. Try on your tablet instead."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"This can’t be accessed on your <xliff:g id="DEVICE">%1$s</xliff:g> at this time. Try on your phone instead."</string>
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (4706276040125072077) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (1824604581465771629) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (7755223160363292105) -->
+ <skip />
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"This app is requesting additional security. Try on your Android TV device instead."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"This app is requesting additional security. Try on your tablet instead."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"This app is requesting additional security. Try on your phone instead."</string>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index e0fdced..ee8e488 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -1959,7 +1959,8 @@
<string name="app_blocked_title" msgid="7353262160455028160">"App is not available"</string>
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> is not available right now."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> unavailable"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Permission needed"</string>
+ <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (3805704317624448487) -->
+ <skip />
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"Camera unavailable"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"Continue on phone"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"Microphone unavailable"</string>
@@ -1970,6 +1971,12 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"This can’t be accessed on your <xliff:g id="DEVICE">%1$s</xliff:g> at this time. Try on your Android TV device instead."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"This can’t be accessed on your <xliff:g id="DEVICE">%1$s</xliff:g> at this time. Try on your tablet instead."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"This can’t be accessed on your <xliff:g id="DEVICE">%1$s</xliff:g> at this time. Try on your phone instead."</string>
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (4706276040125072077) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (1824604581465771629) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (7755223160363292105) -->
+ <skip />
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"This app is requesting additional security. Try on your Android TV device instead."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"This app is requesting additional security. Try on your tablet instead."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"This app is requesting additional security. Try on your phone instead."</string>
diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml
index d25fb70..f67c0d0 100644
--- a/core/res/res/values-en-rXC/strings.xml
+++ b/core/res/res/values-en-rXC/strings.xml
@@ -1959,7 +1959,7 @@
<string name="app_blocked_title" msgid="7353262160455028160">"App is not available"</string>
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> is not available right now."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> unavailable"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Permission needed"</string>
+ <string name="app_streaming_blocked_title_for_permission_dialog" msgid="3805704317624448487">"Permission request suppressed"</string>
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"Camera unavailable"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"Continue on phone"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"Microphone unavailable"</string>
@@ -1970,6 +1970,9 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"This can’t be accessed on your <xliff:g id="DEVICE">%1$s</xliff:g> at this time. Try on your Android TV device instead."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"This can’t be accessed on your <xliff:g id="DEVICE">%1$s</xliff:g> at this time. Try on your tablet instead."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"This can’t be accessed on your <xliff:g id="DEVICE">%1$s</xliff:g> at this time. Try on your phone instead."</string>
+ <string name="app_streaming_blocked_message_for_permission_request" product="tv" msgid="4706276040125072077">"This app is requesting additional permissions, but permissions can’t be granted in a streaming session. Grant the permission on your Android TV device first."</string>
+ <string name="app_streaming_blocked_message_for_permission_request" product="tablet" msgid="1824604581465771629">"This app is requesting additional permissions, but permissions can’t be granted in a streaming session. Grant the permission on your tablet first."</string>
+ <string name="app_streaming_blocked_message_for_permission_request" product="default" msgid="7755223160363292105">"This app is requesting additional permissions, but permissions can’t be granted in a streaming session. Grant the permission on your phone first."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"This app is requesting additional security. Try on your Android TV device instead."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"This app is requesting additional security. Try on your tablet instead."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"This app is requesting additional security. Try on your phone instead."</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 1da5d04..112dbda 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -629,11 +629,11 @@
<string name="biometric_error_generic" msgid="6784371929985434439">"Error de autenticación"</string>
<string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Usar bloqueo de pantalla"</string>
<string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Ingresa tu bloqueo de pantalla para continuar"</string>
- <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Presiona con firmeza el sensor"</string>
+ <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Presiona el sensor con firmeza"</string>
<string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"No se reconoce la huella dactilar. Vuelve a intentarlo."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Limpia el sensor de huellas dactilares y vuelve a intentarlo"</string>
<string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Limpia el sensor y vuelve a intentarlo"</string>
- <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Presiona con firmeza el sensor"</string>
+ <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Presiona el sensor con firmeza"</string>
<string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Moviste el dedo muy lento. Vuelve a intentarlo."</string>
<string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Prueba con otra huella dactilar"</string>
<string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Demasiada luz"</string>
@@ -690,7 +690,7 @@
<string name="face_acquired_too_right" msgid="6245286514593540859">"Mueve el teléfono hacia la izquierda"</string>
<string name="face_acquired_too_left" msgid="9201762240918405486">"Mueve el teléfono hacia la derecha"</string>
<string name="face_acquired_poor_gaze" msgid="4427153558773628020">"Mira directamente al dispositivo."</string>
- <string name="face_acquired_not_detected" msgid="1057966913397548150">"No se ve tu cara. Sostén el teléfono a la altura de los ojos."</string>
+ <string name="face_acquired_not_detected" msgid="1057966913397548150">"No se te ve el rostro. Sostén el teléfono a la altura de los ojos."</string>
<string name="face_acquired_too_much_motion" msgid="8199691445085189528">"Te estás moviendo demasiado. No muevas el teléfono"</string>
<string name="face_acquired_recalibrate" msgid="8724013080976469746">"Vuelve a registrar tu rostro."</string>
<string name="face_acquired_too_different" msgid="2520389515612972889">"No se reconoce el rostro. Vuelve a intentarlo."</string>
@@ -705,8 +705,8 @@
<!-- no translation found for face_acquired_mouth_covering_detected (8219428572168642593) -->
<skip />
<string name="face_acquired_recalibrate_alt" msgid="5702674220280332115">"No se puede crear modelo de rostro. Vuelve a intentarlo."</string>
- <string name="face_acquired_dark_glasses_detected_alt" msgid="4052123776406041972">"Se detectaron lentes oscuros. Tu rostro debe verse completamente."</string>
- <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"Llevas mascarilla. Se debe ver todo tu rostro."</string>
+ <string name="face_acquired_dark_glasses_detected_alt" msgid="4052123776406041972">"Se detectaron lentes oscuros. Se te debe ver todo el rostro."</string>
+ <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"Llevas mascarilla. Se te debe ver todo el rostro."</string>
<string-array name="face_acquired_vendor">
</string-array>
<string name="face_error_hw_not_available" msgid="5085202213036026288">"No se verificó el rostro. Hardware no disponible."</string>
@@ -1960,7 +1960,8 @@
<string name="app_blocked_title" msgid="7353262160455028160">"La app no está disponible"</string>
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> no está disponible en este momento."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> no disponible"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Se necesitan permisos"</string>
+ <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (3805704317624448487) -->
+ <skip />
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"La cámara no está disponible"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"Continúa en el teléfono"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"El micrófono no está disponible"</string>
@@ -1971,6 +1972,12 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Por el momento, no se puede acceder a esto en tu <xliff:g id="DEVICE">%1$s</xliff:g>. Inténtalo en tu dispositivo Android TV."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Por el momento, no se puede acceder a esto en tu <xliff:g id="DEVICE">%1$s</xliff:g>. Inténtalo en tu tablet."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Por el momento, no se puede acceder a esto en tu <xliff:g id="DEVICE">%1$s</xliff:g>. Inténtalo en tu teléfono."</string>
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (4706276040125072077) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (1824604581465771629) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (7755223160363292105) -->
+ <skip />
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"Esta app solicita seguridad adicional. Inténtalo en tu dispositivo Android TV."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"Esta app solicita seguridad adicional. Inténtalo en tu tablet."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Esta app solicita seguridad adicional. Inténtalo en tu teléfono."</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index dc56969..e25f770 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -706,7 +706,7 @@
<skip />
<string name="face_acquired_recalibrate_alt" msgid="5702674220280332115">"No se puede crear tu modelo. Inténtalo de nuevo."</string>
<string name="face_acquired_dark_glasses_detected_alt" msgid="4052123776406041972">"Gafas oscuras detectadas. Tu cara se debe poder ver entera."</string>
- <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"Cara parcialmente cubierta. Tu cara se debe poder ver entera."</string>
+ <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"Cara parcialmente cubierta. Debe verse toda."</string>
<string-array name="face_acquired_vendor">
</string-array>
<string name="face_error_hw_not_available" msgid="5085202213036026288">"No se puede verificar. Hardware no disponible."</string>
@@ -1960,7 +1960,8 @@
<string name="app_blocked_title" msgid="7353262160455028160">"La aplicación no está disponible"</string>
<string name="app_blocked_message" msgid="542972921087873023">"En estos momentos, <xliff:g id="APP_NAME">%1$s</xliff:g> no está disponible."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> no disponible"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Se necesita permiso"</string>
+ <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (3805704317624448487) -->
+ <skip />
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"Cámara no disponible"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"Continúa en el teléfono"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"Micrófono no disponible"</string>
@@ -1971,6 +1972,12 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"En estos momentos, no se puede acceder a este contenido en tu <xliff:g id="DEVICE">%1$s</xliff:g>. Prueba en tu dispositivo Android TV."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"En estos momentos, no se puede acceder a este contenido en tu <xliff:g id="DEVICE">%1$s</xliff:g>. Prueba en tu tablet."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"En estos momentos, no se puede acceder a este contenido en tu <xliff:g id="DEVICE">%1$s</xliff:g>. Prueba en tu teléfono."</string>
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (4706276040125072077) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (1824604581465771629) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (7755223160363292105) -->
+ <skip />
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"Esta aplicación solicita seguridad adicional. Prueba en tu dispositivo Android TV."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"Esta aplicación solicita seguridad adicional. Prueba en tu tablet."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Esta aplicación solicita seguridad adicional. Prueba en tu teléfono."</string>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index de7665c..a64b140 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -1372,7 +1372,7 @@
<string name="usb_power_notification_message" msgid="7284765627437897702">"Ühendatud seadet laetakse. Puudutage lisavalikute nägemiseks."</string>
<string name="usb_unsupported_audio_accessory_title" msgid="2335775548086533065">"Tuvastati analoogne helitarvik"</string>
<string name="usb_unsupported_audio_accessory_message" msgid="1300168007129796621">"Ühendatud seade ei ühildu selle telefoniga. Puudutage lisateabe saamiseks."</string>
- <string name="adb_active_notification_title" msgid="408390247354560331">"USB-silumine ühendatud"</string>
+ <string name="adb_active_notification_title" msgid="408390247354560331">"USB-silumine on ühendatud"</string>
<string name="adb_active_notification_message" msgid="5617264033476778211">"Puudutage USB-silumise väljalülitamiseks"</string>
<string name="adb_active_notification_message" product="tv" msgid="6624498401272780855">"Valige USB silumise keelamiseks"</string>
<string name="adbwifi_active_notification_title" msgid="6147343659168302473">"Juhtmevaba silumine on ühendatud"</string>
@@ -1959,7 +1959,8 @@
<string name="app_blocked_title" msgid="7353262160455028160">"Rakendus ei ole saadaval"</string>
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> ei ole praegu saadaval."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> ei ole saadaval"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Vaja on luba"</string>
+ <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (3805704317624448487) -->
+ <skip />
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"Kaamera pole saadaval"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"Jätkake telefonis"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"Mikrofon pole saadaval"</string>
@@ -1970,6 +1971,12 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Sellele ei pääse praegu teie seadmega (<xliff:g id="DEVICE">%1$s</xliff:g>) juurde. Proovige juurde pääseda oma Android TV seadmega."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Sellele ei pääse praegu teie seadmega (<xliff:g id="DEVICE">%1$s</xliff:g>) juurde. Proovige juurde pääseda oma tahvelarvutiga."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Sellele ei pääse praegu teie seadmega (<xliff:g id="DEVICE">%1$s</xliff:g>) juurde. Proovige juurde pääseda oma telefoniga."</string>
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (4706276040125072077) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (1824604581465771629) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (7755223160363292105) -->
+ <skip />
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"See rakendus nõuab lisaturvalisust. Proovige juurde pääseda oma Android TV seadmes."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"See rakendus nõuab lisaturvalisust. Proovige juurde pääseda oma tahvelarvutis."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"See rakendus nõuab lisaturvalisust. Proovige juurde pääseda oma telefonis."</string>
@@ -2160,7 +2167,7 @@
<string name="resolver_cross_profile_blocked" msgid="3014597376026044840">"Blokeeris teie IT-administraator"</string>
<string name="resolver_cant_share_with_work_apps_explanation" msgid="9071442683080586643">"Seda sisu ei saa töörakendustega jagada"</string>
<string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Seda sisu ei saa töörakendustega avada"</string>
- <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Seda sisu ei saa isiklike rakendustega jagada"</string>
+ <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Seda sisu ei saa isiklike rakendustega jagada."</string>
<string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Seda sisu ei saa isiklike rakendustega avada"</string>
<string name="resolver_turn_on_work_apps" msgid="1535946298236678122">"Töörakendused on peatatud"</string>
<string name="resolver_switch_on_work" msgid="4527096360772311894">"Jätka"</string>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index a07d982..d9c97c6 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -1959,7 +1959,7 @@
<string name="app_blocked_title" msgid="7353262160455028160">"Aplikazioa ez dago erabilgarri"</string>
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> ez dago erabilgarri une honetan."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> ez dago erabilgarri"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Baimena behar da"</string>
+ <string name="app_streaming_blocked_title_for_permission_dialog" msgid="3805704317624448487">"Baztertu da baimen-eskaera"</string>
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"Kamera ez dago erabilgarri"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"Jarraitu telefonoan"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"Mikrofonoa ez dago erabilgarri"</string>
@@ -1970,6 +1970,9 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Une honetan, aplikazioa ezin da <xliff:g id="DEVICE">%1$s</xliff:g> erabilita atzitu. Gailu horren ordez, erabili Android TV gailua."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Une honetan, aplikazioa ezin da <xliff:g id="DEVICE">%1$s</xliff:g> erabilita atzitu. Gailu horren ordez, erabili tableta."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Une honetan, aplikazioa ezin da <xliff:g id="DEVICE">%1$s</xliff:g> erabilita atzitu. Gailu horren ordez, erabili telefonoa."</string>
+ <string name="app_streaming_blocked_message_for_permission_request" product="tv" msgid="4706276040125072077">"Baimen gehigarriak eskatzen ari da aplikazioa, baina ezin da eman baimenik igorpen-saioetan. Lehenik eta behin, eman baimena Android TV darabilen gailuan."</string>
+ <string name="app_streaming_blocked_message_for_permission_request" product="tablet" msgid="1824604581465771629">"Baimen gehigarriak eskatzen ari da aplikazioa, baina ezin da eman baimenik igorpen-saioetan. Lehenik eta behin, eman baimena tabletan."</string>
+ <string name="app_streaming_blocked_message_for_permission_request" product="default" msgid="7755223160363292105">"Baimen gehigarriak eskatzen ari da aplikazioa, baina ezin da eman baimenik igorpen-saioetan. Lehenik eta behin, eman baimena telefonoan."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"Segurtasun gehigarria eskatzen ari da aplikazioa. Gailu horren ordez, erabili Android TV darabilen bat."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"Segurtasun gehigarria eskatzen ari da aplikazioa. Gailu horren ordez, erabili tableta."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Segurtasun gehigarria eskatzen ari da aplikazioa. Gailu horren ordez, erabili telefonoa."</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index bbf5988..52cf5e0 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -1266,7 +1266,7 @@
<string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"خاموش کردن صفحه"</string>
<string name="fp_power_button_bp_negative_button" msgid="3971364246496775178">"ادامه"</string>
<string name="heavy_weight_notification" msgid="8382784283600329576">"<xliff:g id="APP">%1$s</xliff:g> در حال اجرا"</string>
- <string name="heavy_weight_notification_detail" msgid="6802247239468404078">"برای برگشت به بازی، ضربه بزنید"</string>
+ <string name="heavy_weight_notification_detail" msgid="6802247239468404078">"برای برگشتن به بازی، ضربه بزنید"</string>
<string name="heavy_weight_switcher_title" msgid="3861984210040100886">"انتخاب بازی"</string>
<string name="heavy_weight_switcher_text" msgid="6814316627367160126">"برای عملکرد بهتر، هربار فقط یکی از این بازیها را میتوان باز کرد."</string>
<string name="old_app_action" msgid="725331621042848590">"به <xliff:g id="OLD_APP">%1$s</xliff:g> برگردید"</string>
@@ -1959,7 +1959,8 @@
<string name="app_blocked_title" msgid="7353262160455028160">"برنامه در دسترس نیست"</string>
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> درحالحاضر در دسترس نیست."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> دردسترس نیست"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"اجازه لازم است"</string>
+ <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (3805704317624448487) -->
+ <skip />
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"دوربین دردسترس نیست"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"ادامه دادن در تلفن"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"میکروفون دردسترس نیست"</string>
@@ -1970,6 +1971,12 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"درحالحاضر نمیتوان در <xliff:g id="DEVICE">%1$s</xliff:g> شما به این برنامه دسترسی داشت. دسترسی به آن را در دستگاه Android TV امتحان کنید."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"درحالحاضر نمیتوان در <xliff:g id="DEVICE">%1$s</xliff:g> شما به این برنامه دسترسی داشت. دسترسی به آن را در رایانه لوحیتان امتحان کنید."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"درحالحاضر نمیتوان در <xliff:g id="DEVICE">%1$s</xliff:g> شما به این برنامه دسترسی داشت. دسترسی به آن را در تلفنتان امتحان کنید."</string>
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (4706276040125072077) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (1824604581465771629) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (7755223160363292105) -->
+ <skip />
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"این برنامه درخواست امنیت اضافی دارد. دسترسی به آن را در دستگاه Android TV امتحان کنید."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"این برنامه درخواست امنیت اضافی دارد. دسترسی به آن را در رایانه لوحیتان امتحان کنید."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"این برنامه درخواست امنیت اضافی دارد. دسترسی به آن را در تلفنتان امتحان کنید."</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index bf866f6..7b9c023 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -1259,7 +1259,7 @@
<string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Käynnistetään sovelluksia."</string>
<string name="android_upgrading_complete" msgid="409800058018374746">"Viimeistellään päivitystä."</string>
<string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"Painoit virtapainiketta, mikä yleensä sammuttaa näytön.\n\nKosketa painiketta kevyesti tallentaessasi sormenjälkeä."</string>
- <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"Lopeta käyttöönotto sammuttamalla näyttö"</string>
+ <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"Lopeta sammuttamalla näyttö"</string>
<string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"Laita pois päältä"</string>
<string name="fp_power_button_bp_title" msgid="5585506104526820067">"Jatketaanko sormenjäljen vahvistamista?"</string>
<string name="fp_power_button_bp_message" msgid="2983163038168903393">"Painoit virtapainiketta, mikä yleensä sammuttaa näytön.\n\nVahvista sormenjälki koskettamalla painiketta kevyesti."</string>
@@ -1959,7 +1959,8 @@
<string name="app_blocked_title" msgid="7353262160455028160">"Sovellus ei ole käytettävissä"</string>
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> ei ole nyt käytettävissä."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> ei käytettävissä"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Edellyttää käyttöoikeutta"</string>
+ <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (3805704317624448487) -->
+ <skip />
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"Kamera ei käytettävissä"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"Jatka puhelimella"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"Mikrofoni ei ole käytettävissä"</string>
@@ -1970,6 +1971,12 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"<xliff:g id="DEVICE">%1$s</xliff:g> ei tällä hetkellä saa pääsyä sovellukseen. Kokeile striimausta Android TV ‑laitteella."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"<xliff:g id="DEVICE">%1$s</xliff:g> ei tällä hetkellä saa pääsyä sovellukseen. Kokeile striimausta tabletilla."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"<xliff:g id="DEVICE">%1$s</xliff:g> ei tällä hetkellä saa pääsyä sovellukseen. Kokeile striimausta puhelimella."</string>
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (4706276040125072077) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (1824604581465771629) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (7755223160363292105) -->
+ <skip />
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"Sovellus pyytää lisäsuojausta. Kokeile striimausta Android TV ‑laitteella."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"Sovellus pyytää lisäsuojausta. Kokeile striimausta tabletilla."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Sovellus pyytää lisäsuojausta. Kokeile striimausta puhelimella."</string>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 0057a08..fdd3802 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -695,9 +695,9 @@
<string name="face_acquired_recalibrate" msgid="8724013080976469746">"Veuillez inscrire votre visage à nouveau."</string>
<string name="face_acquired_too_different" msgid="2520389515612972889">"Visage non reconnu. Réessayez."</string>
<string name="face_acquired_too_similar" msgid="8882920552674125694">"Modifiez légèrement la position de votre tête"</string>
- <string name="face_acquired_pan_too_extreme" msgid="5417928604710621088">"Regardez plus directement votre téléphone"</string>
- <string name="face_acquired_tilt_too_extreme" msgid="5715715666540716620">"Regardez plus directement votre téléphone"</string>
- <string name="face_acquired_roll_too_extreme" msgid="8261939882838881194">"Regardez plus directement votre téléphone"</string>
+ <string name="face_acquired_pan_too_extreme" msgid="5417928604710621088">"Regardez droit dans le téléphone"</string>
+ <string name="face_acquired_tilt_too_extreme" msgid="5715715666540716620">"Regardez droit dans le téléphone"</string>
+ <string name="face_acquired_roll_too_extreme" msgid="8261939882838881194">"Regardez droit dans le téléphone"</string>
<string name="face_acquired_obscured" msgid="4917643294953326639">"Retirez tout ce qui pourrait couvrir votre visage."</string>
<string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"Nettoyez le haut de l\'écran, y compris la barre noire"</string>
<!-- no translation found for face_acquired_dark_glasses_detected (5643703296620631986) -->
@@ -1960,7 +1960,8 @@
<string name="app_blocked_title" msgid="7353262160455028160">"L\'application n\'est pas accessible"</string>
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> n\'est pas accessible pour le moment."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> non accessible"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Autorisation nécessaire"</string>
+ <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (3805704317624448487) -->
+ <skip />
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"Appareil photo non accessible"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"Continuer sur le téléphone"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"Microphone non accessible"</string>
@@ -1971,6 +1972,12 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Impossible d\'accéder à ce contenu sur votre <xliff:g id="DEVICE">%1$s</xliff:g> pour le moment. Essayez sur votre appareil Android TV à la place."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Impossible d\'accéder à ce contenu sur votre <xliff:g id="DEVICE">%1$s</xliff:g> pour le moment. Essayez sur votre tablette à la place."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Impossible d\'accéder à ce contenu sur votre <xliff:g id="DEVICE">%1$s</xliff:g> pour le moment. Essayez sur votre téléphone à la place."</string>
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (4706276040125072077) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (1824604581465771629) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (7755223160363292105) -->
+ <skip />
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"Cette application demande une sécurité supplémentaire. Essayez sur votre appareil Android TV à la place."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"Cette application demande une sécurité supplémentaire. Essayez sur votre tablette à la place."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Cette application demande une sécurité supplémentaire. Essayez sur votre téléphone à la place."</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 4848eb3..c0c6695 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -689,16 +689,16 @@
<string name="face_acquired_too_low" msgid="4075391872960840081">"Déplacez le téléphone vers le bas"</string>
<string name="face_acquired_too_right" msgid="6245286514593540859">"Déplacez le téléphone vers la gauche"</string>
<string name="face_acquired_too_left" msgid="9201762240918405486">"Déplacez le téléphone vers la droite"</string>
- <string name="face_acquired_poor_gaze" msgid="4427153558773628020">"Veuillez regarder plus directement l\'appareil."</string>
+ <string name="face_acquired_poor_gaze" msgid="4427153558773628020">"Mettez-vous bien de face et regardez l\'appareil."</string>
<string name="face_acquired_not_detected" msgid="1057966913397548150">"Visage non détecté. Tenez votre téléphone à hauteur des yeux."</string>
<string name="face_acquired_too_much_motion" msgid="8199691445085189528">"Trop de mouvement. Ne bougez pas le téléphone."</string>
<string name="face_acquired_recalibrate" msgid="8724013080976469746">"Veuillez enregistrer à nouveau votre visage."</string>
<string name="face_acquired_too_different" msgid="2520389515612972889">"Visage non reconnu. Réessayez."</string>
<string name="face_acquired_too_similar" msgid="8882920552674125694">"Déplacez légèrement votre tête."</string>
- <string name="face_acquired_pan_too_extreme" msgid="5417928604710621088">"Regardez plus directement votre téléphone"</string>
- <string name="face_acquired_tilt_too_extreme" msgid="5715715666540716620">"Centrez bien votre visage devant votre téléphone"</string>
- <string name="face_acquired_roll_too_extreme" msgid="8261939882838881194">"Regardez plus directement votre téléphone"</string>
- <string name="face_acquired_obscured" msgid="4917643294953326639">"Retirez tout ce qui cache votre visage."</string>
+ <string name="face_acquired_pan_too_extreme" msgid="5417928604710621088">"Mettez-vous bien de face et regardez le téléphone"</string>
+ <string name="face_acquired_tilt_too_extreme" msgid="5715715666540716620">"Mettez-vous bien de face et regardez le téléphone"</string>
+ <string name="face_acquired_roll_too_extreme" msgid="8261939882838881194">"Mettez-vous bien de face et regardez le téléphone"</string>
+ <string name="face_acquired_obscured" msgid="4917643294953326639">"Retirez tout ce qui cache votre visage"</string>
<string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"Nettoyez la partie supérieure de l\'écran, y compris la barre noire"</string>
<!-- no translation found for face_acquired_dark_glasses_detected (5643703296620631986) -->
<skip />
@@ -706,7 +706,7 @@
<skip />
<string name="face_acquired_recalibrate_alt" msgid="5702674220280332115">"Impossible de créer votre empreinte faciale. Réessayez."</string>
<string name="face_acquired_dark_glasses_detected_alt" msgid="4052123776406041972">"Lunettes sombres détectées. Votre visage doit être entièrement visible."</string>
- <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"Masque détecté. Votre visage doit être entièrement visible."</string>
+ <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"Visage partiellement couvert. Votre visage doit être entièrement visible."</string>
<string-array name="face_acquired_vendor">
</string-array>
<string name="face_error_hw_not_available" msgid="5085202213036026288">"Imposs. valider visage. Matériel non disponible."</string>
@@ -1260,7 +1260,7 @@
<string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Lancement des applications…"</string>
<string name="android_upgrading_complete" msgid="409800058018374746">"Finalisation de la mise à jour."</string>
<string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"Vous avez appuyé sur le bouton Marche/Arrêt, ce qui éteint généralement l\'écran.\n\nEssayez d\'appuyer doucement pendant la configuration de votre empreinte digitale."</string>
- <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"Éteignez l\'écran pour achever la configuration."</string>
+ <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"Éteignez l\'écran pour finir la config."</string>
<string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"Éteindre"</string>
<string name="fp_power_button_bp_title" msgid="5585506104526820067">"Continuer de valider votre empreinte ?"</string>
<string name="fp_power_button_bp_message" msgid="2983163038168903393">"Vous avez appuyé sur le bouton Marche/Arrêt, ce qui éteint généralement l\'écran.\n\nPour valider votre empreinte digitale, appuyez plus doucement."</string>
@@ -1960,7 +1960,8 @@
<string name="app_blocked_title" msgid="7353262160455028160">"Application non disponible"</string>
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> n\'est pas disponible pour le moment."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> indisponible"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Autorisation nécessaire"</string>
+ <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (3805704317624448487) -->
+ <skip />
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"Caméra indisponible"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"Continuez sur le téléphone"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"Micro indisponible"</string>
@@ -1971,6 +1972,12 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Actuellement, vous ne pouvez pas accéder à cette application sur votre <xliff:g id="DEVICE">%1$s</xliff:g>. Essayez plutôt d\'y accéder sur votre appareil Android TV."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Actuellement, vous ne pouvez pas accéder à cette application sur votre <xliff:g id="DEVICE">%1$s</xliff:g>. Essayez plutôt d\'y accéder sur votre tablette."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Actuellement, vous ne pouvez pas accéder à cette application sur votre <xliff:g id="DEVICE">%1$s</xliff:g>. Essayez plutôt d\'y accéder sur votre téléphone."</string>
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (4706276040125072077) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (1824604581465771629) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (7755223160363292105) -->
+ <skip />
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"Cette appli demande une sécurité supplémentaire. Essayez plutôt d\'y accéder sur votre appareil Android TV."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"Cette appli demande une sécurité supplémentaire. Essayez plutôt d\'y accéder sur votre tablette."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Cette appli demande une sécurité supplémentaire. Essayez plutôt d\'y accéder sur votre téléphone."</string>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index e0cf31d..31034f5 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -648,7 +648,7 @@
<string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Autenticouse a cara, preme Confirmar"</string>
<string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Hardware de impresión dixital non dispoñible."</string>
<string name="fingerprint_error_no_space" msgid="7285481581905967580">"Non se puido configurar a impresión dixital"</string>
- <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Esgotouse o tempo para configurar a impresión dixital Téntao de novo."</string>
+ <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Esgotouse o tempo para configurar a impresión dixital. Téntao de novo."</string>
<string name="fingerprint_error_canceled" msgid="540026881380070750">"Cancelouse a operación da impresión dixital."</string>
<string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"O usuario cancelou a operación da impresión dixital."</string>
<string name="fingerprint_error_lockout" msgid="6626753679019351368">"Houbo demasiados intentos. Mellor usa o bloqueo de pantalla."</string>
@@ -705,7 +705,7 @@
<skip />
<string name="face_acquired_recalibrate_alt" msgid="5702674220280332115">"Non se puido crear o modelo facial. Téntao de novo."</string>
<string name="face_acquired_dark_glasses_detected_alt" msgid="4052123776406041972">"Levas lentes escuras, pero débeseche ver toda a cara"</string>
- <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"Tes a cara tapada, pero débeseche ver enteira"</string>
+ <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"Tes a cara tapada; tense que ver enteira"</string>
<string-array name="face_acquired_vendor">
</string-array>
<string name="face_error_hw_not_available" msgid="5085202213036026288">"Sen verificar a cara. Hardware non dispoñible."</string>
@@ -1959,7 +1959,8 @@
<string name="app_blocked_title" msgid="7353262160455028160">"A aplicación non está dispoñible"</string>
<string name="app_blocked_message" msgid="542972921087873023">"A aplicación <xliff:g id="APP_NAME">%1$s</xliff:g> non está dispoñible neste momento."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> non está dispoñible"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Necesítase permiso"</string>
+ <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (3805704317624448487) -->
+ <skip />
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"A cámara non está dispoñible"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"Continúa no teléfono"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"O micrófono non está dispoñible"</string>
@@ -1970,6 +1971,12 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Nestes momentos, non podes acceder a este contido desde o teu dispositivo (<xliff:g id="DEVICE">%1$s</xliff:g>). Proba a facelo desde o dispositivo Android TV."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Nestes momentos, non podes acceder a este contido desde o teu dispositivo (<xliff:g id="DEVICE">%1$s</xliff:g>). Proba a facelo desde a tableta."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Nestes momentos, non podes acceder a este contido desde o teu dispositivo (<xliff:g id="DEVICE">%1$s</xliff:g>). Proba a facelo desde o teléfono."</string>
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (4706276040125072077) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (1824604581465771629) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (7755223160363292105) -->
+ <skip />
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"Esta aplicación solicita seguranza adicional. Proba a facelo desde o dispositivo Android TV."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"Esta aplicación solicita seguranza adicional. Proba a facelo desde a tableta."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Esta aplicación solicita seguranza adicional. Proba a facelo desde o teléfono."</string>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index eb99a9d..5ef4ffc 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -1959,7 +1959,8 @@
<string name="app_blocked_title" msgid="7353262160455028160">"ઍપ ઉપલબ્ધ નથી"</string>
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> હાલમાં ઉપલબ્ધ નથી."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> ઉપલબ્ધ નથી"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"પરવાનગી જરૂરી છે"</string>
+ <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (3805704317624448487) -->
+ <skip />
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"કૅમેરા ઉપલબ્ધ નથી"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"ફોન પર ચાલુ રાખો"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"માઇક્રોફોન ઉપલબ્ધ નથી"</string>
@@ -1970,6 +1971,12 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"અત્યારે આને તમારા <xliff:g id="DEVICE">%1$s</xliff:g> પર ઍક્સેસ કરી શકાતી નથી. તેના બદલે તમારા Android TV ડિવાઇસ પર પ્રયાસ કરો."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"અત્યારે આને તમારા <xliff:g id="DEVICE">%1$s</xliff:g> પર ઍક્સેસ કરી શકાતી નથી. તેના બદલે તમારા ટૅબ્લેટ પર પ્રયાસ કરો."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"અત્યારે આને તમારા <xliff:g id="DEVICE">%1$s</xliff:g> પર ઍક્સેસ કરી શકાતી નથી. તેના બદલે તમારા ફોન પર પ્રયાસ કરો."</string>
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (4706276040125072077) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (1824604581465771629) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (7755223160363292105) -->
+ <skip />
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"આ ઍપ દ્વારા વધારાની સુરક્ષાની વિનંતી કરવામાં આવી રહી છે. તેના બદલે તમારા Android TV ડિવાઇસ પર પ્રયાસ કરો."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"આ ઍપ દ્વારા વધારાની સુરક્ષાની વિનંતી કરવામાં આવી રહી છે. તેના બદલે તમારા ટૅબ્લેટ પર પ્રયાસ કરો."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"આ ઍપ દ્વારા વધારાની સુરક્ષાની વિનંતી કરવામાં આવી રહી છે. તેના બદલે તમારા ફોન પર પ્રયાસ કરો."</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index e4b57ee..1155a2a 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -1259,7 +1259,7 @@
<string name="android_upgrading_starting_apps" msgid="6206161195076057075">"ऐप्स प्रारंभ होने वाले हैं"</string>
<string name="android_upgrading_complete" msgid="409800058018374746">"बूट खत्म हो रहा है."</string>
<string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"आपने पावर बटन दबाया - आम तौर पर, इससे स्क्रीन बंद हो जाती है.\n\nअपना फ़िंगरप्रिंट सेट अप करते समय, बटन को हल्के से टैप करके देखें."</string>
- <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"सेटअप पूरा होने पर, स्क्रीन बंद करें"</string>
+ <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"सेटअप रोकने के लिए, स्क्रीन बंद करें"</string>
<string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"बंद करें"</string>
<string name="fp_power_button_bp_title" msgid="5585506104526820067">"फ़िंगरप्रिंट की पुष्टि करना जारी रखना है?"</string>
<string name="fp_power_button_bp_message" msgid="2983163038168903393">"आपने पावर बटन दबाया - आम तौर पर, इससे स्क्रीन बंद हो जाती है.\n\nअपने फ़िंगरप्रिंट की पुष्टि करने के लिए, बटन पर हल्के से टैप करके देखें."</string>
@@ -1959,7 +1959,8 @@
<string name="app_blocked_title" msgid="7353262160455028160">"ऐप्लिकेशन उपलब्ध नहीं है"</string>
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> इस समय उपलब्ध नहीं है."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> उपलब्ध नहीं है"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"अनुमति ज़रूरी है"</string>
+ <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (3805704317624448487) -->
+ <skip />
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"कैमरा उपलब्ध नहीं है"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"फ़ोन पर जारी रखें"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"माइक्रोफ़ोन उपलब्ध नहीं है"</string>
@@ -1970,6 +1971,12 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"इस समय, आपके <xliff:g id="DEVICE">%1$s</xliff:g> पर इसे ऐक्सेस नहीं किया जा सकता. इसके बजाय, अपने Android TV डिवाइस पर कोशिश करें."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"इस समय, आपके <xliff:g id="DEVICE">%1$s</xliff:g> पर इसे ऐक्सेस नहीं किया जा सकता. इसके बजाय, अपने टैबलेट पर कोशिश करें."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"इस समय, आपके <xliff:g id="DEVICE">%1$s</xliff:g> पर इसे ऐक्सेस नहीं किया जा सकता. इसके बजाय, अपने फ़ोन पर कोशिश करें."</string>
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (4706276040125072077) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (1824604581465771629) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (7755223160363292105) -->
+ <skip />
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"यह ऐप्लिकेशन ज़्यादा सुरक्षा का अनुरोध कर रहा है. इसके बजाय, अपने Android TV डिवाइस पर ऐक्सेस करने की कोशिश करें."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"यह ऐप्लिकेशन ज़्यादा सुरक्षा का अनुरोध कर रहा है. इसके बजाय, अपने टैबलेट पर ऐक्सेस करने की कोशिश करें."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"यह ऐप्लिकेशन ज़्यादा सुरक्षा का अनुरोध कर रहा है. इसके बजाय, अपने फ़ोन पर ऐक्सेस करने की कोशिश करें."</string>
@@ -2160,7 +2167,7 @@
<string name="resolver_cross_profile_blocked" msgid="3014597376026044840">"आपके आईटी एडमिन ने इस कॉन्टेंट को शेयर करने की सुविधा ब्लॉक कर रखी है"</string>
<string name="resolver_cant_share_with_work_apps_explanation" msgid="9071442683080586643">"इस कॉन्टेंट को ऑफ़िस के काम से जुड़े ऐप्लिकेशन का इस्तेमाल करके, शेयर नहीं किया जा सकता"</string>
<string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"इस कॉन्टेंट को ऑफ़िस के काम से जुड़े ऐप्लिकेशन पर खोला नहीं जा सकता"</string>
- <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"इस कॉन्टेंट को निजी ऐप्लिकेशन का इस्तेमाल करके, शेयर नहीं किया जा सकता"</string>
+ <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"इस कॉन्टेंट को निजी ऐप्लिकेशन के ज़रिए शेयर नहीं किया जा सकता"</string>
<string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"इस कॉन्टेंट को निजी ऐप्लिकेशन पर खोला नहीं जा सकता"</string>
<string name="resolver_turn_on_work_apps" msgid="1535946298236678122">"वर्क ऐप्लिकेशन बंद किए गए हैं"</string>
<string name="resolver_switch_on_work" msgid="4527096360772311894">"चालू करें"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index adbacad..ffda001 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -1960,7 +1960,8 @@
<string name="app_blocked_title" msgid="7353262160455028160">"Aplikacija nije dostupna"</string>
<string name="app_blocked_message" msgid="542972921087873023">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> trenutačno nije dostupna."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> – nije dostupno"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Potrebno je dopuštenje"</string>
+ <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (3805704317624448487) -->
+ <skip />
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"Kamera nije dostupna"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"Nastavite na telefonu"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"Mikrofon nije dostupan"</string>
@@ -1971,6 +1972,12 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Trenutačno toj aplikaciji nije moguće pristupiti na vašem uređaju <xliff:g id="DEVICE">%1$s</xliff:g>. Pokušajte joj pristupiti na Android TV uređaju."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Trenutačno toj aplikaciji nije moguće pristupiti na vašem uređaju <xliff:g id="DEVICE">%1$s</xliff:g>. Pokušajte joj pristupiti na tabletu."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Trenutačno toj aplikaciji nije moguće pristupiti na vašem uređaju <xliff:g id="DEVICE">%1$s</xliff:g>. Pokušajte joj pristupiti na telefonu."</string>
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (4706276040125072077) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (1824604581465771629) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (7755223160363292105) -->
+ <skip />
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"Ta aplikacija zahtijeva dodatnu sigurnost. Pokušajte joj pristupiti na Android TV uređaju."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"Ta aplikacija zahtijeva dodatnu sigurnost. Pokušajte joj pristupiti na tabletu."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Ta aplikacija zahtijeva dodatnu sigurnost. Pokušajte joj pristupiti na telefonu."</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index b9d478f..31a99ae 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -1959,7 +1959,7 @@
<string name="app_blocked_title" msgid="7353262160455028160">"Az alkalmazás nem hozzáférhető"</string>
<string name="app_blocked_message" msgid="542972921087873023">"A(z) <xliff:g id="APP_NAME">%1$s</xliff:g> jelenleg nem hozzáférhető."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"A(z) <xliff:g id="ACTIVITY">%1$s</xliff:g> nem áll rendelkezése"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Engedély szükséges"</string>
+ <string name="app_streaming_blocked_title_for_permission_dialog" msgid="3805704317624448487">"Engedélykérés letiltva"</string>
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"A kamera nem áll rendelkezésre"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"Folytatás a telefonon"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"A mikrofon nem áll rendelkezésre"</string>
@@ -1970,6 +1970,9 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Ehhez jelenleg nem lehet hozzáférni a következő eszközön: <xliff:g id="DEVICE">%1$s</xliff:g>. Próbálja újra Android TV-eszközén."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Ehhez jelenleg nem lehet hozzáférni a következő eszközön: <xliff:g id="DEVICE">%1$s</xliff:g>. Próbálja újra a táblagépén."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Ehhez jelenleg nem lehet hozzáférni a következő eszközön: <xliff:g id="DEVICE">%1$s</xliff:g>. Próbálja újra a telefonján."</string>
+ <string name="app_streaming_blocked_message_for_permission_request" product="tv" msgid="4706276040125072077">"Ez az alkalmazás további engedélyeket kér, de az engedélyeket nem lehet megadni streamelési munkamenetben. Előbb adja meg az engedélyeket Android TV-eszközén."</string>
+ <string name="app_streaming_blocked_message_for_permission_request" product="tablet" msgid="1824604581465771629">"Ez az alkalmazás további engedélyeket kér, de az engedélyeket nem lehet megadni streamelési munkamenetben. Előbb adja meg az engedélyeket a táblagépén."</string>
+ <string name="app_streaming_blocked_message_for_permission_request" product="default" msgid="7755223160363292105">"Ez az alkalmazás további engedélyeket kér, de az engedélyeket nem lehet megadni streamelési munkamenetben. Előbb adja meg az engedélyeket a telefonján."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"Ez az alkalmazás nagyobb biztonságot igényel. Próbálja újra Android TV-eszközén."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"Ez az alkalmazás nagyobb biztonságot igényel. Próbálja újra a táblagépén."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Ez az alkalmazás nagyobb biztonságot igényel. Próbálja újra a telefonján."</string>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index b2dcbc5..fd4f9e6 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -1259,7 +1259,7 @@
<string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Հավելվածները մեկնարկում են:"</string>
<string name="android_upgrading_complete" msgid="409800058018374746">"Բեռնումն ավարտվում է:"</string>
<string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"Դուք սեղմել եք սնուցման կոճակը։ Սովորաբար դրա արդյունքում էկրանն անջատվում է։\n\nՄատնահետքը ավելացնելու համար թեթևակի հպեք կոճակին։"</string>
- <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"Ավարտեք կարգավորումը՝ անջատելով էկրանը"</string>
+ <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"Անջատեք էկրանը և ավարտեք"</string>
<string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"Անջատել"</string>
<string name="fp_power_button_bp_title" msgid="5585506104526820067">"Շարունակե՞լ մատնահետքի սկանավորումը"</string>
<string name="fp_power_button_bp_message" msgid="2983163038168903393">"Դուք սեղմել եք սնուցման կոճակը։ Սովորաբար դրա արդյունքում էկրանն անջատվում է։\n\nՄատնահետքը սկանավորելու համար թեթևակի հպեք կոճակին։"</string>
@@ -1959,7 +1959,8 @@
<string name="app_blocked_title" msgid="7353262160455028160">"Հավելվածը հասանելի չէ"</string>
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածն այս պահին հասանելի չէ։"</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g>՝ անհասանելի է"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Անհրաժեշտ է թույլտվություն"</string>
+ <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (3805704317624448487) -->
+ <skip />
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"Տեսախցիկն անհասանելի է"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"Շարունակեք հեռախոսով"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"Խոսափողն անհասանելի է"</string>
@@ -1970,6 +1971,12 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Այս պահին հնարավոր չէ բացել հավելվածը <xliff:g id="DEVICE">%1$s</xliff:g> սարքում։ Փորձեք Android TV սարքում։"</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Այս պահին հնարավոր չէ բացել հավելվածը <xliff:g id="DEVICE">%1$s</xliff:g> սարքում։ Փորձեք ձեր պլանշետում։"</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Այս պահին հնարավոր չէ բացել հավելվածը <xliff:g id="DEVICE">%1$s</xliff:g> սարքում։ Փորձեք ձեր հեռախոսում։"</string>
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (4706276040125072077) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (1824604581465771629) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (7755223160363292105) -->
+ <skip />
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"Այս հավելվածը պահանջում է անվտանգության լրացուցիչ միջոցներ։ Օգտագործեք ձեր Android TV սարքը։"</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"Այս հավելվածը պահանջում է անվտանգության լրացուցիչ միջոցներ։ Օգտագործեք ձեր պլանշետը։"</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Այս հավելվածը պահանջում է անվտանգության լրացուցիչ միջոցներ։ Օգտագործեք ձեր հեռախոսը։"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index c0aa2f7..c5e8ff9 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -223,7 +223,7 @@
<string name="silent_mode_silent" msgid="5079789070221150912">"Pendering mati"</string>
<string name="silent_mode_vibrate" msgid="8821830448369552678">"Pendering bergetar"</string>
<string name="silent_mode_ring" msgid="6039011004781526678">"Pendering nyala"</string>
- <string name="reboot_to_update_title" msgid="2125818841916373708">"Pemutakhiran sistem Android"</string>
+ <string name="reboot_to_update_title" msgid="2125818841916373708">"Update sistem Android"</string>
<string name="reboot_to_update_prepare" msgid="6978842143587422365">"Bersiap untuk memperbarui..."</string>
<string name="reboot_to_update_package" msgid="4644104795527534811">"Memproses pembaruan paket…"</string>
<string name="reboot_to_update_reboot" msgid="4474726009984452312">"Memulai ulang…"</string>
@@ -705,7 +705,7 @@
<skip />
<string name="face_acquired_recalibrate_alt" msgid="5702674220280332115">"Tidak dapat membuat model wajah Anda. Coba lagi."</string>
<string name="face_acquired_dark_glasses_detected_alt" msgid="4052123776406041972">"Kacamata hitam terdeteksi. Wajah harus terlihat sepenuhnya."</string>
- <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"Penutup wajah terdeteksi. Wajah harus terlihat sepenuhnya."</string>
+ <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"Penutup wajah terdeteksi. Wajah harus terlihat jelas."</string>
<string-array name="face_acquired_vendor">
</string-array>
<string name="face_error_hw_not_available" msgid="5085202213036026288">"Tidak dapat memverifikasi wajah. Hardware tidak tersedia."</string>
@@ -1373,7 +1373,7 @@
<string name="usb_unsupported_audio_accessory_title" msgid="2335775548086533065">"Aksesori audio analog terdeteksi"</string>
<string name="usb_unsupported_audio_accessory_message" msgid="1300168007129796621">"Perangkat yang terpasang tidak kompatibel dengan ponsel ini. Ketuk untuk mempelajari lebih lanjut."</string>
<string name="adb_active_notification_title" msgid="408390247354560331">"Proses debug USB terhubung"</string>
- <string name="adb_active_notification_message" msgid="5617264033476778211">"Ketuk untuk menonaktifkan proses debug USB"</string>
+ <string name="adb_active_notification_message" msgid="5617264033476778211">"Ketuk untuk nonaktifkan proses debug USB"</string>
<string name="adb_active_notification_message" product="tv" msgid="6624498401272780855">"Pilih untuk menonaktifkan debugging USB."</string>
<string name="adbwifi_active_notification_title" msgid="6147343659168302473">"Proses debug nirkabel terhubung"</string>
<string name="adbwifi_active_notification_message" msgid="930987922852867972">"Ketuk untuk menonaktifkan proses debug nirkabel."</string>
@@ -1959,7 +1959,8 @@
<string name="app_blocked_title" msgid="7353262160455028160">"Aplikasi tidak tersedia"</string>
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> tidak tersedia saat ini."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> tidak tersedia"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Perlu izin"</string>
+ <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (3805704317624448487) -->
+ <skip />
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"Kamera tidak tersedia"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"Lanjutkan di ponsel"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"Mikrofon tidak tersedia"</string>
@@ -1970,6 +1971,12 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Aplikasi ini tidak dapat diakses di <xliff:g id="DEVICE">%1$s</xliff:g> untuk saat ini. Coba di perangkat Android TV."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Aplikasi ini tidak dapat diakses di <xliff:g id="DEVICE">%1$s</xliff:g> untuk saat ini. Coba di tablet."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Aplikasi ini tidak dapat diakses di <xliff:g id="DEVICE">%1$s</xliff:g> untuk saat ini. Coba di ponsel."</string>
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (4706276040125072077) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (1824604581465771629) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (7755223160363292105) -->
+ <skip />
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"Aplikasi ini meminta keamanan tambahan. Coba di perangkat Android TV."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"Aplikasi ini meminta keamanan tambahan. Coba di tablet."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Aplikasi ini meminta keamanan tambahan. Coba di ponsel."</string>
@@ -2160,7 +2167,7 @@
<string name="resolver_cross_profile_blocked" msgid="3014597376026044840">"Diblokir oleh admin IT Anda"</string>
<string name="resolver_cant_share_with_work_apps_explanation" msgid="9071442683080586643">"Konten ini tidak dapat dibagikan dengan aplikasi kerja"</string>
<string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Konten ini tidak dapat dibuka dengan aplikasi kerja"</string>
- <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Konten ini tidak dapat dibagikan dengan aplikasi pribadi"</string>
+ <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Konten ini tidak dapat dibagikan ke aplikasi pribadi"</string>
<string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Konten ini tidak dapat dibuka dengan aplikasi pribadi"</string>
<string name="resolver_turn_on_work_apps" msgid="1535946298236678122">"Aplikasi kerja dijeda"</string>
<string name="resolver_switch_on_work" msgid="4527096360772311894">"Batalkan jeda"</string>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index f8dc531..6784ceb 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -1959,7 +1959,8 @@
<string name="app_blocked_title" msgid="7353262160455028160">"Forrit er ekki tiltækt"</string>
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> er ekki tiltækt núna."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> ekki í boði"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Heimildar krafist"</string>
+ <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (3805704317624448487) -->
+ <skip />
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"Myndavél ekki tiltæk"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"Halda áfram í símanum"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"Hljóðnemi ekki tiltækur"</string>
@@ -1970,6 +1971,12 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Aðgangur að þessu í <xliff:g id="DEVICE">%1$s</xliff:g> er ekki í boði eins og er. Prófaðu það í Android TV tækinu í staðinn."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Aðgangur að þessu í <xliff:g id="DEVICE">%1$s</xliff:g> er ekki í boði eins og er. Prófaðu það í spjaldtölvunni í staðinn."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Aðgangur að þessu í <xliff:g id="DEVICE">%1$s</xliff:g> er ekki í boði eins og er. Prófaðu það í símanum í staðinn."</string>
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (4706276040125072077) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (1824604581465771629) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (7755223160363292105) -->
+ <skip />
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"Þetta forrit biður um viðbótaröryggi. Prófaðu það í Android TV tækinu í staðinn."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"Þetta forrit biður um viðbótaröryggi. Prófaðu það í spjaldtölvunni í staðinn."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Þetta forrit biður um viðbótaröryggi. Prófaðu það í símanum í staðinn."</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 30fd6fb..0b420e0 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -695,8 +695,8 @@
<string name="face_acquired_recalibrate" msgid="8724013080976469746">"Ripeti l\'acquisizione del volto."</string>
<string name="face_acquired_too_different" msgid="2520389515612972889">"Impossibile riconoscere il volto. Riprova."</string>
<string name="face_acquired_too_similar" msgid="8882920552674125694">"Cambia leggermente la posizione della testa"</string>
- <string name="face_acquired_pan_too_extreme" msgid="5417928604710621088">"Guarda dritto nel telefono"</string>
- <string name="face_acquired_tilt_too_extreme" msgid="5715715666540716620">"Guarda dritto nel telefono"</string>
+ <string name="face_acquired_pan_too_extreme" msgid="5417928604710621088">"Guarda dritto nello smartphone"</string>
+ <string name="face_acquired_tilt_too_extreme" msgid="5715715666540716620">"Guarda dritto nello smartphone"</string>
<string name="face_acquired_roll_too_extreme" msgid="8261939882838881194">"Guarda dritto nel telefono"</string>
<string name="face_acquired_obscured" msgid="4917643294953326639">"Rimuovi tutto ciò che ti nasconde il viso"</string>
<string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"Pulisci la parte superiore dello schermo, inclusa la barra nera"</string>
@@ -1960,7 +1960,7 @@
<string name="app_blocked_title" msgid="7353262160455028160">"L\'app non è disponibile"</string>
<string name="app_blocked_message" msgid="542972921087873023">"L\'app <xliff:g id="APP_NAME">%1$s</xliff:g> non è al momento disponibile."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> non disponibile"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Autorizzazione necessaria"</string>
+ <string name="app_streaming_blocked_title_for_permission_dialog" msgid="3805704317624448487">"Richiesta di autorizzazione rifiutata"</string>
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"Fotocamera non disponibile"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"Continua sul telefono"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"Microfono non disponibile"</string>
@@ -1971,6 +1971,9 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Al momento non è possibile accedere a questa app su <xliff:g id="DEVICE">%1$s</xliff:g>. Prova a usare il dispositivo Android TV."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Al momento non è possibile accedere a questa app su <xliff:g id="DEVICE">%1$s</xliff:g>. Prova a usare il tablet."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Al momento non è possibile accedere a questa app su <xliff:g id="DEVICE">%1$s</xliff:g>. Prova a usare il telefono."</string>
+ <string name="app_streaming_blocked_message_for_permission_request" product="tv" msgid="4706276040125072077">"Questa app richiede autorizzazioni aggiuntive, ma non è possibile concedere autorizzazioni in una sessione di streaming. Devi prima concedere l\'autorizzazione sul tuo dispositivo Android TV."</string>
+ <string name="app_streaming_blocked_message_for_permission_request" product="tablet" msgid="1824604581465771629">"Questa app richiede autorizzazioni aggiuntive, ma non è possibile concedere autorizzazioni in una sessione di streaming. Devi prima concedere l\'autorizzazione sul tuo tablet."</string>
+ <string name="app_streaming_blocked_message_for_permission_request" product="default" msgid="7755223160363292105">"Questa app richiede autorizzazioni aggiuntive, ma non è possibile concedere autorizzazioni in una sessione di streaming. Devi prima concedere l\'autorizzazione sul tuo smartphone."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"Questa app richiede maggiore sicurezza. Prova a usare il dispositivo Android TV."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"Questa app richiede maggiore sicurezza. Prova a usare il tablet."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Questa app richiede maggiore sicurezza. Prova a usare il telefono."</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index a24becd..9644cb4 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -686,11 +686,11 @@
<string name="face_acquired_too_close" msgid="4453646176196302462">"צריך להרחיק את הטלפון"</string>
<string name="face_acquired_too_far" msgid="2922278214231064859">"צריך לקרב את הטלפון"</string>
<string name="face_acquired_too_high" msgid="8278815780046368576">"צריך להגביה את הטלפון"</string>
- <string name="face_acquired_too_low" msgid="4075391872960840081">"צריך להוריד את הטלפון"</string>
+ <string name="face_acquired_too_low" msgid="4075391872960840081">"צריך להנמיך את הטלפון."</string>
<string name="face_acquired_too_right" msgid="6245286514593540859">"צריך להזיז את הטלפון שמאלה"</string>
<string name="face_acquired_too_left" msgid="9201762240918405486">"צריך להזיז את הטלפון ימינה"</string>
<string name="face_acquired_poor_gaze" msgid="4427153558773628020">"יש להביט ישירות אל המכשיר."</string>
- <string name="face_acquired_not_detected" msgid="1057966913397548150">"כדי לראות את הפנים שלך יש להחזיק את הטלפון בגובה העיניים."</string>
+ <string name="face_acquired_not_detected" msgid="1057966913397548150">"לא רואים את הפנים שלך. יש להחזיק את הטלפון בגובה העיניים."</string>
<string name="face_acquired_too_much_motion" msgid="8199691445085189528">"יותר מדי תנועה. יש להחזיק את הטלפון בצורה יציבה."</string>
<string name="face_acquired_recalibrate" msgid="8724013080976469746">"יש לסרוק שוב את הפנים."</string>
<string name="face_acquired_too_different" msgid="2520389515612972889">"לא ניתן לזהות את הפנים. יש לנסות שוב."</string>
@@ -706,7 +706,7 @@
<skip />
<string name="face_acquired_recalibrate_alt" msgid="5702674220280332115">"לא ניתן ליצור את התבנית לזיהוי הפנים. יש לנסות שוב."</string>
<string name="face_acquired_dark_glasses_detected_alt" msgid="4052123776406041972">"זוהו משקפיים כהים. הפנים שלך חייבות להיות גלויות לגמרי."</string>
- <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"זוהה כיסוי על הפנים. הפנים שלך חייבות להיות גלויות לגמרי."</string>
+ <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"זוהה שהפנים מכוסות. הפנים שלך חייבות להיות גלויות לגמרי."</string>
<string-array name="face_acquired_vendor">
</string-array>
<string name="face_error_hw_not_available" msgid="5085202213036026288">"לא ניתן לאמת את הפנים. החומרה לא זמינה."</string>
@@ -1261,7 +1261,7 @@
<string name="android_upgrading_complete" msgid="409800058018374746">"תהליך האתחול בשלבי סיום."</string>
<string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"לחצת על לחצן ההפעלה – בדרך כלל הפעולה הזו מכבה את המסך.\n\nעליך לנסות להקיש בעדינות במהלך ההגדרה של טביעת האצבע שלך."</string>
<string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"לסיום ההגדרה, יש לכבות את המסך"</string>
- <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"השבתה"</string>
+ <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"כיבוי"</string>
<string name="fp_power_button_bp_title" msgid="5585506104526820067">"להמשיך לאמת את טביעת האצבע שלך?"</string>
<string name="fp_power_button_bp_message" msgid="2983163038168903393">"לחצת על לחצן ההפעלה – בדרך כלל הפעולה הזו מכבה את המסך.\n\nעליך לנסות להקיש בעדינות כדי לאמת את טביעת האצבע שלך."</string>
<string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"כיבוי המסך"</string>
@@ -1369,7 +1369,7 @@
<string name="usb_midi_notification_title" msgid="7404506788950595557">"MIDI באמצעות USB מופעל"</string>
<string name="usb_uvc_notification_title" msgid="2030032862673400008">"המכשיר מחובר כמצלמת אינטרנט"</string>
<string name="usb_accessory_notification_title" msgid="1385394660861956980">"אביזר USB מחובר"</string>
- <string name="usb_notification_message" msgid="4715163067192110676">"יש להקיש להצגת אפשרויות נוספות."</string>
+ <string name="usb_notification_message" msgid="4715163067192110676">"לאפשרויות נוספות, יש להקיש כאן."</string>
<string name="usb_power_notification_message" msgid="7284765627437897702">"המכשיר המחובר בטעינה. יש להקיש לאפשרויות נוספות."</string>
<string name="usb_unsupported_audio_accessory_title" msgid="2335775548086533065">"המכשיר זיהה התקן אודיו אנלוגי"</string>
<string name="usb_unsupported_audio_accessory_message" msgid="1300168007129796621">"ההתקן שחיברת לא תואם לטלפון הזה. יש להקיש לקבלת מידע נוסף."</string>
@@ -1960,7 +1960,8 @@
<string name="app_blocked_title" msgid="7353262160455028160">"האפליקציה לא זמינה"</string>
<string name="app_blocked_message" msgid="542972921087873023">"האפליקציה <xliff:g id="APP_NAME">%1$s</xliff:g> לא זמינה בשלב זה."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> לא זמינה"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"דרושה הרשאה"</string>
+ <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (3805704317624448487) -->
+ <skip />
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"המצלמה לא זמינה"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"יש להמשיך בטלפון"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"המיקרופון לא זמין"</string>
@@ -1971,6 +1972,12 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"אי אפשר לגשת לאפליקציה הזו במכשיר <xliff:g id="DEVICE">%1$s</xliff:g> כרגע. במקום זאת, יש לנסות במכשיר Android TV."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"אי אפשר לגשת לאפליקציה הזו במכשיר <xliff:g id="DEVICE">%1$s</xliff:g> כרגע. במקום זאת, יש לנסות בטאבלט."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"אי אפשר לגשת לאפליקציה הזו במכשיר <xliff:g id="DEVICE">%1$s</xliff:g> כרגע. במקום זאת, אפשר לנסות בטלפון."</string>
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (4706276040125072077) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (1824604581465771629) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (7755223160363292105) -->
+ <skip />
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"האפליקציה הזו מבקשת אמצעי אבטחה נוסף. במקום זאת, יש לנסות במכשיר Android TV."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"האפליקציה הזו מבקשת אמצעי אבטחה נוסף. במקום זאת, יש לנסות בטאבלט."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"האפליקציה הזו מבקשת אמצעי אבטחה נוסף. במקום זאת, יש לנסות בטלפון."</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 2f71e50..ea930a6 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -1959,7 +1959,7 @@
<string name="app_blocked_title" msgid="7353262160455028160">"アプリの利用不可"</string>
<string name="app_blocked_message" msgid="542972921087873023">"現在 <xliff:g id="APP_NAME">%1$s</xliff:g> はご利用になれません。"</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g>は利用できません"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"権限が必要"</string>
+ <string name="app_streaming_blocked_title_for_permission_dialog" msgid="3805704317624448487">"権限のリクエストが抑制されています"</string>
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"カメラ: 使用不可"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"スマートフォンで続行"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"マイク: 使用不可"</string>
@@ -1970,6 +1970,9 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"現在、<xliff:g id="DEVICE">%1$s</xliff:g> からアクセスできません。Android TV デバイスでのアクセスをお試しください。"</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"現在、<xliff:g id="DEVICE">%1$s</xliff:g> からアクセスできません。タブレットでのアクセスをお試しください。"</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"現在、<xliff:g id="DEVICE">%1$s</xliff:g> からアクセスできません。スマートフォンでのアクセスをお試しください。"</string>
+ <string name="app_streaming_blocked_message_for_permission_request" product="tv" msgid="4706276040125072077">"このアプリは追加の権限を求めていますが、ストリーミング セッションでは権限を付与できません。Android TV デバイスで先に権限を付与してください。"</string>
+ <string name="app_streaming_blocked_message_for_permission_request" product="tablet" msgid="1824604581465771629">"このアプリは追加の権限を求めていますが、ストリーミング セッションでは権限を付与できません。タブレットで先に権限を付与してください。"</string>
+ <string name="app_streaming_blocked_message_for_permission_request" product="default" msgid="7755223160363292105">"このアプリは追加の権限を求めていますが、ストリーミング セッションでは権限を付与できません。スマートフォンで先に権限を付与してください。"</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"このアプリはセキュリティの強化を求めています。Android TV デバイスでのアクセスをお試しください。"</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"このアプリはセキュリティの強化を求めています。タブレットでのアクセスをお試しください。"</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"このアプリはセキュリティの強化を求めています。スマートフォンでのアクセスをお試しください。"</string>
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index 3a76bca..988adaf 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -1373,7 +1373,7 @@
<string name="usb_unsupported_audio_accessory_title" msgid="2335775548086533065">"აღმოჩენილია ანალოგური აუდიო აქსესუარი"</string>
<string name="usb_unsupported_audio_accessory_message" msgid="1300168007129796621">"მიერთებული მოწყობილობა არაა თავსებადი ამ ტელეფონთან. მეტის გასაგებად, შეეხეთ."</string>
<string name="adb_active_notification_title" msgid="408390247354560331">"USB გამართვა შეერთებულია"</string>
- <string name="adb_active_notification_message" msgid="5617264033476778211">"შეეხეთ და გამორთეთ USB შეცდ. გამართვა"</string>
+ <string name="adb_active_notification_message" msgid="5617264033476778211">"შეეხეთ და გამორთეთ USB გამართვა"</string>
<string name="adb_active_notification_message" product="tv" msgid="6624498401272780855">"მონიშნეთ რათა შეწყვიტოთ USB-ის გამართვა"</string>
<string name="adbwifi_active_notification_title" msgid="6147343659168302473">"შეცდომების უსადენო გამართვა დაკავშირებულია"</string>
<string name="adbwifi_active_notification_message" msgid="930987922852867972">"შეეხეთ შეცდომების უსადენო გამართვის გამოსართავად"</string>
@@ -1959,7 +1959,7 @@
<string name="app_blocked_title" msgid="7353262160455028160">"აპი მიუწვდომელია"</string>
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> ამჟამად მიუწვდომელია."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> მიუწვდომელია"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"საჭიროა ნებართვა"</string>
+ <string name="app_streaming_blocked_title_for_permission_dialog" msgid="3805704317624448487">"ნებართვის მოთხოვნა შეჩერებულია"</string>
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"კამერა მიუწვდომელია"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"ტელეფონზე გაგრძელება"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"მიკროფონი მიუწვდომელია"</string>
@@ -1970,6 +1970,9 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"ამჟამად ამ აპზე თქვენი <xliff:g id="DEVICE">%1$s</xliff:g>-დან წვდომა შეუძლებელია. ცადეთ Android TV მოწყობილობიდან."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"ამჟამად ამ აპზე თქვენი <xliff:g id="DEVICE">%1$s</xliff:g>-დან წვდომა შეუძლებელია. ცადეთ ტაბლეტიდან."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"ამჟამად ამ აპზე თქვენი <xliff:g id="DEVICE">%1$s</xliff:g>-დან წვდომა შეუძლებელია. ცადეთ ტელეფონიდან."</string>
+ <string name="app_streaming_blocked_message_for_permission_request" product="tv" msgid="4706276040125072077">"ეს აპი დამატებით ნებართვებს მოითხოვს, მაგრამ ნებართვების მიცემა შეუძლებელია სტრიმინგის სესიაში თავდაპირველად მიანიჭეთ ნებართვა Android TV მოწყობილობაზე."</string>
+ <string name="app_streaming_blocked_message_for_permission_request" product="tablet" msgid="1824604581465771629">"ეს აპი დამატებით ნებართვებს მოითხოვს, მაგრამ ნებართვების მიცემა შეუძლებელია სტრიმინგის სესიაში თავდაპირველად მიანიჭეთ ნებართვა ტაბლეტზე."</string>
+ <string name="app_streaming_blocked_message_for_permission_request" product="default" msgid="7755223160363292105">"ეს აპი დამატებით ნებართვებს მოითხოვს, მაგრამ ნებართვების მიცემა შეუძლებელია სტრიმინგის სესიაში თავდაპირველად მიანიჭეთ ნებართვა ტელეფონზე."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"ეს აპი დამატებით უსაფრთხოებას ითხოვს. ცადეთ Android TV მოწყობილობიდან."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"ეს აპი დამატებით უსაფრთხოებას ითხოვს. ცადეთ ტაბლეტიდან."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"ეს აპი დამატებით უსაფრთხოებას ითხოვს. ცადეთ ტელეფონიდან."</string>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index d765aa1..aff1b3e 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -632,7 +632,7 @@
<string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"Саусақ ізін тану мүмкін емес. Қайталап көріңіз."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Саусақ ізін оқу сканерін тазалап, әрекетті қайталаңыз."</string>
<string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Сканерді тазалап, әрекетті қайталаңыз."</string>
- <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Сканерді қатты басыңыз."</string>
+ <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Сканерді қатты басыңыз"</string>
<string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Саусағыңызды тым баяу қозғалттыңыз. Әрекетті қайталап көріңіз."</string>
<string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Басқа саусақ ізін байқап көріңіз."</string>
<string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Тым жарық."</string>
@@ -684,20 +684,20 @@
<string name="face_acquired_too_dark" msgid="8539853432479385326">"Жарық жеткіліксіз"</string>
<string name="face_acquired_too_close" msgid="4453646176196302462">"Телефонды алшақ ұстаңыз."</string>
<string name="face_acquired_too_far" msgid="2922278214231064859">"Телефонды жақынырақ ұстаңыз."</string>
- <string name="face_acquired_too_high" msgid="8278815780046368576">"Телефонды жоғарырақ ұстаңыз."</string>
- <string name="face_acquired_too_low" msgid="4075391872960840081">"Телефонды төменірек ұстаңыз."</string>
- <string name="face_acquired_too_right" msgid="6245286514593540859">"Телефонды солға қарай жылжытыңыз."</string>
- <string name="face_acquired_too_left" msgid="9201762240918405486">"Телефонды оңға қарай жылжытыңыз."</string>
+ <string name="face_acquired_too_high" msgid="8278815780046368576">"Телефонды жоғарырақ ұстаңыз"</string>
+ <string name="face_acquired_too_low" msgid="4075391872960840081">"Телефонды төменірек ұстаңыз"</string>
+ <string name="face_acquired_too_right" msgid="6245286514593540859">"Телефонды солға қарай жылжытыңыз"</string>
+ <string name="face_acquired_too_left" msgid="9201762240918405486">"Телефонды оңға қарай жылжытыңыз"</string>
<string name="face_acquired_poor_gaze" msgid="4427153558773628020">"Құрылғының камерасына тура қараңыз."</string>
<string name="face_acquired_not_detected" msgid="1057966913397548150">"Бетіңіз көрінбей тұр. Телефонды көз деңгейінде ұстаңыз."</string>
<string name="face_acquired_too_much_motion" msgid="8199691445085189528">"Қозғалыс тым көп. Телефонды қозғалтпаңыз."</string>
<string name="face_acquired_recalibrate" msgid="8724013080976469746">"Қайта тіркеліңіз."</string>
<string name="face_acquired_too_different" msgid="2520389515612972889">"Бет танылмады. Қайталап көріңіз."</string>
<string name="face_acquired_too_similar" msgid="8882920552674125694">"Басыңыздың қалпын сәл өзгертіңіз."</string>
- <string name="face_acquired_pan_too_extreme" msgid="5417928604710621088">"Телефонға тура қараңыз."</string>
- <string name="face_acquired_tilt_too_extreme" msgid="5715715666540716620">"Телефонға тура қараңыз."</string>
- <string name="face_acquired_roll_too_extreme" msgid="8261939882838881194">"Телефонға тура қараңыз."</string>
- <string name="face_acquired_obscured" msgid="4917643294953326639">"Бетіңізді жауып тұрған нәрсені алып тастаңыз."</string>
+ <string name="face_acquired_pan_too_extreme" msgid="5417928604710621088">"Телефонға тура қараңыз"</string>
+ <string name="face_acquired_tilt_too_extreme" msgid="5715715666540716620">"Телефонға тура қараңыз"</string>
+ <string name="face_acquired_roll_too_extreme" msgid="8261939882838881194">"Телефонға тура қараңыз"</string>
+ <string name="face_acquired_obscured" msgid="4917643294953326639">"Бетіңізді жауып тұрған нәрсені алыңыз."</string>
<string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"Экранның жоғарғы жағын, сонымен қатар қара жолақты өшіріңіз."</string>
<!-- no translation found for face_acquired_dark_glasses_detected (5643703296620631986) -->
<skip />
@@ -1959,7 +1959,8 @@
<string name="app_blocked_title" msgid="7353262160455028160">"Қолданба қолжетімді емес"</string>
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> қазір қолжетімді емес."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> қолжетімсіз"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Рұқсат қажет"</string>
+ <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (3805704317624448487) -->
+ <skip />
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"Камера қолжетімді емес"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"Телефоннан жалғастыру"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"Микрофон қолжетімді емес"</string>
@@ -1970,6 +1971,12 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Қазір бұған <xliff:g id="DEVICE">%1$s</xliff:g> құрылғысынан кіру мүмкін емес. Оның орнына Android TV құрылғысын пайдаланып көріңіз."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Қазір бұған <xliff:g id="DEVICE">%1$s</xliff:g> құрылғысынан кіру мүмкін емес. Оның орнына планшетті пайдаланып көріңіз."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Қазір бұған <xliff:g id="DEVICE">%1$s</xliff:g> құрылғысынан кіру мүмкін емес. Оның орнына телефонды пайдаланып көріңіз."</string>
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (4706276040125072077) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (1824604581465771629) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (7755223160363292105) -->
+ <skip />
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"Бұл қолданба үшін қосымша қауіпсіздік шарасы қажет. Оның орнына Android TV құрылғысын пайдаланып көріңіз."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"Бұл қолданба үшін қосымша қауіпсіздік шарасы қажет. Оның орнына планшетті пайдаланып көріңіз."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Бұл қолданба үшін қосымша қауіпсіздік шарасы қажет. Оның орнына телефонды пайдаланып көріңіз."</string>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index 72826bb..46a7d8c 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -1373,7 +1373,7 @@
<string name="usb_unsupported_audio_accessory_title" msgid="2335775548086533065">"បានរកឃើញគ្រឿងបរិក្ខារសំឡេងអាណាឡូក"</string>
<string name="usb_unsupported_audio_accessory_message" msgid="1300168007129796621">"ឧបករណ៍ដែលភ្ជាប់មកជាមួយមិនត្រូវគ្នាជាមួយទូរសព្ទនេះទេ។ ចុចដើម្បីស្វែងយល់បន្ថែម។"</string>
<string name="adb_active_notification_title" msgid="408390247354560331">"បានភ្ជាប់ការជួសជុលតាម USB"</string>
- <string name="adb_active_notification_message" msgid="5617264033476778211">"ចុចដើម្បីបិទការជួសជុលតាម USB"</string>
+ <string name="adb_active_notification_message" msgid="5617264033476778211">"ប៉ះដើម្បីបិទការជួសជុលតាម USB"</string>
<string name="adb_active_notification_message" product="tv" msgid="6624498401272780855">"ជ្រើសរើស ដើម្បីបិទការកែកំហុសតាម USB ។"</string>
<string name="adbwifi_active_notification_title" msgid="6147343659168302473">"បានភ្ជាប់ការជួសជុលដោយឥតខ្សែ"</string>
<string name="adbwifi_active_notification_message" msgid="930987922852867972">"ចុច ដើម្បីបិទការជួសជុលដោយឥតខ្សែ"</string>
@@ -1959,7 +1959,7 @@
<string name="app_blocked_title" msgid="7353262160455028160">"មិនអាចប្រើកម្មវិធីនេះបានទេ"</string>
<string name="app_blocked_message" msgid="542972921087873023">"មិនអាចប្រើ <xliff:g id="APP_NAME">%1$s</xliff:g> នៅពេលនេះបានទេ។"</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"មិនអាចប្រើ <xliff:g id="ACTIVITY">%1$s</xliff:g> បានទេ"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"តម្រូវឱ្យមានការអនុញ្ញាត"</string>
+ <string name="app_streaming_blocked_title_for_permission_dialog" msgid="3805704317624448487">"បានទប់ស្កាត់សំណើសុំការអនុញ្ញាត"</string>
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"មិនអាចប្រើកាមេរ៉ាបានទេ"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"បន្តនៅលើទូរសព្ទ"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"មិនអាចប្រើមីក្រូហ្វូនបានទេ"</string>
@@ -1970,6 +1970,9 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"មិនអាចប្រើកម្មវិធីនេះនៅលើ <xliff:g id="DEVICE">%1$s</xliff:g> របស់អ្នកនៅពេលនេះបានទេ។ សូមសាកល្បងប្រើនៅលើឧបករណ៍ Android TV របស់អ្នកជំនួសវិញ។"</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"មិនអាចប្រើកម្មវិធីនេះនៅលើ <xliff:g id="DEVICE">%1$s</xliff:g> របស់អ្នកនៅពេលនេះបានទេ។ សូមសាកល្បងប្រើនៅលើថេប្លេតរបស់អ្នកជំនួសវិញ។"</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"មិនអាចប្រើកម្មវិធីនេះនៅលើ <xliff:g id="DEVICE">%1$s</xliff:g> របស់អ្នកនៅពេលនេះបានទេ។ សូមសាកល្បងប្រើនៅលើទូរសព្ទរបស់អ្នកជំនួសវិញ។"</string>
+ <string name="app_streaming_blocked_message_for_permission_request" product="tv" msgid="4706276040125072077">"កម្មវិធីនេះកំពុងស្នើសុំការអនុញ្ញាតបន្ថែម ប៉ុន្តែមិនអាចផ្តល់ការអនុញ្ញាតក្នុងវគ្គផ្សាយបានទេ។ ផ្តល់ការអនុញ្ញាតនៅលើឧបករណ៍ Android TV របស់អ្នកជាមុនសិន។"</string>
+ <string name="app_streaming_blocked_message_for_permission_request" product="tablet" msgid="1824604581465771629">"កម្មវិធីនេះកំពុងស្នើសុំការអនុញ្ញាតបន្ថែម ប៉ុន្តែមិនអាចផ្តល់ការអនុញ្ញាតក្នុងវគ្គផ្សាយបានទេ។ ផ្តល់ការអនុញ្ញាតនៅលើថេប្លេតរបស់អ្នកជាមុនសិន។"</string>
+ <string name="app_streaming_blocked_message_for_permission_request" product="default" msgid="7755223160363292105">"កម្មវិធីនេះកំពុងស្នើសុំការអនុញ្ញាតបន្ថែម ប៉ុន្តែមិនអាចផ្តល់ការអនុញ្ញាតក្នុងវគ្គផ្សាយបានទេ។ ផ្តល់ការអនុញ្ញាតនៅលើទូរសព្ទរបស់អ្នកជាមុនសិន។"</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"កម្មវិធីនេះកំពុងស្នើសុំសុវត្ថិភាពបន្ថែម។ សូមសាកល្បងប្រើនៅលើឧបករណ៍ Android TV របស់អ្នកជំនួសវិញ។"</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"កម្មវិធីនេះកំពុងស្នើសុំសុវត្ថិភាពបន្ថែម។ សូមសាកល្បងប្រើនៅលើថេប្លេតរបស់អ្នកជំនួសវិញ។"</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"កម្មវិធីនេះកំពុងស្នើសុំសុវត្ថិភាពបន្ថែម។ សូមសាកល្បងប្រើនៅលើទូរសព្ទរបស់អ្នកជំនួសវិញ។"</string>
@@ -2160,7 +2163,7 @@
<string name="resolver_cross_profile_blocked" msgid="3014597376026044840">"បានទប់ស្កាត់ដោយអ្នកគ្រប់គ្រងផ្នែកព័ត៌មានវិទ្យារបស់អ្នក"</string>
<string name="resolver_cant_share_with_work_apps_explanation" msgid="9071442683080586643">"ខ្លឹមសារនេះមិនអាចចែករំលែកតាមរយៈកម្មវិធីការងារបានទេ"</string>
<string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"ខ្លឹមសារនេះមិនអាចបើកតាមរយៈកម្មវិធីការងារបានទេ"</string>
- <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"ខ្លឹមសារនេះមិនអាចចែករំលែកតាមរយៈកម្មវិធីផ្ទាល់ខ្លួនបានទេ"</string>
+ <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"មិនអាចចែករំលែកខ្លឹមសារនេះជាមួយកម្មវិធីផ្ទាល់ខ្លួនបានទេ"</string>
<string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"ខ្លឹមសារនេះមិនអាចបើកតាមរយៈកម្មវិធីផ្ទាល់ខ្លួនបានទេ"</string>
<string name="resolver_turn_on_work_apps" msgid="1535946298236678122">"កម្មវិធីការងារត្រូវបានផ្អាក"</string>
<string name="resolver_switch_on_work" msgid="4527096360772311894">"ឈប់ផ្អាក"</string>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index 736050e..3773c1b 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -648,7 +648,7 @@
<string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"ಮುಖವನ್ನು ದೃಢೀಕರಿಸಲಾಗಿದೆ, ದೃಢೀಕರಣವನ್ನು ಒತ್ತಿ"</string>
<string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"ಫಿಂಗರ್ಪ್ರಿಂಟ್ ಹಾರ್ಡ್ವೇರ್ ಲಭ್ಯವಿಲ್ಲ."</string>
<string name="fingerprint_error_no_space" msgid="7285481581905967580">"ಫಿಂಗರ್ಪ್ರಿಂಟ್ ಅನ್ನು ಸೆಟಪ್ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
- <string name="fingerprint_error_timeout" msgid="7361192266621252164">"ಫಿಂಗರ್ ಪ್ರಿಂಟ್ ಸೆಟಪ್ ಮಾಡುವ ಅವಧಿ ಮುಗಿದಿದೆ. ಪುನಃ ಪ್ರಯತ್ನಿಸಿ."</string>
+ <string name="fingerprint_error_timeout" msgid="7361192266621252164">"ಫಿಂಗರ್ಪ್ರಿಂಟ್ ಸೆಟಪ್ ಮಾಡುವ ಅವಧಿ ಮುಗಿದಿದೆ. ಪುನಃ ಪ್ರಯತ್ನಿಸಿ."</string>
<string name="fingerprint_error_canceled" msgid="540026881380070750">"ಫಿಂಗರ್ಪ್ರಿಂಟ್ ಕಾರ್ಯಾಚರಣೆಯನ್ನು ರದ್ದುಮಾಡಲಾಗಿದೆ."</string>
<string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"ಬಳಕೆದಾರರು ಫಿಂಗರ್ಪ್ರಿಂಟ್ ಕಾರ್ಯಾಚರಣೆಯನ್ನು ರದ್ದುಪಡಿಸಿದ್ದಾರೆ."</string>
<string name="fingerprint_error_lockout" msgid="6626753679019351368">"ಹಲವು ಬಾರಿ ಪ್ರಯತ್ನಿಸಿದ್ದೀರಿ. ಬದಲಾಗಿ ಸ್ಕ್ರೀನ್ಲಾಕ್ ಬಳಸಿ."</string>
@@ -705,7 +705,7 @@
<skip />
<string name="face_acquired_recalibrate_alt" msgid="5702674220280332115">"ಫೇಸ್ ಮಾಡೆಲ್ ರಚಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ. ಪುನಃ ಪ್ರಯತ್ನಿಸಿ."</string>
<string name="face_acquired_dark_glasses_detected_alt" msgid="4052123776406041972">"ಕಪ್ಪು ಕನ್ನಡಕ ಪತ್ತೆಯಾಗಿದೆ. ನಿಮ್ಮ ಮುಖವು ಸಂಪೂರ್ಣವಾಗಿ ಗೋಚರಿಸಬೇಕು."</string>
- <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"ಮುಖವಾಡ ಪತ್ತೆಯಾಗಿದೆ. ಮುಖವು ಸಂಪೂರ್ಣವಾಗಿ ಗೋಚರಿಸಬೇಕು."</string>
+ <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"ಮುಖವು ಕವರ್ ಆಗಿದೆ. ಮುಖವು ಸಂಪೂರ್ಣವಾಗಿ ಗೋಚರಿಸಬೇಕು."</string>
<string-array name="face_acquired_vendor">
</string-array>
<string name="face_error_hw_not_available" msgid="5085202213036026288">"ಮುಖ ದೃಢೀಕರಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ. ಹಾರ್ಡ್ವೇರ್ ಲಭ್ಯವಿಲ್ಲ."</string>
@@ -1373,7 +1373,7 @@
<string name="usb_unsupported_audio_accessory_title" msgid="2335775548086533065">"ಅನ್ಲಾಗ್ ಆಡಿಯೋ ಪರಿಕರ ಪತ್ತೆಯಾಗಿದೆ"</string>
<string name="usb_unsupported_audio_accessory_message" msgid="1300168007129796621">"ಲಗತ್ತಿಸಲಾದ ಸಾಧನವು ಈ ಫೋನಿನೊಂದಿಗೆ ಹೊಂದಿಕೆಯಾಗುವುದಿಲ್ಲ. ಇನ್ನಷ್ಟು ತಿಳಿಯಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
<string name="adb_active_notification_title" msgid="408390247354560331">"USB ಡೀಬಗ್ ಮಾಡುವಿಕೆ ಕನೆಕ್ಟ್ ಆಗಿದೆ"</string>
- <string name="adb_active_notification_message" msgid="5617264033476778211">"USB ಡೀಬಗಿಂಗ್ ಆಫ್ ಮಾಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
+ <string name="adb_active_notification_message" msgid="5617264033476778211">"USB ಡೀಬಗ್ ಮಾಡುವಿಕೆ ಆಫ್ ಮಾಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
<string name="adb_active_notification_message" product="tv" msgid="6624498401272780855">"USB ಡೀಬಗ್ ಮಾಡುವಿಕೆಯನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲು ಆಯ್ಕೆ ಮಾಡಿ."</string>
<string name="adbwifi_active_notification_title" msgid="6147343659168302473">"ವೈರ್ಲೆಸ್ ಡೀಬಗ್ ಮಾಡುವಿಕೆಯನ್ನು ಕನೆಕ್ಟ್ ಮಾಡಲಾಗಿದೆ"</string>
<string name="adbwifi_active_notification_message" msgid="930987922852867972">"ವೈರ್ಲೆಸ್ ಡೀಬಗ್ ಮಾಡುವಿಕೆಯನ್ನು ಆಫ್ ಮಾಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
@@ -1935,7 +1935,7 @@
<string name="default_notification_channel_label" msgid="3697928973567217330">"ವರ್ಗೀಕರಿಸದಿರುವುದು"</string>
<string name="importance_from_user" msgid="2782756722448800447">"ನೀವು ಈ ಅಧಿಸೂಚನೆಗಳ ಪ್ರಾಮುಖ್ಯತೆಯನ್ನು ಹೊಂದಿಸಿರುವಿರಿ."</string>
<string name="importance_from_person" msgid="4235804979664465383">"ಜನರು ತೊಡಗಿಕೊಂಡಿರುವ ಕಾರಣ ಇದು ಅತ್ಯಂತ ಪ್ರಮುಖವಾಗಿದೆ."</string>
- <string name="notification_history_title_placeholder" msgid="7748630986182249599">"ಕಸ್ಟಮ್ ಆ್ಯಪ್ ಅಧಿಸೂಚನೆ"</string>
+ <string name="notification_history_title_placeholder" msgid="7748630986182249599">"ಕಸ್ಟಮ್ ಆ್ಯಪ್ ನೋಟಿಫಿಕೇಶನ್"</string>
<string name="user_creation_account_exists" msgid="2239146360099708035">"<xliff:g id="ACCOUNT">%2$s</xliff:g> (ಈ ಖಾತೆಯ ಬಳಕೆದಾರರು ಈಗಾಗಲೇ ಅಸ್ತಿತ್ವದಲ್ಲಿದ್ದಾರೆ) ಮೂಲಕ ಹೊಸ ಬಳಕೆದಾರರನ್ನು ರಚಿಸಲು <xliff:g id="APP">%1$s</xliff:g> ಗೆ ಅನುಮತಿಸಬೇಕೆ ?"</string>
<string name="user_creation_adding" msgid="7305185499667958364">"<xliff:g id="ACCOUNT">%2$s</xliff:g> ಮೂಲಕ ಹೊಸ ಬಳಕೆದಾರರನ್ನು ರಚಿಸಲು <xliff:g id="APP">%1$s</xliff:g> ಗೆ ಅನುಮತಿಸುವುದೇ ?"</string>
<string name="supervised_user_creation_label" msgid="6884904353827427515">"ಮೇಲ್ವಿಚಾರಣೆಯ ಬಳಕೆದಾರರನ್ನು ಸೇರಿಸಿ"</string>
@@ -1959,7 +1959,8 @@
<string name="app_blocked_title" msgid="7353262160455028160">"ಆ್ಯಪ್ ಲಭ್ಯವಿಲ್ಲ"</string>
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> ಇದೀಗ ಲಭ್ಯವಿಲ್ಲ."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> ಲಭ್ಯವಿಲ್ಲ"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"ಅನುಮತಿಯ ಅಗತ್ಯವಿದೆ"</string>
+ <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (3805704317624448487) -->
+ <skip />
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"ಕ್ಯಾಮರಾ ಲಭ್ಯವಿಲ್ಲ"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"ಫೋನ್ನಲ್ಲಿ ಮುಂದುವರಿಸಿ"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"ಮೈಕ್ರೊಫೋನ್ ಲಭ್ಯವಿಲ್ಲ"</string>
@@ -1970,6 +1971,12 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"ಈ ಸಮಯದಲ್ಲಿ ನಿಮ್ಮ <xliff:g id="DEVICE">%1$s</xliff:g> ನಲ್ಲಿ ಇದನ್ನು ಪ್ರವೇಶಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ. ಅದರ ಬದಲು ನಿಮ್ಮ Android TV ಸಾಧನದಲ್ಲಿ ಪ್ರಯತ್ನಿಸಿ."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"ಈ ಸಮಯದಲ್ಲಿ ನಿಮ್ಮ <xliff:g id="DEVICE">%1$s</xliff:g> ನಲ್ಲಿ ಇದನ್ನು ಪ್ರವೇಶಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ. ಅದರ ಬದಲು ನಿಮ್ಮ ಟ್ಯಾಬ್ಲೆಟ್ನಲ್ಲಿ ಪ್ರಯತ್ನಿಸಿ."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"ಈ ಸಮಯದಲ್ಲಿ ನಿಮ್ಮ <xliff:g id="DEVICE">%1$s</xliff:g> ನಲ್ಲಿ ಇದನ್ನು ಪ್ರವೇಶಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ. ಅದರ ಬದಲು ನಿಮ್ಮ ಫೋನ್ನಲ್ಲಿ ಪ್ರಯತ್ನಿಸಿ."</string>
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (4706276040125072077) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (1824604581465771629) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (7755223160363292105) -->
+ <skip />
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"ಈ ಆ್ಯಪ್ ಹೆಚ್ಚುವರಿ ಭದ್ರತೆಯನ್ನು ವಿನಂತಿಸುತ್ತಿದೆ. ಅದರ ಬದಲು ನಿಮ್ಮ Android TV ಸಾಧನದಲ್ಲಿ ಪ್ರಯತ್ನಿಸಿ."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"ಈ ಆ್ಯಪ್ ಹೆಚ್ಚುವರಿ ಭದ್ರತೆಯನ್ನು ವಿನಂತಿಸುತ್ತಿದೆ. ಅದರ ಬದಲು ನಿಮ್ಮ ಟ್ಯಾಬ್ಲೆಟ್ನಲ್ಲಿ ಪ್ರಯತ್ನಿಸಿ."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"ಈ ಆ್ಯಪ್ ಹೆಚ್ಚುವರಿ ಭದ್ರತೆಯನ್ನು ವಿನಂತಿಸುತ್ತಿದೆ. ಅದರ ಬದಲು ನಿಮ್ಮ ಫೋನ್ನಲ್ಲಿ ಪ್ರಯತ್ನಿಸಿ."</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 8aa80e5..d916ccf 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -628,11 +628,11 @@
<string name="biometric_error_generic" msgid="6784371929985434439">"인증 오류"</string>
<string name="screen_lock_app_setting_name" msgid="6054944352976789228">"화면 잠금 사용"</string>
<string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"계속하려면 화면 잠금용 사용자 인증 정보를 입력하세요"</string>
- <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"센서 위에 손가락을 좀 더 오래 올려놓으세요"</string>
+ <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"센서를 세게 누르세요"</string>
<string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"지문을 인식할 수 없습니다. 다시 시도해 주세요."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"지문 센서를 닦은 후 다시 시도해 보세요."</string>
<string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"센서를 닦은 후 다시 시도해 보세요."</string>
- <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"센서 위에 손가락을 좀 더 오래 올려놓으세요"</string>
+ <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"센서를 세게 누르세요"</string>
<string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"손가락을 너무 느리게 움직였습니다. 다시 시도해 주세요."</string>
<string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"다른 지문으로 시도"</string>
<string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"너무 밝음"</string>
@@ -689,14 +689,14 @@
<string name="face_acquired_too_right" msgid="6245286514593540859">"휴대전화를 왼쪽으로 움직이세요"</string>
<string name="face_acquired_too_left" msgid="9201762240918405486">"휴대전화를 오른쪽으로 움직이세요"</string>
<string name="face_acquired_poor_gaze" msgid="4427153558773628020">"기기에서 더 똑바로 바라보세요."</string>
- <string name="face_acquired_not_detected" msgid="1057966913397548150">"얼굴이 보이지 않습니다. 눈높이에 맞춰 휴대전화를 들어 주세요."</string>
+ <string name="face_acquired_not_detected" msgid="1057966913397548150">"얼굴이 보이지 않습니다. 눈높이에 맞춰 휴대전화를 들어 주세요"</string>
<string name="face_acquired_too_much_motion" msgid="8199691445085189528">"너무 많이 움직였습니다. 휴대전화를 흔들리지 않게 잡으세요."</string>
<string name="face_acquired_recalibrate" msgid="8724013080976469746">"얼굴을 다시 등록해 주세요."</string>
<string name="face_acquired_too_different" msgid="2520389515612972889">"얼굴을 인식할 수 없습니다. 다시 시도해 주세요."</string>
<string name="face_acquired_too_similar" msgid="8882920552674125694">"얼굴의 위치를 조금 변경해 주세요."</string>
- <string name="face_acquired_pan_too_extreme" msgid="5417928604710621088">"휴대전화를 좀 더 정면으로 바라보세요"</string>
- <string name="face_acquired_tilt_too_extreme" msgid="5715715666540716620">"휴대전화를 좀 더 정면으로 바라보세요"</string>
- <string name="face_acquired_roll_too_extreme" msgid="8261939882838881194">"휴대전화를 좀 더 정면으로 바라보세요"</string>
+ <string name="face_acquired_pan_too_extreme" msgid="5417928604710621088">"휴대전화를 좀 더 정면에서 바라보세요."</string>
+ <string name="face_acquired_tilt_too_extreme" msgid="5715715666540716620">"휴대전화를 좀 더 정면에서 바라보세요."</string>
+ <string name="face_acquired_roll_too_extreme" msgid="8261939882838881194">"휴대전화를 좀 더 정면에서 바라보세요."</string>
<string name="face_acquired_obscured" msgid="4917643294953326639">"얼굴이 가려지지 않도록 해 주세요"</string>
<string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"검은색 바를 포함한 화면 상단을 청소하세요."</string>
<!-- no translation found for face_acquired_dark_glasses_detected (5643703296620631986) -->
@@ -1959,7 +1959,8 @@
<string name="app_blocked_title" msgid="7353262160455028160">"앱을 사용할 수 없습니다"</string>
<string name="app_blocked_message" msgid="542972921087873023">"현재 <xliff:g id="APP_NAME">%1$s</xliff:g> 앱을 사용할 수 없습니다."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> 사용할 수 없음"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"권한이 필요함"</string>
+ <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (3805704317624448487) -->
+ <skip />
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"카메라를 사용할 수 없음"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"휴대전화에서 진행하기"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"마이크를 사용할 수 없음"</string>
@@ -1970,6 +1971,12 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"현재 <xliff:g id="DEVICE">%1$s</xliff:g>에서 액세스할 수 없습니다. 대신 Android TV 기기에서 시도해 보세요."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"현재 <xliff:g id="DEVICE">%1$s</xliff:g>에서 액세스할 수 없습니다. 대신 태블릿에서 시도해 보세요."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"현재 <xliff:g id="DEVICE">%1$s</xliff:g>에서 액세스할 수 없습니다. 대신 스마트폰에서 시도해 보세요."</string>
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (4706276040125072077) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (1824604581465771629) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (7755223160363292105) -->
+ <skip />
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"앱에서 추가 보안을 요청합니다. 대신 Android TV 기기에서 시도해 보세요."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"앱에서 추가 보안을 요청합니다. 대신 태블릿에서 시도해 보세요."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"앱에서 추가 보안을 요청합니다. 대신 휴대전화에서 시도해 보세요."</string>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index 6b40da6..b5c09bc 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -1959,7 +1959,8 @@
<string name="app_blocked_title" msgid="7353262160455028160">"Колдонмо учурда жеткиликсиз"</string>
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> учурда жеткиликсиз"</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> жеткиликсиз"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Уруксат керек"</string>
+ <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (3805704317624448487) -->
+ <skip />
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"Камера жеткиликсиз"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"Телефондон улантуу"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"Микрофон жеткиликсиз"</string>
@@ -1970,6 +1971,12 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Учурда буга <xliff:g id="DEVICE">%1$s</xliff:g> түзмөгүңүздөн кире албайсыз. Android TV түзмөгүңүздөн аракет кылып көрүңүз."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Учурда буга <xliff:g id="DEVICE">%1$s</xliff:g> түзмөгүңүздөн кире албайсыз. Планшетиңизден кирип көрүңүз."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Учурда буга <xliff:g id="DEVICE">%1$s</xliff:g> түзмөгүңүздөн кире албайсыз. Анын ордуна телефондон кирип көрүңүз."</string>
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (4706276040125072077) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (1824604581465771629) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (7755223160363292105) -->
+ <skip />
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"Бул колдонмо кошумча коопсуздукту иштетүүнү суранып жатат. Android TV түзмөгүңүздөн аракет кылып көрүңүз."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"Бул колдонмо кошумча коопсуздукту иштетүүнү суранып жатат. Планшетиңизден кирип көрүңүз."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Бул колдонмо кошумча коопсуздукту иштетүүнү суранып жатат. Анын ордуна телефондон кирип көрүңүз."</string>
@@ -2158,10 +2165,10 @@
<string name="resolver_personal_tab_accessibility" msgid="5739524949153091224">"Жеке көрүнүш"</string>
<string name="resolver_work_tab_accessibility" msgid="4753168230363802734">"Жумуш көрүнүшү"</string>
<string name="resolver_cross_profile_blocked" msgid="3014597376026044840">"IT администраторуңуз бөгөттөп койгон"</string>
- <string name="resolver_cant_share_with_work_apps_explanation" msgid="9071442683080586643">"Бул мазмунду жумуш колдонмолору менен бөлүшүү мүмкүн эмес"</string>
- <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Бул мазмунду жумуш колдонмолору менен ачуу мүмкүн эмес"</string>
- <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Бул мазмунду жеке колдонмолор менен бөлүшүү мүмкүн эмес"</string>
- <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Бул мазмунду жеке колдонмолор менен ачуу мүмкүн эмес"</string>
+ <string name="resolver_cant_share_with_work_apps_explanation" msgid="9071442683080586643">"Бул нерсени жумуш колдонмолору менен бөлүшө албайсыз"</string>
+ <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Бул нерсени жумуш колдонмолору менен ача албайсыз"</string>
+ <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Бул нерсени жеке колдонмолор менен бөлүшө албайсыз"</string>
+ <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Бул нерсени жеке колдонмолор менен ача албайсыз"</string>
<string name="resolver_turn_on_work_apps" msgid="1535946298236678122">"Жумуш колдонмолору тындырылды"</string>
<string name="resolver_switch_on_work" msgid="4527096360772311894">"Иштетүү"</string>
<string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Жумуш колдонмолору жок"</string>
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index f1ec5a7..bc3677c 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -1959,7 +1959,8 @@
<string name="app_blocked_title" msgid="7353262160455028160">"ແອັບບໍ່ສາມາດໃຊ້ໄດ້"</string>
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> ບໍ່ສາມາດໃຊ້ໄດ້ໃນຕອນນີ້."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"ບໍ່ສາມາດໃຊ້ <xliff:g id="ACTIVITY">%1$s</xliff:g> ໄດ້"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"ຕ້ອງມີການອະນຸຍາດ"</string>
+ <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (3805704317624448487) -->
+ <skip />
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"ກ້ອງຖ່າຍຮູບບໍ່ສາມາດໃຊ້ໄດ້"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"ສືບຕໍ່ຢູ່ໂທລະສັບ"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"ໄມໂຄຣໂຟນບໍ່ສາມາດໃຊ້ໄດ້"</string>
@@ -1970,6 +1971,12 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"ບໍ່ສາມາດເຂົ້າເຖິງແອັບນີ້ໄດ້ຢູ່ <xliff:g id="DEVICE">%1$s</xliff:g> ຂອງທ່ານໃນຕອນນີ້. ກະລຸນາລອງໃຊ້ຢູ່ອຸປະກອນ Android TV ຂອງທ່ານແທນ."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"ບໍ່ສາມາດເຂົ້າເຖິງແອັບນີ້ໄດ້ຢູ່ <xliff:g id="DEVICE">%1$s</xliff:g> ຂອງທ່ານໃນຕອນນີ້. ກະລຸນາລອງຢູ່ແທັບເລັດຂອງທ່ານແທນ."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"ບໍ່ສາມາດເຂົ້າເຖິງແອັບນີ້ໄດ້ຢູ່ <xliff:g id="DEVICE">%1$s</xliff:g> ຂອງທ່ານໃນຕອນນີ້. ກະລຸນາລອງຢູ່ໂທລະສັບຂອງທ່ານແທນ."</string>
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (4706276040125072077) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (1824604581465771629) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (7755223160363292105) -->
+ <skip />
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"ແອັບນີ້ກຳລັງຮ້ອງຂໍຄວາມປອດໄພເພີ່ມເຕີມ. ກະລຸນາລອງໃຊ້ຢູ່ອຸປະກອນ Android TV ຂອງທ່ານແທນ."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"ແອັບນີ້ກຳລັງຮ້ອງຂໍຄວາມປອດໄພເພີ່ມເຕີມ. ກະລຸນາລອງຢູ່ແທັບເລັດຂອງທ່ານແທນ."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"ແອັບນີ້ກຳລັງຮ້ອງຂໍຄວາມປອດໄພເພີ່ມເຕີມ. ກະລຸນາລອງຢູ່ໂທລະສັບຂອງທ່ານແທນ."</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 677e3d0..1d88adc 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -643,8 +643,8 @@
<string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Kaskart šiek tiek pakeiskite piršto poziciją"</string>
<string-array name="fingerprint_acquired_vendor">
</string-array>
- <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Kontrolinis kodas neatpažintas"</string>
- <string name="fingerprint_udfps_error_not_match" msgid="8236930793223158856">"Kontrolinis kodas neatpažintas"</string>
+ <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Piršto atspaudas neatpažintas"</string>
+ <string name="fingerprint_udfps_error_not_match" msgid="8236930793223158856">"Piršto atspaudas neatpažintas"</string>
<string name="fingerprint_authenticated" msgid="2024862866860283100">"Piršto antspaudas autentifikuotas"</string>
<string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Veidas autentifikuotas"</string>
<string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Veidas autentifikuotas, paspauskite patvirtinimo mygtuką"</string>
@@ -678,7 +678,7 @@
<string name="face_sensor_privacy_enabled" msgid="7407126963510598508">"Jei norite naudoti atrakinimą pagal veidą, įjunkite parinktį "<b>"Prieiga prie fotoaparato"</b>" skiltyje „Nustatymai“ > „Privatumas“"</string>
<string name="fingerprint_setup_notification_title" msgid="2002630611398849495">"Daugiau atrakinimo metodų nustatymas"</string>
<string name="fingerprint_setup_notification_content" msgid="205578121848324852">"Palieskite, kad pridėtumėte kontrolinį kodą"</string>
- <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Atrakinimas kontroliniu kodu"</string>
+ <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"Atrakinimas piršto atspaudu"</string>
<string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"Negalima naudoti kontrolinio kodo jutiklio"</string>
<string name="fingerprint_recalibrate_notification_content" msgid="8519935717822194943">"Apsilankykite pas taisymo paslaugos teikėją."</string>
<string name="face_acquired_insufficient" msgid="6889245852748492218">"Nepavyko sukurti veido modelio. Band. dar kartą."</string>
@@ -1961,7 +1961,8 @@
<string name="app_blocked_title" msgid="7353262160455028160">"Programa nepasiekiama."</string>
<string name="app_blocked_message" msgid="542972921087873023">"Programa „<xliff:g id="APP_NAME">%1$s</xliff:g>“ šiuo metu nepasiekiama."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"„<xliff:g id="ACTIVITY">%1$s</xliff:g>“ nepasiekiama"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Reikalingas leidimas"</string>
+ <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (3805704317624448487) -->
+ <skip />
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"Kamera nepasiekiama"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"Tęsti telefone"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"Mikrofonas nepasiekiamas"</string>
@@ -1972,6 +1973,12 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Šįkart nepavyksta pasiekti programos iš jūsų „<xliff:g id="DEVICE">%1$s</xliff:g>“. Pabandykite naudoti „Android TV“ įrenginį."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Šįkart nepavyksta pasiekti programos iš jūsų „<xliff:g id="DEVICE">%1$s</xliff:g>“. Pabandykite naudoti planšetinį kompiuterį."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Šįkart nepavyksta pasiekti programos iš jūsų „<xliff:g id="DEVICE">%1$s</xliff:g>“. Pabandykite naudoti telefoną."</string>
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (4706276040125072077) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (1824604581465771629) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (7755223160363292105) -->
+ <skip />
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"Ši programa prašo papildomų saugos funkcijų. Pabandykite naudoti „Android TV“ įrenginį."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"Ši programa prašo papildomų saugos funkcijų. Pabandykite naudoti planšetinį kompiuterį."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Ši programa prašo papildomų saugos funkcijų. Pabandykite naudoti telefoną."</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 5d94cc1..9c467c4 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -1960,7 +1960,8 @@
<string name="app_blocked_title" msgid="7353262160455028160">"Lietotne nav pieejama"</string>
<string name="app_blocked_message" msgid="542972921087873023">"Lietotne <xliff:g id="APP_NAME">%1$s</xliff:g> pašlaik nav pieejama."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> nav pieejams"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Nepieciešama atļauja"</string>
+ <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (3805704317624448487) -->
+ <skip />
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"Kamera nav pieejama"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"Turpiniet tālrunī"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"Mikrofons nav pieejams"</string>
@@ -1971,6 +1972,12 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Šajā ierīcē (<xliff:g id="DEVICE">%1$s</xliff:g>) pašlaik nevar piekļūt šai lietotnei. Mēģiniet tai piekļūt savā Android TV ierīcē."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Šajā ierīcē (<xliff:g id="DEVICE">%1$s</xliff:g>) pašlaik nevar piekļūt šai lietotnei. Mēģiniet tai piekļūt savā planšetdatorā."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Šajā ierīcē (<xliff:g id="DEVICE">%1$s</xliff:g>) pašlaik nevar piekļūt šai lietotnei. Mēģiniet tai piekļūt savā tālrunī."</string>
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (4706276040125072077) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (1824604581465771629) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (7755223160363292105) -->
+ <skip />
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"Šī lietotne pieprasa papildu drošību. Mēģiniet tai piekļūt savā Android TV ierīcē."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"Šī lietotne pieprasa papildu drošību. Mēģiniet tai piekļūt savā planšetdatorā."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Šī lietotne pieprasa papildu drošību. Mēģiniet tai piekļūt savā tālrunī."</string>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index 847fee6..d7847d6 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/strings.xml
@@ -697,7 +697,7 @@
<string name="face_acquired_pan_too_extreme" msgid="5417928604710621088">"Гледајте подиректно во телефонот"</string>
<string name="face_acquired_tilt_too_extreme" msgid="5715715666540716620">"Гледајте подиректно во телефонот"</string>
<string name="face_acquired_roll_too_extreme" msgid="8261939882838881194">"Гледајте подиректно во телефонот"</string>
- <string name="face_acquired_obscured" msgid="4917643294953326639">"Отстранете ги работите што ви го покриваат ликот."</string>
+ <string name="face_acquired_obscured" msgid="4917643294953326639">"Отстранете ги работите што ви го покриваат ликот"</string>
<string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"Исчистете го врвот на екранот, вклучувајќи ја црната лента"</string>
<!-- no translation found for face_acquired_dark_glasses_detected (5643703296620631986) -->
<skip />
@@ -1259,7 +1259,7 @@
<string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Се стартуваат апликациите."</string>
<string name="android_upgrading_complete" msgid="409800058018374746">"Подигањето завршува."</string>
<string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"Го притиснавте копчето за вклучување — така обично се исклучува екранот.\n\nДопрете лесно додека го поставувате отпечатокот."</string>
- <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"За да завршите со поставувањето, исклучете го екранот."</string>
+ <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"За да завршите со поставувањето, исклучете го екранот"</string>
<string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"Исклучи"</string>
<string name="fp_power_button_bp_title" msgid="5585506104526820067">"Да продолжи потврдувањето на отпечаток?"</string>
<string name="fp_power_button_bp_message" msgid="2983163038168903393">"Го притиснавте копчето за вклучување — така обично се исклучува екранот.\n\nДопрете лесно за да го потврдите отпечатокот."</string>
@@ -1959,7 +1959,8 @@
<string name="app_blocked_title" msgid="7353262160455028160">"Апликацијата не е достапна"</string>
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> не е достапна во моментов."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> е недостапна"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Потребна е дозвола"</string>
+ <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (3805704317624448487) -->
+ <skip />
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"Камерата е недостапна"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"Продолжете на телефонот"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"Микрофонот не е достапен"</string>
@@ -1970,6 +1971,12 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Ова не може да се отвори на <xliff:g id="DEVICE">%1$s</xliff:g> во моментов. Пробајте на вашиот Android TV како алтернатива."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Ова не може да се отвори на <xliff:g id="DEVICE">%1$s</xliff:g> во моментов. Пробајте на вашиот таблет како алтернатива."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Ова не може да се отвори на <xliff:g id="DEVICE">%1$s</xliff:g> во моментов. Пробајте на вашиот телефон како алтернатива."</string>
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (4706276040125072077) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (1824604581465771629) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (7755223160363292105) -->
+ <skip />
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"Апликацијава бара дополнителна безбедност. Пробајте на вашиот Android TV како алтернатива."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"Апликацијава бара дополнителна безбедност. Пробајте на вашиот таблет како алтернатива."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Апликацијава бара дополнителна безбедност. Пробајте на вашиот телефон како алтернатива."</string>
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index 40578a7..9db30b0 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -1012,7 +1012,7 @@
<string name="lockscreen_forgot_pattern_button_text" msgid="8362442730606839031">"പാറ്റേൺ മറന്നോ?"</string>
<string name="lockscreen_glogin_forgot_pattern" msgid="9218940117797602518">"അക്കൗണ്ട് അൺലോക്ക്"</string>
<string name="lockscreen_glogin_too_many_attempts" msgid="3775904917743034195">"വളരെയധികം പാറ്റേൺ ശ്രമങ്ങൾ"</string>
- <string name="lockscreen_glogin_instructions" msgid="4695162942525531700">"അൺലോക്കുചെയ്യുന്നതിന്, നിങ്ങളുടെ Google അക്കൗണ്ട് ഉപയോഗിച്ച് സൈൻ ഇൻ ചെയ്യുക."</string>
+ <string name="lockscreen_glogin_instructions" msgid="4695162942525531700">"അൺലോക്കുചെയ്യുന്നതിന്, നിങ്ങളുടെ Google Account ഉപയോഗിച്ച് സൈൻ ഇൻ ചെയ്യുക."</string>
<string name="lockscreen_glogin_username_hint" msgid="6916101478673157045">"ഉപയോക്താവിന്റെ പേര് (ഇമെയിൽ)"</string>
<string name="lockscreen_glogin_password_hint" msgid="3031027901286812848">"പാസ്വേഡ്"</string>
<string name="lockscreen_glogin_submit_button" msgid="3590556636347843733">"സൈൻ ഇൻ ചെയ്യുക"</string>
@@ -1663,7 +1663,7 @@
<string name="kg_invalid_puk" msgid="4809502818518963344">"ശരിയായ PUK കോഡ് വീണ്ടും നൽകുക. ആവർത്തിച്ചുള്ള ശ്രമങ്ങൾ സിം ശാശ്വതമായി പ്രവർത്തനരഹിതമാക്കും."</string>
<string name="kg_invalid_confirm_pin_hint" product="default" msgid="4705368340409816254">"പിൻ കോഡുകൾ പൊരുത്തപ്പെടുന്നില്ല"</string>
<string name="kg_login_too_many_attempts" msgid="699292728290654121">"വളരെയധികം പാറ്റേൺ ശ്രമങ്ങൾ"</string>
- <string name="kg_login_instructions" msgid="3619844310339066827">"അൺലോക്കുചെയ്യുന്നതിന്, നിങ്ങളുടെ Google അക്കൗണ്ട് ഉപയോഗിച്ച് സൈൻ ഇൻ ചെയ്യുക."</string>
+ <string name="kg_login_instructions" msgid="3619844310339066827">"അൺലോക്കുചെയ്യുന്നതിന്, നിങ്ങളുടെ Google Account ഉപയോഗിച്ച് സൈൻ ഇൻ ചെയ്യുക."</string>
<string name="kg_login_username_hint" msgid="1765453775467133251">"ഉപയോക്താവിന്റെ പേര് (ഇമെയിൽ)"</string>
<string name="kg_login_password_hint" msgid="3330530727273164402">"പാസ്വേഡ്"</string>
<string name="kg_login_submit_button" msgid="893611277617096870">"സൈൻ ഇൻ ചെയ്യുക"</string>
@@ -1959,7 +1959,7 @@
<string name="app_blocked_title" msgid="7353262160455028160">"ആപ്പ് ലഭ്യമല്ല"</string>
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> ഇപ്പോൾ ലഭ്യമല്ല."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> ലഭ്യമല്ല"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"അനുമതി ആവശ്യമാണ്"</string>
+ <string name="app_streaming_blocked_title_for_permission_dialog" msgid="3805704317624448487">"അനുമതി അഭ്യർത്ഥന നിയന്ത്രിച്ചു"</string>
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"ക്യാമറ ലഭ്യമല്ല"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"ഫോണിൽ തുടരുക"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"മൈക്രോഫോൺ ലഭ്യമല്ല"</string>
@@ -1970,6 +1970,9 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"ഇപ്പോൾ നിങ്ങളുടെ <xliff:g id="DEVICE">%1$s</xliff:g> ഉപകരണത്തിൽ ഇത് ആക്സസ് ചെയ്യാനാകില്ല. പകരം Android TV ഉപകരണത്തിൽ ശ്രമിച്ച് നോക്കൂ."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"ഇപ്പോൾ നിങ്ങളുടെ <xliff:g id="DEVICE">%1$s</xliff:g> ഉപകരണത്തിൽ ഇത് ആക്സസ് ചെയ്യാനാകില്ല. പകരം നിങ്ങളുടെ ടാബ്ലെറ്റിൽ ശ്രമിച്ച് നോക്കൂ."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"ഇപ്പോൾ നിങ്ങളുടെ <xliff:g id="DEVICE">%1$s</xliff:g> ഉപകരണത്തിൽ ഇത് ആക്സസ് ചെയ്യാനാകില്ല. പകരം നിങ്ങളുടെ ഫോണിൽ ശ്രമിച്ച് നോക്കൂ."</string>
+ <string name="app_streaming_blocked_message_for_permission_request" product="tv" msgid="4706276040125072077">"ഈ ആപ്പ് അധിക അനുമതികൾ അഭ്യർത്ഥിക്കുന്നു, എന്നാൽ സ്ട്രീമിംഗ് സെഷനിടയിൽ അനുമതികൾ നൽകാനാകില്ല. ആദ്യം നിങ്ങളുടെ Android TV ഉപകരണത്തിൽ അനുമതി നൽകുക."</string>
+ <string name="app_streaming_blocked_message_for_permission_request" product="tablet" msgid="1824604581465771629">"ഈ ആപ്പ് അധിക അനുമതികൾ അഭ്യർത്ഥിക്കുന്നു, എന്നാൽ സ്ട്രീമിംഗ് സെഷനിടയിൽ അനുമതികൾ നൽകാനാകില്ല. ആദ്യം നിങ്ങളുടെ ടാബ്ലെറ്റിൽ അനുമതി നൽകുക."</string>
+ <string name="app_streaming_blocked_message_for_permission_request" product="default" msgid="7755223160363292105">"ഈ ആപ്പ് അധിക അനുമതികൾ അഭ്യർത്ഥിക്കുന്നു, എന്നാൽ സ്ട്രീമിംഗ് സെഷനിടയിൽ അനുമതികൾ നൽകാനാകില്ല. ആദ്യം നിങ്ങളുടെ ഫോണിൽ അനുമതി നൽകുക."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"ഈ ആപ്പ് അധിക സുരക്ഷ അഭ്യർത്ഥിക്കുന്നു. പകരം നിങ്ങളുടെ Android TV ഉപകരണത്തിൽ ശ്രമിച്ച് നോക്കൂ."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"ഈ ആപ്പ് അധിക സുരക്ഷ അഭ്യർത്ഥിക്കുന്നു. പകരം നിങ്ങളുടെ ടാബ്ലെറ്റിൽ ശ്രമിച്ച് നോക്കൂ."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"ഈ ആപ്പ് അധിക സുരക്ഷ അഭ്യർത്ഥിക്കുന്നു. പകരം നിങ്ങളുടെ ഫോണിൽ ശ്രമിച്ച് നോക്കൂ."</string>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index eb995cf..2476e1e 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -1959,7 +1959,8 @@
<string name="app_blocked_title" msgid="7353262160455028160">"Апп боломжгүй байна"</string>
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> яг одоо боломжгүй байна."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> боломжгүй байна"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Зөвшөөрөл шаардлагатай"</string>
+ <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (3805704317624448487) -->
+ <skip />
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"Камер боломжгүй байна"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"Утсан дээр үргэлжлүүлэх"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"Микрофон боломжгүй байна"</string>
@@ -1970,6 +1971,12 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Одоогоор үүнд таны <xliff:g id="DEVICE">%1$s</xliff:g> дээрээс хандах боломжгүй. Оронд нь Android TV төхөөрөмж дээрээ туршиж үзнэ үү."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Одоогоор үүнд таны <xliff:g id="DEVICE">%1$s</xliff:g> дээрээс хандах боломжгүй. Оронд нь таблет дээрээ туршиж үзнэ үү."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Одоогоор үүнд таны <xliff:g id="DEVICE">%1$s</xliff:g> дээрээс хандах боломжгүй. Оронд нь утсан дээрээ туршиж үзнэ үү."</string>
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (4706276040125072077) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (1824604581465771629) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (7755223160363292105) -->
+ <skip />
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"Энэ апп нэмэлт аюулгүй байдал хүсэж байна. Оронд нь Android TV төхөөрөмж дээрээ туршиж үзнэ үү."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"Энэ апп нэмэлт аюулгүй байдал хүсэж байна. Оронд нь таблет дээрээ туршиж үзнэ үү."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Энэ апп нэмэлт аюулгүй байдал хүсэж байна. Оронд нь утсан дээрээ туршиж үзнэ үү."</string>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index 2b40d39..484af02 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -1959,7 +1959,7 @@
<string name="app_blocked_title" msgid="7353262160455028160">"ॲप उपलब्ध नाही"</string>
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> आता उपलब्ध नाही."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> उपलब्ध नाही"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"परवानगी आवश्यक आहे"</string>
+ <string name="app_streaming_blocked_title_for_permission_dialog" msgid="3805704317624448487">"परवानगीची विनंती ब्लॉक केली आहे"</string>
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"कॅमेरा उपलब्ध नाही"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"फोनवर पुढे सुरू ठेवा"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"मायक्रोफोन उपलब्ध नाही"</string>
@@ -1970,6 +1970,9 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"हे यावेळी तुमच्या <xliff:g id="DEVICE">%1$s</xliff:g> वर अॅक्सेस करू शकत नाही. त्याऐवजी तुमच्या Android TV डिव्हाइसवर अॅक्सेस करून पहा."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"हे यावेळी तुमच्या <xliff:g id="DEVICE">%1$s</xliff:g> वर अॅक्सेस करू शकत नाही. त्याऐवजी तुमच्या टॅबलेटवर अॅक्सेस करून पहा."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"हे यावेळी तुमच्या <xliff:g id="DEVICE">%1$s</xliff:g> वर अॅक्सेस करू शकत नाही. त्याऐवजी तुमच्या फोनवर अॅक्सेस करून पहा."</string>
+ <string name="app_streaming_blocked_message_for_permission_request" product="tv" msgid="4706276040125072077">"हे ॲप अतिरिक्त परवानग्यांची विनंती करत आहे, पण स्ट्रीमिंग सेशनमध्ये परवानग्या दिल्या जाऊ शकत नाहीत. आधी तुमच्या Android TV डिव्हाइसवर परवानगी द्या."</string>
+ <string name="app_streaming_blocked_message_for_permission_request" product="tablet" msgid="1824604581465771629">"हे ॲप अतिरिक्त परवानग्यांची विनंती करत आहे, पण स्ट्रीमिंग सेशनमध्ये परवानग्या दिल्या जाऊ शकत नाहीत. आधी तुमच्या टॅबलेटवर परवानगी द्या."</string>
+ <string name="app_streaming_blocked_message_for_permission_request" product="default" msgid="7755223160363292105">"हे ॲप अतिरिक्त परवानग्यांची विनंती करत आहे, पण स्ट्रीमिंग सेशनमध्ये परवानग्या दिल्या जाऊ शकत नाहीत. आधी तुमच्या फोनवर परवानगी द्या."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"हे अॅप अतिरिक्त सुरक्षेची विनंती करत आहे. त्याऐवजी तुमच्या Android TV डिव्हाइसवर अॅक्सेस करून पहा."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"हे अॅप अतिरिक्त सुरक्षेची विनंती करत आहे. त्याऐवजी तुमच्या टॅबलेटवर अॅक्सेस करून पहा."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"हे अॅप अतिरिक्त सुरक्षेची विनंती करत आहे. त्याऐवजी तुमच्या फोनवर अॅक्सेस करून पहा."</string>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index 7aeb96e..af01461 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -1959,7 +1959,7 @@
<string name="app_blocked_title" msgid="7353262160455028160">"Apl tidak tersedia"</string>
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> tidak tersedia sekarang."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> tidak tersedia"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Kebenaran diperlukan"</string>
+ <string name="app_streaming_blocked_title_for_permission_dialog" msgid="3805704317624448487">"Permintaan kebenaran disekat"</string>
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"Kamera tidak tersedia"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"Teruskan pada telefon"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"Mikrofon tidak tersedia"</string>
@@ -1970,6 +1970,9 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Aplikasi ini tidak boleh diakses pada <xliff:g id="DEVICE">%1$s</xliff:g> anda pada masa ini. Cuba pada peranti Android TV anda."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Aplikasi ini tidak boleh diakses pada <xliff:g id="DEVICE">%1$s</xliff:g> anda pada masa ini. Cuba pada tablet anda."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Aplikasi ini tidak boleh diakses pada <xliff:g id="DEVICE">%1$s</xliff:g> anda pada masa ini. Cuba pada telefon anda."</string>
+ <string name="app_streaming_blocked_message_for_permission_request" product="tv" msgid="4706276040125072077">"Apl ini meminta kebenaran tambahan tetapi kebenaran tidak boleh diberikan dalam sesi penstriman. Berikan kebenaran pada peranti Android TV anda dahulu."</string>
+ <string name="app_streaming_blocked_message_for_permission_request" product="tablet" msgid="1824604581465771629">"Apl ini meminta kebenaran tambahan tetapi kebenaran tidak boleh diberikan dalam sesi penstriman. Berikan kebenaran pada tablet anda dahulu."</string>
+ <string name="app_streaming_blocked_message_for_permission_request" product="default" msgid="7755223160363292105">"Apl ini meminta kebenaran tambahan tetapi kebenaran tidak boleh diberikan dalam sesi penstriman. Berikan kebenaran pada telefon anda dahulu."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"Apl ini meminta keselamatan tambahan. Cuba pada peranti Android TV anda."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"Apl ini meminta keselamatan tambahan. Cuba pada tablet anda."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Apl ini meminta keselamatan tambahan. Cuba pada telefon anda."</string>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index 1fdcb14..d5ba8b6 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -1959,7 +1959,8 @@
<string name="app_blocked_title" msgid="7353262160455028160">"အက်ပ်ကို မရနိုင်ပါ"</string>
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> ကို ယခု မရနိုင်ပါ။"</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> မရနိုင်ပါ"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"ခွင့်ပြုချက်လိုအပ်သည်"</string>
+ <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (3805704317624448487) -->
+ <skip />
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"ကင်မရာ မရနိုင်ပါ"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"ဖုန်းပေါ်တွင် ရှေ့ဆက်ပါ"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"မိုက်ခရိုဖုန်း မရနိုင်ပါ"</string>
@@ -1970,6 +1971,12 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"၎င်းအား ယခု သင့် <xliff:g id="DEVICE">%1$s</xliff:g> တွင် ဝင်၍မရပါ။ ယင်းအစား Android TV စက်တွင် စမ်းကြည့်ပါ။"</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"၎င်းအား ယခု သင့် <xliff:g id="DEVICE">%1$s</xliff:g> တွင် ဝင်၍မရပါ။ ယင်းအစား တက်ဘလက်တွင် စမ်းကြည့်ပါ။"</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"၎င်းအား ယခု သင့် <xliff:g id="DEVICE">%1$s</xliff:g> တွင် ဝင်၍မရပါ။ ယင်းအစား ဖုန်းတွင် စမ်းကြည့်ပါ။"</string>
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (4706276040125072077) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (1824604581465771629) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (7755223160363292105) -->
+ <skip />
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"ဤအက်ပ်က ထပ်ဆောင်းလုံခြုံရေးကို တောင်းဆိုနေသည်။ Android TV စက်တွင် စမ်းကြည့်ပါ။"</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"ဤအက်ပ်က ထပ်ဆောင်းလုံခြုံရေးကို တောင်းဆိုနေသည်။ တက်ဘလက်တွင် စမ်းကြည့်ပါ။"</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"ဤအက်ပ်က ထပ်ဆောင်းလုံခြုံရေးကို တောင်းဆိုနေသည်။ ဖုန်းတွင် စမ်းကြည့်ပါ။"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index dec5664..f2f14b8 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -1959,7 +1959,8 @@
<string name="app_blocked_title" msgid="7353262160455028160">"Appen er ikke tilgjengelig"</string>
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> er ikke tilgjengelig for øyeblikket."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> er utilgjengelig"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Du må gi tillatelse"</string>
+ <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (3805704317624448487) -->
+ <skip />
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"Kameraet er utilgjengelig"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"Fortsett på telefonen"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"Mikrofonen er utilgjengelig"</string>
@@ -1970,6 +1971,12 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Dette er ikke tilgjengelig på <xliff:g id="DEVICE">%1$s</xliff:g> for øyeblikket. Prøv på Android TV-enheten din i stedet."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Dette er ikke tilgjengelig på <xliff:g id="DEVICE">%1$s</xliff:g> for øyeblikket. Prøv på nettbrettet ditt i stedet."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Dette er ikke tilgjengelig på <xliff:g id="DEVICE">%1$s</xliff:g> for øyeblikket. Prøv på telefonen din i stedet."</string>
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (4706276040125072077) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (1824604581465771629) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (7755223160363292105) -->
+ <skip />
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"Denne appen ber om ekstra sikkerhet. Prøv på Android TV-enheten din i stedet."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"Denne appen ber om ekstra sikkerhet. Prøv på nettbrettet ditt i stedet."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Denne appen ber om ekstra sikkerhet. Prøv på telefonen din i stedet."</string>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index 716ad02..9023889 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -1959,7 +1959,8 @@
<string name="app_blocked_title" msgid="7353262160455028160">"एप उपलब्ध छैन"</string>
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> अहिले उपलब्ध छैन।"</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> उपलब्ध छैन"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"अनुमति चाहिन्छ"</string>
+ <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (3805704317624448487) -->
+ <skip />
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"क्यामेरा उपलब्ध छैन"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"फोनमा जारी राख्नुहोस्"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"माइक्रोफोन उपलब्ध छैन"</string>
@@ -1970,6 +1971,12 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"यस बखत तपाईंको <xliff:g id="DEVICE">%1$s</xliff:g> मा यो एप स्ट्रिम गर्न मिल्दैन। बरु तपाईंको Android TV डिभाइसमा स्ट्रिम गरी हेर्नुहोस्।"</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"यस बखत तपाईंको <xliff:g id="DEVICE">%1$s</xliff:g> मा यो एप स्ट्रिम गर्न मिल्दैन। बरु तपाईंको ट्याब्लेटमा स्ट्रिम गरी हेर्नुहोस्।"</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"यस बखत तपाईंको <xliff:g id="DEVICE">%1$s</xliff:g> मा यो एप स्ट्रिम गर्न मिल्दैन। बरु तपाईंको फोनमा स्ट्रिम गरी हेर्नुहोस्।"</string>
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (4706276040125072077) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (1824604581465771629) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (7755223160363292105) -->
+ <skip />
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"यो एपले सुरक्षासम्बन्धी अतिरिक्त सुविधा अन गर्न अनुरोध गरिरहेको छ। बरु तपाईंको Android TV डिभाइसमा स्ट्रिम गरी हेर्नुहोस्।"</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"यो एपले सुरक्षासम्बन्धी अतिरिक्त सुविधा अन गर्न अनुरोध गरिरहेको छ। बरु तपाईंको ट्याब्लेटमा स्ट्रिम गरी हेर्नुहोस्।"</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"यो एपले सुरक्षासम्बन्धी अतिरिक्त सुविधा अन गर्न अनुरोध गरिरहेको छ। बरु तपाईंको फोनमा स्ट्रिम गरी हेर्नुहोस्।"</string>
@@ -2128,7 +2135,7 @@
<string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"कुनै पनि व्यक्तिसँग सेयर गर्ने सिफारिस गरिएको छैन"</string>
<string name="chooser_all_apps_button_label" msgid="3230427756238666328">"अनुप्रयोगहरूको सूची"</string>
<string name="usb_device_resolve_prompt_warn" msgid="325871329788064199">"यो एपलाई रेकर्ड गर्ने अनुमति प्रदान गरिएको छैन तर यसले यो USB यन्त्रमार्फत अडियो क्याप्चर गर्न सक्छ।"</string>
- <string name="accessibility_system_action_home_label" msgid="3234748160850301870">"गृहपृष्ठ"</string>
+ <string name="accessibility_system_action_home_label" msgid="3234748160850301870">"होम"</string>
<string name="accessibility_system_action_back_label" msgid="4205361367345537608">"पछाडि फर्कनुहोस्"</string>
<string name="accessibility_system_action_recents_label" msgid="4782875610281649728">"हालसालैका एपहरू"</string>
<string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"सूचनाहरू"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 7eb3448..ef7ea51 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -697,15 +697,15 @@
<string name="face_acquired_pan_too_extreme" msgid="5417928604710621088">"Kijk goed recht naar je telefoon"</string>
<string name="face_acquired_tilt_too_extreme" msgid="5715715666540716620">"Kijk goed recht naar je telefoon"</string>
<string name="face_acquired_roll_too_extreme" msgid="8261939882838881194">"Kijk goed recht naar je telefoon"</string>
- <string name="face_acquired_obscured" msgid="4917643294953326639">"Zorg dat er niets voor je gezicht zit"</string>
+ <string name="face_acquired_obscured" msgid="4917643294953326639">"Zorg dat niets je gezicht bedekt"</string>
<string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"Reinig de bovenkant van je scherm, inclusief de zwarte balk"</string>
<!-- no translation found for face_acquired_dark_glasses_detected (5643703296620631986) -->
<skip />
<!-- no translation found for face_acquired_mouth_covering_detected (8219428572168642593) -->
<skip />
<string name="face_acquired_recalibrate_alt" msgid="5702674220280332115">"Kan gezichtsmodel niet maken. Probeer het opnieuw."</string>
- <string name="face_acquired_dark_glasses_detected_alt" msgid="4052123776406041972">"Donkere bril waargenomen. Je gezicht moet geheel zichtbaar zijn."</string>
- <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"Gezichtsbedekking waargenomen. Je gezicht moet geheel zichtbaar zijn."</string>
+ <string name="face_acquired_dark_glasses_detected_alt" msgid="4052123776406041972">"Donkere bril waargenomen. Je gezicht moet helemaal zichtbaar zijn."</string>
+ <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"Gezichtsbedekking waargenomen. Je hele gezicht moet zichtbaar zijn."</string>
<string-array name="face_acquired_vendor">
</string-array>
<string name="face_error_hw_not_available" msgid="5085202213036026288">"Kan gezicht niet verifiëren. Hardware niet beschikbaar."</string>
@@ -1259,7 +1259,7 @@
<string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Apps starten."</string>
<string name="android_upgrading_complete" msgid="409800058018374746">"Opstarten afronden."</string>
<string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"Je hebt op de aan/uit-knop gedrukt. Zo zet je meestal het scherm uit.\n\nRaak de knop voorzichtig aan terwijl je je vingerafdruk instelt."</string>
- <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"Zet het scherm uit om het instellen te beëindigen"</string>
+ <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"Zet scherm uit om instellen te beëindigen"</string>
<string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"Uitzetten"</string>
<string name="fp_power_button_bp_title" msgid="5585506104526820067">"Doorgaan met verificatie van je vingerafdruk?"</string>
<string name="fp_power_button_bp_message" msgid="2983163038168903393">"Je hebt op de aan/uit-knop gedrukt. Zo zet je meestal het scherm uit.\n\nRaak de knop voorzichtig aan om je vingerafdruk te verifiëren."</string>
@@ -1959,7 +1959,8 @@
<string name="app_blocked_title" msgid="7353262160455028160">"App is niet beschikbaar"</string>
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> is momenteel niet beschikbaar."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> niet beschikbaar"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Rechten vereist"</string>
+ <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (3805704317624448487) -->
+ <skip />
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"Camera niet beschikbaar"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"Doorgaan op telefoon"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"Microfoon niet beschikbaar"</string>
@@ -1970,6 +1971,12 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Je hebt hier nu geen toegang toe op je <xliff:g id="DEVICE">%1$s</xliff:g>. Probeer het in plaats daarvan op je Android TV-apparaat."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Je hebt hier nu geen toegang toe op je <xliff:g id="DEVICE">%1$s</xliff:g>. Probeer het in plaats daarvan op je tablet."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Je hebt hier nu geen toegang toe op je <xliff:g id="DEVICE">%1$s</xliff:g>. Probeer het in plaats daarvan op je telefoon."</string>
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (4706276040125072077) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (1824604581465771629) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (7755223160363292105) -->
+ <skip />
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"Deze app vraagt om aanvullende beveiliging. Probeer het in plaats daarvan op je Android TV-apparaat."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"Deze app vraagt om aanvullende beveiliging. Probeer het in plaats daarvan op je tablet."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Deze app vraagt om aanvullende beveiliging. Probeer het in plaats daarvan op je telefoon."</string>
diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml
index 4d02fb5..77f7bae 100644
--- a/core/res/res/values-or/strings.xml
+++ b/core/res/res/values-or/strings.xml
@@ -1368,7 +1368,7 @@
<string name="usb_midi_notification_title" msgid="7404506788950595557">"USB ମାଧ୍ୟମରେ MIDIକୁ ଚାଲୁ କରାଗଲା"</string>
<string name="usb_uvc_notification_title" msgid="2030032862673400008">"ୱେବକେମ ଭାବେ ଡିଭାଇସ କନେକ୍ଟ କରାଯାଇଛି"</string>
<string name="usb_accessory_notification_title" msgid="1385394660861956980">"USB ଆକ୍ସେସୋରୀ ଯୋଡ଼ାଗଲା"</string>
- <string name="usb_notification_message" msgid="4715163067192110676">"ଅଧିକ ବିକଳ୍ପ ପାଇଁ ଟାପ୍ କରନ୍ତୁ।"</string>
+ <string name="usb_notification_message" msgid="4715163067192110676">"ଅଧିକ ବିକଳ୍ପ ପାଇଁ ଟାପ କରନ୍ତୁ।"</string>
<string name="usb_power_notification_message" msgid="7284765627437897702">"ଯୋଡ଼ାଯାଇଥିବା ଡିଭାଇସ୍ ଚାର୍ଜ ହେଉଛି। ଅଧିକ ବିକଳ୍ପ ପାଇଁ ଟାପ୍ କରନ୍ତୁ।"</string>
<string name="usb_unsupported_audio_accessory_title" msgid="2335775548086533065">"ଆନାଲଗ୍ ଅଡିଓ ଆକ୍ସେସରୀ ଚିହ୍ନଟ ହେଲା"</string>
<string name="usb_unsupported_audio_accessory_message" msgid="1300168007129796621">"ଏହି ଫୋନ୍ରେ କନେକ୍ଟ ଥିବା ଡିଭାଇସ୍ କମ୍ପାଟିବଲ୍ ନୁହେଁ। ଅଧିକ ଜାଣିବା ପାଇଁ ଟାପ୍ କରନ୍ତୁ।"</string>
@@ -1433,7 +1433,7 @@
<string name="ext_media_nomedia_notification_message" msgid="2832724384636625852">"କିଛି କାର୍ଯ୍ୟକ୍ଷମତା ଠିକ୍ ଭାବେ କାମ ନକରିପାରେ। ନୂଆ ଷ୍ଟୋରେଜ୍ ଭର୍ତ୍ତି କରନ୍ତୁ।"</string>
<string name="ext_media_unmounting_notification_title" msgid="4147986383917892162">"<xliff:g id="NAME">%s</xliff:g>କୁ ଇଜେକ୍ଟ କରାଯାଉଛି"</string>
<string name="ext_media_unmounting_notification_message" msgid="5717036261538754203">"କାଢ଼ନ୍ତୁ ନାହିଁ"</string>
- <string name="ext_media_init_action" msgid="2312974060585056709">"ସେଟ୍ ଅପ୍ କରନ୍ତୁ"</string>
+ <string name="ext_media_init_action" msgid="2312974060585056709">"ସେଟ ଅପ କରନ୍ତୁ"</string>
<string name="ext_media_unmount_action" msgid="966992232088442745">"କାଢ଼ି ଦିଅନ୍ତୁ"</string>
<string name="ext_media_browse_action" msgid="344865351947079139">"ଖୋଜନ୍ତୁ"</string>
<string name="ext_media_seamless_action" msgid="8837030226009268080">"ଆଉଟ୍ପୁଟ୍ ସ୍ୱିଚ୍ କରନ୍ତୁ"</string>
@@ -1959,7 +1959,8 @@
<string name="app_blocked_title" msgid="7353262160455028160">"ଆପ୍ ଉପଲବ୍ଧ ନାହିଁ"</string>
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> ବର୍ତ୍ତମାନ ଉପଲବ୍ଧ ନାହିଁ।"</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> ଉପଲବ୍ଧ ନାହିଁ"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"ଅନୁମତି ଆବଶ୍ୟକ"</string>
+ <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (3805704317624448487) -->
+ <skip />
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"କ୍ୟାମେରା ଉପଲବ୍ଧ ନାହିଁ"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"ଫୋନରେ ଜାରି ରଖନ୍ତୁ"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"ମାଇକ୍ରୋଫୋନ ଉପଲବ୍ଧ ନାହିଁ"</string>
@@ -1970,6 +1971,12 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"ବର୍ତ୍ତମାନ ଏହାକୁ ଆପଣଙ୍କ <xliff:g id="DEVICE">%1$s</xliff:g>ରେ ଆକ୍ସେସ କରାଯାଇପାରିବ ନାହିଁ। ଏହା ପରିବର୍ତ୍ତେ ଆପଣଙ୍କ Android TV ଡିଭାଇସରେ ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"ବର୍ତ୍ତମାନ ଏହାକୁ ଆପଣଙ୍କ <xliff:g id="DEVICE">%1$s</xliff:g>ରେ ଆକ୍ସେସ କରାଯାଇପାରିବ ନାହିଁ। ଏହା ପରିବର୍ତ୍ତେ ଆପଣଙ୍କ ଟାବଲେଟରେ ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"ବର୍ତ୍ତମାନ ଏହାକୁ ଆପଣଙ୍କ <xliff:g id="DEVICE">%1$s</xliff:g>ରେ ଆକ୍ସେସ କରାଯାଇପାରିବ ନାହିଁ। ଏହା ପରିବର୍ତ୍ତେ ଆପଣଙ୍କ ଫୋନରେ ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (4706276040125072077) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (1824604581465771629) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (7755223160363292105) -->
+ <skip />
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"ଏହି ଆପ ଅତିରିକ୍ତ ସୁରକ୍ଷା ପାଇଁ ଅନୁରୋଧ କରୁଛି। ଏହା ପରିବର୍ତ୍ତେ ଆପଣଙ୍କ Android TV ଡିଭାଇସରେ ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"ଏହି ଆପ ଅତିରିକ୍ତ ସୁରକ୍ଷା ପାଇଁ ଅନୁରୋଧ କରୁଛି। ଏହା ପରିବର୍ତ୍ତେ ଆପଣଙ୍କ ଟାବଲେଟରେ ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"ଏହି ଆପ ଅତିରିକ୍ତ ସୁରକ୍ଷା ପାଇଁ ଅନୁରୋଧ କରୁଛି। ଏହା ପରିବର୍ତ୍ତେ ଆପଣଙ୍କ ଫୋନରେ ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index e9fa2ba..68334fc 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -638,7 +638,7 @@
<string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"ਬਹੁਤ ਜ਼ਿਆਦਾ ਚਮਕ"</string>
<string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"ਪਾਵਰ ਬਟਨ ਦਬਾਏ ਜਾਣ ਦਾ ਪਤਾ ਲੱਗਿਆ ਹੈ"</string>
<string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"ਵਿਵਸਥਿਤ ਕਰਕੇ ਦੇਖੋ"</string>
- <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"ਹਰ ਵਾਰ ਆਪਣੀ ਉਂਗਲੀ ਦੀ ਸਥਿਤੀ ਨੂੰ ਥੋੜਾ ਜਿਹਾ ਬਦਲੋ"</string>
+ <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"ਹਰ ਵਾਰ ਆਪਣੀ ਉਂਗਲ ਦੀ ਸਥਿਤੀ ਨੂੰ ਥੋੜਾ ਜਿਹਾ ਬਦਲੋ"</string>
<string-array name="fingerprint_acquired_vendor">
</string-array>
<string name="fingerprint_error_not_match" msgid="4599441812893438961">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਦੀ ਪਛਾਣ ਨਹੀਂ ਹੋਈ"</string>
@@ -705,7 +705,7 @@
<skip />
<string name="face_acquired_recalibrate_alt" msgid="5702674220280332115">"ਤੁਹਾਡੇ ਚਿਹਰੇ ਦਾ ਮਾਡਲ ਨਹੀਂ ਬਣਿਆ। ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
<string name="face_acquired_dark_glasses_detected_alt" msgid="4052123776406041972">"ਧੁੱਪ ਦੀਆਂ ਐਨਕਾਂ ਦਾ ਪਤਾ ਲੱਗਾ। ਤੁਹਾਡਾ ਪੂਰਾ ਚਿਹਰਾ ਦਿਸਣਾ ਲਾਜ਼ਮੀ ਹੈ।"</string>
- <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"ਚਿਹਰਾ ਢੱਕਿਆ ਹੋਣ ਦਾ ਪਤਾ ਲੱਗਾ। ਤੁਹਾਡਾ ਪੂਰਾ ਚਿਹਰਾ ਦਿਸਣਾ ਲਾਜ਼ਮੀ ਹੈ।"</string>
+ <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"ਚਿਹਰਾ ਢੱਕਿਆ ਹੋਇਆ ਹੈ। ਤੁਹਾਡਾ ਪੂਰਾ ਚਿਹਰਾ ਦਿਸਣਾ ਚਾਹੀਦਾ ਹੈ।"</string>
<string-array name="face_acquired_vendor">
</string-array>
<string name="face_error_hw_not_available" msgid="5085202213036026288">"ਚਿਹਰੇ ਦੀ ਪੁਸ਼ਟੀ ਨਹੀਂ ਹੋ ਸਕੀ। ਹਾਰਡਵੇਅਰ ਉਪਲਬਧ ਨਹੀਂ।"</string>
@@ -1959,7 +1959,8 @@
<string name="app_blocked_title" msgid="7353262160455028160">"ਐਪ ਉਪਲਬਧ ਨਹੀਂ ਹੈ"</string>
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਐਪ ਇਸ ਵੇਲੇ ਉਪਲਬਧ ਨਹੀਂ ਹੈ।"</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> ਉਪਲਬਧ ਨਹੀਂ ਹੈ"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"ਇਜਾਜ਼ਤ ਦੀ ਲੋੜ ਹੈ"</string>
+ <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (3805704317624448487) -->
+ <skip />
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"ਕੈਮਰਾ ਉਪਲਬਧ ਨਹੀਂ ਹੈ"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"ਫ਼ੋਨ \'ਤੇ ਜਾਰੀ ਰੱਖੋ"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"ਮਾਈਕ੍ਰੋਫ਼ੋਨ ਅਣਉਪਲਬਧ ਹੈ"</string>
@@ -1970,6 +1971,12 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"ਇਸ ਸਮੇਂ ਤੁਹਾਡੇ <xliff:g id="DEVICE">%1$s</xliff:g> \'ਤੇ ਇਸ ਤੱਕ ਪਹੁੰਚ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ। ਇਸਦੀ ਬਜਾਏ ਆਪਣੇ Android TV ਡੀਵਾਈਸ \'ਤੇ ਵਰਤ ਕੇ ਦੇਖੋ।"</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"ਇਸ ਸਮੇਂ ਤੁਹਾਡੇ <xliff:g id="DEVICE">%1$s</xliff:g> \'ਤੇ ਇਸ ਤੱਕ ਪਹੁੰਚ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ। ਇਸਦੀ ਬਜਾਏ ਆਪਣੇ ਟੈਬਲੈੱਟ \'ਤੇ ਵਰਤ ਕੇ ਦੇਖੋ।"</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"ਇਸ ਸਮੇਂ ਤੁਹਾਡੇ <xliff:g id="DEVICE">%1$s</xliff:g> \'ਤੇ ਇਸ ਤੱਕ ਪਹੁੰਚ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ। ਇਸਦੀ ਬਜਾਏ ਆਪਣੇ ਫ਼ੋਨ \'ਤੇ ਵਰਤ ਕੇ ਦੇਖੋ।"</string>
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (4706276040125072077) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (1824604581465771629) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (7755223160363292105) -->
+ <skip />
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"ਇਹ ਐਪ ਵਧੀਕ ਸੁਰੱਖਿਆ ਦੀ ਬੇਨਤੀ ਕਰ ਰਹੀ ਹੈ। ਇਸਦੀ ਬਜਾਏ ਆਪਣੇ Android TV ਡੀਵਾਈਸ \'ਤੇ ਵਰਤ ਕੇ ਦੇਖੋ।"</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"ਇਹ ਐਪ ਵਧੀਕ ਸੁਰੱਖਿਆ ਦੀ ਬੇਨਤੀ ਕਰ ਰਹੀ ਹੈ। ਇਸਦੀ ਬਜਾਏ ਆਪਣੇ ਟੈਬਲੈੱਟ \'ਤੇ ਵਰਤ ਕੇ ਦੇਖੋ।"</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"ਇਹ ਐਪ ਵਧੀਕ ਸੁਰੱਖਿਆ ਦੀ ਬੇਨਤੀ ਕਰ ਰਹੀ ਹੈ। ਇਸਦੀ ਬਜਾਏ ਆਪਣੇ ਫ਼ੋਨ \'ਤੇ ਵਰਤ ਕੇ ਦੇਖੋ।"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 1f93f8e..e0bcd67 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -1961,7 +1961,8 @@
<string name="app_blocked_title" msgid="7353262160455028160">"Aplikacja jest niedostępna"</string>
<string name="app_blocked_message" msgid="542972921087873023">"Aplikacja <xliff:g id="APP_NAME">%1$s</xliff:g> jest obecnie niedostępna."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> – brak dostępu"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Wymagane są uprawnienia"</string>
+ <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (3805704317624448487) -->
+ <skip />
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"Aparat niedostępny"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"Kontynuuj na telefonie"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"Mikrofon niedostępny"</string>
@@ -1972,6 +1973,12 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"W tej chwili nie można z tego skorzystać na urządzeniu <xliff:g id="DEVICE">%1$s</xliff:g>. Użyj urządzenia z Androidem TV."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"W tej chwili nie można z tego skorzystać na urządzeniu <xliff:g id="DEVICE">%1$s</xliff:g>. Użyj tabletu."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"W tej chwili nie można z tego skorzystać na urządzeniu <xliff:g id="DEVICE">%1$s</xliff:g>. Użyj telefonu."</string>
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (4706276040125072077) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (1824604581465771629) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (7755223160363292105) -->
+ <skip />
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"Ta aplikacja wymaga dodatkowych zabezpieczeń. Użyj urządzenia z Androidem TV."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"Ta aplikacja wymaga dodatkowych zabezpieczeń. Użyj tabletu."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Ta aplikacja wymaga dodatkowych zabezpieczeń. Użyj telefonu."</string>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index fa830a6..2d11772 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -649,7 +649,7 @@
<string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Rosto autenticado, pressione \"Confirmar\""</string>
<string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Hardware de impressão digital não disponível."</string>
<string name="fingerprint_error_no_space" msgid="7285481581905967580">"Não foi possível configurar a impressão digital"</string>
- <string name="fingerprint_error_timeout" msgid="7361192266621252164">"A configuração da impressão digital expirou. Tente de novo."</string>
+ <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Tempo de configuração esgotado. Tente de novo."</string>
<string name="fingerprint_error_canceled" msgid="540026881380070750">"Operação de impressão digital cancelada."</string>
<string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Operação de impressão digital cancelada pelo usuário."</string>
<string name="fingerprint_error_lockout" msgid="6626753679019351368">"Excesso de tentativas. Use o bloqueio de tela."</string>
@@ -1369,7 +1369,7 @@
<string name="usb_midi_notification_title" msgid="7404506788950595557">"MIDI via USB ativado"</string>
<string name="usb_uvc_notification_title" msgid="2030032862673400008">"Dispositivo conectado como Webcam"</string>
<string name="usb_accessory_notification_title" msgid="1385394660861956980">"Acessório USB conectado"</string>
- <string name="usb_notification_message" msgid="4715163067192110676">"Toque para ver mais opções."</string>
+ <string name="usb_notification_message" msgid="4715163067192110676">"Toque para conferir mais opções."</string>
<string name="usb_power_notification_message" msgid="7284765627437897702">"Carregando dispositivo conectado. Toque para ver mais opções."</string>
<string name="usb_unsupported_audio_accessory_title" msgid="2335775548086533065">"Acessório de áudio analógico detectado"</string>
<string name="usb_unsupported_audio_accessory_message" msgid="1300168007129796621">"O dispositivo anexo não é compatível com esse smartphone. Toque para saber mais."</string>
@@ -1960,7 +1960,7 @@
<string name="app_blocked_title" msgid="7353262160455028160">"O app não está disponível"</string>
<string name="app_blocked_message" msgid="542972921087873023">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> não está disponível no momento."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> indisponível"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Permissão necessária"</string>
+ <string name="app_streaming_blocked_title_for_permission_dialog" msgid="3805704317624448487">"Solicitação de permissão suprimida"</string>
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"Câmera indisponível"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"Continuar no smartphone"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"Microfone indisponível"</string>
@@ -1971,6 +1971,9 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"No momento, não é possível acessar esse app pelo <xliff:g id="DEVICE">%1$s</xliff:g>. Tente pelo dispositivo Android TV."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"No momento, não é possível acessar esse app pelo <xliff:g id="DEVICE">%1$s</xliff:g>. Tente pelo seu tablet."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"No momento, não é possível acessar esse app pelo <xliff:g id="DEVICE">%1$s</xliff:g>. Tente pelo seu smartphone."</string>
+ <string name="app_streaming_blocked_message_for_permission_request" product="tv" msgid="4706276040125072077">"Esse app está solicitando permissões extras, mas elas não podem ser concedidas em uma sessão de streaming. Dê permissão pelo dispositivo Android TV primeiro."</string>
+ <string name="app_streaming_blocked_message_for_permission_request" product="tablet" msgid="1824604581465771629">"Esse app está solicitando permissões extras, mas elas não podem ser concedidas em uma sessão de streaming. Dê permissão pelo tablet primeiro."</string>
+ <string name="app_streaming_blocked_message_for_permission_request" product="default" msgid="7755223160363292105">"Esse app está solicitando permissões extras, mas elas não podem ser concedidas em uma sessão de streaming. Dê permissão pelo smartphone primeiro."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"Esse app está solicitando segurança extra. Tente pelo dispositivo Android TV."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"Esse app está solicitando segurança extra. Tente pelo tablet."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Esse app está solicitando segurança extra. Tente pelo smartphone."</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index e9c1056..f6d9771 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -698,7 +698,7 @@
<string name="face_acquired_pan_too_extreme" msgid="5417928604710621088">"Olhe mais diretamente para o telemóvel"</string>
<string name="face_acquired_tilt_too_extreme" msgid="5715715666540716620">"Olhe mais diretamente para o telemóvel"</string>
<string name="face_acquired_roll_too_extreme" msgid="8261939882838881194">"Olhe mais diretamente para o telemóvel"</string>
- <string name="face_acquired_obscured" msgid="4917643294953326639">"Remova tudo o que esteja a ocultar o seu rosto."</string>
+ <string name="face_acquired_obscured" msgid="4917643294953326639">"Remova tudo o que esteja a ocultar o seu rosto"</string>
<string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"Limpe a parte superior do ecrã, incluindo a barra preta."</string>
<!-- no translation found for face_acquired_dark_glasses_detected (5643703296620631986) -->
<skip />
@@ -706,7 +706,7 @@
<skip />
<string name="face_acquired_recalibrate_alt" msgid="5702674220280332115">"Não é possível criar o seu modelo de rosto. Tente novamente."</string>
<string name="face_acquired_dark_glasses_detected_alt" msgid="4052123776406041972">"Óculos escuros detetados. O seu rosto tem de estar completamente visível."</string>
- <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"Máscara detetada. Todo o rosto tem de estar visível."</string>
+ <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"Máscara detetada. Todo o rosto tem de estar visível"</string>
<string-array name="face_acquired_vendor">
</string-array>
<string name="face_error_hw_not_available" msgid="5085202213036026288">"Não pode validar o rosto. Hardware não disponível."</string>
@@ -1260,8 +1260,8 @@
<string name="android_upgrading_starting_apps" msgid="6206161195076057075">"A iniciar aplicações"</string>
<string name="android_upgrading_complete" msgid="409800058018374746">"A concluir o arranque."</string>
<string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"Premiu o botão ligar/desligar. Geralmente, esta ação desliga o ecrã.\n\nExperimente tocar levemente ao configurar a sua impressão digital."</string>
- <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"Termine a configuração ao desligar ecrã"</string>
- <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"Desativar"</string>
+ <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"Para terminar, desligue o ecrã"</string>
+ <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"Desligar"</string>
<string name="fp_power_button_bp_title" msgid="5585506104526820067">"Continuar a validar a impressão digital?"</string>
<string name="fp_power_button_bp_message" msgid="2983163038168903393">"Premiu o botão ligar/desligar. Geralmente, esta ação desliga o ecrã.\n\nExperimente tocar levemente para validar a sua impressão digital."</string>
<string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"Desligar ecrã"</string>
@@ -1960,7 +1960,8 @@
<string name="app_blocked_title" msgid="7353262160455028160">"A app não está disponível"</string>
<string name="app_blocked_message" msgid="542972921087873023">"De momento, a app <xliff:g id="APP_NAME">%1$s</xliff:g> não está disponível."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> indisponível"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Autorização necessária"</string>
+ <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (3805704317624448487) -->
+ <skip />
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"Câmara indisponível"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"Continue no telemóvel"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"Microfone indisponível"</string>
@@ -1971,6 +1972,12 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"De momento, não é possível aceder a esta app no seu <xliff:g id="DEVICE">%1$s</xliff:g>. Em alternativa, experimente no dispositivo Android TV."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"De momento, não é possível aceder a esta app no seu <xliff:g id="DEVICE">%1$s</xliff:g>. Em alternativa, experimente no tablet."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"De momento, não é possível aceder a esta app no seu <xliff:g id="DEVICE">%1$s</xliff:g>. Em alternativa, experimente no telemóvel."</string>
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (4706276040125072077) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (1824604581465771629) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (7755223160363292105) -->
+ <skip />
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"Esta app está a solicitar segurança adicional. Em alternativa, experimente no dispositivo Android TV."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"Esta app está a solicitar segurança adicional. Em alternativa, experimente no tablet."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Esta app está a solicitar segurança adicional. Em alternativa, experimente no telemóvel."</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index fa830a6..2d11772 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -649,7 +649,7 @@
<string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Rosto autenticado, pressione \"Confirmar\""</string>
<string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Hardware de impressão digital não disponível."</string>
<string name="fingerprint_error_no_space" msgid="7285481581905967580">"Não foi possível configurar a impressão digital"</string>
- <string name="fingerprint_error_timeout" msgid="7361192266621252164">"A configuração da impressão digital expirou. Tente de novo."</string>
+ <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Tempo de configuração esgotado. Tente de novo."</string>
<string name="fingerprint_error_canceled" msgid="540026881380070750">"Operação de impressão digital cancelada."</string>
<string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Operação de impressão digital cancelada pelo usuário."</string>
<string name="fingerprint_error_lockout" msgid="6626753679019351368">"Excesso de tentativas. Use o bloqueio de tela."</string>
@@ -1369,7 +1369,7 @@
<string name="usb_midi_notification_title" msgid="7404506788950595557">"MIDI via USB ativado"</string>
<string name="usb_uvc_notification_title" msgid="2030032862673400008">"Dispositivo conectado como Webcam"</string>
<string name="usb_accessory_notification_title" msgid="1385394660861956980">"Acessório USB conectado"</string>
- <string name="usb_notification_message" msgid="4715163067192110676">"Toque para ver mais opções."</string>
+ <string name="usb_notification_message" msgid="4715163067192110676">"Toque para conferir mais opções."</string>
<string name="usb_power_notification_message" msgid="7284765627437897702">"Carregando dispositivo conectado. Toque para ver mais opções."</string>
<string name="usb_unsupported_audio_accessory_title" msgid="2335775548086533065">"Acessório de áudio analógico detectado"</string>
<string name="usb_unsupported_audio_accessory_message" msgid="1300168007129796621">"O dispositivo anexo não é compatível com esse smartphone. Toque para saber mais."</string>
@@ -1960,7 +1960,7 @@
<string name="app_blocked_title" msgid="7353262160455028160">"O app não está disponível"</string>
<string name="app_blocked_message" msgid="542972921087873023">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> não está disponível no momento."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> indisponível"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Permissão necessária"</string>
+ <string name="app_streaming_blocked_title_for_permission_dialog" msgid="3805704317624448487">"Solicitação de permissão suprimida"</string>
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"Câmera indisponível"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"Continuar no smartphone"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"Microfone indisponível"</string>
@@ -1971,6 +1971,9 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"No momento, não é possível acessar esse app pelo <xliff:g id="DEVICE">%1$s</xliff:g>. Tente pelo dispositivo Android TV."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"No momento, não é possível acessar esse app pelo <xliff:g id="DEVICE">%1$s</xliff:g>. Tente pelo seu tablet."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"No momento, não é possível acessar esse app pelo <xliff:g id="DEVICE">%1$s</xliff:g>. Tente pelo seu smartphone."</string>
+ <string name="app_streaming_blocked_message_for_permission_request" product="tv" msgid="4706276040125072077">"Esse app está solicitando permissões extras, mas elas não podem ser concedidas em uma sessão de streaming. Dê permissão pelo dispositivo Android TV primeiro."</string>
+ <string name="app_streaming_blocked_message_for_permission_request" product="tablet" msgid="1824604581465771629">"Esse app está solicitando permissões extras, mas elas não podem ser concedidas em uma sessão de streaming. Dê permissão pelo tablet primeiro."</string>
+ <string name="app_streaming_blocked_message_for_permission_request" product="default" msgid="7755223160363292105">"Esse app está solicitando permissões extras, mas elas não podem ser concedidas em uma sessão de streaming. Dê permissão pelo smartphone primeiro."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"Esse app está solicitando segurança extra. Tente pelo dispositivo Android TV."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"Esse app está solicitando segurança extra. Tente pelo tablet."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Esse app está solicitando segurança extra. Tente pelo smartphone."</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 9f55272..a38dacb 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -1260,7 +1260,7 @@
<string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Se pornesc aplicațiile."</string>
<string name="android_upgrading_complete" msgid="409800058018374746">"Se finalizează pornirea."</string>
<string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"Ai apăsat butonul de pornire. De obicei, astfel se dezactivează ecranul.\n\nAtinge ușor când îți configurezi amprenta."</string>
- <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"Ca să termini configurarea, dezactivează ecranul"</string>
+ <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"Termină configurarea dezactivând ecranul"</string>
<string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"Dezactivează"</string>
<string name="fp_power_button_bp_title" msgid="5585506104526820067">"Continui cu verificarea amprentei?"</string>
<string name="fp_power_button_bp_message" msgid="2983163038168903393">"Ai apăsat butonul de pornire. De obicei, astfel se dezactivează ecranul.\n\nAtinge ușor pentru verificarea amprentei."</string>
@@ -1373,7 +1373,7 @@
<string name="usb_power_notification_message" msgid="7284765627437897702">"Se încarcă dispozitivul conectat. Atinge pentru mai multe opțiuni."</string>
<string name="usb_unsupported_audio_accessory_title" msgid="2335775548086533065">"S-a detectat un accesoriu audio analogic"</string>
<string name="usb_unsupported_audio_accessory_message" msgid="1300168007129796621">"Dispozitivul atașat nu este compatibil cu acest telefon. Atinge pentru a afla mai multe."</string>
- <string name="adb_active_notification_title" msgid="408390247354560331">"Remedierea erorilor prin USB conectată"</string>
+ <string name="adb_active_notification_title" msgid="408390247354560331">"Remedierea prin USB conectată"</string>
<string name="adb_active_notification_message" msgid="5617264033476778211">"Atinge pentru a dezactiva."</string>
<string name="adb_active_notification_message" product="tv" msgid="6624498401272780855">"Selectează pentru a dezactiva remedierea erorilor prin USB."</string>
<string name="adbwifi_active_notification_title" msgid="6147343659168302473">"Remedierea erorilor wireless este activă"</string>
@@ -1960,7 +1960,8 @@
<string name="app_blocked_title" msgid="7353262160455028160">"Aplicația nu este disponibilă"</string>
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> nu este disponibilă momentan."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> nu este disponibilă"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Necesită permisiune"</string>
+ <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (3805704317624448487) -->
+ <skip />
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"Camera video nu este disponibilă"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"Continuă pe telefon"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"Microfon indisponibil"</string>
@@ -1971,6 +1972,12 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Aplicația nu poate fi accesată pe <xliff:g id="DEVICE">%1$s</xliff:g> momentan. Încearcă pe dispozitivul Android TV."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Aplicația nu poate fi accesată pe <xliff:g id="DEVICE">%1$s</xliff:g> momentan. Încearcă pe tabletă."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Aplicația nu poate fi accesată pe <xliff:g id="DEVICE">%1$s</xliff:g> momentan. Încearcă pe telefon."</string>
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (4706276040125072077) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (1824604581465771629) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (7755223160363292105) -->
+ <skip />
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"Aplicația necesită securitate suplimentară. Încearcă pe dispozitivul Android TV."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"Aplicația necesită securitate suplimentară. Încearcă pe tabletă."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Aplicația necesită securitate suplimentară. Încearcă pe telefon."</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index c0f6095..9dd5e4f 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -1375,7 +1375,7 @@
<string name="usb_unsupported_audio_accessory_title" msgid="2335775548086533065">"Обнаружено аналоговое аудиоустройство"</string>
<string name="usb_unsupported_audio_accessory_message" msgid="1300168007129796621">"Подсоединенное устройство несовместимо с этим телефоном. Нажмите, чтобы узнать подробности."</string>
<string name="adb_active_notification_title" msgid="408390247354560331">"Отладка по USB активна"</string>
- <string name="adb_active_notification_message" msgid="5617264033476778211">"Нажмите, чтобы отключить"</string>
+ <string name="adb_active_notification_message" msgid="5617264033476778211">"Нажмите, чтобы отключить."</string>
<string name="adb_active_notification_message" product="tv" msgid="6624498401272780855">"Нажмите, чтобы запретить"</string>
<string name="adbwifi_active_notification_title" msgid="6147343659168302473">"Отладка по Wi-Fi включена"</string>
<string name="adbwifi_active_notification_message" msgid="930987922852867972">"Нажмите, чтобы отключить отладку по Wi-Fi."</string>
@@ -1961,7 +1961,8 @@
<string name="app_blocked_title" msgid="7353262160455028160">"Приложение недоступно"</string>
<string name="app_blocked_message" msgid="542972921087873023">"Приложение \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" сейчас недоступно."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"Недоступно: <xliff:g id="ACTIVITY">%1$s</xliff:g>"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Требуется разрешение"</string>
+ <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (3805704317624448487) -->
+ <skip />
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"Камера недоступна"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"Продолжите на телефоне"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"Микрофон недоступен"</string>
@@ -1972,6 +1973,12 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Эта функция пока недоступна на устройстве <xliff:g id="DEVICE">%1$s</xliff:g>. Используйте Android TV."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Эта функция пока недоступна на устройстве <xliff:g id="DEVICE">%1$s</xliff:g>. Используйте планшет."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"На устройстве <xliff:g id="DEVICE">%1$s</xliff:g> эта функция пока недоступна. Используйте телефон."</string>
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (4706276040125072077) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (1824604581465771629) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (7755223160363292105) -->
+ <skip />
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"Это приложение запрашивает дополнительные меры защиты. Используйте Android TV."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"Это приложение запрашивает дополнительные меры защиты. Используйте планшет."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Это приложение запрашивает дополнительные меры защиты. Используйте телефон."</string>
@@ -2162,7 +2169,7 @@
<string name="resolver_cross_profile_blocked" msgid="3014597376026044840">"Заблокировано вашим администратором"</string>
<string name="resolver_cant_share_with_work_apps_explanation" msgid="9071442683080586643">"Этот контент нельзя открывать через рабочие приложения."</string>
<string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Этот контент нельзя открыть в рабочем приложении."</string>
- <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Этот контент нельзя открывать через личные приложения."</string>
+ <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Этим контентом нельзя делиться с личными приложениями."</string>
<string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Этот контент нельзя открыть в личном приложении."</string>
<string name="resolver_turn_on_work_apps" msgid="1535946298236678122">"Рабочие приложения приостановлены."</string>
<string name="resolver_switch_on_work" msgid="4527096360772311894">"Включить"</string>
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index ff4aa77..92b7f51 100644
--- a/core/res/res/values-si/strings.xml
+++ b/core/res/res/values-si/strings.xml
@@ -1959,7 +1959,8 @@
<string name="app_blocked_title" msgid="7353262160455028160">"යෙදුම ලබා ගත නොහැකිය"</string>
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> මේ දැන් ලබා ගත නොහැකිය."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> නොතිබේ"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"අවසරය අවශ්යයි"</string>
+ <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (3805704317624448487) -->
+ <skip />
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"කැමරාව ලබා ගත නොහැකිය"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"දුරකථනයෙන් දිගටම කර ගෙන යන්න"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"මයික්රෆෝනය ලබා ගත නොහැකිය"</string>
@@ -1970,6 +1971,12 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"මේ අවස්ථාවේදී මෙයට ඔබගේ <xliff:g id="DEVICE">%1$s</xliff:g> හි ප්රවේශ විය නොහැකිය. ඒ වෙනුවට ඔබගේ Android TV උපාංගයෙහි උත්සාහ කරන්න."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"මේ අවස්ථාවේදී මෙයට ඔබගේ <xliff:g id="DEVICE">%1$s</xliff:g> හි ප්රවේශ විය නොහැකිය. ඒ වෙනුවට ඔබගේ ටැබ්ලටයෙහි උත්සාහ කරන්න."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"මේ අවස්ථාවේදී මෙයට ඔබගේ <xliff:g id="DEVICE">%1$s</xliff:g> හි ප්රවේශ විය නොහැකිය. ඒ වෙනුවට ඔබගේ දුරකථනයෙහි උත්සාහ කරන්න."</string>
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (4706276040125072077) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (1824604581465771629) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (7755223160363292105) -->
+ <skip />
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"මෙම යෙදුම අමතර ආරක්ෂාවක් ඉල්ලා සිටී. ඒ වෙනුවට ඔබගේ Android TV උපාංගයෙහි උත්සාහ කරන්න."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"මෙම යෙදුම අමතර ආරක්ෂාවක් ඉල්ලා සිටී. ඒ වෙනුවට ඔබගේ ටැබ්ලටයෙහි උත්සාහ කරන්න."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"මෙම යෙදුම අමතර ආරක්ෂාවක් ඉල්ලා සිටී. ඒ වෙනුවට ඔබගේ දුරකථනයෙහි උත්සාහ කරන්න."</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 791039a..f76c617 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -1961,7 +1961,8 @@
<string name="app_blocked_title" msgid="7353262160455028160">"Aplikácia nie je dostupná"</string>
<string name="app_blocked_message" msgid="542972921087873023">"Aplikácia <xliff:g id="APP_NAME">%1$s</xliff:g> nie je teraz dostupná."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> nie je k dispozícii"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Vyžaduje sa povolenie"</string>
+ <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (3805704317624448487) -->
+ <skip />
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"Kamera nie je k dispozícii"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"Pokračujte v telefóne"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"Mikrofón nie je k dispozícii"</string>
@@ -1972,6 +1973,12 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"V zariadení <xliff:g id="DEVICE">%1$s</xliff:g> momentálne nemáte k tomuto obsahu prístup. Skúste namiesto toho použiť zariadenie Android TV."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"V zariadení <xliff:g id="DEVICE">%1$s</xliff:g> momentálne nemáte k tomuto obsahu prístup. Skúste namiesto toho použiť tablet."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"V zariadení <xliff:g id="DEVICE">%1$s</xliff:g> momentálne nemáte k tomuto obsahu prístup. Skúste použiť telefón."</string>
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (4706276040125072077) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (1824604581465771629) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (7755223160363292105) -->
+ <skip />
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"Táto aplikácia požaduje dodatočné zabezpečenie. Skúste namiesto toho použiť zariadenie Android TV."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"Táto aplikácia požaduje dodatočné zabezpečenie. Skúste namiesto toho použiť tablet."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Táto aplikácia požaduje dodatočné zabezpečenie. Skúste použiť telefón."</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 62f6b0c..97dc284 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -707,7 +707,7 @@
<skip />
<string name="face_acquired_recalibrate_alt" msgid="5702674220280332115">"Modela obraza ni mogoče ustvariti. Poskusite znova."</string>
<string name="face_acquired_dark_glasses_detected_alt" msgid="4052123776406041972">"Zaznana so temna očala. Videti se mora cel obraz."</string>
- <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"Zaznano je, da je obraz prekrit. Videti se mora cel obraz."</string>
+ <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"Zaznano je obrazno pokrivalo. Videti se mora ves obraz."</string>
<string-array name="face_acquired_vendor">
</string-array>
<string name="face_error_hw_not_available" msgid="5085202213036026288">"Obraza ni mogoče preveriti. Str. opr. ni na voljo."</string>
@@ -1961,7 +1961,8 @@
<string name="app_blocked_title" msgid="7353262160455028160">"Aplikacija ni na voljo"</string>
<string name="app_blocked_message" msgid="542972921087873023">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> trenutno ni na voljo."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"»<xliff:g id="ACTIVITY">%1$s</xliff:g>« ni na voljo"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Potrebno je dovoljenje"</string>
+ <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (3805704317624448487) -->
+ <skip />
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"Fotoaparat ni na voljo"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"Nadaljevanje v telefonu"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"Mikrofon ni na voljo"</string>
@@ -1972,6 +1973,12 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"V napravi <xliff:g id="DEVICE">%1$s</xliff:g> trenutno ni mogoče dostopati do te vsebine. Poskusite z napravo Android TV."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"V napravi <xliff:g id="DEVICE">%1$s</xliff:g> trenutno ni mogoče dostopati do te vsebine. Poskusite s tabličnim računalnikom."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"V napravi <xliff:g id="DEVICE">%1$s</xliff:g> trenutno ni mogoče dostopati do te vsebine. Poskusite s telefonom."</string>
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (4706276040125072077) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (1824604581465771629) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (7755223160363292105) -->
+ <skip />
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"Ta aplikacija zahteva dodatno varnost. Poskusite z napravo Android TV."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"Ta aplikacija zahteva dodatno varnost. Poskusite s tabličnim računalnikom."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Ta aplikacija zahteva dodatno varnost. Poskusite s telefonom."</string>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index 141a94f..3744696 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -638,7 +638,7 @@
<string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Me shumë ndriçim"</string>
<string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"U zbulua shtypja e \"Energjisë\""</string>
<string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Provo ta rregullosh"</string>
- <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Ndrysho pak pozicionin e gishtit çdo herë"</string>
+ <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Ndrysho paksa pozicionin e gishtit çdo herë"</string>
<string-array name="fingerprint_acquired_vendor">
</string-array>
<string name="fingerprint_error_not_match" msgid="4599441812893438961">"Gjurma e gishtit nuk u njoh"</string>
@@ -697,7 +697,7 @@
<string name="face_acquired_pan_too_extreme" msgid="5417928604710621088">"Shiko më drejtpërdrejt telefonin"</string>
<string name="face_acquired_tilt_too_extreme" msgid="5715715666540716620">"Shiko më drejtpërdrejt telefonin"</string>
<string name="face_acquired_roll_too_extreme" msgid="8261939882838881194">"Shiko më drejtpërdrejt telefonin"</string>
- <string name="face_acquired_obscured" msgid="4917643294953326639">"Hiq gjithçka që fsheh fytyrën tënde."</string>
+ <string name="face_acquired_obscured" msgid="4917643294953326639">"Hiq gjithçka që ta mbulon fytyrën."</string>
<string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"Pastro kreun e ekranit, duke përfshirë shiritin e zi"</string>
<!-- no translation found for face_acquired_dark_glasses_detected (5643703296620631986) -->
<skip />
@@ -1959,7 +1959,8 @@
<string name="app_blocked_title" msgid="7353262160455028160">"Aplikacioni nuk ofrohet"</string>
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> nuk ofrohet për momentin."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> nuk ofrohet"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Kërkohet leje"</string>
+ <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (3805704317624448487) -->
+ <skip />
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"Kamera nuk ofrohet"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"Vazhdo në telefon"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"Mikrofoni nuk ofrohet"</string>
@@ -1970,6 +1971,12 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Qasja është e pamundur në <xliff:g id="DEVICE">%1$s</xliff:g> për momentin. Provoje në pajisjen Android TV më mirë."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Qasja është e pamundur në <xliff:g id="DEVICE">%1$s</xliff:g> për momentin. Provoje në tablet më mirë."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Qasja është e pamundur në <xliff:g id="DEVICE">%1$s</xliff:g> për momentin. Provoje në telefon më mirë."</string>
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (4706276040125072077) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (1824604581465771629) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (7755223160363292105) -->
+ <skip />
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"Ky aplikacion po kërkon siguri shtesë. Provoje në pajisjen Android TV më mirë."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"Ky aplikacion po kërkon siguri shtesë. Provoje në tablet më mirë."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Ky aplikacion po kërkon siguri shtesë. Provoje në telefon më mirë."</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 1e98cffc..7bc4ee9 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -1367,7 +1367,7 @@
<string name="usb_ptp_notification_title" msgid="5043437571863443281">"Режим PTP преко USB-а је укључен"</string>
<string name="usb_tether_notification_title" msgid="8828527870612663771">"USB привезивање је укључено"</string>
<string name="usb_midi_notification_title" msgid="7404506788950595557">"Режим MIDI преко USB-а је укључен"</string>
- <string name="usb_uvc_notification_title" msgid="2030032862673400008">"Уређај повезан са веб-камером"</string>
+ <string name="usb_uvc_notification_title" msgid="2030032862673400008">"Уређај повезан као веб-камера"</string>
<string name="usb_accessory_notification_title" msgid="1385394660861956980">"USB додатак је повезан"</string>
<string name="usb_notification_message" msgid="4715163067192110676">"Додирните за још опција."</string>
<string name="usb_power_notification_message" msgid="7284765627437897702">"Повезани уређај се пуни. Додирните за још опција."</string>
@@ -1960,7 +1960,8 @@
<string name="app_blocked_title" msgid="7353262160455028160">"Апликација није доступна"</string>
<string name="app_blocked_message" msgid="542972921087873023">"Апликација <xliff:g id="APP_NAME">%1$s</xliff:g> тренутно није доступна."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> – није доступно"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Потребна је дозвола"</string>
+ <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (3805704317624448487) -->
+ <skip />
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"Камера није доступна"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"Наставите на телефону"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"Микрофон је недоступан"</string>
@@ -1971,6 +1972,12 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Овој апликацији тренутно не може да се приступи са уређаја <xliff:g id="DEVICE">%1$s</xliff:g>. Пробајте на Android TV уређају."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Овој апликацији тренутно не може да се приступи са уређаја <xliff:g id="DEVICE">%1$s</xliff:g>. Пробајте на таблету."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Овој апликацији тренутно не може да се приступи са уређаја <xliff:g id="DEVICE">%1$s</xliff:g>. Пробајте на телефону."</string>
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (4706276040125072077) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (1824604581465771629) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (7755223160363292105) -->
+ <skip />
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"Ова апликација захтева додатну безбедност. Пробајте на Android TV уређају."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"Ова апликација захтева додатну безбедност. Пробајте на таблету."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Ова апликација захтева додатну безбедност. Пробајте на телефону."</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index f05d9a3..f7c9058 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -628,7 +628,7 @@
<string name="biometric_error_generic" msgid="6784371929985434439">"Ett fel uppstod vid autentiseringen"</string>
<string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Använd skärmlåset"</string>
<string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Fortsätt med hjälp av ditt skärmlås"</string>
- <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Tryck på sensorn med ett stadigt tryck"</string>
+ <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Tryck hårt på sensorn"</string>
<string name="fingerprint_acquired_insufficient" msgid="623888149088216458">"Fingeravtrycket kändes inte igen. Försök igen."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Rengör fingeravtryckssensorn och försök igen"</string>
<string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Rengör sensorn och försök igen"</string>
@@ -648,7 +648,7 @@
<string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Ansiktet har autentiserats. Tryck på Bekräfta"</string>
<string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Det finns ingen maskinvara för fingeravtryck."</string>
<string name="fingerprint_error_no_space" msgid="7285481581905967580">"Det gick inte att konfigurera fingeravtryck"</string>
- <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Fingeravtryckskonfigurering nådde tidsgränsen. Försök igen."</string>
+ <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Tiden för fingeravtrycksinställning gick ut. Försök igen."</string>
<string name="fingerprint_error_canceled" msgid="540026881380070750">"Fingeravtrycksåtgärden avbröts."</string>
<string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Fingeravtrycksåtgärden avbröts av användaren."</string>
<string name="fingerprint_error_lockout" msgid="6626753679019351368">"För många försök. Använd låsskärmen i stället."</string>
@@ -1959,7 +1959,8 @@
<string name="app_blocked_title" msgid="7353262160455028160">"Appen är inte tillgänglig"</string>
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> är inte tillgängligt just nu."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> är inte tillgänglig"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Behörighet krävs"</string>
+ <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (3805704317624448487) -->
+ <skip />
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"Kameran är inte tillgänglig"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"Fortsätt på telefonen"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"Mikrofonen är inte tillgänglig"</string>
@@ -1970,6 +1971,12 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Det går inte att streama detta till <xliff:g id="DEVICE">%1$s</xliff:g> för närvarande. Testa med Android TV-enheten i stället."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Det går inte att streama detta till <xliff:g id="DEVICE">%1$s</xliff:g> för närvarande. Testa med surfplattan i stället."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Det går inte att streama detta till <xliff:g id="DEVICE">%1$s</xliff:g> för närvarande. Testa med telefonen i stället."</string>
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (4706276040125072077) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (1824604581465771629) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (7755223160363292105) -->
+ <skip />
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"Appen begär ytterligare säkerhet. Testa med Android TV-enheten i stället."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"Appen begär ytterligare säkerhet. Testa med surfplattan i stället."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Appen begär ytterligare säkerhet. Testa med telefonen i stället."</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 62a96c5..ac6ae4c 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -1959,7 +1959,8 @@
<string name="app_blocked_title" msgid="7353262160455028160">"Programu haipatikani"</string>
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> haipatikani hivi sasa."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> haipatikani"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Ruhusa inahitajika"</string>
+ <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (3805704317624448487) -->
+ <skip />
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"Kamera haipatikani"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"Endelea kwenye simu"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"Maikrofoni haipatikani"</string>
@@ -1970,6 +1971,12 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Programu hii haiwezi kufikiwa kwenye <xliff:g id="DEVICE">%1$s</xliff:g> kwa muda huu. Badala yake jaribu kwenye kifaa chako cha Android TV."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Programu hii haiwezi kufikiwa kwenye <xliff:g id="DEVICE">%1$s</xliff:g> kwa muda huu. Badala yake jaribu kwenye kompyuta kibao yako."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Programu hii haiwezi kufikiwa kwenye <xliff:g id="DEVICE">%1$s</xliff:g> kwa muda huu. Badala yake jaribu kwenye simu yako."</string>
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (4706276040125072077) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (1824604581465771629) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (7755223160363292105) -->
+ <skip />
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"Programu hii inaomba usalama wa ziada. Badala yake jaribu kwenye kifaa chako cha Android TV."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"Programu hii inaomba usalama wa ziada. Badala yake jaribu kwenye kompyuta yako kibao."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Programu hii inaomba usalama wa ziada. Badala yake jaribu kwenye simu yako."</string>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index e69d1c8..1d67c4a 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -1959,7 +1959,8 @@
<string name="app_blocked_title" msgid="7353262160455028160">"இந்த ஆப்ஸ் இப்போது கிடைப்பதில்லை"</string>
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> ஆப்ஸ் இப்போது கிடைப்பதில்லை."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> இல்லை"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"அனுமதி தேவை"</string>
+ <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (3805704317624448487) -->
+ <skip />
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"கேமராவைப் பயன்படுத்த முடியாது"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"மொபைலில் தொடருங்கள்"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"மைக்ரோஃபோனைப் பயன்படுத்த முடியாது"</string>
@@ -1970,6 +1971,12 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"தற்போது உங்கள் <xliff:g id="DEVICE">%1$s</xliff:g> சாதனத்தில் இதை அணுக முடியாது. அதற்குப் பதிலாக Android TV சாதனத்தில் பயன்படுத்திப் பாருங்கள்."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"தற்போது உங்கள் <xliff:g id="DEVICE">%1$s</xliff:g> சாதனத்தில் இதை அணுக முடியாது. அதற்குப் பதிலாக உங்கள் டேப்லெட்டில் பயன்படுத்திப் பாருங்கள்."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"தற்போது உங்கள் <xliff:g id="DEVICE">%1$s</xliff:g> சாதனத்தில் இதை அணுக முடியாது. அதற்குப் பதிலாக உங்கள் மொபைலில் பயன்படுத்திப் பாருங்கள்."</string>
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (4706276040125072077) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (1824604581465771629) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (7755223160363292105) -->
+ <skip />
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"இந்த ஆப்ஸ் கூடுதல் பாதுகாப்பைக் கோருகிறது. அதற்குப் பதிலாக உங்கள் Android TV சாதனத்தில் பயன்படுத்திப் பார்க்கவும்."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"இந்த ஆப்ஸ் கூடுதல் பாதுகாப்பைக் கோருகிறது. அதற்குப் பதிலாக உங்கள் டேப்லெட்டில் பயன்படுத்திப் பார்க்கவும்."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"இந்த ஆப்ஸ் கூடுதல் பாதுகாப்பைக் கோருகிறது. அதற்குப் பதிலாக உங்கள் மொபைலில் பயன்படுத்திப் பார்க்கவும்."</string>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index 022740d..7e3cfc1 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -705,7 +705,7 @@
<skip />
<string name="face_acquired_recalibrate_alt" msgid="5702674220280332115">"మీ ఫేస్మోడల్ క్రియేషన్ కుదరదు. మళ్లీ ట్రై చేయండి."</string>
<string name="face_acquired_dark_glasses_detected_alt" msgid="4052123776406041972">"డార్క్ గ్లాసెస్ గుర్తించబడ్డాయి. మీ ముఖం పూర్తిగా కనిపించాలి."</string>
- <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"ముఖం కవర్ చేయబడింది. మీ ముఖం పూర్తిగా కనిపించాలి."</string>
+ <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"ముఖం మీద ఏదో కవరింగ్ ఉన్నట్టు గుర్తించబడింది."</string>
<string-array name="face_acquired_vendor">
</string-array>
<string name="face_error_hw_not_available" msgid="5085202213036026288">"ముఖం ధృవీకరించలేరు. హార్డ్వేర్ అందుబాటులో లేదు."</string>
@@ -1259,7 +1259,7 @@
<string name="android_upgrading_starting_apps" msgid="6206161195076057075">"యాప్లను ప్రారంభిస్తోంది."</string>
<string name="android_upgrading_complete" msgid="409800058018374746">"బూట్ను ముగిస్తోంది."</string>
<string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"మీరు పవర్ బటన్ను నొక్కారు — ఇది సాధారణంగా స్క్రీన్ను ఆఫ్ చేస్తుంది.\n\nమీ వేలిముద్రను సెటప్ చేస్తున్నప్పుడు తేలికగా ట్యాప్ చేయడానికి ట్రై చేయండి."</string>
- <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"సెటప్ ముగించడానికి, స్క్రీన్ను ఆఫ్ చేయండి"</string>
+ <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"సెటప్ ముగించడానికి, స్క్రీన్ ఆఫ్ చేయండి"</string>
<string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"ఆఫ్ చేయండి"</string>
<string name="fp_power_button_bp_title" msgid="5585506104526820067">"మీ వేలిముద్ర వెరిఫైను కొనసాగించాలా?"</string>
<string name="fp_power_button_bp_message" msgid="2983163038168903393">"మీరు పవర్ బటన్ను నొక్కారు — ఇది సాధారణంగా స్క్రీన్ను ఆఫ్ చేస్తుంది.\n\nమీ వేలిముద్రను వెరిఫై చేయడానికి తేలికగా ట్యాప్ చేయడం ట్రై చేయండి."</string>
@@ -1368,7 +1368,7 @@
<string name="usb_midi_notification_title" msgid="7404506788950595557">"USB ద్వారా MIDI ఆన్ చేయబడింది"</string>
<string name="usb_uvc_notification_title" msgid="2030032862673400008">"పరికరం వెబ్క్యామ్గా కనెక్ట్ చేయబడింది"</string>
<string name="usb_accessory_notification_title" msgid="1385394660861956980">"USB ఉపకరణం కనెక్ట్ చేయబడింది"</string>
- <string name="usb_notification_message" msgid="4715163067192110676">"మరిన్ని ఆప్షన్ల కోసం నొక్కండి."</string>
+ <string name="usb_notification_message" msgid="4715163067192110676">"మరిన్ని ఆప్షన్ల కోసం ట్యాప్ చేయండి."</string>
<string name="usb_power_notification_message" msgid="7284765627437897702">"కనెక్ట్ చేయబడిన పరికరాన్ని ఛార్జ్ చేస్తోంది. మరిన్ని ఎంపికల కోసం నొక్కండి."</string>
<string name="usb_unsupported_audio_accessory_title" msgid="2335775548086533065">"అనలాగ్ ఆడియో ఉపకరణం కనుగొనబడింది"</string>
<string name="usb_unsupported_audio_accessory_message" msgid="1300168007129796621">"జోడించిన పరికరం ఈ ఫోన్కు అనుకూలంగా లేదు. మరింత తెలుసుకోవడానికి నొక్కండి."</string>
@@ -1699,7 +1699,7 @@
<string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"ఆన్"</string>
<string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"ఆఫ్"</string>
<string name="accessibility_enable_service_title" msgid="3931558336268541484">"<xliff:g id="SERVICE">%1$s</xliff:g>కి మీ పరికరంపై పూర్తి కంట్రోల్ను ఇవ్వాలనుకుంటున్నారా?"</string>
- <string name="accessibility_service_warning_description" msgid="291674995220940133">"అవసరమైన యాక్సెసిబిలిటీ కోసం యాప్లకు పూర్తి కంట్రోల్ ఇవ్వడం తగిన పనే అయినా, అన్ని యాప్లకు అలా ఇవ్వడం సరికాదు."</string>
+ <string name="accessibility_service_warning_description" msgid="291674995220940133">"యాక్సెసిబిలిటీ అవసరాలు ఉన్నప్పుడు మీకు సహాయం చేయడానికి యాప్లకు ఫుల్ కంట్రోల్ ఇవ్వడం సమంజసమే. అయితే అన్ని యాప్లకు అలా కంట్రోల్ ఇవ్వడం సరికాదు."</string>
<string name="accessibility_service_screen_control_title" msgid="190017412626919776">"స్క్రీన్ను చూసి, కంట్రోల్ చేయగలగడం"</string>
<string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"స్క్రీన్పై ఉండే కంటెంట్ మొత్తాన్ని చదవగలుగుతుంది. అంతే కాక, ఇతర యాప్లపై కంటెంట్ను డిస్ప్లే చేస్తుంది."</string>
<string name="accessibility_service_action_perform_title" msgid="779670378951658160">"చర్యలను చూసి, అమలు చేయగలగడం"</string>
@@ -1959,7 +1959,7 @@
<string name="app_blocked_title" msgid="7353262160455028160">"యాప్ అందుబాటులో లేదు"</string>
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> ప్రస్తుతం అందుబాటులో లేదు."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> అందుబాటులో లేదు"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"అనుమతి అవసరం"</string>
+ <string name="app_streaming_blocked_title_for_permission_dialog" msgid="3805704317624448487">"అనుమతి రిక్వెస్ట్ బ్లాక్ చేయబడింది"</string>
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"కెమెరా అందుబాటులో లేదు"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"ఫోన్లో కొనసాగించండి"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"మైక్రోఫోన్ అందుబాటులో లేదు"</string>
@@ -1970,6 +1970,9 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"ఈ సమయంలో మీ <xliff:g id="DEVICE">%1$s</xliff:g>లో దీన్ని యాక్సెస్ చేయడం సాధ్యపడదు. బదులుగా మీ Android TV పరికరంలో ట్రై చేయండి."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"ఈ సమయంలో మీ <xliff:g id="DEVICE">%1$s</xliff:g>లో దీన్ని యాక్సెస్ చేయడం సాధ్యపడదు. బదులుగా మీ టాబ్లెట్లో ట్రై చేయండి."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"ఈ సమయంలో మీ <xliff:g id="DEVICE">%1$s</xliff:g>లో దీన్ని యాక్సెస్ చేయడం సాధ్యపడదు. బదులుగా మీ ఫోన్లో ట్రై చేయండి."</string>
+ <string name="app_streaming_blocked_message_for_permission_request" product="tv" msgid="4706276040125072077">"ఈ యాప్ అదనపు అనుమతి కోసం రిక్వెస్ట్ చేస్తోంది, కానీ స్ట్రీమింగ్ సెషన్లో అనుమతులను మంజూరు చేయడం సాధ్యం కాదు. ముందుగా మీ Android TV పరికరంలో అనుమతిని మంజూరు చేయండి."</string>
+ <string name="app_streaming_blocked_message_for_permission_request" product="tablet" msgid="1824604581465771629">"ఈ యాప్ అదనపు అనుమతి కోసం రిక్వెస్ట్ చేస్తోంది, కానీ స్ట్రీమింగ్ సెషన్లో అనుమతులను మంజూరు చేయడం సాధ్యం కాదు. ముందుగా మీ టాబ్లెట్లో అనుమతిని మంజూరు చేయండి."</string>
+ <string name="app_streaming_blocked_message_for_permission_request" product="default" msgid="7755223160363292105">"ఈ యాప్ అదనపు అనుమతి కోసం రిక్వెస్ట్ చేస్తోంది, కానీ స్ట్రీమింగ్ సెషన్లో అనుమతులను మంజూరు చేయడం సాధ్యం కాదు. ముందుగా మీ ఫోన్లో అనుమతిని మంజూరు చేయండి."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"ఈ యాప్ అదనపు సెక్యూరిటీ కోసం రిక్వెస్ట్ చేస్తోంది. బదులుగా మీ Android TV పరికరంలో ట్రై చేయండి."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"ఈ యాప్ అదనపు సెక్యూరిటీ కోసం రిక్వెస్ట్ చేస్తోంది. బదులుగా మీ టాబ్లెట్లో ట్రై చేయండి."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"ఈ యాప్ అదనపు సెక్యూరిటీ కోసం రిక్వెస్ట్ చేస్తోంది. బదులుగా మీ ఫోన్లో ట్రై చేయండి."</string>
@@ -2154,7 +2157,7 @@
<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_work_tab" msgid="2690019516263167035">"ఆఫీస్"</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>
<string name="resolver_cross_profile_blocked" msgid="3014597376026044840">"మీ IT అడ్మిన్ ద్వారా బ్లాక్ చేయబడింది"</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 83c92e9..512b526 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -705,7 +705,7 @@
<skip />
<string name="face_acquired_recalibrate_alt" msgid="5702674220280332115">"สร้างรูปแบบใบหน้าไม่ได้ โปรดลองอีกครั้ง"</string>
<string name="face_acquired_dark_glasses_detected_alt" msgid="4052123776406041972">"ตรวจพบแว่นตาดำ ต้องมองเห็นใบหน้าของคุณทั้งหมด"</string>
- <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"ตรวจพบหน้ากากอนามัย ต้องมองเห็นใบหน้าของคุณทั้งหมด"</string>
+ <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"ตรวจพบหน้ากาก ต้องมองเห็นใบหน้าของคุณทั้งหมด"</string>
<string-array name="face_acquired_vendor">
</string-array>
<string name="face_error_hw_not_available" msgid="5085202213036026288">"ยืนยันใบหน้าไม่ได้ ฮาร์ดแวร์ไม่พร้อมใช้งาน"</string>
@@ -1959,7 +1959,8 @@
<string name="app_blocked_title" msgid="7353262160455028160">"แอปไม่พร้อมใช้งาน"</string>
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> ไม่พร้อมใช้งานในขณะนี้"</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> ไม่พร้อมใช้งาน"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"ต้องการสิทธิ์"</string>
+ <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (3805704317624448487) -->
+ <skip />
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"กล้องไม่พร้อมใช้งาน"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"ดำเนินการต่อบนโทรศัพท์"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"ไมโครโฟนไม่พร้อมใช้งาน"</string>
@@ -1970,6 +1971,12 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"เข้าถึงแอปนี้ใน <xliff:g id="DEVICE">%1$s</xliff:g> ของคุณไม่ได้ในขณะนี้ โปรดลองเข้าถึงในอุปกรณ์ Android TV แทน"</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"เข้าถึงแอปนี้ใน <xliff:g id="DEVICE">%1$s</xliff:g> ของคุณไม่ได้ในขณะนี้ โปรดลองเข้าถึงในแท็บเล็ตแทน"</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"เข้าถึงแอปนี้ใน <xliff:g id="DEVICE">%1$s</xliff:g> ของคุณไม่ได้ในขณะนี้ โปรดลองเข้าถึงในโทรศัพท์แทน"</string>
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (4706276040125072077) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (1824604581465771629) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (7755223160363292105) -->
+ <skip />
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"แอปนี้มีการขอการรักษาความปลอดภัยเพิ่มเติม โปรดลองเข้าถึงในอุปกรณ์ Android TV แทน"</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"แอปนี้มีการขอการรักษาความปลอดภัยเพิ่มเติม โปรดลองเข้าถึงในแท็บเล็ตแทน"</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"แอปนี้มีการขอการรักษาความปลอดภัยเพิ่มเติม โปรดลองเข้าถึงในโทรศัพท์แทน"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index fc443e9..c6fe8d3 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -1959,7 +1959,8 @@
<string name="app_blocked_title" msgid="7353262160455028160">"Hindi available ang app"</string>
<string name="app_blocked_message" msgid="542972921087873023">"Hindi available sa ngayon ang <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"Hindi available ang <xliff:g id="ACTIVITY">%1$s</xliff:g>"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Kailangan ng pahintulot"</string>
+ <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (3805704317624448487) -->
+ <skip />
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"Hindi available ang camera"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"Magpatuloy sa telepono"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"Hindi available ang mikropono"</string>
@@ -1970,6 +1971,12 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Hindi ito maa-access sa iyong <xliff:g id="DEVICE">%1$s</xliff:g> sa ngayon. Subukan na lang sa iyong Android TV device."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Hindi ito maa-access sa iyong <xliff:g id="DEVICE">%1$s</xliff:g> sa ngayon. Subukan na lang sa iyong tablet."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Hindi ito maa-access sa iyong <xliff:g id="DEVICE">%1$s</xliff:g> sa ngayon. Subukan na lang sa iyong telepono."</string>
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (4706276040125072077) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (1824604581465771629) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (7755223160363292105) -->
+ <skip />
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"Humihiling ng karagdagang seguridad ang app na ito. Subukan na lang sa iyong Android TV device."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"Humihiling ng karagdagang seguridad ang app na ito. Subukan na lang sa iyong tablet."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Humihiling ng karagdagang seguridad ang app na ito. Subukan na lang sa iyong telepono."</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index e83bbc3..32e85d91 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -1953,13 +1953,14 @@
<string name="app_suspended_default_message" msgid="6451215678552004172">"<xliff:g id="APP_NAME_0">%1$s</xliff:g> uygulaması şu anda kullanılamıyor. Uygulamanın kullanım durumu <xliff:g id="APP_NAME_1">%2$s</xliff:g> tarafından yönetiliyor."</string>
<string name="app_suspended_more_details" msgid="211260942831587014">"Daha fazla bilgi"</string>
<string name="app_suspended_unsuspend_message" msgid="1665438589450555459">"Uygulamanın duraklatmasını kaldır"</string>
- <string name="work_mode_off_title" msgid="6367463960165135829">"İş uygulamaları devam ettirilsin mi?"</string>
+ <string name="work_mode_off_title" msgid="6367463960165135829">"İş uygulamaları açılsın mı?"</string>
<string name="work_mode_turn_on" msgid="5316648862401307800">"Devam ettir"</string>
<string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Acil durum"</string>
<string name="app_blocked_title" msgid="7353262160455028160">"Uygulama kullanılamıyor"</string>
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> uygulaması şu anda kullanılamıyor."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> kullanılamıyor"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"İzin gerekli"</string>
+ <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (3805704317624448487) -->
+ <skip />
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"Kamera kullanılamıyor"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"İşleme telefonda devam edin"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"Mikrofon kullanılamıyor"</string>
@@ -1970,6 +1971,12 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Bu uygulamaya şu anda <xliff:g id="DEVICE">%1$s</xliff:g> cihazınızdan erişilemiyor. Bunun yerine Android TV cihazınızı kullanmayı deneyin."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Bu uygulamaya şu anda <xliff:g id="DEVICE">%1$s</xliff:g> cihazınızdan erişilemiyor. Bunun yerine tabletinizi kullanmayı deneyin."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Bu uygulamaya şu anda <xliff:g id="DEVICE">%1$s</xliff:g> cihazınızdan erişilemiyor. Bunun yerine telefonunuzu kullanmayı deneyin."</string>
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (4706276040125072077) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (1824604581465771629) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (7755223160363292105) -->
+ <skip />
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"Bu uygulama daha fazla güvenlik istiyor. Bunun yerine Android TV cihazınızı kullanmayı deneyin."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"Bu uygulama daha fazla güvenlik istiyor. Bunun yerine tabletinizi kullanmayı deneyin."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Bu uygulama daha fazla güvenlik istiyor. Bunun yerine telefonunuzu kullanmayı deneyin."</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 11877ec..fc975f4 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -699,7 +699,7 @@
<string name="face_acquired_pan_too_extreme" msgid="5417928604710621088">"Дивіться на телефон прямо"</string>
<string name="face_acquired_tilt_too_extreme" msgid="5715715666540716620">"Дивіться на телефон прямо"</string>
<string name="face_acquired_roll_too_extreme" msgid="8261939882838881194">"Дивіться на телефон прямо"</string>
- <string name="face_acquired_obscured" msgid="4917643294953326639">"Приберіть об’єкти, які затуляють ваше обличчя."</string>
+ <string name="face_acquired_obscured" msgid="4917643294953326639">"Приберіть об’єкти, які затуляють ваше обличчя"</string>
<string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"Очистьте верхню частину екрана, зокрема чорну панель"</string>
<!-- no translation found for face_acquired_dark_glasses_detected (5643703296620631986) -->
<skip />
@@ -707,7 +707,7 @@
<skip />
<string name="face_acquired_recalibrate_alt" msgid="5702674220280332115">"Не вдається створити модель обличчя. Повторіть спробу."</string>
<string name="face_acquired_dark_glasses_detected_alt" msgid="4052123776406041972">"Виявлено темні окуляри. Обличчя має бути видно повністю."</string>
- <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"Обличчя не видно повністю, бо його закриває аксесуар."</string>
+ <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"Обличчя не видно повністю, бо його закриває аксесуар"</string>
<string-array name="face_acquired_vendor">
</string-array>
<string name="face_error_hw_not_available" msgid="5085202213036026288">"Не вдається перевірити обличчя. Апаратне забезпечення недоступне."</string>
@@ -1961,7 +1961,8 @@
<string name="app_blocked_title" msgid="7353262160455028160">"Додаток недоступний"</string>
<string name="app_blocked_message" msgid="542972921087873023">"Додаток <xliff:g id="APP_NAME">%1$s</xliff:g> зараз недоступний."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"Недоступно: <xliff:g id="ACTIVITY">%1$s</xliff:g>"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Потрібен дозвіл"</string>
+ <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (3805704317624448487) -->
+ <skip />
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"Камера недоступна"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"Продовжте на телефоні"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"Мікрофон недоступний"</string>
@@ -1972,6 +1973,12 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Цей додаток зараз недоступний на вашому <xliff:g id="DEVICE">%1$s</xliff:g>. Спробуйте натомість скористатися пристроєм Android TV."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Цей додаток зараз недоступний на вашому <xliff:g id="DEVICE">%1$s</xliff:g>. Спробуйте натомість скористатися планшетом."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Цей додаток зараз недоступний на вашому <xliff:g id="DEVICE">%1$s</xliff:g>. Спробуйте натомість скористатися телефоном."</string>
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (4706276040125072077) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (1824604581465771629) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (7755223160363292105) -->
+ <skip />
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"Цьому додатку потрібен додатковий рівень безпеки. Спробуйте натомість скористатися пристроєм Android TV."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"Цьому додатку потрібен додатковий рівень безпеки. Спробуйте натомість скористатися планшетом."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Цьому додатку потрібен додатковий рівень безпеки. Спробуйте натомість скористатися телефоном."</string>
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index 4b508c7..01858b8 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -1959,7 +1959,8 @@
<string name="app_blocked_title" msgid="7353262160455028160">"ایپ دستیاب نہیں ہے"</string>
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> ابھی دستیاب نہیں ہے۔"</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> دستیاب نہیں ہے"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"اجازت درکار ہے"</string>
+ <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (3805704317624448487) -->
+ <skip />
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"کیمرا دستیاب نہیں ہے"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"فون پر جاری رکھیں"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"مائیکروفون دستیاب نہیں ہے"</string>
@@ -1970,6 +1971,12 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"اس وقت آپ کے <xliff:g id="DEVICE">%1$s</xliff:g> پر اس تک رسائی نہیں مل سکتی۔ اس کے بجائے اپنے Android TV آلے پر کوشش کریں۔"</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"اس وقت آپ کے <xliff:g id="DEVICE">%1$s</xliff:g> پر اس تک رسائی نہیں مل سکتی۔ اس کے بجائے اپنے ٹیبلیٹ پر کوشش کریں۔"</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"اس وقت آپ کے <xliff:g id="DEVICE">%1$s</xliff:g> پر اس تک رسائی نہیں مل سکتی۔ اس کے بجائے اپنے فون پر کوشش کریں۔"</string>
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (4706276040125072077) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (1824604581465771629) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (7755223160363292105) -->
+ <skip />
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"یہ ایپ اضافی سیکیورٹی کی درخواست کر رہی ہے۔ اس کے بجائے اپنے Android TV آلے پر کوشش کریں۔"</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"یہ ایپ اضافی سیکیورٹی کی درخواست کر رہی ہے۔ اس کے بجائے اپنے ٹیبلیٹ پر کوشش کریں۔"</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"یہ ایپ اضافی سیکیورٹی کی درخواست کر رہی ہے۔ اس کے بجائے اپنے فون پر کوشش کریں۔"</string>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index 2c52936..cfaeca4 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -697,7 +697,7 @@
<string name="face_acquired_pan_too_extreme" msgid="5417928604710621088">"Telefonga tik qarab turing"</string>
<string name="face_acquired_tilt_too_extreme" msgid="5715715666540716620">"Telefonga tik qarab turing"</string>
<string name="face_acquired_roll_too_extreme" msgid="8261939882838881194">"Telefonga tik qarab turing"</string>
- <string name="face_acquired_obscured" msgid="4917643294953326639">"Yuzingizni berkitayotgan narsalarni olib tashlang."</string>
+ <string name="face_acquired_obscured" msgid="4917643294953326639">"Yuzingiz yaxshi koʻrinmayapti."</string>
<string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"Ekranning yuqori qismini, shuningdek, qora panelni ham tozalang"</string>
<!-- no translation found for face_acquired_dark_glasses_detected (5643703296620631986) -->
<skip />
@@ -1259,7 +1259,7 @@
<string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Ilovalar ishga tushirilmoqda."</string>
<string name="android_upgrading_complete" msgid="409800058018374746">"Tizimni yuklashni tugatish."</string>
<string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"Quvvat tugmasini bosdingiz — bu odatda ekranni oʻchiradi.\n\nBarmoq izini qoʻshish vaqtida tugmaga yengilgina tegining."</string>
- <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"Sozlashni yakunlash uchun ekranni oʻchiring"</string>
+ <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"Yakunlash uchun ekranni oʻchiring"</string>
<string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"Faolsizlantirish"</string>
<string name="fp_power_button_bp_title" msgid="5585506104526820067">"Barmoq izi tasdiqlashda davom etilsinmi?"</string>
<string name="fp_power_button_bp_message" msgid="2983163038168903393">"Quvvat tugmasini bosdingiz. Bu odatda ekranni oʻchiradi.\n\nBarmoq izingizni tasdiqlash uchun tugmaga yengilgina tegining."</string>
@@ -1959,7 +1959,8 @@
<string name="app_blocked_title" msgid="7353262160455028160">"Ilova ishlamayapti"</string>
<string name="app_blocked_message" msgid="542972921087873023">"Ayni vaqtda <xliff:g id="APP_NAME">%1$s</xliff:g> ilovasi ishlamayapti."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> kanali ish faoliyatida emas"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Ruxsat zarur"</string>
+ <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (3805704317624448487) -->
+ <skip />
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"Kamera ishlamayapti"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"Telefonda davom ettirish"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"Mikrofon ishlamayapti"</string>
@@ -1970,6 +1971,12 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Ayni vaqtda bu translatsiya <xliff:g id="DEVICE">%1$s</xliff:g> qurilmangizda ishlamaydi. Android TV qurilmasi orqali urinib koʻring."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Ayni vaqtda bu translatsiya <xliff:g id="DEVICE">%1$s</xliff:g> qurilmangizda ishlamaydi. Planshet orqali urinib koʻring."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Ayni vaqtda bu translatsiya <xliff:g id="DEVICE">%1$s</xliff:g> qurilmangizda ishlamaydi. Telefon orqali urininb koʻring."</string>
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (4706276040125072077) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (1824604581465771629) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (7755223160363292105) -->
+ <skip />
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"Bu ilova qoʻshimcha himoyani talab qilmoqda. Android TV qurilmasi orqali urinib koʻring."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"Bu ilova qoʻshimcha himoyani talab qilmoqda. Planshet orqali urinib koʻring."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Bu ilova qoʻshimcha himoyani talab qilmoqda. Telefon orqali urininb koʻring."</string>
@@ -2334,7 +2341,7 @@
<string name="concurrent_display_notification_power_save_title" msgid="1794569070730736281">"Ikki ekranli rejim ishlamaydi"</string>
<string name="concurrent_display_notification_power_save_content" msgid="2198116070583851493">"Quvvatni tejash yoniqligi uchun hozir ikki ekranli rejim ishlamaydi. Buni Sozlamalarda faolsizlantirishingiz mumkin."</string>
<string name="device_state_notification_settings_button" msgid="691937505741872749">"Sozlamalarni ochish"</string>
- <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Faolsizlantirish"</string>
+ <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Oʻchirish"</string>
<string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"<xliff:g id="DEVICE_NAME">%s</xliff:g> sozlandi"</string>
<string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"Klaviatura terilmasi bunga sozlandi: <xliff:g id="LAYOUT_1">%s</xliff:g>. Oʻzgartirish uchun ustiga bosing."</string>
<string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"Klaviatura terilmasi bunga sozlandi: <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>. Oʻzgartirish uchun ustiga bosing."</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 584e5bb..4b03591 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -648,7 +648,7 @@
<string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Đã xác thực khuôn mặt, vui lòng nhấn để xác nhận"</string>
<string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"Phần cứng vân tay không khả dụng."</string>
<string name="fingerprint_error_no_space" msgid="7285481581905967580">"Không thể thiết lập vân tay"</string>
- <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Hết thời gian thiết lập vân tay. Hãy thử lại."</string>
+ <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Hết thời gian chờ thiết lập vân tay. Hãy thử lại."</string>
<string name="fingerprint_error_canceled" msgid="540026881380070750">"Thao tác dùng dấu vân tay bị hủy."</string>
<string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Người dùng đã hủy thao tác dùng dấu vân tay."</string>
<string name="fingerprint_error_lockout" msgid="6626753679019351368">"Bạn đã thử quá nhiều lần. Hãy dùng phương thức khoá màn hình."</string>
@@ -689,7 +689,7 @@
<string name="face_acquired_too_right" msgid="6245286514593540859">"Đưa điện thoại sang bên trái"</string>
<string name="face_acquired_too_left" msgid="9201762240918405486">"Đưa điện thoại sang bên phải"</string>
<string name="face_acquired_poor_gaze" msgid="4427153558773628020">"Vui lòng nhìn thẳng vào thiết bị."</string>
- <string name="face_acquired_not_detected" msgid="1057966913397548150">"Không thấy khuôn mặt. Hãy cầm điện thoại ngang tầm mắt"</string>
+ <string name="face_acquired_not_detected" msgid="1057966913397548150">"Không thấy khuôn mặt. Hãy cầm điện thoại ngang tầm mắt."</string>
<string name="face_acquired_too_much_motion" msgid="8199691445085189528">"Thiết bị di chuyển quá nhiều. Giữ yên thiết bị."</string>
<string name="face_acquired_recalibrate" msgid="8724013080976469746">"Vui lòng đăng ký lại khuôn mặt của bạn."</string>
<string name="face_acquired_too_different" msgid="2520389515612972889">"Không thể nhận dạng khuôn mặt. Hãy thử lại."</string>
@@ -704,7 +704,7 @@
<!-- no translation found for face_acquired_mouth_covering_detected (8219428572168642593) -->
<skip />
<string name="face_acquired_recalibrate_alt" msgid="5702674220280332115">"Không thể tạo mẫu khuôn mặt của bạn. Hãy thử lại."</string>
- <string name="face_acquired_dark_glasses_detected_alt" msgid="4052123776406041972">"Đã phát hiện thấy kính râm. Toàn bộ khuôn mặt của bạn phải được trông thấy rõ ràng."</string>
+ <string name="face_acquired_dark_glasses_detected_alt" msgid="4052123776406041972">"Đã phát hiện thấy kính râm. Bạn phải cho thấy toàn bộ khuôn mặt."</string>
<string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"Khuôn mặt bị che. Bạn phải cho thấy toàn bộ khuôn mặt."</string>
<string-array name="face_acquired_vendor">
</string-array>
@@ -1959,7 +1959,8 @@
<string name="app_blocked_title" msgid="7353262160455028160">"Ứng dụng này không dùng được"</string>
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> hiện không dùng được."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"Không hỗ trợ <xliff:g id="ACTIVITY">%1$s</xliff:g>"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Cần có quyền"</string>
+ <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (3805704317624448487) -->
+ <skip />
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"Không dùng được máy ảnh"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"Tiếp tục trên điện thoại"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"Không dùng được micrô"</string>
@@ -1970,6 +1971,12 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Hiện tại, bạn không thể truy cập vào ứng dụng này trên <xliff:g id="DEVICE">%1$s</xliff:g>. Hãy thử trên thiết bị Android TV."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Hiện tại, bạn không thể truy cập vào ứng dụng này trên <xliff:g id="DEVICE">%1$s</xliff:g>. Hãy thử trên máy tính bảng."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Hiện tại, bạn không thể truy cập vào ứng dụng này trên <xliff:g id="DEVICE">%1$s</xliff:g>. Hãy thử trên điện thoại."</string>
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (4706276040125072077) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (1824604581465771629) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (7755223160363292105) -->
+ <skip />
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"Ứng dụng này đang yêu cầu tính năng bảo mật bổ sung. Hãy thử trên thiết bị Android TV."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"Ứng dụng này đang yêu cầu tính năng bảo mật bổ sung. Hãy thử trên máy tính bảng."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Ứng dụng này đang yêu cầu tính năng bảo mật bổ sung. Hãy thử trên điện thoại."</string>
@@ -2128,7 +2135,7 @@
<string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"Không có gợi ý nào về người mà bạn có thể chia sẻ"</string>
<string name="chooser_all_apps_button_label" msgid="3230427756238666328">"Danh sách ứng dụng"</string>
<string name="usb_device_resolve_prompt_warn" msgid="325871329788064199">"Ứng dụng này chưa được cấp quyền ghi âm nhưng vẫn có thể ghi âm thông qua thiết bị USB này."</string>
- <string name="accessibility_system_action_home_label" msgid="3234748160850301870">"Màn hình chính"</string>
+ <string name="accessibility_system_action_home_label" msgid="3234748160850301870">"Nhà"</string>
<string name="accessibility_system_action_back_label" msgid="4205361367345537608">"Quay lại"</string>
<string name="accessibility_system_action_recents_label" msgid="4782875610281649728">"Ứng dụng gần đây"</string>
<string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"Thông báo"</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index c8cc398..19a34c6 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -705,7 +705,7 @@
<skip />
<string name="face_acquired_recalibrate_alt" msgid="5702674220280332115">"无法创建您的脸部模型,请重试。"</string>
<string name="face_acquired_dark_glasses_detected_alt" msgid="4052123776406041972">"检测到墨镜,您的脸部必须完全可见。"</string>
- <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"检测到脸部存在遮挡,请露出整张脸。"</string>
+ <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"检测到面部被遮挡,请露出整个面部。"</string>
<string-array name="face_acquired_vendor">
</string-array>
<string name="face_error_hw_not_available" msgid="5085202213036026288">"无法验证人脸。硬件无法使用。"</string>
@@ -1366,7 +1366,7 @@
<string name="usb_ptp_notification_title" msgid="5043437571863443281">"已开启 USB PTP 模式"</string>
<string name="usb_tether_notification_title" msgid="8828527870612663771">"已开启 USB 网络共享模式"</string>
<string name="usb_midi_notification_title" msgid="7404506788950595557">"已开启 USB MIDI 模式"</string>
- <string name="usb_uvc_notification_title" msgid="2030032862673400008">"设备已连接为摄像头"</string>
+ <string name="usb_uvc_notification_title" msgid="2030032862673400008">"设备已连接并作为摄像头使用"</string>
<string name="usb_accessory_notification_title" msgid="1385394660861956980">"USB 配件已连接"</string>
<string name="usb_notification_message" msgid="4715163067192110676">"点按即可查看更多选项。"</string>
<string name="usb_power_notification_message" msgid="7284765627437897702">"正在为连接的设备充电。点按即可查看更多选项。"</string>
@@ -1959,7 +1959,7 @@
<string name="app_blocked_title" msgid="7353262160455028160">"应用无法使用"</string>
<string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g>目前无法使用。"</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g>不可用"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"需要权限"</string>
+ <string name="app_streaming_blocked_title_for_permission_dialog" msgid="3805704317624448487">"权限请求被阻止"</string>
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"无法使用摄像头"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"继续在手机上操作"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"无法使用麦克风"</string>
@@ -1970,6 +1970,9 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"目前无法在您的<xliff:g id="DEVICE">%1$s</xliff:g>上访问此内容。您可以尝试在 Android TV 设备上访问。"</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"目前无法在您的<xliff:g id="DEVICE">%1$s</xliff:g>上访问此内容。您可以尝试在平板电脑上访问。"</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"目前无法在您的<xliff:g id="DEVICE">%1$s</xliff:g>上访问此内容。您可以尝试在手机上访问。"</string>
+ <string name="app_streaming_blocked_message_for_permission_request" product="tv" msgid="4706276040125072077">"此应用请求获得额外的权限,但在流式传输会话期间无法授予权限。请先在 Android TV 设备上授予相应权限。"</string>
+ <string name="app_streaming_blocked_message_for_permission_request" product="tablet" msgid="1824604581465771629">"此应用请求获得额外的权限,但在流式传输会话期间无法授予权限。请先在平板电脑上授予相应权限。"</string>
+ <string name="app_streaming_blocked_message_for_permission_request" product="default" msgid="7755223160363292105">"此应用请求获得额外的权限,但在流式传输会话期间无法授予权限。请先在手机上授予相应权限。"</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"此应用要求进行额外的安全性验证,您可以尝试在 Android TV 设备上访问。"</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"此应用要求进行额外的安全性验证,您可以尝试在平板电脑上访问。"</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"此应用要求进行额外的安全性验证,您可以尝试在手机上访问。"</string>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index 00f94b4..b4584bc 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -1959,7 +1959,8 @@
<string name="app_blocked_title" msgid="7353262160455028160">"無法使用應用程式"</string>
<string name="app_blocked_message" msgid="542972921087873023">"目前無法使用「<xliff:g id="APP_NAME">%1$s</xliff:g>」。"</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"無法使用「<xliff:g id="ACTIVITY">%1$s</xliff:g>」"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"需要權限"</string>
+ <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (3805704317624448487) -->
+ <skip />
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"無法使用相機"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"請繼續透過手機操作"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"無法使用麥克風"</string>
@@ -1970,6 +1971,12 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"目前無法在 <xliff:g id="DEVICE">%1$s</xliff:g> 上存取此應用程式,請改用 Android TV 裝置存取。"</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"目前無法在 <xliff:g id="DEVICE">%1$s</xliff:g> 上存取此應用程式,請改用平板電腦存取。"</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"目前無法在 <xliff:g id="DEVICE">%1$s</xliff:g> 上存取此應用程式,請改用手機存取。"</string>
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (4706276040125072077) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (1824604581465771629) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (7755223160363292105) -->
+ <skip />
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"此應用程式要求額外的安全措施,請改用 Android TV 裝置。"</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"此應用程式要求額外的安全措施,請改用平板電腦。"</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"此應用程式要求額外的安全措施,請改用手機。"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index c04fe7a..dd4a484 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -689,7 +689,7 @@
<string name="face_acquired_too_right" msgid="6245286514593540859">"請將手機向左移"</string>
<string name="face_acquired_too_left" msgid="9201762240918405486">"請將手機向右移"</string>
<string name="face_acquired_poor_gaze" msgid="4427153558773628020">"請儘可能直視裝置正面。"</string>
- <string name="face_acquired_not_detected" msgid="1057966913397548150">"未偵測到你的臉,請將手機舉到與視線同高。"</string>
+ <string name="face_acquired_not_detected" msgid="1057966913397548150">"未偵測到你的臉,請將手機舉到與眼睛同高的位置。"</string>
<string name="face_acquired_too_much_motion" msgid="8199691445085189528">"鏡頭過度晃動,請拿穩手機。"</string>
<string name="face_acquired_recalibrate" msgid="8724013080976469746">"請重新註冊你的臉孔。"</string>
<string name="face_acquired_too_different" msgid="2520389515612972889">"無法辨識這張臉,請再試一次。"</string>
@@ -1959,7 +1959,8 @@
<string name="app_blocked_title" msgid="7353262160455028160">"應用程式無法使用"</string>
<string name="app_blocked_message" msgid="542972921087873023">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」目前無法使用。"</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"無法存取「<xliff:g id="ACTIVITY">%1$s</xliff:g>」"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"需要相關權限"</string>
+ <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (3805704317624448487) -->
+ <skip />
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"無法使用相機"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"請繼續在手機上操作"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"無法使用麥克風"</string>
@@ -1970,6 +1971,12 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"目前無法在 <xliff:g id="DEVICE">%1$s</xliff:g> 上存取這個應用程式,請改用 Android TV 裝置。"</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"目前無法在 <xliff:g id="DEVICE">%1$s</xliff:g> 上存取這個項目,請改用平板電腦。"</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"目前無法在 <xliff:g id="DEVICE">%1$s</xliff:g> 上存取這個應用程式,請改用手機。"</string>
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (4706276040125072077) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (1824604581465771629) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (7755223160363292105) -->
+ <skip />
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"這個應用程式要求進行額外的安全性驗證,請改用 Android TV 裝置。"</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"這個應用程式要求進行額外的安全性驗證,請改用平板電腦。"</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"這個應用程式要求進行額外的安全性驗證,請改用手機。"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 84a6802..03a21de 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -1959,7 +1959,8 @@
<string name="app_blocked_title" msgid="7353262160455028160">"Uhlelo lokusebenza alutholakali"</string>
<string name="app_blocked_message" msgid="542972921087873023">"I-<xliff:g id="APP_NAME">%1$s</xliff:g> ayitholakali khona manje."</string>
<string name="app_streaming_blocked_title" msgid="6090945835898766139">"okungatholakali <xliff:g id="ACTIVITY">%1$s</xliff:g>"</string>
- <string name="app_streaming_blocked_title_for_permission_dialog" msgid="4483161748582966785">"Kudingeka imvume"</string>
+ <!-- no translation found for app_streaming_blocked_title_for_permission_dialog (3805704317624448487) -->
+ <skip />
<string name="app_streaming_blocked_title_for_camera_dialog" msgid="3935701653713853065">"Ikhamera ayitholakali"</string>
<string name="app_streaming_blocked_title_for_fingerprint_dialog" msgid="3516853717714141951">"Qhubeka kufoni"</string>
<string name="app_streaming_blocked_title_for_microphone_dialog" msgid="544822455127171206">"Imakrofoni ayitholakali"</string>
@@ -1970,6 +1971,12 @@
<string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Lokhu akukwazi ukufinyelelwa ku-<xliff:g id="DEVICE">%1$s</xliff:g> yakho ngalesi sikhathi. Zama kudivayisi yakho ye-Android TV kunalokho."</string>
<string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Lokhu akukwazi ukufinyelelwa ku-<xliff:g id="DEVICE">%1$s</xliff:g> yakho ngalesi sikhathi. Zama kuthebhulethi yakho kunalokho."</string>
<string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Lokhu akukwazi ukufinyelelwa ku-<xliff:g id="DEVICE">%1$s</xliff:g> yakho ngalesi sikhathi. Zama efonini yakho kunalokho."</string>
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (4706276040125072077) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (1824604581465771629) -->
+ <skip />
+ <!-- no translation found for app_streaming_blocked_message_for_permission_request (7755223160363292105) -->
+ <skip />
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"Le app icela ukuvikeleka okwengeziwe. Zama kudivayisi yakho ye-Android TV kunalokho."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"Le app icela ukuvikeleka okwengeziwe. Zama kuthebhulethi yakho kunalokho."</string>
<string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Le app icela ukuvikeleka okwengeziwe. Zama efonini yakho kunalokho."</string>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index a8e3f86..d05c10f 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -5718,6 +5718,9 @@
TODO(b/255532890) Enable when ignoreOrientationRequest is set -->
<bool name="config_letterboxIsEnabledForTranslucentActivities">false</bool>
+ <!-- Whether per-app user aspect ratio override settings is enabled -->
+ <bool name="config_appCompatUserAppAspectRatioSettingsIsEnabled">false</bool>
+
<!-- Whether sending compat fake focus for split screen resumed activities is enabled.
Needed because some game engines wait to get focus before drawing the content of
the app which isn't guaranteed by default in multi-window modes. -->
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 4387197..7f66a83 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1793,6 +1793,8 @@
<string name="biometric_error_hw_unavailable">Biometric hardware unavailable</string>
<!-- Message shown when biometric authentication was canceled by the user [CHAR LIMIT=50] -->
<string name="biometric_error_user_canceled">Authentication canceled</string>
+ <!-- Message shown by the biometric dialog when biometric is not recognized -->
+ <string name="biometric_not_recognized">Not recognized</string>
<!-- Message shown by the biometric dialog when face is not recognized [CHAR LIMIT=50] -->
<string name="biometric_face_not_recognized">Face not recognized</string>
<!-- Message shown when biometric authentication has been canceled [CHAR LIMIT=50] -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 8ac8397..bb4b16c 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -4458,9 +4458,6 @@
<!-- Set to true to make assistant show in front of the dream/screensaver. -->
<java-symbol type="bool" name="config_assistantOnTopOfDream"/>
- <!-- Set to true to enable letterboxing on translucent activities. -->
- <java-symbol type="bool" name="config_letterboxIsEnabledForTranslucentActivities" />
-
<java-symbol type="string" name="config_overrideComponentUiPackage" />
<java-symbol type="string" name="notification_channel_network_status" />
@@ -4555,6 +4552,12 @@
<java-symbol type="dimen" name="config_letterboxDefaultMinAspectRatioForUnresizableApps" />
<java-symbol type="bool" name="config_letterboxIsSplitScreenAspectRatioForUnresizableAppsEnabled" />
<java-symbol type="bool" name="config_letterboxIsDisplayAspectRatioForFixedOrientationLetterboxEnabled" />
+ <!-- Set to true to enable letterboxing on translucent activities. -->
+ <java-symbol type="bool" name="config_letterboxIsEnabledForTranslucentActivities" />
+
+ <!-- Whether per-app user aspect ratio override settings is enabled -->
+ <java-symbol type="bool" name="config_appCompatUserAppAspectRatioSettingsIsEnabled" />
+
<java-symbol type="bool" name="config_isCompatFakeFocusEnabled" />
<java-symbol type="bool" name="config_isWindowManagerCameraCompatTreatmentEnabled" />
<java-symbol type="bool" name="config_isWindowManagerCameraCompatSplitScreenAspectRatioEnabled" />
diff --git a/core/res/res/xml/sms_short_codes.xml b/core/res/res/xml/sms_short_codes.xml
index df3ae0e..f28da1f 100644
--- a/core/res/res/xml/sms_short_codes.xml
+++ b/core/res/res/xml/sms_short_codes.xml
@@ -162,7 +162,7 @@
<shortcode country="jp" pattern="\\d{1,5}" free="8083" />
<!-- Kenya: 5 digits, known premium codes listed -->
- <shortcode country="ke" pattern="\\d{5}" free="21725|21562|40520" />
+ <shortcode country="ke" pattern="\\d{5}" free="21725|21562|40520|23342" />
<!-- Kyrgyzstan: 4 digits, known premium codes listed -->
<shortcode country="kg" pattern="\\d{4}" premium="415[2367]|444[69]" />
@@ -235,6 +235,9 @@
<!-- Russia: 4 digits, known premium codes listed: http://smscoin.net/info/pricing-russia/ -->
<shortcode country="ru" pattern="\\d{4}" premium="1(?:1[56]1|899)|2(?:09[57]|322|47[46]|880|990)|3[589]33|4161|44(?:4[3-9]|81)|77(?:33|81)|8424" free="6954|8501" standard="2037|2044"/>
+ <!-- Rwanda: 4 digits -->
+ <shortcode country="rw" pattern="\\d{4}" free="5060" />
+
<!-- Saudi Arabia -->
<shortcode country="sa" pattern="\\d{1,5}" free="8145" />
diff --git a/core/tests/coretests/res/values/overlayable_icons_test.xml b/core/tests/coretests/res/values/overlayable_icons_test.xml
index 7ea1848..6a50e9a 100644
--- a/core/tests/coretests/res/values/overlayable_icons_test.xml
+++ b/core/tests/coretests/res/values/overlayable_icons_test.xml
@@ -21,7 +21,6 @@
<item>@*android:drawable/ic_audio_alarm</item>
<item>@*android:drawable/ic_audio_alarm_mute</item>
<item>@*android:drawable/ic_battery_80_24dp</item>
- <item>@*android:drawable/ic_bluetooth_share_icon</item>
<item>@*android:drawable/ic_bt_headphones_a2dp</item>
<item>@*android:drawable/ic_bt_headset_hfp</item>
<item>@*android:drawable/ic_bt_hearing_aid</item>
diff --git a/core/tests/coretests/src/android/util/apk/SourceStampVerifierTest.java b/core/tests/coretests/src/android/util/apk/SourceStampVerifierTest.java
index bc0bddb..e0c583d 100644
--- a/core/tests/coretests/src/android/util/apk/SourceStampVerifierTest.java
+++ b/core/tests/coretests/src/android/util/apk/SourceStampVerifierTest.java
@@ -100,7 +100,7 @@
SourceStampVerificationResult result =
SourceStampVerifier.verify(mPrimaryApk.getAbsolutePath());
- assertTrue(result.isPresent());
+ assertFalse(result.isPresent());
assertFalse(result.isVerified());
assertNull(result.getCertificate());
}
diff --git a/core/tests/coretests/src/com/android/internal/util/FakeLatencyTrackerTest.java b/core/tests/coretests/src/com/android/internal/util/FakeLatencyTrackerTest.java
index e6f10ad..3946cdf 100644
--- a/core/tests/coretests/src/com/android/internal/util/FakeLatencyTrackerTest.java
+++ b/core/tests/coretests/src/com/android/internal/util/FakeLatencyTrackerTest.java
@@ -16,14 +16,19 @@
package com.android.internal.util;
+import static android.provider.DeviceConfig.NAMESPACE_LATENCY_TRACKER;
+
import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_SHOW_VOICE_INTERACTION;
import static com.android.internal.util.FrameworkStatsLog.UI_ACTION_LATENCY_REPORTED;
import static com.android.internal.util.LatencyTracker.ACTION_SHOW_VOICE_INTERACTION;
import static com.google.common.truth.Truth.assertThat;
+import android.provider.DeviceConfig;
+
import androidx.test.ext.junit.runners.AndroidJUnit4;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -40,12 +45,22 @@
public class FakeLatencyTrackerTest {
private FakeLatencyTracker mFakeLatencyTracker;
+ private int mInitialSyncDisabledMode;
@Before
public void setUp() throws Exception {
+ mInitialSyncDisabledMode = DeviceConfig.getSyncDisabledMode();
+ DeviceConfig.setSyncDisabledMode(DeviceConfig.SYNC_DISABLED_MODE_NONE);
mFakeLatencyTracker = FakeLatencyTracker.create();
}
+ @After
+ public void tearDown() throws Exception {
+ DeviceConfig.setProperties(
+ new DeviceConfig.Properties.Builder(NAMESPACE_LATENCY_TRACKER).build());
+ DeviceConfig.setSyncDisabledMode(mInitialSyncDisabledMode);
+ }
+
@Test
public void testForceEnabled() throws Exception {
mFakeLatencyTracker.logAction(ACTION_SHOW_VOICE_INTERACTION, 1234);
diff --git a/core/tests/coretests/src/com/android/internal/util/LatencyTrackerTest.java b/core/tests/coretests/src/com/android/internal/util/LatencyTrackerTest.java
index 584ad20..f24894e 100644
--- a/core/tests/coretests/src/com/android/internal/util/LatencyTrackerTest.java
+++ b/core/tests/coretests/src/com/android/internal/util/LatencyTrackerTest.java
@@ -58,15 +58,21 @@
// Fake is used because it tests the real logic of LatencyTracker, and it only fakes the
// outcomes (PerfettoTrigger and FrameworkStatsLog).
private FakeLatencyTracker mLatencyTracker;
+ private int mInitialSyncDisabledMode;
@Before
public void setUp() throws Exception {
+ mInitialSyncDisabledMode = DeviceConfig.getSyncDisabledMode();
+ DeviceConfig.setSyncDisabledMode(DeviceConfig.SYNC_DISABLED_MODE_NONE);
mLatencyTracker = FakeLatencyTracker.create();
}
@After
- public void tearDown() {
+ public void tearDown() throws Exception {
mLatencyTracker.stopListeningForLatencyTrackerConfigChanges();
+ DeviceConfig.setProperties(
+ new DeviceConfig.Properties.Builder(NAMESPACE_LATENCY_TRACKER).build());
+ DeviceConfig.setSyncDisabledMode(mInitialSyncDisabledMode);
}
@Test
diff --git a/graphics/java/android/graphics/RenderNode.java b/graphics/java/android/graphics/RenderNode.java
index 2e91c24..15d26eb 100644
--- a/graphics/java/android/graphics/RenderNode.java
+++ b/graphics/java/android/graphics/RenderNode.java
@@ -971,6 +971,23 @@
}
/**
+ * Configure the {@link android.graphics.RenderEffect} to apply to the backdrop contents of
+ * this RenderNode. This will apply a visual effect to the result of the backdrop contents
+ * of this RenderNode before the RenderNode is drawn into the destination. For example if
+ * {@link RenderEffect#createBlurEffect(float, float, RenderEffect, Shader.TileMode)}
+ * is provided, the previous content behind this RenderNode will be blurred before the
+ * RenderNode is drawn in to the destination.
+ * @param renderEffect to be applied to the backdrop contents of this RenderNode. Passing
+ * null clears all previously configured RenderEffects
+ * @return True if the value changed, false if the new value was the same as the previous value.
+ * @hide
+ */
+ public boolean setBackdropRenderEffect(@Nullable RenderEffect renderEffect) {
+ return nSetBackdropRenderEffect(mNativeRenderNode,
+ renderEffect != null ? renderEffect.getNativeInstance() : 0);
+ }
+
+ /**
* Returns the translucency level of this display list.
*
* @return A value between 0.0f and 1.0f
@@ -1797,6 +1814,9 @@
private static native boolean nSetRenderEffect(long renderNode, long renderEffect);
@CriticalNative
+ private static native boolean nSetBackdropRenderEffect(long renderNode, long renderEffect);
+
+ @CriticalNative
private static native boolean nSetHasOverlappingRendering(long renderNode,
boolean hasOverlappingRendering);
diff --git a/libs/WindowManager/Shell/res/values-fa/strings.xml b/libs/WindowManager/Shell/res/values-fa/strings.xml
index 13a2ea2..edff47a 100644
--- a/libs/WindowManager/Shell/res/values-fa/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fa/strings.xml
@@ -59,7 +59,7 @@
<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="bubble_overflow_button_content_description" msgid="8160974472718594382">"سرریز"</string>
- <string name="bubble_accessibility_action_add_back" msgid="1830101076853540953">"افزودن برگشت به پشته"</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>
<string name="bubble_content_description_stack" msgid="8071515017164630429">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> از <xliff:g id="APP_NAME">%2$s</xliff:g> و <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> مورد بیشتر"</string>
<string name="bubble_accessibility_action_move_top_left" msgid="2644118920500782758">"انتقال به بالا سمت راست"</string>
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java
index 504839f..7e09c98 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java
@@ -422,6 +422,7 @@
}
if (mBubbleBarExpandedView != null) {
mBubbleBarExpandedView.cleanUpExpandedState();
+ mBubbleBarExpandedView = null;
}
if (mIntent != null) {
mIntent.unregisterCancelListener(mIntentCancelListener);
@@ -549,10 +550,10 @@
/**
* Set visibility of bubble in the expanded state.
*
- * @param visibility {@code true} if the expanded bubble should be visible on the screen.
- *
- * Note that this contents visibility doesn't affect visibility at {@link android.view.View},
+ * <p>Note that this contents visibility doesn't affect visibility at {@link android.view.View},
* and setting {@code false} actually means rendering the expanded view in transparent.
+ *
+ * @param visibility {@code true} if the expanded bubble should be visible on the screen.
*/
@Override
public void setTaskViewVisibility(boolean visibility) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
index c48f2fd..6880237 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
@@ -64,7 +64,6 @@
import android.os.Handler;
import android.os.RemoteException;
import android.os.ServiceManager;
-import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.UserManager;
import android.service.notification.NotificationListenerService;
@@ -92,6 +91,7 @@
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.WindowManagerShellWrapper;
import com.android.wm.shell.bubbles.bar.BubbleBarLayerView;
+import com.android.wm.shell.bubbles.properties.BubbleProperties;
import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.ExternalInterfaceBinder;
import com.android.wm.shell.common.FloatingContentCoordinator;
@@ -143,16 +143,6 @@
private static final String SYSTEM_DIALOG_REASON_KEY = "reason";
private static final String SYSTEM_DIALOG_REASON_GESTURE_NAV = "gestureNav";
- // TODO(b/256873975) Should use proper flag when available to shell/launcher
- /**
- * Whether bubbles are showing in the bubble bar from launcher. This is only available
- * on large screens and {@link BubbleController#isShowingAsBubbleBar()} should be used
- * to check all conditions that indicate if the bubble bar is in use.
- */
- private static final boolean BUBBLE_BAR_ENABLED =
- SystemProperties.getBoolean("persist.wm.debug.bubble_bar", false);
-
-
/**
* Common interface to send updates to bubble views.
*/
@@ -195,6 +185,7 @@
private final ShellController mShellController;
private final ShellCommandHandler mShellCommandHandler;
private final IWindowManager mWmService;
+ private final BubbleProperties mBubbleProperties;
// Used to post to main UI thread
private final ShellExecutor mMainExecutor;
@@ -291,7 +282,8 @@
@ShellBackgroundThread ShellExecutor bgExecutor,
TaskViewTransitions taskViewTransitions,
SyncTransactionQueue syncQueue,
- IWindowManager wmService) {
+ IWindowManager wmService,
+ BubbleProperties bubbleProperties) {
mContext = context;
mShellCommandHandler = shellCommandHandler;
mShellController = shellController;
@@ -328,6 +320,7 @@
mDragAndDropController = dragAndDropController;
mSyncQueue = syncQueue;
mWmService = wmService;
+ mBubbleProperties = bubbleProperties;
shellInit.addInitCallback(this::onInit, this);
}
@@ -518,11 +511,14 @@
/**
* Sets a listener to be notified of bubble updates. This is used by launcher so that
* it may render bubbles in itself. Only one listener is supported.
+ *
+ * <p>If bubble bar is supported, bubble views will be updated to switch to bar mode.
*/
public void registerBubbleStateListener(Bubbles.BubbleStateListener listener) {
- if (isShowingAsBubbleBar()) {
- // Only set the listener if bubble bar is showing.
+ if (canShowAsBubbleBar() && listener != null) {
+ // Only set the listener if we can show the bubble bar.
mBubbleStateListener = listener;
+ setUpBubbleViewsForMode();
sendInitialListenerUpdate();
} else {
mBubbleStateListener = null;
@@ -531,9 +527,15 @@
/**
* Unregisters the {@link Bubbles.BubbleStateListener}.
+ *
+ * <p>If there's an existing listener, then we're switching back to stack mode and bubble views
+ * will be updated accordingly.
*/
public void unregisterBubbleStateListener() {
- mBubbleStateListener = null;
+ if (mBubbleStateListener != null) {
+ mBubbleStateListener = null;
+ setUpBubbleViewsForMode();
+ }
}
/**
@@ -645,8 +647,12 @@
/** Whether bubbles are showing in the bubble bar. */
public boolean isShowingAsBubbleBar() {
- // TODO(b/269670598): should also check that we're in gesture nav
- return BUBBLE_BAR_ENABLED && mBubblePositioner.isLargeScreen();
+ return canShowAsBubbleBar() && mBubbleStateListener != null;
+ }
+
+ /** Whether the current configuration supports showing as bubble bar. */
+ private boolean canShowAsBubbleBar() {
+ return mBubbleProperties.isBubbleBarEnabled() && mBubblePositioner.isLargeScreen();
}
/** Whether this userId belongs to the current user. */
@@ -774,12 +780,12 @@
try {
mAddedToWindowManager = true;
registerBroadcastReceiver();
- mBubbleData.getOverflow().initialize(this);
+ mBubbleData.getOverflow().initialize(this, isShowingAsBubbleBar());
// (TODO: b/273314541) some duplication in the inset listener
if (isShowingAsBubbleBar()) {
mWindowManager.addView(mLayerView, mWmLayoutParams);
mLayerView.setOnApplyWindowInsetsListener((view, windowInsets) -> {
- if (!windowInsets.equals(mWindowInsets)) {
+ if (!windowInsets.equals(mWindowInsets) && mLayerView != null) {
mWindowInsets = windowInsets;
mBubblePositioner.update();
mLayerView.onDisplaySizeChanged();
@@ -789,7 +795,7 @@
} else {
mWindowManager.addView(mStackView, mWmLayoutParams);
mStackView.setOnApplyWindowInsetsListener((view, windowInsets) -> {
- if (!windowInsets.equals(mWindowInsets)) {
+ if (!windowInsets.equals(mWindowInsets) && mStackView != null) {
mWindowInsets = windowInsets;
mBubblePositioner.update();
mStackView.onDisplaySizeChanged();
@@ -1066,9 +1072,18 @@
* Expands and selects the provided bubble as long as it already exists in the stack or the
* overflow.
*
- * This is used by external callers (launcher).
+ * <p>This is used by external callers (launcher).
*/
- public void expandStackAndSelectBubbleFromLauncher(String key) {
+ @VisibleForTesting
+ public void expandStackAndSelectBubbleFromLauncher(String key, boolean onLauncherHome) {
+ mBubblePositioner.setShowingInBubbleBar(onLauncherHome);
+
+ if (BubbleOverflow.KEY.equals(key)) {
+ mBubbleData.setSelectedBubbleFromLauncher(mBubbleData.getOverflow());
+ mLayerView.showExpandedView(mBubbleData.getOverflow());
+ return;
+ }
+
Bubble b = mBubbleData.getAnyBubbleWithkey(key);
if (b == null) {
return;
@@ -1267,7 +1282,9 @@
return;
}
mOverflowDataLoadNeeded = false;
- mDataRepository.loadBubbles(mCurrentUserId, (bubbles) -> {
+ List<UserInfo> users = mUserManager.getAliveUsers();
+ List<Integer> userIds = users.stream().map(userInfo -> userInfo.id).toList();
+ mDataRepository.loadBubbles(mCurrentUserId, userIds, (bubbles) -> {
bubbles.forEach(bubble -> {
if (mBubbleData.hasAnyBubbleWithKey(bubble.getKey())) {
// if the bubble is already active, there's no need to push it to overflow
@@ -1286,6 +1303,50 @@
});
}
+ void setUpBubbleViewsForMode() {
+ mBubbleViewCallback = isShowingAsBubbleBar()
+ ? mBubbleBarViewCallback
+ : mBubbleStackViewCallback;
+
+ // reset the overflow so that it can be re-added later if needed.
+ if (mStackView != null) {
+ mStackView.resetOverflowView();
+ mStackView.removeAllViews();
+ }
+ // cleanup existing bubble views so they can be recreated later if needed.
+ mBubbleData.getBubbles().forEach(Bubble::cleanupViews);
+
+ // remove the current bubble container from window manager, null it out, and create a new
+ // container based on the current mode.
+ removeFromWindowManagerMaybe();
+ mLayerView = null;
+ mStackView = null;
+ ensureBubbleViewsAndWindowCreated();
+
+ // inflate bubble views
+ BubbleViewInfoTask.Callback callback = null;
+ if (!isShowingAsBubbleBar()) {
+ callback = b -> {
+ if (mStackView != null) {
+ mStackView.addBubble(b);
+ mStackView.setSelectedBubble(b);
+ } else {
+ Log.w(TAG, "Tried to add a bubble to the stack but the stack is null");
+ }
+ };
+ }
+ for (int i = mBubbleData.getBubbles().size() - 1; i >= 0; i--) {
+ Bubble bubble = mBubbleData.getBubbles().get(i);
+ bubble.inflate(callback,
+ mContext,
+ this,
+ mStackView,
+ mLayerView,
+ mBubbleIconFactory,
+ false /* skipInflation */);
+ }
+ }
+
/**
* Adds or updates a bubble associated with the provided notification entry.
*
@@ -1746,7 +1807,7 @@
// Update the cached state for queries from SysUI
mImpl.mCachedState.update(update);
- if (isShowingAsBubbleBar() && mBubbleStateListener != null) {
+ if (isShowingAsBubbleBar()) {
BubbleBarUpdate bubbleBarUpdate = update.toBubbleBarUpdate();
// Some updates aren't relevant to the bubble bar so check first.
if (bubbleBarUpdate.anythingChanged()) {
@@ -1868,10 +1929,17 @@
}
@VisibleForTesting
+ @Nullable
public BubbleStackView getStackView() {
return mStackView;
}
+ @VisibleForTesting
+ @Nullable
+ public BubbleBarLayerView getLayerView() {
+ return mLayerView;
+ }
+
/**
* Check if notification panel is in an expanded state.
* Makes a call to System UI process and delivers the result via {@code callback} on the
@@ -2010,22 +2078,18 @@
@Override
public void registerBubbleListener(IBubblesListener listener) {
- mMainExecutor.execute(() -> {
- mListener.register(listener);
- });
+ mMainExecutor.execute(() -> mListener.register(listener));
}
@Override
public void unregisterBubbleListener(IBubblesListener listener) {
- mMainExecutor.execute(() -> mListener.unregister());
+ mMainExecutor.execute(mListener::unregister);
}
@Override
public void showBubble(String key, boolean onLauncherHome) {
- mMainExecutor.execute(() -> {
- mBubblePositioner.setShowingInBubbleBar(onLauncherHome);
- mController.expandStackAndSelectBubbleFromLauncher(key);
- });
+ mMainExecutor.execute(
+ () -> mController.expandStackAndSelectBubbleFromLauncher(key, onLauncherHome));
}
@Override
@@ -2037,11 +2101,6 @@
public void collapseBubbles() {
mMainExecutor.execute(() -> mController.collapseStack());
}
-
- @Override
- public void onTaskbarStateChanged(int newState) {
- // TODO (b/269670598)
- }
}
private class BubblesImpl implements Bubbles {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleDataRepository.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleDataRepository.kt
index e37c785..896a334 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleDataRepository.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleDataRepository.kt
@@ -17,7 +17,6 @@
import android.annotation.SuppressLint
import android.annotation.UserIdInt
-import android.content.Context
import android.content.pm.LauncherApps
import android.content.pm.LauncherApps.ShortcutQuery.FLAG_MATCH_CACHED
import android.content.pm.LauncherApps.ShortcutQuery.FLAG_MATCH_DYNAMIC
@@ -25,6 +24,8 @@
import android.content.pm.UserInfo
import android.os.UserHandle
import android.util.Log
+import android.util.SparseArray
+import com.android.internal.annotations.VisibleForTesting
import com.android.wm.shell.bubbles.Bubbles.BubbleMetadataFlagListener
import com.android.wm.shell.bubbles.storage.BubbleEntity
import com.android.wm.shell.bubbles.storage.BubblePersistentRepository
@@ -33,19 +34,19 @@
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
+import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.cancelAndJoin
import kotlinx.coroutines.launch
import kotlinx.coroutines.yield
-internal class BubbleDataRepository(
- context: Context,
+class BubbleDataRepository(
private val launcherApps: LauncherApps,
- private val mainExecutor: ShellExecutor
+ private val mainExecutor: ShellExecutor,
+ private val persistentRepository: BubblePersistentRepository,
) {
private val volatileRepository = BubbleVolatileRepository(launcherApps)
- private val persistentRepository = BubblePersistentRepository(context)
- private val ioScope = CoroutineScope(Dispatchers.IO)
+ private val coroutineScope = CoroutineScope(Dispatchers.IO + SupervisorJob())
private var job: Job? = null
// For use in Bubble construction.
@@ -98,6 +99,43 @@
if (volatileRepository.sanitizeBubbles(userIds)) persistToDisk()
}
+ /**
+ * Removes all entities that don't have a user in the activeUsers list, if any entities were
+ * removed it persists the new list to disk.
+ */
+ private fun filterForActiveUsersAndPersist(
+ activeUsers: List<Int>,
+ entitiesByUser: SparseArray<List<BubbleEntity>>
+ ): SparseArray<List<BubbleEntity>> {
+ val validEntitiesByUser = SparseArray<List<BubbleEntity>>()
+ var entitiesChanged = false
+ for (i in 0 until entitiesByUser.size()) {
+ val parentUserId = entitiesByUser.keyAt(i)
+ if (activeUsers.contains(parentUserId)) {
+ val validEntities = mutableListOf<BubbleEntity>()
+ // Check if each of the bubbles in the top-level user still has a valid user
+ // as it could belong to a profile and have a different id from the parent.
+ for (entity in entitiesByUser.get(parentUserId)) {
+ if (activeUsers.contains(entity.userId)) {
+ validEntities.add(entity)
+ } else {
+ entitiesChanged = true
+ }
+ }
+ if (validEntities.isNotEmpty()) {
+ validEntitiesByUser.put(parentUserId, validEntities)
+ }
+ } else {
+ entitiesChanged = true
+ }
+ }
+ if (entitiesChanged) {
+ persistToDisk(validEntitiesByUser)
+ return validEntitiesByUser
+ }
+ return entitiesByUser
+ }
+
private fun transform(bubbles: List<Bubble>): List<BubbleEntity> {
return bubbles.mapNotNull { b ->
BubbleEntity(
@@ -129,15 +167,17 @@
* Job C resumes and reaches yield() and is then cancelled
* Job D resumes and performs another blocking I/O
*/
- private fun persistToDisk() {
+ private fun persistToDisk(
+ entitiesByUser: SparseArray<List<BubbleEntity>> = volatileRepository.bubbles
+ ) {
val prev = job
- job = ioScope.launch {
+ job = coroutineScope.launch {
// if there was an ongoing disk I/O operation, they can be cancelled
prev?.cancelAndJoin()
// check for cancellation before disk I/O
yield()
// save to disk
- persistentRepository.persistsToDisk(volatileRepository.bubbles)
+ persistentRepository.persistsToDisk(entitiesByUser)
}
}
@@ -148,7 +188,12 @@
* bubbles.
*/
@SuppressLint("WrongConstant")
- fun loadBubbles(userId: Int, cb: (List<Bubble>) -> Unit) = ioScope.launch {
+ @VisibleForTesting
+ fun loadBubbles(
+ userId: Int,
+ currentUsers: List<Int>,
+ cb: (List<Bubble>) -> Unit
+ ) = coroutineScope.launch {
/**
* Load BubbleEntity from disk.
* e.g.
@@ -159,7 +204,12 @@
* ]
*/
val entitiesByUser = persistentRepository.readFromDisk()
- val entities = entitiesByUser.get(userId) ?: return@launch
+
+ // Before doing anything, validate that the entities we loaded are valid & have an existing
+ // user.
+ val validEntitiesByUser = filterForActiveUsersAndPersist(currentUsers, entitiesByUser)
+
+ val entities = validEntitiesByUser.get(userId) ?: return@launch
volatileRepository.addBubbles(userId, entities)
/**
* Extract userId/packageName from these entities.
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java
index e1a3f3a..6718565 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java
@@ -948,9 +948,9 @@
mTaskView.onLocationChanged();
}
if (mIsOverflow) {
- post(() -> {
- mOverflowView.show();
- });
+ // post this to the looper so that the view has a chance to be laid out before it can
+ // calculate row and column sizes correctly.
+ post(() -> mOverflowView.show());
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflow.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflow.kt
index df7f5b4..df19757 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflow.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflow.kt
@@ -44,6 +44,7 @@
private val inflater: LayoutInflater = LayoutInflater.from(context)
private var expandedView: BubbleExpandedView?
+ private var bubbleBarExpandedView: BubbleBarExpandedView? = null
private var overflowBtn: BadgedImageView?
init {
@@ -53,19 +54,26 @@
}
/** Call before use and again if cleanUpExpandedState was called. */
- fun initialize(controller: BubbleController) {
- createExpandedView()
- getExpandedView()?.initialize(controller, controller.stackView, true /* isOverflow */)
+ fun initialize(controller: BubbleController, forBubbleBar: Boolean) {
+ if (forBubbleBar) {
+ createBubbleBarExpandedView().initialize(controller, true /* isOverflow */)
+ } else {
+ createExpandedView()
+ .initialize(controller, controller.stackView, true /* isOverflow */)
+ }
}
fun cleanUpExpandedState() {
expandedView?.cleanUpExpandedState()
expandedView = null
+ bubbleBarExpandedView?.cleanUpExpandedState()
+ bubbleBarExpandedView = null
}
fun update() {
updateResources()
getExpandedView()?.applyThemeAttrs()
+ getBubbleBarExpandedView()?.applyThemeAttrs()
// Apply inset and new style to fresh icon drawable.
getIconView()?.setIconImageResource(R.drawable.bubble_ic_overflow_button)
updateBtnTheme()
@@ -151,26 +159,39 @@
overflowBtn?.updateDotVisibility(true /* animate */)
}
- fun createExpandedView(): BubbleExpandedView? {
- expandedView =
+ /** Creates the expanded view for bubbles showing in the stack view. */
+ private fun createExpandedView(): BubbleExpandedView {
+ val view =
inflater.inflate(
R.layout.bubble_expanded_view,
null /* root */,
false /* attachToRoot */
) as BubbleExpandedView
- expandedView?.applyThemeAttrs()
+ view.applyThemeAttrs()
+ expandedView = view
updateResources()
- return expandedView
+ return view
}
override fun getExpandedView(): BubbleExpandedView? {
return expandedView
}
- override fun getBubbleBarExpandedView(): BubbleBarExpandedView? {
- return null
+ /** Creates the expanded view for bubbles showing in the bubble bar. */
+ private fun createBubbleBarExpandedView(): BubbleBarExpandedView {
+ val view =
+ inflater.inflate(
+ R.layout.bubble_bar_expanded_view,
+ null, /* root */
+ false /* attachToRoot*/
+ ) as BubbleBarExpandedView
+ view.applyThemeAttrs()
+ bubbleBarExpandedView = view
+ return view
}
+ override fun getBubbleBarExpandedView(): BubbleBarExpandedView? = bubbleBarExpandedView
+
override fun getDotColor(): Int {
return dotColor
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java
index d101b0c..cb08f93 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java
@@ -732,17 +732,25 @@
/**
* How wide the expanded view should be when showing from the bubble bar.
*/
- public int getExpandedViewWidthForBubbleBar() {
- return mExpandedViewLargeScreenWidth;
+ public int getExpandedViewWidthForBubbleBar(boolean isOverflow) {
+ return isOverflow ? mOverflowWidth : mExpandedViewLargeScreenWidth;
}
/**
* How tall the expanded view should be when showing from the bubble bar.
*/
- public int getExpandedViewHeightForBubbleBar() {
+ public int getExpandedViewHeightForBubbleBar(boolean isOverflow) {
+ return isOverflow
+ ? mOverflowHeight
+ : getExpandedViewBottomForBubbleBar() - mInsets.top - mExpandedViewPadding;
+ }
+
+ /** The bottom position of the expanded view when showing above the bubble bar. */
+ public int getExpandedViewBottomForBubbleBar() {
return getAvailableRect().height()
+ + mInsets.top
- mBubbleBarSize
- - mExpandedViewPadding * 2
+ - mExpandedViewPadding
- getBubbleBarHomeAdjustment();
}
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 9860b07..282db9e 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
@@ -309,6 +309,7 @@
String bubblesOnScreen = BubbleDebugConfig.formatBubblesString(
getBubblesOnScreen(), getExpandedBubble());
+ pw.print(" stack visibility : "); pw.println(getVisibility());
pw.print(" bubbles on screen: "); pw.println(bubblesOnScreen);
pw.print(" gestureInProgress: "); pw.println(mIsGestureInProgress);
pw.print(" showingDismiss: "); pw.println(mDismissView.isShowing());
@@ -970,6 +971,8 @@
mBubbleContainer.bringToFront();
mBubbleOverflow = mBubbleData.getOverflow();
+
+ resetOverflowView();
mBubbleContainer.addView(mBubbleOverflow.getIconView(),
mBubbleContainer.getChildCount() /* index */,
new FrameLayout.LayoutParams(mPositioner.getBubbleSize(),
@@ -1497,9 +1500,6 @@
getViewTreeObserver().removeOnPreDrawListener(mViewUpdater);
getViewTreeObserver().removeOnDrawListener(mSystemGestureExcludeUpdater);
getViewTreeObserver().removeOnComputeInternalInsetsListener(this);
- if (mBubbleOverflow != null) {
- mBubbleOverflow.cleanUpExpandedState();
- }
}
@Override
@@ -3414,6 +3414,19 @@
}
/**
+ * Removes the overflow view from the stack. This allows for re-adding it later to a new stack.
+ */
+ void resetOverflowView() {
+ BadgedImageView overflowIcon = mBubbleOverflow.getIconView();
+ if (overflowIcon != null) {
+ PhysicsAnimationLayout parent = (PhysicsAnimationLayout) overflowIcon.getParent();
+ if (parent != null) {
+ parent.removeViewNoAnimation(overflowIcon);
+ }
+ }
+ }
+
+ /**
* Holds some commonly queried information about the stack.
*/
public static class StackViewState {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewInfoTask.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewInfoTask.java
index 80e2999..66e6930 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewInfoTask.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewInfoTask.java
@@ -176,44 +176,14 @@
LayoutInflater inflater = LayoutInflater.from(c);
info.bubbleBarExpandedView = (BubbleBarExpandedView) inflater.inflate(
R.layout.bubble_bar_expanded_view, layerView, false /* attachToRoot */);
- info.bubbleBarExpandedView.initialize(controller);
+ info.bubbleBarExpandedView.initialize(controller, false /* isOverflow */);
}
- if (b.getShortcutInfo() != null) {
- info.shortcutInfo = b.getShortcutInfo();
- }
-
- // App name & app icon
- PackageManager pm = BubbleController.getPackageManagerForUser(c,
- b.getUser().getIdentifier());
- ApplicationInfo appInfo;
- Drawable badgedIcon;
- Drawable appIcon;
- try {
- appInfo = pm.getApplicationInfo(
- b.getPackageName(),
- PackageManager.MATCH_UNINSTALLED_PACKAGES
- | PackageManager.MATCH_DISABLED_COMPONENTS
- | PackageManager.MATCH_DIRECT_BOOT_UNAWARE
- | PackageManager.MATCH_DIRECT_BOOT_AWARE);
- if (appInfo != null) {
- info.appName = String.valueOf(pm.getApplicationLabel(appInfo));
- }
- appIcon = pm.getApplicationIcon(b.getPackageName());
- badgedIcon = pm.getUserBadgedIcon(appIcon, b.getUser());
- } catch (PackageManager.NameNotFoundException exception) {
- // If we can't find package... don't think we should show the bubble.
- Log.w(TAG, "Unable to find package: " + b.getPackageName());
+ if (!populateCommonInfo(info, c, b, iconFactory)) {
+ // if we failed to update common fields return null
return null;
}
- info.rawBadgeBitmap = iconFactory.getBadgeBitmap(badgedIcon, false).icon;
- float[] bubbleBitmapScale = new float[1];
- info.bubbleBitmap = iconFactory.getBubbleBitmap(
- iconFactory.getBubbleDrawable(c, info.shortcutInfo,
- b.getIcon()), bubbleBitmapScale);
-
-
return info;
}
@@ -236,66 +206,11 @@
info.expandedView.initialize(controller, stackView, false /* isOverflow */);
}
- if (b.getShortcutInfo() != null) {
- info.shortcutInfo = b.getShortcutInfo();
- }
-
- // App name & app icon
- PackageManager pm = BubbleController.getPackageManagerForUser(c,
- b.getUser().getIdentifier());
- ApplicationInfo appInfo;
- Drawable badgedIcon;
- Drawable appIcon;
- try {
- appInfo = pm.getApplicationInfo(
- b.getPackageName(),
- PackageManager.MATCH_UNINSTALLED_PACKAGES
- | PackageManager.MATCH_DISABLED_COMPONENTS
- | PackageManager.MATCH_DIRECT_BOOT_UNAWARE
- | PackageManager.MATCH_DIRECT_BOOT_AWARE);
- if (appInfo != null) {
- info.appName = String.valueOf(pm.getApplicationLabel(appInfo));
- }
- appIcon = pm.getApplicationIcon(b.getPackageName());
- badgedIcon = pm.getUserBadgedIcon(appIcon, b.getUser());
- } catch (PackageManager.NameNotFoundException exception) {
- // If we can't find package... don't think we should show the bubble.
- Log.w(TAG, "Unable to find package: " + b.getPackageName());
+ if (!populateCommonInfo(info, c, b, iconFactory)) {
+ // if we failed to update common fields return null
return null;
}
- // Badged bubble image
- Drawable bubbleDrawable = iconFactory.getBubbleDrawable(c, info.shortcutInfo,
- b.getIcon());
- if (bubbleDrawable == null) {
- // Default to app icon
- bubbleDrawable = appIcon;
- }
-
- BitmapInfo badgeBitmapInfo = iconFactory.getBadgeBitmap(badgedIcon,
- b.isImportantConversation());
- info.badgeBitmap = badgeBitmapInfo.icon;
- // Raw badge bitmap never includes the important conversation ring
- info.rawBadgeBitmap = b.isImportantConversation()
- ? iconFactory.getBadgeBitmap(badgedIcon, false).icon
- : badgeBitmapInfo.icon;
-
- float[] bubbleBitmapScale = new float[1];
- info.bubbleBitmap = iconFactory.getBubbleBitmap(bubbleDrawable, bubbleBitmapScale);
-
- // Dot color & placement
- Path iconPath = PathParser.createPathFromPathData(
- c.getResources().getString(com.android.internal.R.string.config_icon_mask));
- Matrix matrix = new Matrix();
- float scale = bubbleBitmapScale[0];
- float radius = DEFAULT_PATH_SIZE / 2f;
- matrix.setScale(scale /* x scale */, scale /* y scale */, radius /* pivot x */,
- radius /* pivot y */);
- iconPath.transform(matrix);
- info.dotPath = iconPath;
- info.dotColor = ColorUtils.blendARGB(badgeBitmapInfo.color,
- Color.WHITE, WHITE_SCRIM_ALPHA);
-
// Flyout
info.flyoutMessage = b.getFlyoutMessage();
if (info.flyoutMessage != null) {
@@ -306,6 +221,75 @@
}
}
+ /**
+ * Modifies the given {@code info} object and populates common fields in it.
+ *
+ * <p>This method returns {@code true} if the update was successful and {@code false} otherwise.
+ * Callers should assume that the info object is unusable if the update was unsuccessful.
+ */
+ private static boolean populateCommonInfo(
+ BubbleViewInfo info, Context c, Bubble b, BubbleIconFactory iconFactory) {
+ if (b.getShortcutInfo() != null) {
+ info.shortcutInfo = b.getShortcutInfo();
+ }
+
+ // App name & app icon
+ PackageManager pm = BubbleController.getPackageManagerForUser(c,
+ b.getUser().getIdentifier());
+ ApplicationInfo appInfo;
+ Drawable badgedIcon;
+ Drawable appIcon;
+ try {
+ appInfo = pm.getApplicationInfo(
+ b.getPackageName(),
+ PackageManager.MATCH_UNINSTALLED_PACKAGES
+ | PackageManager.MATCH_DISABLED_COMPONENTS
+ | PackageManager.MATCH_DIRECT_BOOT_UNAWARE
+ | PackageManager.MATCH_DIRECT_BOOT_AWARE);
+ if (appInfo != null) {
+ info.appName = String.valueOf(pm.getApplicationLabel(appInfo));
+ }
+ appIcon = pm.getApplicationIcon(b.getPackageName());
+ badgedIcon = pm.getUserBadgedIcon(appIcon, b.getUser());
+ } catch (PackageManager.NameNotFoundException exception) {
+ // If we can't find package... don't think we should show the bubble.
+ Log.w(TAG, "Unable to find package: " + b.getPackageName());
+ return false;
+ }
+
+ // Badged bubble image
+ Drawable bubbleDrawable = iconFactory.getBubbleDrawable(c, info.shortcutInfo, b.getIcon());
+ if (bubbleDrawable == null) {
+ // Default to app icon
+ bubbleDrawable = appIcon;
+ }
+
+ BitmapInfo badgeBitmapInfo = iconFactory.getBadgeBitmap(badgedIcon,
+ b.isImportantConversation());
+ info.badgeBitmap = badgeBitmapInfo.icon;
+ // Raw badge bitmap never includes the important conversation ring
+ info.rawBadgeBitmap = b.isImportantConversation() // is this needed for bar?
+ ? iconFactory.getBadgeBitmap(badgedIcon, false).icon
+ : badgeBitmapInfo.icon;
+
+ float[] bubbleBitmapScale = new float[1];
+ info.bubbleBitmap = iconFactory.getBubbleBitmap(bubbleDrawable, bubbleBitmapScale);
+
+ // Dot color & placement
+ Path iconPath = PathParser.createPathFromPathData(
+ c.getResources().getString(com.android.internal.R.string.config_icon_mask));
+ Matrix matrix = new Matrix();
+ float scale = bubbleBitmapScale[0];
+ float radius = DEFAULT_PATH_SIZE / 2f;
+ matrix.setScale(scale /* x scale */, scale /* y scale */, radius /* pivot x */,
+ radius /* pivot y */);
+ iconPath.transform(matrix);
+ info.dotPath = iconPath;
+ info.dotColor = ColorUtils.blendARGB(badgeBitmapInfo.color,
+ Color.WHITE, WHITE_SCRIM_ALPHA);
+ return true;
+ }
+
@Nullable
static Drawable loadSenderAvatar(@NonNull final Context context, @Nullable final Icon icon) {
Objects.requireNonNull(context);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java
index 4d329dd..759246e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java
@@ -60,9 +60,11 @@
DISMISS_NOTIF_CANCEL, DISMISS_ACCESSIBILITY_ACTION, DISMISS_NO_LONGER_BUBBLE,
DISMISS_USER_CHANGED, DISMISS_GROUP_CANCELLED, DISMISS_INVALID_INTENT,
DISMISS_OVERFLOW_MAX_REACHED, DISMISS_SHORTCUT_REMOVED, DISMISS_PACKAGE_REMOVED,
- DISMISS_NO_BUBBLE_UP, DISMISS_RELOAD_FROM_DISK, DISMISS_USER_REMOVED})
+ DISMISS_NO_BUBBLE_UP, DISMISS_RELOAD_FROM_DISK, DISMISS_USER_REMOVED,
+ DISMISS_SWITCH_TO_STACK})
@Target({FIELD, LOCAL_VARIABLE, PARAMETER})
- @interface DismissReason {}
+ @interface DismissReason {
+ }
int DISMISS_USER_GESTURE = 1;
int DISMISS_AGED = 2;
@@ -80,6 +82,7 @@
int DISMISS_NO_BUBBLE_UP = 14;
int DISMISS_RELOAD_FROM_DISK = 15;
int DISMISS_USER_REMOVED = 16;
+ int DISMISS_SWITCH_TO_STACK = 17;
/** Returns a binder that can be passed to an external process to manipulate Bubbles. */
default IBubbles createExternalInterface() {
@@ -120,8 +123,8 @@
/**
* This method has different behavior depending on:
- * - if an app bubble exists
- * - if an app bubble is expanded
+ * - if an app bubble exists
+ * - if an app bubble is expanded
*
* If no app bubble exists, this will add and expand a bubble with the provided intent. The
* intent must be explicit (i.e. include a package name or fully qualified component class name)
@@ -135,13 +138,13 @@
* the bubble or bubble stack.
*
* Some notes:
- * - Only one app bubble is supported at a time, regardless of users. Multi-users support is
- * tracked in b/273533235.
- * - Calling this method with a different intent than the existing app bubble will do nothing
+ * - Only one app bubble is supported at a time, regardless of users. Multi-users support is
+ * tracked in b/273533235.
+ * - Calling this method with a different intent than the existing app bubble will do nothing
*
* @param intent the intent to display in the bubble expanded view.
- * @param user the {@link UserHandle} of the user to start this activity for.
- * @param icon the {@link Icon} to use for the bubble view.
+ * @param user the {@link UserHandle} of the user to start this activity for.
+ * @param icon the {@link Icon} to use for the bubble view.
*/
void showOrHideAppBubble(Intent intent, UserHandle user, @Nullable Icon icon);
@@ -172,13 +175,12 @@
* {@link Bubble#setSuppressNotification}. For the case of suppressed summaries, we also add
* {@link BubbleData#addSummaryToSuppress}.
*
- * @param entry the notification of the BubbleEntry should be removed.
- * @param children the list of child notification of the BubbleEntry from 1st param entry,
- * this will be null if entry does have no children.
+ * @param entry the notification of the BubbleEntry should be removed.
+ * @param children the list of child notification of the BubbleEntry from 1st param entry,
+ * this will be null if entry does have no children.
* @param removeCallback the remove callback for SystemUI side to remove notification, the int
* number should be list position of children list and use -1 for
* removing the parent notification.
- *
* @return true if we want to intercept the dismissal of the entry, else false.
*/
boolean handleDismissalInterception(BubbleEntry entry, @Nullable List<BubbleEntry> children,
@@ -200,9 +202,9 @@
/**
* Called when new notification entry updated.
*
- * @param entry the {@link BubbleEntry} by the notification.
+ * @param entry the {@link BubbleEntry} by the notification.
* @param shouldBubbleUp {@code true} if this notification should bubble up.
- * @param fromSystem {@code true} if this update is from NotificationManagerService.
+ * @param fromSystem {@code true} if this update is from NotificationManagerService.
*/
void onEntryUpdated(BubbleEntry entry, boolean shouldBubbleUp, boolean fromSystem);
@@ -218,7 +220,7 @@
* filtering and sorting. This is used to dismiss or create bubbles based on changes in
* permissions on the notification channel or the global setting.
*
- * @param rankingMap the updated ranking map from NotificationListenerService
+ * @param rankingMap the updated ranking map from NotificationListenerService
* @param entryDataByKey a map of ranking key to bubble entry and whether the entry should
* bubble up
*/
@@ -230,9 +232,9 @@
* Called when a notification channel is modified, in response to
* {@link NotificationListenerService#onNotificationChannelModified}.
*
- * @param pkg the package the notification channel belongs to.
- * @param user the user the notification channel belongs to.
- * @param channel the channel being modified.
+ * @param pkg the package the notification channel belongs to.
+ * @param user the user the notification channel belongs to.
+ * @param channel the channel being modified.
* @param modificationType the type of modification that occurred to the channel.
*/
void onNotificationChannelModified(
@@ -300,7 +302,7 @@
* Called when the expansion state of the bubble stack changes.
*
* @param isExpanding whether it's expanding or collapsing
- * @param key the notification key associated with bubble being expanded
+ * @param key the notification key associated with bubble being expanded
*/
void onBubbleExpandChanged(boolean isExpanding, String key);
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/IBubbles.aidl b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/IBubbles.aidl
index 862e818..20ae846 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/IBubbles.aidl
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/IBubbles.aidl
@@ -35,6 +35,4 @@
oneway void collapseBubbles() = 5;
- oneway void onTaskbarStateChanged(in int newState) = 6;
-
}
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/PhysicsAnimationLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/PhysicsAnimationLayout.java
index beb1c5f..f3cc514 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/PhysicsAnimationLayout.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/PhysicsAnimationLayout.java
@@ -327,6 +327,12 @@
addViewInternal(child, index, params, false /* isReorder */);
}
+ /** Removes the child view immediately. */
+ public void removeViewNoAnimation(View view) {
+ super.removeView(view);
+ view.setTag(R.id.physics_animator_tag, null);
+ }
+
@Override
public void removeView(View view) {
if (mController != null) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarAnimationHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarAnimationHelper.java
index 23f65f9..f729d02 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarAnimationHelper.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarAnimationHelper.java
@@ -27,6 +27,7 @@
import com.android.wm.shell.animation.Interpolators;
import com.android.wm.shell.animation.PhysicsAnimator;
+import com.android.wm.shell.bubbles.BubbleOverflow;
import com.android.wm.shell.bubbles.BubblePositioner;
import com.android.wm.shell.bubbles.BubbleViewProvider;
import com.android.wm.shell.bubbles.animation.AnimatableScaleMatrix;
@@ -215,9 +216,10 @@
}
BubbleBarExpandedView bbev = mExpandedBubble.getBubbleBarExpandedView();
+ boolean isOverflowExpanded = mExpandedBubble.getKey().equals(BubbleOverflow.KEY);
final int padding = mPositioner.getBubbleBarExpandedViewPadding();
- final int width = mPositioner.getExpandedViewWidthForBubbleBar();
- final int height = mPositioner.getExpandedViewHeightForBubbleBar();
+ final int width = mPositioner.getExpandedViewWidthForBubbleBar(isOverflowExpanded);
+ final int height = mPositioner.getExpandedViewHeightForBubbleBar(isOverflowExpanded);
FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) bbev.getLayoutParams();
lp.width = width;
lp.height = height;
@@ -227,7 +229,8 @@
} else {
bbev.setX(mPositioner.getAvailableRect().width() - width - padding);
}
- bbev.setY(mPositioner.getInsets().top + padding);
+ bbev.setY(mPositioner.getExpandedViewBottomForBubbleBar() - height);
bbev.updateLocation();
+ bbev.maybeShowOverflow();
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedView.java
index 32ed102..396aa0e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedView.java
@@ -25,6 +25,7 @@
import android.graphics.Outline;
import android.graphics.Rect;
import android.util.AttributeSet;
+import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewOutlineProvider;
import android.widget.FrameLayout;
@@ -33,6 +34,7 @@
import com.android.wm.shell.R;
import com.android.wm.shell.bubbles.Bubble;
import com.android.wm.shell.bubbles.BubbleController;
+import com.android.wm.shell.bubbles.BubbleOverflowContainerView;
import com.android.wm.shell.bubbles.BubbleTaskViewHelper;
import com.android.wm.shell.bubbles.Bubbles;
import com.android.wm.shell.taskview.TaskView;
@@ -51,6 +53,7 @@
private static final int INVALID_TASK_ID = -1;
private BubbleController mController;
+ private boolean mIsOverflow;
private BubbleTaskViewHelper mBubbleTaskViewHelper;
private BubbleBarMenuViewController mMenuViewController;
private @Nullable Supplier<Rect> mLayerBoundsSupplier;
@@ -58,6 +61,7 @@
private BubbleBarHandleView mHandleView = new BubbleBarHandleView(getContext());
private @Nullable TaskView mTaskView;
+ private @Nullable BubbleOverflowContainerView mOverflowView;
private int mHandleHeight;
private int mBackgroundColor;
@@ -114,15 +118,25 @@
}
/** Set the BubbleController on the view, must be called before doing anything else. */
- public void initialize(BubbleController controller) {
+ public void initialize(BubbleController controller, boolean isOverflow) {
mController = controller;
- mBubbleTaskViewHelper = new BubbleTaskViewHelper(mContext, mController,
- /* listener= */ this,
- /* viewParent= */ this);
- mTaskView = mBubbleTaskViewHelper.getTaskView();
- addView(mTaskView);
- mTaskView.setEnableSurfaceClipping(true);
- mTaskView.setCornerRadius(mCornerRadius);
+ mIsOverflow = isOverflow;
+
+ if (mIsOverflow) {
+ mOverflowView = (BubbleOverflowContainerView) LayoutInflater.from(getContext()).inflate(
+ R.layout.bubble_overflow_container, null /* root */);
+ mOverflowView.setBubbleController(mController);
+ addView(mOverflowView);
+ } else {
+
+ mBubbleTaskViewHelper = new BubbleTaskViewHelper(mContext, mController,
+ /* listener= */ this,
+ /* viewParent= */ this);
+ mTaskView = mBubbleTaskViewHelper.getTaskView();
+ addView(mTaskView);
+ mTaskView.setEnableSurfaceClipping(true);
+ mTaskView.setCornerRadius(mCornerRadius);
+ }
mMenuViewController = new BubbleBarMenuViewController(mContext, this);
mMenuViewController.setListener(new BubbleBarMenuViewController.Listener() {
@Override
@@ -156,7 +170,8 @@
}
// TODO (b/275087636): call this when theme/config changes
- void applyThemeAttrs() {
+ /** Updates the view based on the current theme. */
+ public void applyThemeAttrs() {
boolean supportsRoundedCorners = ScreenDecorationsUtils.supportsRoundedCornersOnWindows(
mContext.getResources());
final TypedArray ta = mContext.obtainStyledAttributes(new int[]{
@@ -257,8 +272,18 @@
* Call when the location or size of the view has changed to update TaskView.
*/
public void updateLocation() {
- if (mTaskView == null) return;
- mTaskView.onLocationChanged();
+ if (mTaskView != null) {
+ mTaskView.onLocationChanged();
+ }
+ }
+
+ /** Shows the expanded view for the overflow if it exists. */
+ void maybeShowOverflow() {
+ if (mOverflowView != null) {
+ // post this to the looper so that the view has a chance to be laid out before it can
+ // calculate row and column sizes correctly.
+ post(() -> mOverflowView.show());
+ }
}
/** Sets the alpha of the task view. */
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerView.java
index bc622e7..d20b33e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerView.java
@@ -29,6 +29,7 @@
import android.widget.FrameLayout;
import com.android.wm.shell.bubbles.BubbleController;
+import com.android.wm.shell.bubbles.BubbleOverflow;
import com.android.wm.shell.bubbles.BubblePositioner;
import com.android.wm.shell.bubbles.BubbleViewProvider;
@@ -146,8 +147,9 @@
if (mExpandedView == null) {
mExpandedBubble = b;
mExpandedView = expandedView;
- final int width = mPositioner.getExpandedViewWidthForBubbleBar();
- final int height = mPositioner.getExpandedViewHeightForBubbleBar();
+ boolean isOverflowExpanded = b.getKey().equals(BubbleOverflow.KEY);
+ final int width = mPositioner.getExpandedViewWidthForBubbleBar(isOverflowExpanded);
+ final int height = mPositioner.getExpandedViewHeightForBubbleBar(isOverflowExpanded);
mExpandedView.setVisibility(GONE);
mExpandedView.setUnBubbleConversationCallback(mUnBubbleConversationCallback);
mExpandedView.setLayerBoundsSupplier(() -> new Rect(0, 0, getWidth(), getHeight()));
@@ -156,6 +158,7 @@
mUnBubbleConversationCallback.accept(bubbleKey);
}
});
+ mExpandedView.setY(mPositioner.getExpandedViewBottomForBubbleBar() - height);
addView(mExpandedView, new FrameLayout.LayoutParams(width, height));
}
@@ -184,9 +187,10 @@
/** Updates the expanded view size and position. */
private void updateExpandedView() {
if (mExpandedView == null) return;
+ boolean isOverflowExpanded = mExpandedBubble.getKey().equals(BubbleOverflow.KEY);
final int padding = mPositioner.getBubbleBarExpandedViewPadding();
- final int width = mPositioner.getExpandedViewWidthForBubbleBar();
- final int height = mPositioner.getExpandedViewHeightForBubbleBar();
+ final int width = mPositioner.getExpandedViewWidthForBubbleBar(isOverflowExpanded);
+ final int height = mPositioner.getExpandedViewHeightForBubbleBar(isOverflowExpanded);
FrameLayout.LayoutParams lp = (LayoutParams) mExpandedView.getLayoutParams();
lp.width = width;
lp.height = height;
@@ -196,7 +200,7 @@
} else {
mExpandedView.setX(mPositioner.getAvailableRect().width() - width - padding);
}
- mExpandedView.setY(mPositioner.getInsets().top + padding);
+ mExpandedView.setY(mPositioner.getExpandedViewBottomForBubbleBar() - height);
mExpandedView.updateLocation();
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/properties/BubbleProperties.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/properties/BubbleProperties.kt
new file mode 100644
index 0000000..85aaa8e
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/properties/BubbleProperties.kt
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.bubbles.properties
+
+/**
+ * An interface for exposing bubble properties via flags which can be controlled easily in tests.
+ */
+interface BubbleProperties {
+ /**
+ * Whether bubble bar is enabled.
+ *
+ * When this is `true`, depending on additional factors, such as screen size and taskbar state,
+ * bubbles will be displayed in the bubble bar instead of floating.
+ *
+ * When this is `false`, bubbles will be floating.
+ */
+ val isBubbleBarEnabled: Boolean
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/properties/ProdBubbleProperties.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/properties/ProdBubbleProperties.kt
new file mode 100644
index 0000000..9d8b9a6
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/properties/ProdBubbleProperties.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.bubbles.properties
+
+import android.os.SystemProperties
+
+/** Provides bubble properties in production. */
+object ProdBubbleProperties : BubbleProperties {
+
+ // TODO(b/256873975) Should use proper flag when available to shell/launcher
+ override val isBubbleBarEnabled =
+ SystemProperties.getBoolean("persist.wm.debug.bubble_bar", false)
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/OWNERS b/libs/WindowManager/Shell/src/com/android/wm/shell/common/OWNERS
new file mode 100644
index 0000000..7af0389
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/OWNERS
@@ -0,0 +1 @@
+madym@google.com
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
index 99959ae..20c3bd2 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
@@ -36,6 +36,8 @@
import com.android.wm.shell.bubbles.BubbleDataRepository;
import com.android.wm.shell.bubbles.BubbleLogger;
import com.android.wm.shell.bubbles.BubblePositioner;
+import com.android.wm.shell.bubbles.properties.ProdBubbleProperties;
+import com.android.wm.shell.bubbles.storage.BubblePersistentRepository;
import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.DisplayImeController;
import com.android.wm.shell.common.DisplayInsetsController;
@@ -183,11 +185,12 @@
IWindowManager wmService) {
return new BubbleController(context, shellInit, shellCommandHandler, shellController, data,
null /* synchronizer */, floatingContentCoordinator,
- new BubbleDataRepository(context, launcherApps, mainExecutor),
+ new BubbleDataRepository(launcherApps, mainExecutor,
+ new BubblePersistentRepository(context)),
statusBarService, windowManager, windowManagerShellWrapper, userManager,
launcherApps, logger, taskStackListener, organizer, positioner, displayController,
oneHandedOptional, dragAndDropController, mainExecutor, mainHandler, bgExecutor,
- taskViewTransitions, syncQueue, wmService);
+ taskViewTransitions, syncQueue, wmService, ProdBubbleProperties.INSTANCE);
}
//
@@ -219,12 +222,12 @@
desktopTasksController);
}
return new CaptionWindowDecorViewModel(
- context,
- mainHandler,
- mainChoreographer,
- taskOrganizer,
- displayController,
- syncQueue);
+ context,
+ mainHandler,
+ mainChoreographer,
+ taskOrganizer,
+ displayController,
+ syncQueue);
}
//
@@ -584,13 +587,13 @@
animators.add(fullscreenAnimator);
return new UnfoldAnimationController(
- shellInit,
- transactionPool,
- progressProvider.get(),
- animators,
- unfoldTransitionHandler,
- mainExecutor
- );
+ shellInit,
+ transactionPool,
+ progressProvider.get(),
+ animators,
+ unfoldTransitionHandler,
+ mainExecutor
+ );
}
@Provides
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 2b763ad..65a35b2 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
@@ -33,6 +33,7 @@
import android.os.SystemProperties
import android.util.DisplayMetrics.DENSITY_DEFAULT
import android.view.SurfaceControl
+import android.view.SurfaceControl.Transaction
import android.view.WindowManager.TRANSIT_CHANGE
import android.view.WindowManager.TRANSIT_NONE
import android.view.WindowManager.TRANSIT_OPEN
@@ -267,16 +268,24 @@
*/
fun cancelMoveToFreeform(task: RunningTaskInfo, position: Point) {
KtProtoLog.v(
- WM_SHELL_DESKTOP_MODE,
- "DesktopTasksController: cancelMoveToFreeform taskId=%d",
- task.taskId
+ WM_SHELL_DESKTOP_MODE,
+ "DesktopTasksController: cancelMoveToFreeform taskId=%d",
+ task.taskId
)
val wct = WindowContainerTransaction()
- addMoveToFullscreenChanges(wct, task)
+ wct.setBounds(task.token, null)
+
if (Transitions.ENABLE_SHELL_TRANSITIONS) {
- enterDesktopTaskTransitionHandler.startCancelMoveToDesktopMode(wct, position,
- mOnAnimationFinishedCallback)
+ enterDesktopTaskTransitionHandler.startCancelMoveToDesktopMode(
+ wct, position) { t ->
+ val callbackWCT = WindowContainerTransaction()
+ visualIndicator?.releaseVisualIndicator(t)
+ visualIndicator = null
+ addMoveToFullscreenChanges(callbackWCT, task)
+ shellTaskOrganizer.applyTransaction(callbackWCT)
+ }
} else {
+ addMoveToFullscreenChanges(wct, task)
shellTaskOrganizer.applyTransaction(wct)
releaseVisualIndicator()
}
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 3733b91..3e175f3 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
@@ -17,7 +17,6 @@
package com.android.wm.shell.desktopmode;
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
-import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -200,7 +199,7 @@
}
if (type == Transitions.TRANSIT_CANCEL_ENTERING_DESKTOP_MODE
- && taskInfo.getWindowingMode() == WINDOWING_MODE_FULLSCREEN
+ && taskInfo.getWindowingMode() == WINDOWING_MODE_FREEFORM
&& mPosition != null) {
// This Transition animates a task to fullscreen after being dragged from the status
// bar and then released back into the status bar area
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
index cf38990..b14c3c1 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
@@ -447,7 +447,7 @@
}
/**
- * Callback when launcher finishes swipe-pip-to-home operation.
+ * Callback when launcher finishes preparation of swipe-pip-to-home operation.
* Expect {@link #onTaskAppeared(ActivityManager.RunningTaskInfo, SurfaceControl)} afterwards.
*/
public void stopSwipePipToHome(int taskId, ComponentName componentName, Rect destinationBounds,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
index e04e9f7..24aaa9b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
@@ -856,6 +856,9 @@
final int enterAnimationType = mEnterAnimationType;
if (enterAnimationType == ANIM_TYPE_ALPHA) {
startTransaction.setAlpha(leash, 0f);
+ } else {
+ // set alpha to 1, because for multi-activity PiP it will create a new task with alpha 0
+ startTransaction.setAlpha(leash, 1f);
}
startTransaction.apply();
@@ -953,7 +956,8 @@
if (swipePipToHomeOverlay != null) {
// Launcher fade in the overlay on top of the fullscreen Task. It is possible we
// reparent the PIP activity to a new PIP task (in case there are other activities
- // in the original Task), so we should also reparent the overlay to the PIP task.
+ // in the original Task, in other words multi-activity apps), so we should also reparent
+ // the overlay to the final PIP task.
startTransaction.reparent(swipePipToHomeOverlay, leash)
.setLayer(swipePipToHomeOverlay, Integer.MAX_VALUE);
mPipOrganizer.mSwipePipToHomeOverlay = null;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
index b9106d6..acc1c5e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
@@ -2453,6 +2453,8 @@
mSplitLayout.setFreezeDividerWindow(false);
final StageChangeRecord record = new StageChangeRecord();
+ final int transitType = info.getType();
+ boolean hasEnteringPip = false;
for (int iC = 0; iC < info.getChanges().size(); ++iC) {
final TransitionInfo.Change change = info.getChanges().get(iC);
if (change.getMode() == TRANSIT_CHANGE
@@ -2460,6 +2462,10 @@
mSplitLayout.update(startTransaction);
}
+ if (mMixedHandler.isEnteringPip(change, transitType)) {
+ hasEnteringPip = true;
+ }
+
final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo();
if (taskInfo == null) continue;
if (taskInfo.token.equals(mRootTaskInfo.token)) {
@@ -2508,6 +2514,13 @@
}
}
}
+
+ if (hasEnteringPip) {
+ mMixedHandler.animatePendingEnterPipFromSplit(transition, info,
+ startTransaction, finishTransaction, finishCallback);
+ return true;
+ }
+
final ArraySet<StageTaskListener> dismissStages = record.getShouldDismissedStage();
if (mMainStage.getChildCount() == 0 || mSideStage.getChildCount() == 0
|| dismissStages.size() == 1) {
@@ -2847,7 +2860,9 @@
for (int i = info.getChanges().size() - 1; i >= 0; --i) {
final TransitionInfo.Change change = info.getChanges().get(i);
final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo();
- if (taskInfo != null && getStageOfTask(taskInfo) != null) {
+ if (taskInfo != null && (getStageOfTask(taskInfo) != null
+ || getSplitItemPosition(change.getLastParent())
+ != SPLIT_POSITION_UNDEFINED)) {
recentTasks.removeSplitPair(taskInfo.taskId);
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java
index 182c275..a28ce55 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java
@@ -42,10 +42,10 @@
import android.window.WindowContainerTransactionCallback;
import com.android.internal.protolog.common.ProtoLog;
+import com.android.wm.shell.common.split.SplitScreenUtils;
import com.android.wm.shell.desktopmode.DesktopModeController;
import com.android.wm.shell.desktopmode.DesktopModeStatus;
import com.android.wm.shell.desktopmode.DesktopTasksController;
-import com.android.wm.shell.common.split.SplitScreenUtils;
import com.android.wm.shell.keyguard.KeyguardTransitionHandler;
import com.android.wm.shell.pip.PipTransitionController;
import com.android.wm.shell.pip.phone.PipTouchHandler;
@@ -470,7 +470,8 @@
}
finishCallback.onTransitionFinished(mixed.mFinishWCT, wctCB);
};
- if (isGoingHome) {
+ if (isGoingHome || mSplitHandler.getSplitItemPosition(pipChange.getLastParent())
+ != SPLIT_POSITION_UNDEFINED) {
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " Animation is actually mixed "
+ "since entering-PiP caused us to leave split and return home.");
// We need to split the transition into 2 parts: the pip part (animated by pip)
@@ -539,10 +540,27 @@
}
/**
+ * This is intended to be called by SplitCoordinator as a helper to mix a split handling
+ * transition with an entering-pip change. The use-case for this is when an auto-pip change
+ * gets collected into the transition which has already claimed by
+ * StageCoordinator.handleRequest. This happens when launching a fullscreen app while having an
+ * auto-pip activity in the foreground split pair.
+ */
+ // TODO(b/287704263): Remove when split/mixed are reversed.
+ public boolean animatePendingEnterPipFromSplit(IBinder transition, TransitionInfo info,
+ SurfaceControl.Transaction startT, SurfaceControl.Transaction finishT,
+ Transitions.TransitionFinishCallback finishCallback) {
+ final MixedTransition mixed = new MixedTransition(
+ MixedTransition.TYPE_ENTER_PIP_FROM_SPLIT, transition);
+ mActiveTransitions.add(mixed);
+ return animateEnterPipFromSplit(mixed, info, startT, finishT, finishCallback);
+ }
+
+ /**
* This is intended to be called by SplitCoordinator as a helper to mix an already-pending
* split transition with a display-change. The use-case for this is when a display
* change/rotation gets collected into a split-screen enter/exit transition which has already
- * been claimed by StageCoordinator.handleRequest . This happens during launcher tests.
+ * been claimed by StageCoordinator.handleRequest. This happens during launcher tests.
*/
public boolean animatePendingSplitWithDisplayChange(@NonNull IBinder transition,
@NonNull TransitionInfo info, @NonNull SurfaceControl.Transaction startT,
@@ -704,6 +722,13 @@
return mPipHandler.requestHasPipEnter(request);
}
+ /** Whether a particular change is a window that is entering pip. */
+ // TODO(b/287704263): Remove when split/mixed are reversed.
+ public boolean isEnteringPip(TransitionInfo.Change change,
+ @WindowManager.TransitionType int transitType) {
+ return mPipHandler.isEnteringPip(change, transitType);
+ }
+
@Override
public void mergeAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info,
@NonNull SurfaceControl.Transaction t, @NonNull IBinder mergeTarget,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java
index 742893f..e5fc66a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java
@@ -56,7 +56,6 @@
*/
class DragResizeInputListener implements AutoCloseable {
private static final String TAG = "DragResizeInputListener";
- private static final float TOP_CORNER_PADDING = 1.5f;
private final IWindowSession mWindowSession = WindowManagerGlobal.getWindowSession();
private final Handler mHandler;
private final Choreographer mChoreographer;
@@ -435,10 +434,7 @@
}
double distanceFromCenter = Math.hypot(x - centerX, y - centerY);
- // TODO(b/286461778): Remove this when input in top corner gap no longer goes to header
- float cornerPadding = (ctrlType & CTRL_TYPE_TOP) != 0 ? TOP_CORNER_PADDING : 1;
-
- if (distanceFromCenter < mTaskCornerRadius + mResizeHandleThickness * cornerPadding
+ if (distanceFromCenter < mTaskCornerRadius + mResizeHandleThickness
&& distanceFromCenter >= mTaskCornerRadius) {
return ctrlType;
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java
index 4407f2e..ddc7fef 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java
@@ -237,7 +237,12 @@
final int captionHeight = loadDimensionPixelSize(resources, params.mCaptionHeightId);
final int captionWidth = taskBounds.width();
+
+ // We use mDecorationContainerSurface to define input window for task resizing; by layering
+ // it in front of mCaptionContainerSurface, we can allow it to handle input prior to
+ // caption view itself, treating corner inputs as resize events rather than repositioning.
startT.setWindowCrop(mCaptionContainerSurface, captionWidth, captionHeight)
+ .setLayer(mCaptionContainerSurface, -1)
.show(mCaptionContainerSurface);
if (ViewRootImpl.CAPTION_ON_SHELL) {
diff --git a/libs/WindowManager/Shell/tests/flicker/manifests/AndroidManifest.xml b/libs/WindowManager/Shell/tests/flicker/manifests/AndroidManifest.xml
index 4721741..6a87de4 100644
--- a/libs/WindowManager/Shell/tests/flicker/manifests/AndroidManifest.xml
+++ b/libs/WindowManager/Shell/tests/flicker/manifests/AndroidManifest.xml
@@ -15,6 +15,7 @@
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
package="com.android.wm.shell.flicker">
<uses-sdk android:minSdkVersion="29" android:targetSdkVersion="29"/>
@@ -57,10 +58,11 @@
<action android:name="android.service.notification.NotificationListenerService" />
</intent-filter>
</service>
- </application>
- <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
- android:targetPackage="com.android.wm.shell.flicker"
- android:label="WindowManager Shell Flicker Tests">
- </instrumentation>
+ <!-- (b/197936012) Remove startup provider due to test timeout issue -->
+ <provider
+ android:name="androidx.startup.InitializationProvider"
+ android:authorities="${applicationId}.androidx-startup"
+ tools:node="remove" />
+ </application>
</manifest>
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/BaseBenchmarkTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/BaseBenchmarkTest.kt
index e06e074..0f3e0f5 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/BaseBenchmarkTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/BaseBenchmarkTest.kt
@@ -19,14 +19,14 @@
import android.app.Instrumentation
import android.tools.device.flicker.junit.FlickerBuilderProvider
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTest
import androidx.test.platform.app.InstrumentationRegistry
import com.android.launcher3.tapl.LauncherInstrumentation
abstract class BaseBenchmarkTest
@JvmOverloads
constructor(
- protected open val flicker: FlickerTest,
+ protected open val flicker: LegacyFlickerTest,
protected val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation(),
protected val tapl: LauncherInstrumentation = LauncherInstrumentation()
) {
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/BaseTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/BaseTest.kt
index c98c5a0..d2fe9fe 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/BaseTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/BaseTest.kt
@@ -18,7 +18,7 @@
import android.app.Instrumentation
import android.tools.common.traces.component.ComponentNameMatcher
-import android.tools.device.flicker.legacy.FlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTest
import androidx.test.platform.app.InstrumentationRegistry
import com.android.launcher3.tapl.LauncherInstrumentation
@@ -30,7 +30,7 @@
abstract class BaseTest
@JvmOverloads
constructor(
- override val flicker: FlickerTest,
+ override val flicker: LegacyFlickerTest,
instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation(),
tapl: LauncherInstrumentation = LauncherInstrumentation()
) : BaseBenchmarkTest(flicker, instrumentation, tapl), ICommonAssertions
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonAssertions.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonAssertions.kt
index 798cc95..9cc03a5 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonAssertions.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonAssertions.kt
@@ -23,18 +23,18 @@
import android.tools.common.flicker.subject.layers.LayerTraceEntrySubject
import android.tools.common.flicker.subject.layers.LayersTraceSubject
import android.tools.common.traces.component.IComponentMatcher
-import android.tools.device.flicker.legacy.FlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTest
import android.tools.device.helpers.WindowUtils
-fun FlickerTest.appPairsDividerIsVisibleAtEnd() {
+fun LegacyFlickerTest.appPairsDividerIsVisibleAtEnd() {
assertLayersEnd { this.isVisible(APP_PAIR_SPLIT_DIVIDER_COMPONENT) }
}
-fun FlickerTest.appPairsDividerIsInvisibleAtEnd() {
+fun LegacyFlickerTest.appPairsDividerIsInvisibleAtEnd() {
assertLayersEnd { this.notContains(APP_PAIR_SPLIT_DIVIDER_COMPONENT) }
}
-fun FlickerTest.appPairsDividerBecomesVisible() {
+fun LegacyFlickerTest.appPairsDividerBecomesVisible() {
assertLayers {
this.isInvisible(DOCKED_STACK_DIVIDER_COMPONENT)
.then()
@@ -42,7 +42,7 @@
}
}
-fun FlickerTest.splitScreenEntered(
+fun LegacyFlickerTest.splitScreenEntered(
component1: IComponentMatcher,
component2: IComponentMatcher,
fromOtherApp: Boolean,
@@ -69,7 +69,7 @@
splitScreenDividerIsVisibleAtEnd()
}
-fun FlickerTest.splitScreenDismissed(
+fun LegacyFlickerTest.splitScreenDismissed(
component1: IComponentMatcher,
component2: IComponentMatcher,
toHome: Boolean
@@ -87,27 +87,27 @@
splitScreenDividerIsInvisibleAtEnd()
}
-fun FlickerTest.splitScreenDividerIsVisibleAtStart() {
+fun LegacyFlickerTest.splitScreenDividerIsVisibleAtStart() {
assertLayersStart { this.isVisible(SPLIT_SCREEN_DIVIDER_COMPONENT) }
}
-fun FlickerTest.splitScreenDividerIsVisibleAtEnd() {
+fun LegacyFlickerTest.splitScreenDividerIsVisibleAtEnd() {
assertLayersEnd { this.isVisible(SPLIT_SCREEN_DIVIDER_COMPONENT) }
}
-fun FlickerTest.splitScreenDividerIsInvisibleAtStart() {
+fun LegacyFlickerTest.splitScreenDividerIsInvisibleAtStart() {
assertLayersStart { this.isInvisible(SPLIT_SCREEN_DIVIDER_COMPONENT) }
}
-fun FlickerTest.splitScreenDividerIsInvisibleAtEnd() {
+fun LegacyFlickerTest.splitScreenDividerIsInvisibleAtEnd() {
assertLayersEnd { this.isInvisible(SPLIT_SCREEN_DIVIDER_COMPONENT) }
}
-fun FlickerTest.splitScreenDividerBecomesVisible() {
+fun LegacyFlickerTest.splitScreenDividerBecomesVisible() {
layerBecomesVisible(SPLIT_SCREEN_DIVIDER_COMPONENT)
}
-fun FlickerTest.splitScreenDividerBecomesInvisible() {
+fun LegacyFlickerTest.splitScreenDividerBecomesInvisible() {
assertLayers {
this.isVisible(SPLIT_SCREEN_DIVIDER_COMPONENT)
.then()
@@ -115,23 +115,23 @@
}
}
-fun FlickerTest.layerBecomesVisible(component: IComponentMatcher) {
+fun LegacyFlickerTest.layerBecomesVisible(component: IComponentMatcher) {
assertLayers { this.isInvisible(component).then().isVisible(component) }
}
-fun FlickerTest.layerBecomesInvisible(component: IComponentMatcher) {
+fun LegacyFlickerTest.layerBecomesInvisible(component: IComponentMatcher) {
assertLayers { this.isVisible(component).then().isInvisible(component) }
}
-fun FlickerTest.layerIsVisibleAtEnd(component: IComponentMatcher) {
+fun LegacyFlickerTest.layerIsVisibleAtEnd(component: IComponentMatcher) {
assertLayersEnd { this.isVisible(component) }
}
-fun FlickerTest.layerKeepVisible(component: IComponentMatcher) {
+fun LegacyFlickerTest.layerKeepVisible(component: IComponentMatcher) {
assertLayers { this.isVisible(component) }
}
-fun FlickerTest.splitAppLayerBoundsBecomesVisible(
+fun LegacyFlickerTest.splitAppLayerBoundsBecomesVisible(
component: IComponentMatcher,
landscapePosLeft: Boolean,
portraitPosTop: Boolean
@@ -150,7 +150,7 @@
}
}
-fun FlickerTest.splitAppLayerBoundsBecomesVisibleByDrag(component: IComponentMatcher) {
+fun LegacyFlickerTest.splitAppLayerBoundsBecomesVisibleByDrag(component: IComponentMatcher) {
assertLayers {
this.notContains(SPLIT_SCREEN_DIVIDER_COMPONENT.or(component), isOptional = true)
.then()
@@ -161,7 +161,7 @@
}
}
-fun FlickerTest.splitAppLayerBoundsBecomesInvisible(
+fun LegacyFlickerTest.splitAppLayerBoundsBecomesInvisible(
component: IComponentMatcher,
landscapePosLeft: Boolean,
portraitPosTop: Boolean
@@ -180,7 +180,7 @@
}
}
-fun FlickerTest.splitAppLayerBoundsIsVisibleAtEnd(
+fun LegacyFlickerTest.splitAppLayerBoundsIsVisibleAtEnd(
component: IComponentMatcher,
landscapePosLeft: Boolean,
portraitPosTop: Boolean
@@ -195,7 +195,7 @@
}
}
-fun FlickerTest.splitAppLayerBoundsKeepVisible(
+fun LegacyFlickerTest.splitAppLayerBoundsKeepVisible(
component: IComponentMatcher,
landscapePosLeft: Boolean,
portraitPosTop: Boolean
@@ -210,7 +210,7 @@
}
}
-fun FlickerTest.splitAppLayerBoundsChanges(
+fun LegacyFlickerTest.splitAppLayerBoundsChanges(
component: IComponentMatcher,
landscapePosLeft: Boolean,
portraitPosTop: Boolean
@@ -304,7 +304,7 @@
}
}
-fun FlickerTest.appWindowBecomesVisible(component: IComponentMatcher) {
+fun LegacyFlickerTest.appWindowBecomesVisible(component: IComponentMatcher) {
assertWm {
this.isAppWindowInvisible(component)
.then()
@@ -316,39 +316,39 @@
}
}
-fun FlickerTest.appWindowBecomesInvisible(component: IComponentMatcher) {
+fun LegacyFlickerTest.appWindowBecomesInvisible(component: IComponentMatcher) {
assertWm { this.isAppWindowVisible(component).then().isAppWindowInvisible(component) }
}
-fun FlickerTest.appWindowIsVisibleAtStart(component: IComponentMatcher) {
+fun LegacyFlickerTest.appWindowIsVisibleAtStart(component: IComponentMatcher) {
assertWmStart { this.isAppWindowVisible(component) }
}
-fun FlickerTest.appWindowIsVisibleAtEnd(component: IComponentMatcher) {
+fun LegacyFlickerTest.appWindowIsVisibleAtEnd(component: IComponentMatcher) {
assertWmEnd { this.isAppWindowVisible(component) }
}
-fun FlickerTest.appWindowIsInvisibleAtStart(component: IComponentMatcher) {
+fun LegacyFlickerTest.appWindowIsInvisibleAtStart(component: IComponentMatcher) {
assertWmStart { this.isAppWindowInvisible(component) }
}
-fun FlickerTest.appWindowIsInvisibleAtEnd(component: IComponentMatcher) {
+fun LegacyFlickerTest.appWindowIsInvisibleAtEnd(component: IComponentMatcher) {
assertWmEnd { this.isAppWindowInvisible(component) }
}
-fun FlickerTest.appWindowIsNotContainAtStart(component: IComponentMatcher) {
+fun LegacyFlickerTest.appWindowIsNotContainAtStart(component: IComponentMatcher) {
assertWmStart { this.notContains(component) }
}
-fun FlickerTest.appWindowKeepVisible(component: IComponentMatcher) {
+fun LegacyFlickerTest.appWindowKeepVisible(component: IComponentMatcher) {
assertWm { this.isAppWindowVisible(component) }
}
-fun FlickerTest.dockedStackDividerIsVisibleAtEnd() {
+fun LegacyFlickerTest.dockedStackDividerIsVisibleAtEnd() {
assertLayersEnd { this.isVisible(DOCKED_STACK_DIVIDER_COMPONENT) }
}
-fun FlickerTest.dockedStackDividerBecomesVisible() {
+fun LegacyFlickerTest.dockedStackDividerBecomesVisible() {
assertLayers {
this.isInvisible(DOCKED_STACK_DIVIDER_COMPONENT)
.then()
@@ -356,7 +356,7 @@
}
}
-fun FlickerTest.dockedStackDividerBecomesInvisible() {
+fun LegacyFlickerTest.dockedStackDividerBecomesInvisible() {
assertLayers {
this.isVisible(DOCKED_STACK_DIVIDER_COMPONENT)
.then()
@@ -364,11 +364,11 @@
}
}
-fun FlickerTest.dockedStackDividerNotExistsAtEnd() {
+fun LegacyFlickerTest.dockedStackDividerNotExistsAtEnd() {
assertLayersEnd { this.notContains(DOCKED_STACK_DIVIDER_COMPONENT) }
}
-fun FlickerTest.appPairsPrimaryBoundsIsVisibleAtEnd(
+fun LegacyFlickerTest.appPairsPrimaryBoundsIsVisibleAtEnd(
rotation: Rotation,
primaryComponent: IComponentMatcher
) {
@@ -380,7 +380,7 @@
}
}
-fun FlickerTest.dockedStackPrimaryBoundsIsVisibleAtEnd(
+fun LegacyFlickerTest.dockedStackPrimaryBoundsIsVisibleAtEnd(
rotation: Rotation,
primaryComponent: IComponentMatcher
) {
@@ -392,7 +392,7 @@
}
}
-fun FlickerTest.appPairsSecondaryBoundsIsVisibleAtEnd(
+fun LegacyFlickerTest.appPairsSecondaryBoundsIsVisibleAtEnd(
rotation: Rotation,
secondaryComponent: IComponentMatcher
) {
@@ -404,7 +404,7 @@
}
}
-fun FlickerTest.dockedStackSecondaryBoundsIsVisibleAtEnd(
+fun LegacyFlickerTest.dockedStackSecondaryBoundsIsVisibleAtEnd(
rotation: Rotation,
secondaryComponent: IComponentMatcher
) {
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/ICommonAssertions.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/ICommonAssertions.kt
index 02d9a056..7b32901 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/ICommonAssertions.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/ICommonAssertions.kt
@@ -18,7 +18,7 @@
import android.platform.test.annotations.Presubmit
import android.tools.common.traces.component.ComponentNameMatcher
-import android.tools.device.flicker.legacy.FlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTest
import com.android.server.wm.flicker.entireScreenCovered
import com.android.server.wm.flicker.navBarLayerIsVisibleAtStartAndEnd
import com.android.server.wm.flicker.navBarLayerPositionAtStartAndEnd
@@ -32,7 +32,7 @@
import org.junit.Test
interface ICommonAssertions {
- val flicker: FlickerTest
+ val flicker: LegacyFlickerTest
/** Checks that all parts of the screen are covered during the transition */
@Presubmit @Test fun entireScreenCovered() = flicker.entireScreenCovered()
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/BaseAppCompat.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/BaseAppCompat.kt
index 3000008..0f9579d 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/BaseAppCompat.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/BaseAppCompat.kt
@@ -20,20 +20,20 @@
import android.system.helpers.CommandsHelper
import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import com.android.server.wm.flicker.helpers.setRotation
+import android.tools.device.flicker.legacy.FlickerTestData
+import android.tools.device.flicker.legacy.LegacyFlickerTest
import com.android.server.wm.flicker.helpers.LetterboxAppHelper
-import android.tools.device.flicker.legacy.IFlickerTestData
+import com.android.server.wm.flicker.helpers.setRotation
import com.android.wm.shell.flicker.BaseTest
-import com.android.wm.shell.flicker.appWindowIsVisibleAtStart
import com.android.wm.shell.flicker.appWindowIsVisibleAtEnd
+import com.android.wm.shell.flicker.appWindowIsVisibleAtStart
import com.android.wm.shell.flicker.appWindowKeepVisible
import com.android.wm.shell.flicker.layerKeepVisible
import org.junit.After
import org.junit.Assume
import org.junit.Before
-abstract class BaseAppCompat(flicker: FlickerTest) : BaseTest(flicker) {
+abstract class BaseAppCompat(flicker: LegacyFlickerTest) : BaseTest(flicker) {
protected val context: Context = instrumentation.context
protected val letterboxApp = LetterboxAppHelper(instrumentation)
lateinit var cmdHelper: CommandsHelper
@@ -47,9 +47,7 @@
letterboxApp.launchViaIntent(wmHelper)
setEndRotation()
}
- teardown {
- letterboxApp.exit(wmHelper)
- }
+ teardown { letterboxApp.exit(wmHelper) }
}
@Before
@@ -100,9 +98,9 @@
return res != null && res.contains("true")
}
- fun IFlickerTestData.setStartRotation() = setRotation(flicker.scenario.startRotation)
+ fun FlickerTestData.setStartRotation() = setRotation(flicker.scenario.startRotation)
- fun IFlickerTestData.setEndRotation() = setRotation(flicker.scenario.endRotation)
+ fun FlickerTestData.setEndRotation() = setRotation(flicker.scenario.endRotation)
/** Checks that app entering letterboxed state have rounded corners */
fun assertLetterboxAppAtStartHasRoundedCorners() {
@@ -131,13 +129,13 @@
}
fun assertAppLetterboxedAtEnd() =
- flicker.assertLayersEnd { isVisible(ComponentNameMatcher.LETTERBOX) }
+ flicker.assertLayersEnd { isVisible(ComponentNameMatcher.LETTERBOX) }
fun assertAppLetterboxedAtStart() =
- flicker.assertLayersStart { isVisible(ComponentNameMatcher.LETTERBOX) }
+ flicker.assertLayersStart { isVisible(ComponentNameMatcher.LETTERBOX) }
fun assertAppStaysLetterboxed() =
- flicker.assertLayers { isVisible(ComponentNameMatcher.LETTERBOX) }
+ flicker.assertLayers { isVisible(ComponentNameMatcher.LETTERBOX) }
fun assertLetterboxAppLayerKeepVisible() = flicker.layerKeepVisible(letterboxApp)
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/OpenAppInSizeCompatModeTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/OpenAppInSizeCompatModeTest.kt
index 3d83455..a7bd258 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/OpenAppInSizeCompatModeTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/OpenAppInSizeCompatModeTest.kt
@@ -17,11 +17,12 @@
package com.android.wm.shell.flicker.appcompat
import android.platform.test.annotations.Postsubmit
+import android.tools.common.flicker.assertions.FlickerTest
import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import androidx.test.filters.RequiresDevice
import org.junit.Test
import org.junit.runner.RunWith
@@ -46,7 +47,7 @@
@RequiresDevice
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
-class OpenAppInSizeCompatModeTest(flicker: FlickerTest) : BaseAppCompat(flicker) {
+class OpenAppInSizeCompatModeTest(flicker: LegacyFlickerTest) : BaseAppCompat(flicker) {
/** {@inheritDoc} */
override val transition: FlickerBuilder.() -> Unit
@@ -71,9 +72,7 @@
@Test
fun letterboxedAppHasRoundedCorners() = assertLetterboxAppAtEndHasRoundedCorners()
- @Postsubmit
- @Test
- fun appIsLetterboxedAtEnd() = assertAppLetterboxedAtEnd()
+ @Postsubmit @Test fun appIsLetterboxedAtEnd() = assertAppLetterboxedAtEnd()
/**
* Checks that the [ComponentNameMatcher.ROTATION] layer appears during the transition, doesn't
@@ -96,13 +95,13 @@
/**
* Creates the test configurations.
*
- * See [FlickerTestFactory.rotationTests] for configuring screen orientation and
+ * See [LegacyFlickerTestFactory.rotationTests] for configuring screen orientation and
* navigation modes.
*/
@Parameterized.Parameters(name = "{0}")
@JvmStatic
fun getParams(): Collection<FlickerTest> {
- return FlickerTestFactory.rotationTests()
+ return LegacyFlickerTestFactory.rotationTests()
}
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/RepositionFixedPortraitAppTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/RepositionFixedPortraitAppTest.kt
index c3355ed..e875aae 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/RepositionFixedPortraitAppTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/RepositionFixedPortraitAppTest.kt
@@ -18,29 +18,29 @@
import android.platform.test.annotations.Postsubmit
import android.tools.common.Rotation
+import android.tools.common.flicker.assertions.FlickerTest
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import android.tools.device.helpers.WindowUtils
-
import androidx.test.filters.RequiresDevice
import org.junit.Test
-
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
/**
* Test launching a fixed portrait letterboxed app in landscape and repositioning to the right.
*
- * To run this test: `atest WMShellFlickerTests:RepositionFixedPortraitAppTest`
- * Actions:
+ * To run this test: `atest WMShellFlickerTests:RepositionFixedPortraitAppTest` Actions:
+ *
* ```
* Launch a fixed portrait app in landscape to letterbox app
* Double tap to the right to reposition app and wait for app to move
* ```
*
- * Notes:
+ * Notes:
+ *
* ```
* Some default assertions (e.g., nav bar, status bar and screen covered)
* are inherited [BaseTest]
@@ -49,7 +49,7 @@
@RequiresDevice
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
-class RepositionFixedPortraitAppTest(flicker: FlickerTest) : BaseAppCompat(flicker) {
+class RepositionFixedPortraitAppTest(flicker: LegacyFlickerTest) : BaseAppCompat(flicker) {
val displayBounds = WindowUtils.getDisplayBounds(flicker.scenario.startRotation).bounds
/** {@inheritDoc} */
@@ -73,31 +73,25 @@
@Test
fun letterboxedAppHasRoundedCorners() = assertLetterboxAppAtEndHasRoundedCorners()
- @Postsubmit
- @Test
- fun letterboxAppLayerKeepVisible() = assertLetterboxAppLayerKeepVisible()
+ @Postsubmit @Test fun letterboxAppLayerKeepVisible() = assertLetterboxAppLayerKeepVisible()
- @Postsubmit
- @Test
- fun appStaysLetterboxed() = assertAppStaysLetterboxed()
+ @Postsubmit @Test fun appStaysLetterboxed() = assertAppStaysLetterboxed()
- @Postsubmit
- @Test
- fun appKeepVisible() = assertLetterboxAppKeepVisible()
+ @Postsubmit @Test fun appKeepVisible() = assertLetterboxAppKeepVisible()
companion object {
/**
* Creates the test configurations.
*
- * See [FlickerTestFactory.nonRotationTests] for configuring screen orientation and
+ * See [LegacyFlickerTestFactory.nonRotationTests] for configuring screen orientation and
* navigation modes.
*/
@Parameterized.Parameters(name = "{0}")
@JvmStatic
fun getParams(): Collection<FlickerTest> {
- return FlickerTestFactory.nonRotationTests(
+ return LegacyFlickerTestFactory.nonRotationTests(
supportedRotations = listOf(Rotation.ROTATION_90)
)
}
}
-}
\ No newline at end of file
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/RestartAppInSizeCompatModeTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/RestartAppInSizeCompatModeTest.kt
index c2057d2..a18a144 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/RestartAppInSizeCompatModeTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/RestartAppInSizeCompatModeTest.kt
@@ -17,10 +17,11 @@
package com.android.wm.shell.flicker.appcompat
import android.platform.test.annotations.Postsubmit
+import android.tools.common.flicker.assertions.FlickerTest
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import android.tools.device.helpers.WindowUtils
import androidx.test.filters.RequiresDevice
import org.junit.Test
@@ -47,7 +48,7 @@
@RequiresDevice
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
-class RestartAppInSizeCompatModeTest(flicker: FlickerTest) : BaseAppCompat(flicker) {
+class RestartAppInSizeCompatModeTest(flicker: LegacyFlickerTest) : BaseAppCompat(flicker) {
/** {@inheritDoc} */
override val transition: FlickerBuilder.() -> Unit
@@ -70,13 +71,9 @@
}
}
- @Postsubmit
- @Test
- fun appLayerKeepVisible() = assertLetterboxAppLayerKeepVisible()
+ @Postsubmit @Test fun appLayerKeepVisible() = assertLetterboxAppLayerKeepVisible()
- @Postsubmit
- @Test
- fun appIsLetterboxedAtStart() = assertAppLetterboxedAtStart()
+ @Postsubmit @Test fun appIsLetterboxedAtStart() = assertAppLetterboxedAtStart()
@Postsubmit
@Test
@@ -94,13 +91,13 @@
/**
* Creates the test configurations.
*
- * See [FlickerTestFactory.rotationTests] for configuring screen orientation and
+ * See [LegacyFlickerTestFactory.rotationTests] for configuring screen orientation and
* navigation modes.
*/
@Parameterized.Parameters(name = "{0}")
@JvmStatic
fun getParams(): Collection<FlickerTest> {
- return FlickerTestFactory.rotationTests()
+ return LegacyFlickerTestFactory.rotationTests()
}
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/BaseBubbleScreen.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/BaseBubbleScreen.kt
index bab81d7..5c7d1d8 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/BaseBubbleScreen.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/BaseBubbleScreen.kt
@@ -23,9 +23,9 @@
import android.os.ServiceManager
import android.tools.common.Rotation
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
-import android.tools.device.flicker.legacy.IFlickerTestData
+import android.tools.device.flicker.legacy.FlickerTestData
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import android.tools.device.helpers.SYSTEMUI_PACKAGE
import androidx.test.uiautomator.By
import androidx.test.uiautomator.UiObject2
@@ -35,7 +35,7 @@
import org.junit.runners.Parameterized
/** Base configurations for Bubble flicker tests */
-abstract class BaseBubbleScreen(flicker: FlickerTest) : BaseTest(flicker) {
+abstract class BaseBubbleScreen(flicker: LegacyFlickerTest) : BaseTest(flicker) {
protected val context: Context = instrumentation.context
protected val testApp = LaunchBubbleHelper(instrumentation)
@@ -72,28 +72,31 @@
uid,
NotificationManager.BUBBLE_PREFERENCE_NONE
)
- testApp.exit()
+ device.wait(
+ Until.gone(By.res(SYSTEM_UI_PACKAGE, BUBBLE_RES_NAME)),
+ FIND_OBJECT_TIMEOUT
+ )
+ testApp.exit(wmHelper)
}
extraSpec(this)
}
}
- protected fun IFlickerTestData.waitAndGetAddBubbleBtn(): UiObject2? =
+ protected fun FlickerTestData.waitAndGetAddBubbleBtn(): UiObject2? =
device.wait(Until.findObject(By.text("Add Bubble")), FIND_OBJECT_TIMEOUT)
- protected fun IFlickerTestData.waitAndGetCancelAllBtn(): UiObject2? =
+ protected fun FlickerTestData.waitAndGetCancelAllBtn(): UiObject2? =
device.wait(Until.findObject(By.text("Cancel All Bubble")), FIND_OBJECT_TIMEOUT)
companion object {
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): List<FlickerTest> {
- return FlickerTestFactory.nonRotationTests(
+ fun getParams() =
+ LegacyFlickerTestFactory.nonRotationTests(
supportedRotations = listOf(Rotation.ROTATION_0)
)
- }
- const val FIND_OBJECT_TIMEOUT = 2000L
+ const val FIND_OBJECT_TIMEOUT = 4000L
const val SYSTEM_UI_PACKAGE = SYSTEMUI_PACKAGE
const val BUBBLE_RES_NAME = "bubble_view"
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/ChangeActiveActivityFromBubbleTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/ChangeActiveActivityFromBubbleTest.kt
index 2474ecf..bc565bc 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/ChangeActiveActivityFromBubbleTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/ChangeActiveActivityFromBubbleTest.kt
@@ -21,7 +21,7 @@
import android.platform.test.annotations.Presubmit
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTest
import androidx.test.filters.RequiresDevice
import androidx.test.uiautomator.By
import androidx.test.uiautomator.UiObject2
@@ -44,7 +44,8 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FlakyTest(bugId = 217777115)
-open class ChangeActiveActivityFromBubbleTest(flicker: FlickerTest) : BaseBubbleScreen(flicker) {
+open class ChangeActiveActivityFromBubbleTest(flicker: LegacyFlickerTest) :
+ BaseBubbleScreen(flicker) {
/** {@inheritDoc} */
override val transition: FlickerBuilder.() -> Unit
get() = buildTransition {
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/ChangeActiveActivityFromBubbleTestCfArm.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/ChangeActiveActivityFromBubbleTestCfArm.kt
index bdfdad5..abc6b9f 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/ChangeActiveActivityFromBubbleTestCfArm.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/ChangeActiveActivityFromBubbleTestCfArm.kt
@@ -17,11 +17,11 @@
package com.android.wm.shell.flicker.bubble
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
-import android.tools.device.flicker.legacy.FlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTest
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
-open class ChangeActiveActivityFromBubbleTestCfArm(flicker: FlickerTest) :
+open class ChangeActiveActivityFromBubbleTestCfArm(flicker: LegacyFlickerTest) :
ChangeActiveActivityFromBubbleTest(flicker)
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/DragToDismissBubbleScreenTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/DragToDismissBubbleScreenTest.kt
index 8474ce0..3f28ae8 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/DragToDismissBubbleScreenTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/DragToDismissBubbleScreenTest.kt
@@ -19,9 +19,10 @@
import android.content.Context
import android.graphics.Point
import android.platform.test.annotations.Presubmit
+import android.tools.common.flicker.subject.layers.LayersTraceSubject
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTest
import android.util.DisplayMetrics
import android.view.WindowManager
import androidx.test.filters.RequiresDevice
@@ -44,7 +45,7 @@
@RequiresDevice
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
-open class DragToDismissBubbleScreenTest(flicker: FlickerTest) : BaseBubbleScreen(flicker) {
+open class DragToDismissBubbleScreenTest(flicker: LegacyFlickerTest) : BaseBubbleScreen(flicker) {
private val wm = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
private val displaySize = DisplayMetrics()
@@ -73,4 +74,14 @@
open fun testAppIsAlwaysVisible() {
flicker.assertLayers { this.isVisible(testApp) }
}
+
+ @Presubmit
+ @Test
+ override fun visibleLayersShownMoreThanOneConsecutiveEntry() {
+ flicker.assertLayers {
+ this.visibleLayersShownMoreThanOneConsecutiveEntry(
+ LayersTraceSubject.VISIBLE_FOR_MORE_THAN_ONE_ENTRY_IGNORE_LAYERS + listOf(testApp)
+ )
+ }
+ }
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/DragToDismissBubbleScreenTestCfArm.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/DragToDismissBubbleScreenTestCfArm.kt
index 62fa7b4..ee55eca 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/DragToDismissBubbleScreenTestCfArm.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/DragToDismissBubbleScreenTestCfArm.kt
@@ -17,11 +17,11 @@
package com.android.wm.shell.flicker.bubble
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
-import android.tools.device.flicker.legacy.FlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTest
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
-class DragToDismissBubbleScreenTestCfArm(flicker: FlickerTest) :
+class DragToDismissBubbleScreenTestCfArm(flicker: LegacyFlickerTest) :
DragToDismissBubbleScreenTest(flicker)
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/OpenActivityFromBubbleOnLocksreenTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/OpenActivityFromBubbleOnLocksreenTest.kt
index 889e177..26aca18 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/OpenActivityFromBubbleOnLocksreenTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/OpenActivityFromBubbleOnLocksreenTest.kt
@@ -21,7 +21,7 @@
import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTest
import android.view.WindowInsets
import android.view.WindowManager
import androidx.test.filters.RequiresDevice
@@ -48,7 +48,8 @@
@RequiresDevice
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
-class OpenActivityFromBubbleOnLocksreenTest(flicker: FlickerTest) : BaseBubbleScreen(flicker) {
+class OpenActivityFromBubbleOnLocksreenTest(flicker: LegacyFlickerTest) :
+ BaseBubbleScreen(flicker) {
/** {@inheritDoc} */
override val transition: FlickerBuilder.() -> Unit
@@ -80,7 +81,7 @@
instrumentation.uiAutomation.syncInputTransactions()
val showBubble =
device.wait(
- Until.findObject(By.res("com.android.systemui", "bubble_view")),
+ Until.findObject(By.res(SYSTEM_UI_PACKAGE, BUBBLE_RES_NAME)),
FIND_OBJECT_TIMEOUT
)
showBubble?.click() ?: error("Bubble notify not found")
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/OpenActivityFromBubbleTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/OpenActivityFromBubbleTest.kt
index 07ba4133..5085394 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/OpenActivityFromBubbleTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/OpenActivityFromBubbleTest.kt
@@ -19,7 +19,7 @@
import android.platform.test.annotations.Presubmit
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTest
import androidx.test.filters.RequiresDevice
import androidx.test.uiautomator.By
import androidx.test.uiautomator.Until
@@ -42,7 +42,7 @@
@RequiresDevice
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
-open class OpenActivityFromBubbleTest(flicker: FlickerTest) : BaseBubbleScreen(flicker) {
+open class OpenActivityFromBubbleTest(flicker: LegacyFlickerTest) : BaseBubbleScreen(flicker) {
/** {@inheritDoc} */
override val transition: FlickerBuilder.() -> Unit
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/OpenActivityFromBubbleTestCfArm.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/OpenActivityFromBubbleTestCfArm.kt
index 6c61710..6a46d23 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/OpenActivityFromBubbleTestCfArm.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/OpenActivityFromBubbleTestCfArm.kt
@@ -17,10 +17,11 @@
package com.android.wm.shell.flicker.bubble
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
-import android.tools.device.flicker.legacy.FlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTest
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
-class OpenActivityFromBubbleTestCfArm(flicker: FlickerTest) : OpenActivityFromBubbleTest(flicker)
+class OpenActivityFromBubbleTestCfArm(flicker: LegacyFlickerTest) :
+ OpenActivityFromBubbleTest(flicker)
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/SendBubbleNotificationTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/SendBubbleNotificationTest.kt
index 29f76d0..a926bb7 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/SendBubbleNotificationTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/SendBubbleNotificationTest.kt
@@ -19,7 +19,7 @@
import android.platform.test.annotations.Presubmit
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTest
import androidx.test.filters.RequiresDevice
import androidx.test.uiautomator.By
import androidx.test.uiautomator.Until
@@ -41,7 +41,7 @@
@RequiresDevice
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
-open class SendBubbleNotificationTest(flicker: FlickerTest) : BaseBubbleScreen(flicker) {
+open class SendBubbleNotificationTest(flicker: LegacyFlickerTest) : BaseBubbleScreen(flicker) {
/** {@inheritDoc} */
override val transition: FlickerBuilder.() -> Unit
@@ -55,6 +55,7 @@
FIND_OBJECT_TIMEOUT
)
?: error("No bubbles found")
+ device.waitForIdle()
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/SendBubbleNotificationTestCfArm.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/SendBubbleNotificationTestCfArm.kt
index e323ebf..a401cb4 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/SendBubbleNotificationTestCfArm.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/SendBubbleNotificationTestCfArm.kt
@@ -17,11 +17,11 @@
package com.android.wm.shell.flicker.bubble
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
-import android.tools.device.flicker.legacy.FlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTest
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
-open class SendBubbleNotificationTestCfArm(flicker: FlickerTest) :
+open class SendBubbleNotificationTestCfArm(flicker: LegacyFlickerTest) :
SendBubbleNotificationTest(flicker)
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/AutoEnterPipFromSplitScreenOnGoToHomeTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/AutoEnterPipFromSplitScreenOnGoToHomeTest.kt
index f7ce870..36bbafb 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/AutoEnterPipFromSplitScreenOnGoToHomeTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/AutoEnterPipFromSplitScreenOnGoToHomeTest.kt
@@ -24,8 +24,8 @@
import android.tools.device.apphelpers.StandardAppHelper
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import android.tools.device.helpers.WindowUtils
import android.tools.device.traces.parsers.toFlickerComponent
import androidx.test.filters.RequiresDevice
@@ -69,17 +69,17 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class AutoEnterPipFromSplitScreenOnGoToHomeTest(flicker: FlickerTest) :
- AutoEnterPipOnGoToHomeTest(flicker) {
+class AutoEnterPipFromSplitScreenOnGoToHomeTest(flicker: LegacyFlickerTest) :
+ AutoEnterPipOnGoToHomeTest(flicker) {
private val portraitDisplayBounds = WindowUtils.getDisplayBounds(Rotation.ROTATION_0)
/** Second app used to enter split screen mode */
protected val secondAppForSplitScreen = getSplitScreenApp(instrumentation)
fun getSplitScreenApp(instrumentation: Instrumentation): StandardAppHelper =
- SimpleAppHelper(
- instrumentation,
- ActivityOptions.SplitScreen.Primary.LABEL,
- ActivityOptions.SplitScreen.Primary.COMPONENT.toFlickerComponent()
- )
+ SimpleAppHelper(
+ instrumentation,
+ ActivityOptions.SplitScreen.Primary.LABEL,
+ ActivityOptions.SplitScreen.Primary.COMPONENT.toFlickerComponent()
+ )
/** Defines the transition used to run the test */
override val transition: FlickerBuilder.() -> Unit
@@ -91,11 +91,11 @@
enterSplitScreen()
// wait until split screen is established
wmHelper
- .StateSyncBuilder()
- .withWindowSurfaceAppeared(pipApp)
- .withWindowSurfaceAppeared(secondAppForSplitScreen)
- .withSplitDividerVisible()
- .waitForAndVerify()
+ .StateSyncBuilder()
+ .withWindowSurfaceAppeared(pipApp)
+ .withWindowSurfaceAppeared(secondAppForSplitScreen)
+ .withSplitDividerVisible()
+ .waitForAndVerify()
pipApp.enableAutoEnterForPipActivity()
}
teardown {
@@ -120,8 +120,8 @@
// contains more than 3 task views. We need to use uiautomator directly to find the
// second task to split.
tapl.workspace.switchToOverview().overviewActions.clickSplit()
- val snapshots = tapl.device.wait(Until.findObjects(overviewSnapshotSelector),
- TIMEOUT_MS)
+ val snapshots =
+ tapl.device.wait(Until.findObjects(overviewSnapshotSelector), TIMEOUT_MS)
if (snapshots == null || snapshots.size < 1) {
error("Fail to find a overview snapshot to split.")
}
@@ -137,12 +137,12 @@
snapshots[0].click()
} else {
tapl.workspace
- .switchToOverview()
- .currentTask
- .tapMenu()
- .tapSplitMenuItem()
- .currentTask
- .open()
+ .switchToOverview()
+ .currentTask
+ .tapMenu()
+ .tapSplitMenuItem()
+ .currentTask
+ .open()
}
SystemClock.sleep(TIMEOUT_MS)
}
@@ -190,11 +190,10 @@
companion object {
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): List<FlickerTest> {
- return FlickerTestFactory.nonRotationTests(
- // TODO(b/176061063):The 3 buttons of nav bar do not exist in the hierarchy.
- supportedNavigationModes = listOf(NavBar.MODE_GESTURAL)
+ fun getParams() =
+ LegacyFlickerTestFactory.nonRotationTests(
+ // TODO(b/176061063):The 3 buttons of nav bar do not exist in the hierarchy.
+ supportedNavigationModes = listOf(NavBar.MODE_GESTURAL)
)
- }
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/AutoEnterPipOnGoToHomeTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/AutoEnterPipOnGoToHomeTest.kt
index b95732e..2f7a25e 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/AutoEnterPipOnGoToHomeTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/AutoEnterPipOnGoToHomeTest.kt
@@ -19,7 +19,7 @@
import android.platform.test.annotations.Presubmit
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTest
import androidx.test.filters.RequiresDevice
import org.junit.Assume
import org.junit.FixMethodOrder
@@ -53,10 +53,9 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class AutoEnterPipOnGoToHomeTest(flicker: FlickerTest) : EnterPipViaAppUiButtonTest(flicker) {
- override val thisTransition: FlickerBuilder.() -> Unit = {
- transitions { tapl.goHome() }
- }
+open class AutoEnterPipOnGoToHomeTest(flicker: LegacyFlickerTest) :
+ EnterPipViaAppUiButtonTest(flicker) {
+ override val thisTransition: FlickerBuilder.() -> Unit = { transitions { tapl.goHome() } }
override val defaultEnterPip: FlickerBuilder.() -> Unit = {
setup {
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ClosePipBySwipingDownTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ClosePipBySwipingDownTest.kt
index afcc172..68bc9a2 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ClosePipBySwipingDownTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ClosePipBySwipingDownTest.kt
@@ -20,7 +20,7 @@
import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTest
import androidx.test.filters.RequiresDevice
import org.junit.FixMethodOrder
import org.junit.Test
@@ -53,7 +53,7 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class ClosePipBySwipingDownTest(flicker: FlickerTest) : ClosePipTransition(flicker) {
+open class ClosePipBySwipingDownTest(flicker: LegacyFlickerTest) : ClosePipTransition(flicker) {
override val thisTransition: FlickerBuilder.() -> Unit = {
transitions {
val pipRegion = wmHelper.getWindowRegion(pipApp).bounds
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ClosePipBySwipingDownTestCfArm.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ClosePipBySwipingDownTestCfArm.kt
index 02f6010..7a66889 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ClosePipBySwipingDownTestCfArm.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ClosePipBySwipingDownTestCfArm.kt
@@ -18,8 +18,8 @@
import android.tools.common.Rotation
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import org.junit.FixMethodOrder
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
@@ -28,20 +28,20 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class ClosePipBySwipingDownTestCfArm(flicker: FlickerTest) : ClosePipBySwipingDownTest(flicker) {
+class ClosePipBySwipingDownTestCfArm(flicker: LegacyFlickerTest) :
+ ClosePipBySwipingDownTest(flicker) {
companion object {
/**
* Creates the test configurations.
*
- * See [FlickerTestFactory.nonRotationTests] for configuring repetitions, screen orientation
- * and navigation modes.
+ * See [LegacyFlickerTestFactory.nonRotationTests] for configuring repetitions, screen
+ * orientation and navigation modes.
*/
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): List<FlickerTest> {
- return FlickerTestFactory.nonRotationTests(
+ fun getParams() =
+ LegacyFlickerTestFactory.nonRotationTests(
supportedRotations = listOf(Rotation.ROTATION_0)
)
- }
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ClosePipTransition.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ClosePipTransition.kt
index e52b71e..a17144b 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ClosePipTransition.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ClosePipTransition.kt
@@ -20,14 +20,14 @@
import android.tools.common.Rotation
import android.tools.common.traces.component.ComponentNameMatcher.Companion.LAUNCHER
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import com.android.server.wm.flicker.helpers.setRotation
import org.junit.Test
import org.junit.runners.Parameterized
/** Base class for exiting pip (closing pip window) without returning to the app */
-abstract class ClosePipTransition(flicker: FlickerTest) : PipTransition(flicker) {
+abstract class ClosePipTransition(flicker: LegacyFlickerTest) : PipTransition(flicker) {
override val thisTransition: FlickerBuilder.() -> Unit = {
setup { this.setRotation(flicker.scenario.startRotation) }
teardown { this.setRotation(Rotation.ROTATION_0) }
@@ -74,15 +74,14 @@
/**
* Creates the test configurations.
*
- * See [FlickerTestFactory.nonRotationTests] for configuring repetitions, screen orientation
- * and navigation modes.
+ * See [LegacyFlickerTestFactory.nonRotationTests] for configuring repetitions, screen
+ * orientation and navigation modes.
*/
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): List<FlickerTest> {
- return FlickerTestFactory.nonRotationTests(
+ fun getParams() =
+ LegacyFlickerTestFactory.nonRotationTests(
supportedRotations = listOf(Rotation.ROTATION_0)
)
- }
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ClosePipWithDismissButtonTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ClosePipWithDismissButtonTest.kt
index 86fe583..dc48696 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ClosePipWithDismissButtonTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ClosePipWithDismissButtonTest.kt
@@ -19,7 +19,7 @@
import android.platform.test.annotations.Presubmit
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTest
import androidx.test.filters.RequiresDevice
import org.junit.FixMethodOrder
import org.junit.Test
@@ -53,7 +53,7 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class ClosePipWithDismissButtonTest(flicker: FlickerTest) : ClosePipTransition(flicker) {
+open class ClosePipWithDismissButtonTest(flicker: LegacyFlickerTest) : ClosePipTransition(flicker) {
override val thisTransition: FlickerBuilder.() -> Unit = {
transitions { pipApp.closePipWindow(wmHelper) }
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ClosePipWithDismissButtonTestCfArm.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ClosePipWithDismissButtonTestCfArm.kt
index 05262fe..718b14b 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ClosePipWithDismissButtonTestCfArm.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ClosePipWithDismissButtonTestCfArm.kt
@@ -18,8 +18,8 @@
import android.tools.common.Rotation
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import org.junit.FixMethodOrder
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
@@ -28,21 +28,20 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class ClosePipWithDismissButtonTestCfArm(flicker: FlickerTest) :
+open class ClosePipWithDismissButtonTestCfArm(flicker: LegacyFlickerTest) :
ClosePipWithDismissButtonTest(flicker) {
companion object {
/**
* Creates the test configurations.
*
- * See [FlickerTestFactory.nonRotationTests] for configuring repetitions, screen orientation
- * and navigation modes.
+ * See [LegacyFlickerTestFactory.nonRotationTests] for configuring repetitions, screen
+ * orientation and navigation modes.
*/
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): List<FlickerTest> {
- return FlickerTestFactory.nonRotationTests(
+ fun getParams() =
+ LegacyFlickerTestFactory.nonRotationTests(
supportedRotations = listOf(Rotation.ROTATION_0)
)
- }
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipOnUserLeaveHintTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipOnUserLeaveHintTest.kt
index 01d67cc..5e39262 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipOnUserLeaveHintTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipOnUserLeaveHintTest.kt
@@ -19,7 +19,7 @@
import android.platform.test.annotations.Presubmit
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTest
import androidx.test.filters.RequiresDevice
import org.junit.Assume
import org.junit.FixMethodOrder
@@ -44,10 +44,8 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class EnterPipOnUserLeaveHintTest(flicker: FlickerTest) : EnterPipTransition(flicker) {
- override val thisTransition: FlickerBuilder.() -> Unit = {
- transitions { tapl.goHome() }
- }
+open class EnterPipOnUserLeaveHintTest(flicker: LegacyFlickerTest) : EnterPipTransition(flicker) {
+ override val thisTransition: FlickerBuilder.() -> Unit = { transitions { tapl.goHome() } }
override val defaultEnterPip: FlickerBuilder.() -> Unit = {
setup {
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipOnUserLeaveHintTestCfArm.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipOnUserLeaveHintTestCfArm.kt
index 90f99c0..2b3e76a 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipOnUserLeaveHintTestCfArm.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipOnUserLeaveHintTestCfArm.kt
@@ -17,7 +17,7 @@
package com.android.wm.shell.flicker.pip
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
-import android.tools.device.flicker.legacy.FlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTest
import org.junit.FixMethodOrder
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
@@ -27,4 +27,5 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class EnterPipOnUserLeaveHintTestCfArm(flicker: FlickerTest) : EnterPipOnUserLeaveHintTest(flicker)
+class EnterPipOnUserLeaveHintTestCfArm(flicker: LegacyFlickerTest) :
+ EnterPipOnUserLeaveHintTest(flicker)
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientation.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientation.kt
index 5480144..ec35837 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientation.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientation.kt
@@ -21,11 +21,12 @@
import android.platform.test.annotations.Postsubmit
import android.platform.test.annotations.Presubmit
import android.tools.common.Rotation
+import android.tools.common.flicker.assertions.FlickerTest
import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import android.tools.device.helpers.WindowUtils
import androidx.test.filters.RequiresDevice
import com.android.server.wm.flicker.entireScreenCovered
@@ -68,15 +69,13 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class EnterPipToOtherOrientation(flicker: FlickerTest) : PipTransition(flicker) {
+open class EnterPipToOtherOrientation(flicker: LegacyFlickerTest) : PipTransition(flicker) {
private val testApp = FixedOrientationAppHelper(instrumentation)
private val startingBounds = WindowUtils.getDisplayBounds(Rotation.ROTATION_90)
private val endingBounds = WindowUtils.getDisplayBounds(Rotation.ROTATION_0)
override val thisTransition: FlickerBuilder.() -> Unit = {
- teardown {
- testApp.exit(wmHelper)
- }
+ teardown { testApp.exit(wmHelper) }
transitions {
// Enter PiP, and assert that the PiP is within bounds now that the device is back
// in portrait
@@ -95,14 +94,13 @@
setup {
// Launch a portrait only app on the fullscreen stack
testApp.launchViaIntent(
- wmHelper,
- stringExtras = mapOf(EXTRA_FIXED_ORIENTATION to ORIENTATION_PORTRAIT.toString())
+ wmHelper,
+ stringExtras = mapOf(EXTRA_FIXED_ORIENTATION to ORIENTATION_PORTRAIT.toString())
)
// Launch the PiP activity fixed as landscape, but don't enter PiP
pipApp.launchViaIntent(
- wmHelper,
- stringExtras =
- mapOf(EXTRA_FIXED_ORIENTATION to ORIENTATION_LANDSCAPE.toString())
+ wmHelper,
+ stringExtras = mapOf(EXTRA_FIXED_ORIENTATION to ORIENTATION_LANDSCAPE.toString())
)
}
}
@@ -207,13 +205,13 @@
/**
* Creates the test configurations.
*
- * See [FlickerTestFactory.nonRotationTests] for configuring screen orientation and
+ * See [LegacyFlickerTestFactory.nonRotationTests] for configuring screen orientation and
* navigation modes.
*/
@Parameterized.Parameters(name = "{0}")
@JvmStatic
fun getParams(): Collection<FlickerTest> {
- return FlickerTestFactory.nonRotationTests(
+ return LegacyFlickerTestFactory.nonRotationTests(
supportedRotations = listOf(Rotation.ROTATION_0)
)
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientationCfArm.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientationCfArm.kt
index 5841666..9264219 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientationCfArm.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientationCfArm.kt
@@ -17,9 +17,10 @@
package com.android.wm.shell.flicker.pip
import android.tools.common.Rotation
+import android.tools.common.flicker.assertions.FlickerTest
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import org.junit.FixMethodOrder
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
@@ -29,19 +30,19 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class EnterPipToOtherOrientationCfArm(flicker: FlickerTest) :
+open class EnterPipToOtherOrientationCfArm(flicker: LegacyFlickerTest) :
EnterPipToOtherOrientation(flicker) {
companion object {
/**
* Creates the test configurations.
*
- * See [FlickerTestFactory.nonRotationTests] for configuring screen orientation and
+ * See [LegacyFlickerTestFactory.nonRotationTests] for configuring screen orientation and
* navigation modes.
*/
@Parameterized.Parameters(name = "{0}")
@JvmStatic
fun getParams(): Collection<FlickerTest> {
- return FlickerTestFactory.nonRotationTests(
+ return LegacyFlickerTestFactory.nonRotationTests(
supportedRotations = listOf(Rotation.ROTATION_0)
)
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTransition.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTransition.kt
index cdbdb85..6d20740 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTransition.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTransition.kt
@@ -20,16 +20,14 @@
import android.tools.common.Rotation
import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import org.junit.Test
import org.junit.runners.Parameterized
-abstract class EnterPipTransition(flicker: FlickerTest) : PipTransition(flicker) {
+abstract class EnterPipTransition(flicker: LegacyFlickerTest) : PipTransition(flicker) {
override val defaultEnterPip: FlickerBuilder.() -> Unit = {
- setup {
- pipApp.launchViaIntent(wmHelper)
- }
+ setup { pipApp.launchViaIntent(wmHelper) }
}
/** Checks [pipApp] window remains visible throughout the animation */
@@ -126,15 +124,14 @@
/**
* Creates the test configurations.
*
- * See [FlickerTestFactory.nonRotationTests] for configuring repetitions, screen orientation
- * and navigation modes.
+ * See [LegacyFlickerTestFactory.nonRotationTests] for configuring repetitions, screen
+ * orientation and navigation modes.
*/
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): List<FlickerTest> {
- return FlickerTestFactory.nonRotationTests(
+ fun getParams() =
+ LegacyFlickerTestFactory.nonRotationTests(
supportedRotations = listOf(Rotation.ROTATION_0)
)
- }
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipViaAppUiButtonTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipViaAppUiButtonTest.kt
index 95725b6..76c811c 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipViaAppUiButtonTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipViaAppUiButtonTest.kt
@@ -18,7 +18,7 @@
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTest
import androidx.test.filters.RequiresDevice
import org.junit.FixMethodOrder
import org.junit.runner.RunWith
@@ -50,7 +50,7 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class EnterPipViaAppUiButtonTest(flicker: FlickerTest) : EnterPipTransition(flicker) {
+open class EnterPipViaAppUiButtonTest(flicker: LegacyFlickerTest) : EnterPipTransition(flicker) {
override val thisTransition: FlickerBuilder.() -> Unit = {
transitions { pipApp.clickEnterPipButton(wmHelper) }
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipViaAppUiButtonTestCfArm.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipViaAppUiButtonTestCfArm.kt
index 4390f0b..78e8049 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipViaAppUiButtonTestCfArm.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipViaAppUiButtonTestCfArm.kt
@@ -18,8 +18,8 @@
import android.tools.common.Rotation
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import org.junit.FixMethodOrder
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
@@ -28,20 +28,20 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class EnterPipViaAppUiButtonTestCfArm(flicker: FlickerTest) : EnterPipViaAppUiButtonTest(flicker) {
+class EnterPipViaAppUiButtonTestCfArm(flicker: LegacyFlickerTest) :
+ EnterPipViaAppUiButtonTest(flicker) {
companion object {
/**
* Creates the test configurations.
*
- * See [FlickerTestFactory.nonRotationTests] for configuring repetitions, screen orientation
- * and navigation modes.
+ * See [LegacyFlickerTestFactory.nonRotationTests] for configuring repetitions, screen
+ * orientation and navigation modes.
*/
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): List<FlickerTest> {
- return FlickerTestFactory.nonRotationTests(
+ fun getParams() =
+ LegacyFlickerTestFactory.nonRotationTests(
supportedRotations = listOf(Rotation.ROTATION_0)
)
- }
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipToAppTransition.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipToAppTransition.kt
index 5ac9829..dfffba8 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipToAppTransition.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipToAppTransition.kt
@@ -19,14 +19,14 @@
import android.platform.test.annotations.Presubmit
import android.tools.common.Rotation
import android.tools.common.traces.component.ComponentNameMatcher
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import com.android.server.wm.flicker.helpers.SimpleAppHelper
import org.junit.Test
import org.junit.runners.Parameterized
/** Base class for pip expand tests */
-abstract class ExitPipToAppTransition(flicker: FlickerTest) : PipTransition(flicker) {
+abstract class ExitPipToAppTransition(flicker: LegacyFlickerTest) : PipTransition(flicker) {
protected val testApp = SimpleAppHelper(instrumentation)
/**
@@ -130,15 +130,14 @@
/**
* Creates the test configurations.
*
- * See [FlickerTestFactory.nonRotationTests] for configuring screen orientation and
+ * See [LegacyFlickerTestFactory.nonRotationTests] for configuring screen orientation and
* navigation modes.
*/
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): List<FlickerTest> {
- return FlickerTestFactory.nonRotationTests(
+ fun getParams() =
+ LegacyFlickerTestFactory.nonRotationTests(
supportedRotations = listOf(Rotation.ROTATION_0)
)
- }
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipToAppViaExpandButtonTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipToAppViaExpandButtonTest.kt
index 0b3d16a..b80b748 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipToAppViaExpandButtonTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipToAppViaExpandButtonTest.kt
@@ -18,7 +18,7 @@
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTest
import androidx.test.filters.RequiresDevice
import org.junit.FixMethodOrder
import org.junit.runner.RunWith
@@ -52,7 +52,8 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class ExitPipToAppViaExpandButtonTest(flicker: FlickerTest) : ExitPipToAppTransition(flicker) {
+open class ExitPipToAppViaExpandButtonTest(flicker: LegacyFlickerTest) :
+ ExitPipToAppTransition(flicker) {
override val thisTransition: FlickerBuilder.() -> Unit = {
setup {
// launch an app behind the pip one
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipToAppViaExpandButtonTestCfArm.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipToAppViaExpandButtonTestCfArm.kt
index eccb85d..e25c0d6 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipToAppViaExpandButtonTestCfArm.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipToAppViaExpandButtonTestCfArm.kt
@@ -18,8 +18,8 @@
import android.tools.common.Rotation
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import org.junit.FixMethodOrder
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
@@ -28,21 +28,20 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class ExitPipToAppViaExpandButtonTestCfArm(flicker: FlickerTest) :
+class ExitPipToAppViaExpandButtonTestCfArm(flicker: LegacyFlickerTest) :
ExitPipToAppViaExpandButtonTest(flicker) {
companion object {
/**
* Creates the test configurations.
*
- * See [FlickerTestFactory.nonRotationTests] for configuring screen orientation and
+ * See [LegacyFlickerTestFactory.nonRotationTests] for configuring screen orientation and
* navigation modes.
*/
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): List<FlickerTest> {
- return FlickerTestFactory.nonRotationTests(
+ fun getParams() =
+ LegacyFlickerTestFactory.nonRotationTests(
supportedRotations = listOf(Rotation.ROTATION_0)
)
- }
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipToAppViaIntentTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipToAppViaIntentTest.kt
index bb2d40b..f003ed8 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipToAppViaIntentTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipToAppViaIntentTest.kt
@@ -18,7 +18,7 @@
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTest
import androidx.test.filters.RequiresDevice
import org.junit.FixMethodOrder
import org.junit.runner.RunWith
@@ -51,7 +51,7 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class ExitPipToAppViaIntentTest(flicker: FlickerTest) : ExitPipToAppTransition(flicker) {
+open class ExitPipToAppViaIntentTest(flicker: LegacyFlickerTest) : ExitPipToAppTransition(flicker) {
override val thisTransition: FlickerBuilder.() -> Unit = {
setup {
// launch an app behind the pip one
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipToAppViaIntentTestCfArm.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipToAppViaIntentTestCfArm.kt
index 6ab6a1f..be19f3c 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipToAppViaIntentTestCfArm.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipToAppViaIntentTestCfArm.kt
@@ -18,8 +18,8 @@
import android.tools.common.Rotation
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import org.junit.FixMethodOrder
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
@@ -28,20 +28,20 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class ExitPipToAppViaIntentTestCfArm(flicker: FlickerTest) : ExitPipToAppViaIntentTest(flicker) {
+class ExitPipToAppViaIntentTestCfArm(flicker: LegacyFlickerTest) :
+ ExitPipToAppViaIntentTest(flicker) {
companion object {
/**
* Creates the test configurations.
*
- * See [FlickerTestFactory.nonRotationTests] for configuring repetitions, screen orientation
- * and navigation modes.
+ * See [LegacyFlickerTestFactory.nonRotationTests] for configuring repetitions, screen
+ * orientation and navigation modes.
*/
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): List<FlickerTest> {
- return FlickerTestFactory.nonRotationTests(
+ fun getParams() =
+ LegacyFlickerTestFactory.nonRotationTests(
supportedRotations = listOf(Rotation.ROTATION_0)
)
- }
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTest.kt
index fd16b6e..a1d3a11 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTest.kt
@@ -21,8 +21,8 @@
import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import androidx.test.filters.RequiresDevice
import org.junit.FixMethodOrder
import org.junit.Test
@@ -55,7 +55,7 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class ExpandPipOnDoubleClickTest(flicker: FlickerTest) : PipTransition(flicker) {
+open class ExpandPipOnDoubleClickTest(flicker: LegacyFlickerTest) : PipTransition(flicker) {
override val thisTransition: FlickerBuilder.() -> Unit = {
transitions { pipApp.doubleClickPipWindow(wmHelper) }
}
@@ -142,15 +142,14 @@
/**
* Creates the test configurations.
*
- * See [FlickerTestFactory.nonRotationTests] for configuring screen orientation and
+ * See [LegacyFlickerTestFactory.nonRotationTests] for configuring screen orientation and
* navigation modes.
*/
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): List<FlickerTest> {
- return FlickerTestFactory.nonRotationTests(
+ fun getParams() =
+ LegacyFlickerTestFactory.nonRotationTests(
supportedRotations = listOf(Rotation.ROTATION_0)
)
- }
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTestTestCfArm.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTestTestCfArm.kt
index c096234..3095cac 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTestTestCfArm.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTestTestCfArm.kt
@@ -18,8 +18,8 @@
import android.tools.common.Rotation
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import org.junit.FixMethodOrder
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
@@ -28,21 +28,20 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class ExpandPipOnDoubleClickTestTestCfArm(flicker: FlickerTest) :
+class ExpandPipOnDoubleClickTestTestCfArm(flicker: LegacyFlickerTest) :
ExpandPipOnDoubleClickTest(flicker) {
companion object {
/**
* Creates the test configurations.
*
- * See [FlickerTestFactory.nonRotationTests] for configuring screen orientation and
+ * See [LegacyFlickerTestFactory.nonRotationTests] for configuring screen orientation and
* navigation modes.
*/
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): List<FlickerTest> {
- return FlickerTestFactory.nonRotationTests(
+ fun getParams() =
+ LegacyFlickerTestFactory.nonRotationTests(
supportedRotations = listOf(Rotation.ROTATION_0)
)
- }
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnPinchOpenTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnPinchOpenTest.kt
index 253aa4c..8c8d280 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnPinchOpenTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnPinchOpenTest.kt
@@ -20,8 +20,8 @@
import android.tools.common.Rotation
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import androidx.test.filters.RequiresDevice
import org.junit.FixMethodOrder
import org.junit.Test
@@ -34,7 +34,7 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class ExpandPipOnPinchOpenTest(flicker: FlickerTest) : PipTransition(flicker) {
+open class ExpandPipOnPinchOpenTest(flicker: LegacyFlickerTest) : PipTransition(flicker) {
override val thisTransition: FlickerBuilder.() -> Unit = {
transitions { pipApp.pinchOpenPipWindow(wmHelper, 0.25f, 30) }
}
@@ -55,15 +55,14 @@
/**
* Creates the test configurations.
*
- * See [FlickerTestFactory.nonRotationTests] for configuring screen orientation and
+ * See [LegacyFlickerTestFactory.nonRotationTests] for configuring screen orientation and
* navigation modes.
*/
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): List<FlickerTest> {
- return FlickerTestFactory.nonRotationTests(
+ fun getParams() =
+ LegacyFlickerTestFactory.nonRotationTests(
supportedRotations = listOf(Rotation.ROTATION_0)
)
- }
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnPinchOpenTestCfArm.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnPinchOpenTestCfArm.kt
index e064bf2..1a1ce68 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnPinchOpenTestCfArm.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnPinchOpenTestCfArm.kt
@@ -18,8 +18,8 @@
import android.tools.common.Rotation
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import org.junit.FixMethodOrder
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
@@ -28,20 +28,20 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class ExpandPipOnPinchOpenTestCfArm(flicker: FlickerTest) : ExpandPipOnPinchOpenTest(flicker) {
+class ExpandPipOnPinchOpenTestCfArm(flicker: LegacyFlickerTest) :
+ ExpandPipOnPinchOpenTest(flicker) {
companion object {
/**
* Creates the test configurations.
*
- * See [FlickerTestFactory.nonRotationTests] for configuring screen orientation and
+ * See [LegacyFlickerTestFactory.nonRotationTests] for configuring screen orientation and
* navigation modes.
*/
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): List<FlickerTest> {
- return FlickerTestFactory.nonRotationTests(
+ fun getParams() =
+ LegacyFlickerTestFactory.nonRotationTests(
supportedRotations = listOf(Rotation.ROTATION_0)
)
- }
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipDownOnShelfHeightChange.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipDownOnShelfHeightChange.kt
index 094060f..4f88184 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipDownOnShelfHeightChange.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipDownOnShelfHeightChange.kt
@@ -19,7 +19,7 @@
import android.platform.test.annotations.Presubmit
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTest
import androidx.test.filters.RequiresDevice
import com.android.wm.shell.flicker.Direction
import org.junit.FixMethodOrder
@@ -55,7 +55,8 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class MovePipDownOnShelfHeightChange(flicker: FlickerTest) : MovePipShelfHeightTransition(flicker) {
+class MovePipDownOnShelfHeightChange(flicker: LegacyFlickerTest) :
+ MovePipShelfHeightTransition(flicker) {
override val thisTransition: FlickerBuilder.() -> Unit = {
teardown { testApp.exit(wmHelper) }
transitions { testApp.launchViaIntent(wmHelper) }
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipOnImeVisibilityChangeTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipOnImeVisibilityChangeTest.kt
index ff51c27..dffc822 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipOnImeVisibilityChangeTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipOnImeVisibilityChangeTest.kt
@@ -18,11 +18,12 @@
import android.platform.test.annotations.Presubmit
import android.tools.common.Rotation
+import android.tools.common.flicker.assertions.FlickerTest
import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import android.tools.device.helpers.WindowUtils
import androidx.test.filters.RequiresDevice
import com.android.server.wm.flicker.helpers.ImeAppHelper
@@ -38,7 +39,7 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class MovePipOnImeVisibilityChangeTest(flicker: FlickerTest) : PipTransition(flicker) {
+open class MovePipOnImeVisibilityChangeTest(flicker: LegacyFlickerTest) : PipTransition(flicker) {
private val imeApp = ImeAppHelper(instrumentation)
override val thisTransition: FlickerBuilder.() -> Unit = {
@@ -80,7 +81,7 @@
@Parameterized.Parameters(name = "{0}")
@JvmStatic
fun getParams(): Collection<FlickerTest> {
- return FlickerTestFactory.nonRotationTests(
+ return LegacyFlickerTestFactory.nonRotationTests(
supportedRotations = listOf(Rotation.ROTATION_0)
)
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipOnImeVisibilityChangeTestCfArm.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipOnImeVisibilityChangeTestCfArm.kt
index d3d77d2..63292a4 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipOnImeVisibilityChangeTestCfArm.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipOnImeVisibilityChangeTestCfArm.kt
@@ -17,9 +17,10 @@
package com.android.wm.shell.flicker.pip
import android.tools.common.Rotation
+import android.tools.common.flicker.assertions.FlickerTest
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import org.junit.FixMethodOrder
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
@@ -28,7 +29,7 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class MovePipOnImeVisibilityChangeTestCfArm(flicker: FlickerTest) :
+class MovePipOnImeVisibilityChangeTestCfArm(flicker: LegacyFlickerTest) :
MovePipOnImeVisibilityChangeTest(flicker) {
companion object {
private const val TAG_IME_VISIBLE = "imeIsVisible"
@@ -36,7 +37,7 @@
@Parameterized.Parameters(name = "{0}")
@JvmStatic
fun getParams(): Collection<FlickerTest> {
- return FlickerTestFactory.nonRotationTests(
+ return LegacyFlickerTestFactory.nonRotationTests(
supportedRotations = listOf(Rotation.ROTATION_0)
)
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipShelfHeightTransition.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipShelfHeightTransition.kt
index 109354a..9a2fa09 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipShelfHeightTransition.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipShelfHeightTransition.kt
@@ -19,15 +19,15 @@
import android.platform.test.annotations.Presubmit
import android.tools.common.Rotation
import android.tools.common.flicker.subject.region.RegionSubject
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import com.android.server.wm.flicker.helpers.FixedOrientationAppHelper
import com.android.wm.shell.flicker.Direction
import org.junit.Test
import org.junit.runners.Parameterized
/** Base class for pip tests with Launcher shelf height change */
-abstract class MovePipShelfHeightTransition(flicker: FlickerTest) : PipTransition(flicker) {
+abstract class MovePipShelfHeightTransition(flicker: LegacyFlickerTest) : PipTransition(flicker) {
protected val testApp = FixedOrientationAppHelper(instrumentation)
/** Checks [pipApp] window remains visible throughout the animation */
@@ -111,15 +111,14 @@
/**
* Creates the test configurations.
*
- * See [FlickerTestFactory.nonRotationTests] for configuring screen orientation and
+ * See [LegacyFlickerTestFactory.nonRotationTests] for configuring screen orientation and
* navigation modes.
*/
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): List<FlickerTest> {
- return FlickerTestFactory.nonRotationTests(
+ fun getParams() =
+ LegacyFlickerTestFactory.nonRotationTests(
supportedRotations = listOf(Rotation.ROTATION_0)
)
- }
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipUpOnShelfHeightChangeTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipUpOnShelfHeightChangeTest.kt
index 27b061b..afb4af6 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipUpOnShelfHeightChangeTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipUpOnShelfHeightChangeTest.kt
@@ -19,7 +19,7 @@
import android.platform.test.annotations.Presubmit
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTest
import androidx.test.filters.RequiresDevice
import com.android.wm.shell.flicker.Direction
import org.junit.FixMethodOrder
@@ -55,14 +55,13 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class MovePipUpOnShelfHeightChangeTest(flicker: FlickerTest) :
+open class MovePipUpOnShelfHeightChangeTest(flicker: LegacyFlickerTest) :
MovePipShelfHeightTransition(flicker) {
- override val thisTransition: FlickerBuilder.() -> Unit =
- {
- setup { testApp.launchViaIntent(wmHelper) }
- transitions { tapl.pressHome() }
- teardown { testApp.exit(wmHelper) }
- }
+ override val thisTransition: FlickerBuilder.() -> Unit = {
+ setup { testApp.launchViaIntent(wmHelper) }
+ transitions { tapl.pressHome() }
+ teardown { testApp.exit(wmHelper) }
+ }
/** Checks that the visible region of [pipApp] window always moves up during the animation. */
@Presubmit @Test fun pipWindowMovesUp() = pipWindowMoves(Direction.UP)
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipDragTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipDragTest.kt
index 9f81ba8..7085d55 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipDragTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipDragTest.kt
@@ -20,8 +20,8 @@
import android.platform.test.annotations.RequiresDevice
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import com.android.server.wm.flicker.testapp.ActivityOptions
import org.junit.FixMethodOrder
import org.junit.Test
@@ -34,7 +34,7 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class PipDragTest(flicker: FlickerTest) : PipTransition(flicker) {
+class PipDragTest(flicker: LegacyFlickerTest) : PipTransition(flicker) {
private var isDraggedLeft: Boolean = true
override val thisTransition: FlickerBuilder.() -> Unit = {
@@ -81,13 +81,11 @@
/**
* Creates the test configurations.
*
- * See [FlickerTestFactory.nonRotationTests] for configuring screen orientation and
+ * See [LegacyFlickerTestFactory.nonRotationTests] for configuring screen orientation and
* navigation modes.
*/
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): List<FlickerTest> {
- return FlickerTestFactory.nonRotationTests()
- }
+ fun getParams() = LegacyFlickerTestFactory.nonRotationTests()
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipDragThenSnapTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipDragThenSnapTest.kt
index 9fe9f52..2b87766 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipDragThenSnapTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipDragThenSnapTest.kt
@@ -21,8 +21,8 @@
import android.tools.common.Rotation
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import android.tools.device.flicker.rules.RemoveAllTasksButHomeRule
import androidx.test.filters.RequiresDevice
import com.android.server.wm.flicker.helpers.setRotation
@@ -38,7 +38,7 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class PipDragThenSnapTest(flicker: FlickerTest) : PipTransition(flicker) {
+class PipDragThenSnapTest(flicker: LegacyFlickerTest) : PipTransition(flicker) {
// represents the direction in which the pip window should be snapping
private var willSnapRight: Boolean = true
@@ -99,15 +99,14 @@
/**
* Creates the test configurations.
*
- * See [FlickerTestFactory.nonRotationTests] for configuring screen orientation and
+ * See [LegacyFlickerTestFactory.nonRotationTests] for configuring screen orientation and
* navigation modes.
*/
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): List<FlickerTest> {
- return FlickerTestFactory.nonRotationTests(
+ fun getParams() =
+ LegacyFlickerTestFactory.nonRotationTests(
supportedRotations = listOf(Rotation.ROTATION_0)
)
- }
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipPinchInTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipPinchInTest.kt
index 60bf5ff..adc5ee3 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipPinchInTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipPinchInTest.kt
@@ -21,8 +21,8 @@
import android.tools.common.Rotation
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import androidx.test.filters.RequiresDevice
import org.junit.FixMethodOrder
import org.junit.Test
@@ -36,7 +36,7 @@
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@FlakyTest(bugId = 270677470)
-class PipPinchInTest(flicker: FlickerTest) : PipTransition(flicker) {
+class PipPinchInTest(flicker: LegacyFlickerTest) : PipTransition(flicker) {
override val thisTransition: FlickerBuilder.() -> Unit = {
transitions { pipApp.pinchInPipWindow(wmHelper, 0.4f, 30) }
}
@@ -57,15 +57,14 @@
/**
* Creates the test configurations.
*
- * See [FlickerTestFactory.nonRotationTests] for configuring screen orientation and
+ * See [LegacyFlickerTestFactory.nonRotationTests] for configuring screen orientation and
* navigation modes.
*/
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): List<FlickerTest> {
- return FlickerTestFactory.nonRotationTests(
+ fun getParams() =
+ LegacyFlickerTestFactory.nonRotationTests(
supportedRotations = listOf(Rotation.ROTATION_0)
)
- }
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipTransition.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipTransition.kt
index 17a178f..096af39 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipTransition.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipTransition.kt
@@ -22,7 +22,7 @@
import android.tools.common.Rotation
import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTest
import android.tools.device.flicker.rules.RemoveAllTasksButHomeRule.Companion.removeAllTasksButHome
import android.tools.device.helpers.WindowUtils
import com.android.server.wm.flicker.helpers.PipAppHelper
@@ -32,7 +32,7 @@
import com.google.common.truth.Truth
import org.junit.Test
-abstract class PipTransition(flicker: FlickerTest) : BaseTest(flicker) {
+abstract class PipTransition(flicker: LegacyFlickerTest) : BaseTest(flicker) {
protected val pipApp = PipAppHelper(instrumentation)
protected val displayBounds = WindowUtils.getDisplayBounds(flicker.scenario.startRotation)
protected val broadcastActionTrigger = BroadcastActionTrigger(instrumentation)
@@ -78,16 +78,16 @@
/** Defines the default method of entering PiP */
protected open val defaultEnterPip: FlickerBuilder.() -> Unit = {
setup {
- pipApp.launchViaIntentAndWaitForPip(wmHelper,
- stringExtras = mapOf(ActivityOptions.Pip.EXTRA_ENTER_PIP to "true"))
+ pipApp.launchViaIntentAndWaitForPip(
+ wmHelper,
+ stringExtras = mapOf(ActivityOptions.Pip.EXTRA_ENTER_PIP to "true")
+ )
}
}
/** Defines the default teardown required to clean up after the test */
protected open val defaultTeardown: FlickerBuilder.() -> Unit = {
- teardown {
- pipApp.exit(wmHelper)
- }
+ teardown { pipApp.exit(wmHelper) }
}
@Presubmit
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/SetRequestedOrientationWhilePinned.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/SetRequestedOrientationWhilePinned.kt
index c618e5a..c315e74 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/SetRequestedOrientationWhilePinned.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/SetRequestedOrientationWhilePinned.kt
@@ -21,10 +21,11 @@
import android.platform.test.annotations.Postsubmit
import android.platform.test.annotations.Presubmit
import android.tools.common.Rotation
+import android.tools.common.flicker.assertions.FlickerTest
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import android.tools.device.helpers.WindowUtils
import androidx.test.filters.RequiresDevice
import com.android.server.wm.flicker.testapp.ActivityOptions
@@ -46,7 +47,7 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class SetRequestedOrientationWhilePinned(flicker: FlickerTest) : PipTransition(flicker) {
+open class SetRequestedOrientationWhilePinned(flicker: LegacyFlickerTest) : PipTransition(flicker) {
private val startingBounds = WindowUtils.getDisplayBounds(Rotation.ROTATION_0)
private val endingBounds = WindowUtils.getDisplayBounds(Rotation.ROTATION_90)
@@ -69,20 +70,19 @@
setup {
// Launch the PiP activity fixed as landscape.
pipApp.launchViaIntent(
- wmHelper,
- stringExtras =
- mapOf(EXTRA_FIXED_ORIENTATION to ORIENTATION_LANDSCAPE.toString())
+ wmHelper,
+ stringExtras = mapOf(EXTRA_FIXED_ORIENTATION to ORIENTATION_LANDSCAPE.toString())
)
// Enter PiP.
broadcastActionTrigger.doAction(ActivityOptions.Pip.ACTION_ENTER_PIP)
// System bar may fade out during fixed rotation.
wmHelper
- .StateSyncBuilder()
- .withPipShown()
- .withRotation(Rotation.ROTATION_0)
- .withNavOrTaskBarVisible()
- .withStatusBarVisible()
- .waitForAndVerify()
+ .StateSyncBuilder()
+ .withPipShown()
+ .withRotation(Rotation.ROTATION_0)
+ .withNavOrTaskBarVisible()
+ .withStatusBarVisible()
+ .waitForAndVerify()
}
}
@@ -150,7 +150,7 @@
@Parameterized.Parameters(name = "{0}")
@JvmStatic
fun getParams(): Collection<FlickerTest> {
- return FlickerTestFactory.nonRotationTests(
+ return LegacyFlickerTestFactory.nonRotationTests(
supportedRotations = listOf(Rotation.ROTATION_0)
)
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ShowPipAndRotateDisplay.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ShowPipAndRotateDisplay.kt
index 43d6c8f..0ff9cff 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ShowPipAndRotateDisplay.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ShowPipAndRotateDisplay.kt
@@ -17,10 +17,11 @@
package com.android.wm.shell.flicker.pip
import android.platform.test.annotations.Presubmit
+import android.tools.common.flicker.assertions.FlickerTest
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import android.tools.device.helpers.WindowUtils
import androidx.test.filters.RequiresDevice
import com.android.server.wm.flicker.helpers.SimpleAppHelper
@@ -58,7 +59,7 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class ShowPipAndRotateDisplay(flicker: FlickerTest) : PipTransition(flicker) {
+open class ShowPipAndRotateDisplay(flicker: LegacyFlickerTest) : PipTransition(flicker) {
private val testApp = SimpleAppHelper(instrumentation)
private val screenBoundsStart = WindowUtils.getDisplayBounds(flicker.scenario.startRotation)
private val screenBoundsEnd = WindowUtils.getDisplayBounds(flicker.scenario.endRotation)
@@ -154,13 +155,13 @@
/**
* Creates the test configurations.
*
- * See [FlickerTestFactory.nonRotationTests] for configuring repetitions, screen orientation
- * and navigation modes.
+ * See [LegacyFlickerTestFactory.nonRotationTests] for configuring repetitions, screen
+ * orientation and navigation modes.
*/
@Parameterized.Parameters(name = "{0}")
@JvmStatic
fun getParams(): Collection<FlickerTest> {
- return FlickerTestFactory.rotationTests()
+ return LegacyFlickerTestFactory.rotationTests()
}
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ShowPipAndRotateDisplayCfArm.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ShowPipAndRotateDisplayCfArm.kt
index b7a2c47..2516471 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ShowPipAndRotateDisplayCfArm.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ShowPipAndRotateDisplayCfArm.kt
@@ -16,9 +16,10 @@
package com.android.wm.shell.flicker.pip
+import android.tools.common.flicker.assertions.FlickerTest
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import org.junit.FixMethodOrder
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
@@ -27,18 +28,18 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class ShowPipAndRotateDisplayCfArm(flicker: FlickerTest) : ShowPipAndRotateDisplay(flicker) {
+class ShowPipAndRotateDisplayCfArm(flicker: LegacyFlickerTest) : ShowPipAndRotateDisplay(flicker) {
companion object {
/**
* Creates the test configurations.
*
- * See [FlickerTestFactory.nonRotationTests] for configuring repetitions, screen orientation
- * and navigation modes.
+ * See [LegacyFlickerTestFactory.nonRotationTests] for configuring repetitions, screen
+ * orientation and navigation modes.
*/
@Parameterized.Parameters(name = "{0}")
@JvmStatic
fun getParams(): Collection<FlickerTest> {
- return FlickerTestFactory.rotationTests()
+ return LegacyFlickerTestFactory.rotationTests()
}
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/CopyContentInSplit.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/CopyContentInSplit.kt
index d1f0980..a43ad9b 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/CopyContentInSplit.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/CopyContentInSplit.kt
@@ -23,8 +23,8 @@
import android.tools.common.traces.component.EdgeExtensionComponentMatcher
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import androidx.test.filters.RequiresDevice
import com.android.wm.shell.flicker.ICommonAssertions
import com.android.wm.shell.flicker.SPLIT_SCREEN_DIVIDER_COMPONENT
@@ -45,13 +45,13 @@
/**
* Test copy content from the left to the right side of the split-screen.
*
- * To run this test: `atest WMShellFlickerTests:CopyContentInSplit`
+ * To run this test: `atest WMShellFlickerTestsSplitScreen:CopyContentInSplit`
*/
@RequiresDevice
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class CopyContentInSplit(override val flicker: FlickerTest) :
+class CopyContentInSplit(override val flicker: LegacyFlickerTest) :
CopyContentInSplitBenchmark(flicker), ICommonAssertions {
override val transition: FlickerBuilder.() -> Unit
get() = {
@@ -136,8 +136,6 @@
companion object {
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): List<FlickerTest> {
- return FlickerTestFactory.nonRotationTests()
- }
+ fun getParams() = LegacyFlickerTestFactory.nonRotationTests()
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByDivider.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByDivider.kt
index 4505b99..0b8f109 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByDivider.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByDivider.kt
@@ -21,7 +21,7 @@
import android.platform.test.annotations.Presubmit
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTest
import android.tools.device.helpers.WindowUtils
import androidx.test.filters.RequiresDevice
import com.android.wm.shell.flicker.ICommonAssertions
@@ -41,13 +41,13 @@
/**
* Test dismiss split screen by dragging the divider bar.
*
- * To run this test: `atest WMShellFlickerTests:DismissSplitScreenByDivider`
+ * To run this test: `atest WMShellFlickerTestsSplitScreen:DismissSplitScreenByDivider`
*/
@RequiresDevice
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class DismissSplitScreenByDivider(override val flicker: FlickerTest) :
+class DismissSplitScreenByDivider(override val flicker: LegacyFlickerTest) :
DismissSplitScreenByDividerBenchmark(flicker), ICommonAssertions {
override val transition: FlickerBuilder.() -> Unit
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByGoHome.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByGoHome.kt
index e05b221..38d4b40 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByGoHome.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByGoHome.kt
@@ -20,8 +20,8 @@
import android.platform.test.annotations.Presubmit
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import androidx.test.filters.RequiresDevice
import com.android.wm.shell.flicker.ICommonAssertions
import com.android.wm.shell.flicker.appWindowBecomesInvisible
@@ -38,13 +38,13 @@
/**
* Test dismiss split screen by go home.
*
- * To run this test: `atest WMShellFlickerTests:DismissSplitScreenByGoHome`
+ * To run this test: `atest WMShellFlickerTestsSplitScreen:DismissSplitScreenByGoHome`
*/
@RequiresDevice
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class DismissSplitScreenByGoHome(override val flicker: FlickerTest) :
+class DismissSplitScreenByGoHome(override val flicker: LegacyFlickerTest) :
DismissSplitScreenByGoHomeBenchmark(flicker), ICommonAssertions {
override val transition: FlickerBuilder.() -> Unit
get() = {
@@ -154,8 +154,6 @@
companion object {
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): List<FlickerTest> {
- return FlickerTestFactory.nonRotationTests()
- }
+ fun getParams() = LegacyFlickerTestFactory.nonRotationTests()
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DragDividerToResize.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DragDividerToResize.kt
index 63c5d14..a118c08 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DragDividerToResize.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DragDividerToResize.kt
@@ -21,8 +21,8 @@
import android.platform.test.annotations.Presubmit
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import androidx.test.filters.RequiresDevice
import com.android.wm.shell.flicker.ICommonAssertions
import com.android.wm.shell.flicker.SPLIT_SCREEN_DIVIDER_COMPONENT
@@ -43,13 +43,13 @@
/**
* Test resize split by dragging the divider bar.
*
- * To run this test: `atest WMShellFlickerTests:DragDividerToResize`
+ * To run this test: `atest WMShellFlickerTestsSplitScreen:DragDividerToResize`
*/
@RequiresDevice
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class DragDividerToResize(override val flicker: FlickerTest) :
+class DragDividerToResize(override val flicker: LegacyFlickerTest) :
DragDividerToResizeBenchmark(flicker), ICommonAssertions {
override val transition: FlickerBuilder.() -> Unit
get() = {
@@ -127,8 +127,6 @@
companion object {
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): List<FlickerTest> {
- return FlickerTestFactory.nonRotationTests()
- }
+ fun getParams() = LegacyFlickerTestFactory.nonRotationTests()
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromAllApps.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromAllApps.kt
index e558686..05c0480 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromAllApps.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromAllApps.kt
@@ -22,8 +22,8 @@
import android.tools.common.NavBar
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import androidx.test.filters.RequiresDevice
import com.android.wm.shell.flicker.ICommonAssertions
import com.android.wm.shell.flicker.SPLIT_SCREEN_DIVIDER_COMPONENT
@@ -45,13 +45,13 @@
* Test enter split screen by dragging app icon from all apps. This test is only for large screen
* devices.
*
- * To run this test: `atest WMShellFlickerTests:EnterSplitScreenByDragFromAllApps`
+ * To run this test: `atest WMShellFlickerTestsSplitScreen:EnterSplitScreenByDragFromAllApps`
*/
@RequiresDevice
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class EnterSplitScreenByDragFromAllApps(override val flicker: FlickerTest) :
+class EnterSplitScreenByDragFromAllApps(override val flicker: LegacyFlickerTest) :
EnterSplitScreenByDragFromAllAppsBenchmark(flicker), ICommonAssertions {
override val transition: FlickerBuilder.() -> Unit
get() = {
@@ -160,11 +160,10 @@
companion object {
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): List<FlickerTest> {
- return FlickerTestFactory.nonRotationTests(
+ fun getParams() =
+ LegacyFlickerTestFactory.nonRotationTests(
// TODO(b/176061063):The 3 buttons of nav bar do not exist in the hierarchy.
supportedNavigationModes = listOf(NavBar.MODE_GESTURAL)
)
- }
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromNotification.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromNotification.kt
index ab8ecc5..3a75fa6 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromNotification.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromNotification.kt
@@ -22,8 +22,8 @@
import android.tools.common.NavBar
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import androidx.test.filters.RequiresDevice
import com.android.wm.shell.flicker.ICommonAssertions
import com.android.wm.shell.flicker.SPLIT_SCREEN_DIVIDER_COMPONENT
@@ -44,13 +44,13 @@
* Test enter split screen by dragging app icon from notification. This test is only for large
* screen devices.
*
- * To run this test: `atest WMShellFlickerTests:EnterSplitScreenByDragFromNotification`
+ * To run this test: `atest WMShellFlickerTestsSplitScreen:EnterSplitScreenByDragFromNotification`
*/
@RequiresDevice
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class EnterSplitScreenByDragFromNotification(override val flicker: FlickerTest) :
+class EnterSplitScreenByDragFromNotification(override val flicker: LegacyFlickerTest) :
EnterSplitScreenByDragFromNotificationBenchmark(flicker), ICommonAssertions {
/** {@inheritDoc} */
override val transition: FlickerBuilder.() -> Unit
@@ -162,11 +162,10 @@
companion object {
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): List<FlickerTest> {
- return FlickerTestFactory.nonRotationTests(
+ fun getParams() =
+ LegacyFlickerTestFactory.nonRotationTests(
// TODO(b/176061063):The 3 buttons of nav bar do not exist in the hierarchy.
supportedNavigationModes = listOf(NavBar.MODE_GESTURAL)
)
- }
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromShortcut.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromShortcut.kt
index 516ca97..6d73f92 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromShortcut.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromShortcut.kt
@@ -21,8 +21,8 @@
import android.tools.common.NavBar
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import androidx.test.filters.RequiresDevice
import com.android.wm.shell.flicker.ICommonAssertions
import com.android.wm.shell.flicker.appWindowIsVisibleAtEnd
@@ -41,13 +41,13 @@
/**
* Test enter split screen by dragging a shortcut. This test is only for large screen devices.
*
- * To run this test: `atest WMShellFlickerTests:EnterSplitScreenByDragFromShortcut`
+ * To run this test: `atest WMShellFlickerTestsSplitScreen:EnterSplitScreenByDragFromShortcut`
*/
@RequiresDevice
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class EnterSplitScreenByDragFromShortcut(override val flicker: FlickerTest) :
+class EnterSplitScreenByDragFromShortcut(override val flicker: LegacyFlickerTest) :
EnterSplitScreenByDragFromShortcutBenchmark(flicker), ICommonAssertions {
override val transition: FlickerBuilder.() -> Unit
@@ -105,11 +105,10 @@
companion object {
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): List<FlickerTest> {
- return FlickerTestFactory.nonRotationTests(
+ fun getParams() =
+ LegacyFlickerTestFactory.nonRotationTests(
// TODO(b/176061063):The 3 buttons of nav bar do not exist in the hierarchy.
supportedNavigationModes = listOf(NavBar.MODE_GESTURAL)
)
- }
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromTaskbar.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromTaskbar.kt
index 4af7e24..15cae69 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromTaskbar.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromTaskbar.kt
@@ -22,8 +22,8 @@
import android.tools.common.NavBar
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import androidx.test.filters.RequiresDevice
import com.android.wm.shell.flicker.ICommonAssertions
import com.android.wm.shell.flicker.SPLIT_SCREEN_DIVIDER_COMPONENT
@@ -45,13 +45,13 @@
* Test enter split screen by dragging app icon from taskbar. This test is only for large screen
* devices.
*
- * To run this test: `atest WMShellFlickerTests:EnterSplitScreenByDragFromTaskbar`
+ * To run this test: `atest WMShellFlickerTestsSplitScreen:EnterSplitScreenByDragFromTaskbar`
*/
@RequiresDevice
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class EnterSplitScreenByDragFromTaskbar(override val flicker: FlickerTest) :
+class EnterSplitScreenByDragFromTaskbar(override val flicker: LegacyFlickerTest) :
EnterSplitScreenByDragFromTaskbarBenchmark(flicker), ICommonAssertions {
/** {@inheritDoc} */
override val transition: FlickerBuilder.() -> Unit
@@ -163,10 +163,9 @@
companion object {
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): List<FlickerTest> {
- return FlickerTestFactory.nonRotationTests(
+ fun getParams() =
+ LegacyFlickerTestFactory.nonRotationTests(
supportedNavigationModes = listOf(NavBar.MODE_GESTURAL)
)
- }
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenFromOverview.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenFromOverview.kt
index faad9e8..90399fc 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenFromOverview.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenFromOverview.kt
@@ -20,8 +20,8 @@
import android.platform.test.annotations.Presubmit
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import androidx.test.filters.RequiresDevice
import com.android.wm.shell.flicker.ICommonAssertions
import com.android.wm.shell.flicker.appWindowBecomesVisible
@@ -40,13 +40,13 @@
/**
* Test enter split screen from Overview.
*
- * To run this test: `atest WMShellFlickerTests:EnterSplitScreenFromOverview`
+ * To run this test: `atest WMShellFlickerTestsSplitScreen:EnterSplitScreenFromOverview`
*/
@RequiresDevice
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class EnterSplitScreenFromOverview(override val flicker: FlickerTest) :
+class EnterSplitScreenFromOverview(override val flicker: LegacyFlickerTest) :
EnterSplitScreenFromOverviewBenchmark(flicker), ICommonAssertions {
override val transition: FlickerBuilder.() -> Unit
get() = {
@@ -106,8 +106,6 @@
companion object {
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): List<FlickerTest> {
- return FlickerTestFactory.nonRotationTests()
- }
+ fun getParams() = LegacyFlickerTestFactory.nonRotationTests()
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SplitScreenBase.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SplitScreenBase.kt
index 195b73a..580b153 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SplitScreenBase.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SplitScreenBase.kt
@@ -18,11 +18,11 @@
import android.content.Context
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTest
import com.android.server.wm.flicker.helpers.setRotation
import com.android.wm.shell.flicker.BaseBenchmarkTest
-abstract class SplitScreenBase(flicker: FlickerTest) : BaseBenchmarkTest(flicker) {
+abstract class SplitScreenBase(flicker: LegacyFlickerTest) : BaseBenchmarkTest(flicker) {
protected val context: Context = instrumentation.context
protected val primaryApp = SplitScreenUtils.getPrimary(instrumentation)
protected val secondaryApp = SplitScreenUtils.getSecondary(instrumentation)
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SplitScreenUtils.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SplitScreenUtils.kt
index 1063dfd..27eaa40 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SplitScreenUtils.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SplitScreenUtils.kt
@@ -39,6 +39,7 @@
import com.android.server.wm.flicker.helpers.NotificationAppHelper
import com.android.server.wm.flicker.helpers.SimpleAppHelper
import com.android.server.wm.flicker.testapp.ActivityOptions
+import com.android.server.wm.flicker.testapp.ActivityOptions.SplitScreen.Primary
import com.android.wm.shell.flicker.LAUNCHER_UI_PACKAGE_NAME
import com.android.wm.shell.flicker.SYSTEM_UI_PACKAGE_NAME
import org.junit.Assert.assertNotNull
@@ -112,6 +113,17 @@
waitForSplitComplete(wmHelper, primaryApp, secondaryApp)
}
+ fun enterSplitViaIntent(
+ wmHelper: WindowManagerStateHelper,
+ primaryApp: StandardAppHelper,
+ secondaryApp: StandardAppHelper
+ ) {
+ val stringExtras = mapOf(Primary.EXTRA_LAUNCH_ADJACENT to "true")
+ primaryApp.launchViaIntent(wmHelper, null, null,
+ stringExtras)
+ waitForSplitComplete(wmHelper, primaryApp, secondaryApp)
+ }
+
fun splitFromOverview(tapl: LauncherInstrumentation, device: UiDevice) {
// Note: The initial split position in landscape is different between tablet and phone.
// In landscape, tablet will let the first app split to right side, and phone will
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchAppByDoubleTapDivider.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchAppByDoubleTapDivider.kt
index 03b8a75..e0a47b3 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchAppByDoubleTapDivider.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchAppByDoubleTapDivider.kt
@@ -22,8 +22,8 @@
import android.tools.common.NavBar
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import androidx.test.filters.RequiresDevice
import com.android.wm.shell.flicker.ICommonAssertions
import com.android.wm.shell.flicker.SPLIT_SCREEN_DIVIDER_COMPONENT
@@ -44,13 +44,13 @@
/**
* Test double tap the divider bar to switch the two apps.
*
- * To run this test: `atest WMShellFlickerTests:SwitchAppByDoubleTapDivider`
+ * To run this test: `atest WMShellFlickerTestsSplitScreen:SwitchAppByDoubleTapDivider`
*/
@RequiresDevice
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class SwitchAppByDoubleTapDivider(override val flicker: FlickerTest) :
+class SwitchAppByDoubleTapDivider(override val flicker: LegacyFlickerTest) :
SwitchAppByDoubleTapDividerBenchmark(flicker), ICommonAssertions {
override val transition: FlickerBuilder.() -> Unit
get() = {
@@ -120,11 +120,10 @@
companion object {
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): List<FlickerTest> {
- return FlickerTestFactory.nonRotationTests(
+ fun getParams() =
+ LegacyFlickerTestFactory.nonRotationTests(
// TODO(b/176061063):The 3 buttons of nav bar do not exist in the hierarchy.
supportedNavigationModes = listOf(NavBar.MODE_GESTURAL)
)
- }
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromAnotherApp.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromAnotherApp.kt
index 078d95d..a406009 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromAnotherApp.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromAnotherApp.kt
@@ -21,8 +21,8 @@
import android.tools.common.NavBar
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import androidx.test.filters.RequiresDevice
import com.android.wm.shell.flicker.ICommonAssertions
import com.android.wm.shell.flicker.appWindowBecomesVisible
@@ -39,13 +39,13 @@
/**
* Test quick switch to split pair from another app.
*
- * To run this test: `atest WMShellFlickerTests:SwitchBackToSplitFromAnotherApp`
+ * To run this test: `atest WMShellFlickerTestsSplitScreen:SwitchBackToSplitFromAnotherApp`
*/
@RequiresDevice
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class SwitchBackToSplitFromAnotherApp(override val flicker: FlickerTest) :
+class SwitchBackToSplitFromAnotherApp(override val flicker: LegacyFlickerTest) :
SwitchBackToSplitFromAnotherAppBenchmark(flicker), ICommonAssertions {
override val transition: FlickerBuilder.() -> Unit
get() = {
@@ -149,11 +149,10 @@
companion object {
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): List<FlickerTest> {
- return FlickerTestFactory.nonRotationTests(
+ fun getParams() =
+ LegacyFlickerTestFactory.nonRotationTests(
// TODO(b/176061063):The 3 buttons of nav bar do not exist in the hierarchy.
supportedNavigationModes = listOf(NavBar.MODE_GESTURAL)
)
- }
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromHome.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromHome.kt
index 7c84243..251bd10 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromHome.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromHome.kt
@@ -21,8 +21,8 @@
import android.tools.common.NavBar
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import androidx.test.filters.RequiresDevice
import com.android.wm.shell.flicker.ICommonAssertions
import com.android.wm.shell.flicker.appWindowBecomesVisible
@@ -39,13 +39,13 @@
/**
* Test quick switch to split pair from home.
*
- * To run this test: `atest WMShellFlickerTests:SwitchBackToSplitFromHome`
+ * To run this test: `atest WMShellFlickerTestsSplitScreen:SwitchBackToSplitFromHome`
*/
@RequiresDevice
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class SwitchBackToSplitFromHome(override val flicker: FlickerTest) :
+class SwitchBackToSplitFromHome(override val flicker: LegacyFlickerTest) :
SwitchBackToSplitFromHomeBenchmark(flicker), ICommonAssertions {
override val transition: FlickerBuilder.() -> Unit
get() = {
@@ -149,11 +149,10 @@
companion object {
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): List<FlickerTest> {
- return FlickerTestFactory.nonRotationTests(
+ fun getParams() =
+ LegacyFlickerTestFactory.nonRotationTests(
// TODO(b/176061063):The 3 buttons of nav bar do not exist in the hierarchy.
supportedNavigationModes = listOf(NavBar.MODE_GESTURAL)
)
- }
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromRecent.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromRecent.kt
index 7c46d3e..1dd45fe 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromRecent.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromRecent.kt
@@ -21,8 +21,8 @@
import android.tools.common.NavBar
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import androidx.test.filters.RequiresDevice
import com.android.wm.shell.flicker.ICommonAssertions
import com.android.wm.shell.flicker.appWindowBecomesVisible
@@ -39,13 +39,13 @@
/**
* Test switch back to split pair from recent.
*
- * To run this test: `atest WMShellFlickerTests:SwitchBackToSplitFromRecent`
+ * To run this test: `atest WMShellFlickerTestsSplitScreen:SwitchBackToSplitFromRecent`
*/
@RequiresDevice
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class SwitchBackToSplitFromRecent(override val flicker: FlickerTest) :
+class SwitchBackToSplitFromRecent(override val flicker: LegacyFlickerTest) :
SwitchBackToSplitFromRecentBenchmark(flicker), ICommonAssertions {
override val transition: FlickerBuilder.() -> Unit
get() = {
@@ -149,11 +149,10 @@
companion object {
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): List<FlickerTest> {
- return FlickerTestFactory.nonRotationTests(
+ fun getParams() =
+ LegacyFlickerTestFactory.nonRotationTests(
// TODO(b/176061063):The 3 buttons of nav bar do not exist in the hierarchy.
supportedNavigationModes = listOf(NavBar.MODE_GESTURAL)
)
- }
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBetweenSplitPairs.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBetweenSplitPairs.kt
index 674ba40..8f867df 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBetweenSplitPairs.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBetweenSplitPairs.kt
@@ -21,8 +21,8 @@
import android.platform.test.annotations.Presubmit
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import androidx.test.filters.RequiresDevice
import com.android.wm.shell.flicker.ICommonAssertions
import com.android.wm.shell.flicker.SPLIT_SCREEN_DIVIDER_COMPONENT
@@ -47,13 +47,13 @@
/**
* Test quick switch between two split pairs.
*
- * To run this test: `atest WMShellFlickerTests:SwitchBetweenSplitPairs`
+ * To run this test: `atest WMShellFlickerTestsSplitScreen:SwitchBetweenSplitPairs`
*/
@RequiresDevice
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class SwitchBetweenSplitPairs(override val flicker: FlickerTest) :
+class SwitchBetweenSplitPairs(override val flicker: LegacyFlickerTest) :
SwitchBetweenSplitPairsBenchmark(flicker), ICommonAssertions {
override val transition: FlickerBuilder.() -> Unit
get() = {
@@ -223,8 +223,6 @@
companion object {
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): List<FlickerTest> {
- return FlickerTestFactory.nonRotationTests()
- }
+ fun getParams() = LegacyFlickerTestFactory.nonRotationTests()
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/UnlockKeyguardToSplitScreen.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/UnlockKeyguardToSplitScreen.kt
index 676c150..994d6cb 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/UnlockKeyguardToSplitScreen.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/UnlockKeyguardToSplitScreen.kt
@@ -21,8 +21,8 @@
import android.tools.common.flicker.subject.region.RegionSubject
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import androidx.test.filters.RequiresDevice
import com.android.wm.shell.flicker.ICommonAssertions
import com.android.wm.shell.flicker.SPLIT_SCREEN_DIVIDER_COMPONENT
@@ -37,21 +37,21 @@
import org.junit.runners.Parameterized
/**
- * Test unlocking insecure keyguard to back to split screen tasks and verify the transition behavior.
+ * Test unlocking insecure keyguard to back to split screen tasks and verify the transition
+ * behavior.
*
- * To run this test: `atest WMShellFlickerTests:UnlockKeyguardToSplitScreen`
+ * To run this test: `atest WMShellFlickerTestsSplitScreen:UnlockKeyguardToSplitScreen`
*/
@RequiresDevice
@Postsubmit
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class UnlockKeyguardToSplitScreen(override val flicker: FlickerTest) :
- UnlockKeyguardToSplitScreenBenchmark(flicker), ICommonAssertions {
+class UnlockKeyguardToSplitScreen(override val flicker: LegacyFlickerTest) :
+ UnlockKeyguardToSplitScreenBenchmark(flicker), ICommonAssertions {
/** {@inheritDoc} */
override val transition: FlickerBuilder.() -> Unit
get() = {
- defaultSetup(this)
defaultTeardown(this)
thisTransition(this)
}
@@ -65,33 +65,35 @@
@Test
fun primaryAppBoundsIsVisibleAtEnd() =
- flicker.splitAppLayerBoundsIsVisibleAtEnd(
- primaryApp,
- landscapePosLeft = false,
- portraitPosTop = false
- )
+ flicker.splitAppLayerBoundsIsVisibleAtEnd(
+ primaryApp,
+ landscapePosLeft = false,
+ portraitPosTop = false
+ )
@Test
fun secondaryAppBoundsIsVisibleAtEnd() =
- flicker.splitAppLayerBoundsIsVisibleAtEnd(
- secondaryApp,
- landscapePosLeft = true,
- portraitPosTop = true
- )
+ flicker.splitAppLayerBoundsIsVisibleAtEnd(
+ secondaryApp,
+ landscapePosLeft = true,
+ portraitPosTop = true
+ )
- @Test
- fun primaryAppWindowIsVisibleAtEnd() = flicker.appWindowIsVisibleAtEnd(primaryApp)
+ @Test fun primaryAppWindowIsVisibleAtEnd() = flicker.appWindowIsVisibleAtEnd(primaryApp)
- @Test
- fun secondaryAppWindowIsVisibleAtEnd() = flicker.appWindowIsVisibleAtEnd(secondaryApp)
+ @Test fun secondaryAppWindowIsVisibleAtEnd() = flicker.appWindowIsVisibleAtEnd(secondaryApp)
@Test
fun notOverlapsForPrimaryAndSecondaryAppLayers() {
flicker.assertLayers {
this.invoke("notOverlapsForPrimaryAndSecondaryLayers") {
- val primaryAppRegions = it.subjects.filter { subject ->
- subject.name.contains(primaryApp.toLayerName()) && subject.isVisible
- }.mapNotNull { primaryApp -> primaryApp.layer.visibleRegion }.toTypedArray()
+ val primaryAppRegions =
+ it.subjects
+ .filter { subject ->
+ subject.name.contains(primaryApp.toLayerName()) && subject.isVisible
+ }
+ .mapNotNull { primaryApp -> primaryApp.layer.visibleRegion }
+ .toTypedArray()
val primaryAppRegionArea = RegionSubject(primaryAppRegions, it.timestamp)
it.visibleRegion(secondaryApp).notOverlaps(primaryAppRegionArea.region)
@@ -102,10 +104,9 @@
companion object {
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): List<FlickerTest> {
- return FlickerTestFactory.nonRotationTests(
- supportedNavigationModes = listOf(NavBar.MODE_GESTURAL)
+ fun getParams() =
+ LegacyFlickerTestFactory.nonRotationTests(
+ supportedNavigationModes = listOf(NavBar.MODE_GESTURAL)
)
- }
}
-}
\ No newline at end of file
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/CopyContentInSplitBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/CopyContentInSplitBenchmark.kt
index c3c5f88..d1ca9ea 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/CopyContentInSplitBenchmark.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/CopyContentInSplitBenchmark.kt
@@ -21,8 +21,8 @@
import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import androidx.test.filters.RequiresDevice
import com.android.wm.shell.flicker.splitscreen.SplitScreenBase
import com.android.wm.shell.flicker.splitscreen.SplitScreenUtils
@@ -36,7 +36,7 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class CopyContentInSplitBenchmark(override val flicker: FlickerTest) :
+open class CopyContentInSplitBenchmark(override val flicker: LegacyFlickerTest) :
SplitScreenBase(flicker) {
protected val textEditApp = SplitScreenUtils.getIme(instrumentation)
protected val magnifierLayer = ComponentNameMatcher("", "magnifier surface bbq wrapper#")
@@ -72,8 +72,6 @@
companion object {
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): List<FlickerTest> {
- return FlickerTestFactory.nonRotationTests()
- }
+ fun getParams() = LegacyFlickerTestFactory.nonRotationTests()
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/DismissSplitScreenByDividerBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/DismissSplitScreenByDividerBenchmark.kt
index 37cd18f..73acb1f 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/DismissSplitScreenByDividerBenchmark.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/DismissSplitScreenByDividerBenchmark.kt
@@ -20,8 +20,8 @@
import android.platform.test.annotations.Presubmit
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import androidx.test.filters.RequiresDevice
import com.android.wm.shell.flicker.splitScreenDismissed
import com.android.wm.shell.flicker.splitscreen.SplitScreenBase
@@ -36,7 +36,8 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class DismissSplitScreenByDividerBenchmark(flicker: FlickerTest) : SplitScreenBase(flicker) {
+open class DismissSplitScreenByDividerBenchmark(override val flicker: LegacyFlickerTest) :
+ SplitScreenBase(flicker) {
protected val thisTransition: FlickerBuilder.() -> Unit
get() = {
setup { SplitScreenUtils.enterSplit(wmHelper, tapl, device, primaryApp, secondaryApp) }
@@ -76,8 +77,6 @@
companion object {
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): List<FlickerTest> {
- return FlickerTestFactory.nonRotationTests()
- }
+ fun getParams() = LegacyFlickerTestFactory.nonRotationTests()
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/DismissSplitScreenByGoHomeBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/DismissSplitScreenByGoHomeBenchmark.kt
index 0ec6dc9..86ffd2a 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/DismissSplitScreenByGoHomeBenchmark.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/DismissSplitScreenByGoHomeBenchmark.kt
@@ -20,8 +20,8 @@
import android.platform.test.annotations.Presubmit
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import androidx.test.filters.RequiresDevice
import com.android.wm.shell.flicker.splitScreenDismissed
import com.android.wm.shell.flicker.splitscreen.SplitScreenBase
@@ -36,7 +36,7 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class DismissSplitScreenByGoHomeBenchmark(override val flicker: FlickerTest) :
+open class DismissSplitScreenByGoHomeBenchmark(override val flicker: LegacyFlickerTest) :
SplitScreenBase(flicker) {
protected val thisTransition: FlickerBuilder.() -> Unit
get() = {
@@ -63,8 +63,6 @@
companion object {
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): List<FlickerTest> {
- return FlickerTestFactory.nonRotationTests()
- }
+ fun getParams() = LegacyFlickerTestFactory.nonRotationTests()
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/DragDividerToResizeBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/DragDividerToResizeBenchmark.kt
index 190e2e7..dfde3b6 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/DragDividerToResizeBenchmark.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/DragDividerToResizeBenchmark.kt
@@ -20,8 +20,8 @@
import android.platform.test.annotations.Presubmit
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import androidx.test.filters.RequiresDevice
import com.android.wm.shell.flicker.splitscreen.SplitScreenBase
import com.android.wm.shell.flicker.splitscreen.SplitScreenUtils
@@ -37,7 +37,7 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class DragDividerToResizeBenchmark(override val flicker: FlickerTest) :
+open class DragDividerToResizeBenchmark(override val flicker: LegacyFlickerTest) :
SplitScreenBase(flicker) {
protected val thisTransition: FlickerBuilder.() -> Unit
get() = {
@@ -69,8 +69,6 @@
companion object {
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): List<FlickerTest> {
- return FlickerTestFactory.nonRotationTests()
- }
+ fun getParams() = LegacyFlickerTestFactory.nonRotationTests()
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromAllAppsBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromAllAppsBenchmark.kt
index 3a1d1a4..d13e413 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromAllAppsBenchmark.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromAllAppsBenchmark.kt
@@ -21,8 +21,8 @@
import android.tools.common.NavBar
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import androidx.test.filters.RequiresDevice
import com.android.wm.shell.flicker.splitScreenEntered
import com.android.wm.shell.flicker.splitscreen.SplitScreenBase
@@ -39,7 +39,7 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class EnterSplitScreenByDragFromAllAppsBenchmark(override val flicker: FlickerTest) :
+open class EnterSplitScreenByDragFromAllAppsBenchmark(override val flicker: LegacyFlickerTest) :
SplitScreenBase(flicker) {
protected val thisTransition: FlickerBuilder.() -> Unit
@@ -84,11 +84,10 @@
companion object {
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): List<FlickerTest> {
- return FlickerTestFactory.nonRotationTests(
+ fun getParams() =
+ LegacyFlickerTestFactory.nonRotationTests(
// TODO(b/176061063):The 3 buttons of nav bar do not exist in the hierarchy.
supportedNavigationModes = listOf(NavBar.MODE_GESTURAL)
)
- }
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromNotificationBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromNotificationBenchmark.kt
index 2033b7d..1d41669 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromNotificationBenchmark.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromNotificationBenchmark.kt
@@ -21,8 +21,8 @@
import android.tools.common.NavBar
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import androidx.test.filters.RequiresDevice
import com.android.wm.shell.flicker.splitScreenEntered
import com.android.wm.shell.flicker.splitscreen.SplitScreenBase
@@ -39,8 +39,9 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class EnterSplitScreenByDragFromNotificationBenchmark(override val flicker: FlickerTest) :
- SplitScreenBase(flicker) {
+open class EnterSplitScreenByDragFromNotificationBenchmark(
+ override val flicker: LegacyFlickerTest
+) : SplitScreenBase(flicker) {
protected val sendNotificationApp = SplitScreenUtils.getSendNotification(instrumentation)
protected val thisTransition: FlickerBuilder.() -> Unit
get() = {
@@ -81,11 +82,10 @@
companion object {
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): List<FlickerTest> {
- return FlickerTestFactory.nonRotationTests(
+ fun getParams() =
+ LegacyFlickerTestFactory.nonRotationTests(
// TODO(b/176061063):The 3 buttons of nav bar do not exist in the hierarchy.
supportedNavigationModes = listOf(NavBar.MODE_GESTURAL)
)
- }
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromShortcutBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromShortcutBenchmark.kt
index b7a7110..b4bafa7 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromShortcutBenchmark.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromShortcutBenchmark.kt
@@ -21,8 +21,8 @@
import android.tools.common.NavBar
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import androidx.test.filters.RequiresDevice
import com.android.wm.shell.flicker.splitScreenEntered
import com.android.wm.shell.flicker.splitscreen.SplitScreenBase
@@ -39,7 +39,7 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class EnterSplitScreenByDragFromShortcutBenchmark(flicker: FlickerTest) :
+open class EnterSplitScreenByDragFromShortcutBenchmark(override val flicker: LegacyFlickerTest) :
SplitScreenBase(flicker) {
@Before
fun before() {
@@ -84,11 +84,10 @@
companion object {
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): List<FlickerTest> {
- return FlickerTestFactory.nonRotationTests(
+ fun getParams() =
+ LegacyFlickerTestFactory.nonRotationTests(
// TODO(b/176061063):The 3 buttons of nav bar do not exist in the hierarchy.
supportedNavigationModes = listOf(NavBar.MODE_GESTURAL)
)
- }
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromTaskbarBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromTaskbarBenchmark.kt
index b1ce62f..da44ecd 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromTaskbarBenchmark.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromTaskbarBenchmark.kt
@@ -21,8 +21,8 @@
import android.tools.common.NavBar
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import androidx.test.filters.RequiresDevice
import com.android.wm.shell.flicker.splitScreenEntered
import com.android.wm.shell.flicker.splitscreen.SplitScreenBase
@@ -39,7 +39,7 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class EnterSplitScreenByDragFromTaskbarBenchmark(override val flicker: FlickerTest) :
+open class EnterSplitScreenByDragFromTaskbarBenchmark(override val flicker: LegacyFlickerTest) :
SplitScreenBase(flicker) {
protected val thisTransition: FlickerBuilder.() -> Unit
get() = {
@@ -84,10 +84,9 @@
companion object {
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): List<FlickerTest> {
- return FlickerTestFactory.nonRotationTests(
+ fun getParams() =
+ LegacyFlickerTestFactory.nonRotationTests(
supportedNavigationModes = listOf(NavBar.MODE_GESTURAL)
)
- }
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenFromOverviewBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenFromOverviewBenchmark.kt
index 14f0745..af06d6d 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenFromOverviewBenchmark.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenFromOverviewBenchmark.kt
@@ -20,8 +20,8 @@
import android.platform.test.annotations.Presubmit
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import androidx.test.filters.RequiresDevice
import com.android.wm.shell.flicker.splitScreenEntered
import com.android.wm.shell.flicker.splitscreen.SplitScreenBase
@@ -36,7 +36,7 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class EnterSplitScreenFromOverviewBenchmark(override val flicker: FlickerTest) :
+open class EnterSplitScreenFromOverviewBenchmark(override val flicker: LegacyFlickerTest) :
SplitScreenBase(flicker) {
protected val thisTransition: FlickerBuilder.() -> Unit
get() = {
@@ -72,8 +72,6 @@
companion object {
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): List<FlickerTest> {
- return FlickerTestFactory.nonRotationTests()
- }
+ fun getParams() = LegacyFlickerTestFactory.nonRotationTests()
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchAppByDoubleTapDividerBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchAppByDoubleTapDividerBenchmark.kt
index 65fb135..23156b5 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchAppByDoubleTapDividerBenchmark.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchAppByDoubleTapDividerBenchmark.kt
@@ -22,8 +22,8 @@
import android.tools.common.Rotation
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import android.tools.device.helpers.WindowUtils
import android.tools.device.traces.parsers.WindowManagerStateHelper
import androidx.test.filters.RequiresDevice
@@ -39,7 +39,7 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class SwitchAppByDoubleTapDividerBenchmark(override val flicker: FlickerTest) :
+open class SwitchAppByDoubleTapDividerBenchmark(override val flicker: LegacyFlickerTest) :
SplitScreenBase(flicker) {
protected val thisTransition: FlickerBuilder.() -> Unit
get() = {
@@ -145,11 +145,10 @@
companion object {
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): List<FlickerTest> {
- return FlickerTestFactory.nonRotationTests(
+ fun getParams() =
+ LegacyFlickerTestFactory.nonRotationTests(
// TODO(b/176061063):The 3 buttons of nav bar do not exist in the hierarchy.
supportedNavigationModes = listOf(NavBar.MODE_GESTURAL)
)
- }
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromAnotherAppBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromAnotherAppBenchmark.kt
index b333aba..2d810d3 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromAnotherAppBenchmark.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromAnotherAppBenchmark.kt
@@ -21,8 +21,8 @@
import android.tools.common.NavBar
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import androidx.test.filters.RequiresDevice
import com.android.wm.shell.flicker.splitScreenEntered
import com.android.wm.shell.flicker.splitscreen.SplitScreenBase
@@ -37,7 +37,7 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class SwitchBackToSplitFromAnotherAppBenchmark(override val flicker: FlickerTest) :
+open class SwitchBackToSplitFromAnotherAppBenchmark(override val flicker: LegacyFlickerTest) :
SplitScreenBase(flicker) {
private val thirdApp = SplitScreenUtils.getNonResizeable(instrumentation)
@@ -71,11 +71,10 @@
companion object {
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): List<FlickerTest> {
- return FlickerTestFactory.nonRotationTests(
+ fun getParams() =
+ LegacyFlickerTestFactory.nonRotationTests(
// TODO(b/176061063):The 3 buttons of nav bar do not exist in the hierarchy.
supportedNavigationModes = listOf(NavBar.MODE_GESTURAL)
)
- }
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromHomeBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromHomeBenchmark.kt
index a27540e..f6df1e4 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromHomeBenchmark.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromHomeBenchmark.kt
@@ -21,8 +21,8 @@
import android.tools.common.NavBar
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import androidx.test.filters.RequiresDevice
import com.android.wm.shell.flicker.splitScreenEntered
import com.android.wm.shell.flicker.splitscreen.SplitScreenBase
@@ -37,7 +37,7 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class SwitchBackToSplitFromHomeBenchmark(override val flicker: FlickerTest) :
+open class SwitchBackToSplitFromHomeBenchmark(override val flicker: LegacyFlickerTest) :
SplitScreenBase(flicker) {
protected val thisTransition: FlickerBuilder.() -> Unit
get() = {
@@ -69,11 +69,10 @@
companion object {
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): List<FlickerTest> {
- return FlickerTestFactory.nonRotationTests(
+ fun getParams() =
+ LegacyFlickerTestFactory.nonRotationTests(
// TODO(b/176061063):The 3 buttons of nav bar do not exist in the hierarchy.
supportedNavigationModes = listOf(NavBar.MODE_GESTURAL)
)
- }
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromRecentBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromRecentBenchmark.kt
index 18bf4ff..ba46bdc 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromRecentBenchmark.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromRecentBenchmark.kt
@@ -21,8 +21,8 @@
import android.tools.common.NavBar
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import androidx.test.filters.RequiresDevice
import com.android.wm.shell.flicker.splitScreenEntered
import com.android.wm.shell.flicker.splitscreen.SplitScreenBase
@@ -37,7 +37,7 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class SwitchBackToSplitFromRecentBenchmark(override val flicker: FlickerTest) :
+open class SwitchBackToSplitFromRecentBenchmark(override val flicker: LegacyFlickerTest) :
SplitScreenBase(flicker) {
protected val thisTransition: FlickerBuilder.() -> Unit
get() = {
@@ -69,11 +69,10 @@
companion object {
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): List<FlickerTest> {
- return FlickerTestFactory.nonRotationTests(
+ fun getParams() =
+ LegacyFlickerTestFactory.nonRotationTests(
// TODO(b/176061063):The 3 buttons of nav bar do not exist in the hierarchy.
supportedNavigationModes = listOf(NavBar.MODE_GESTURAL)
)
- }
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBetweenSplitPairsBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBetweenSplitPairsBenchmark.kt
index c5fe61e..0d871e5 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBetweenSplitPairsBenchmark.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBetweenSplitPairsBenchmark.kt
@@ -20,8 +20,8 @@
import android.platform.test.annotations.Presubmit
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import androidx.test.filters.RequiresDevice
import com.android.wm.shell.flicker.splitscreen.SplitScreenBase
import com.android.wm.shell.flicker.splitscreen.SplitScreenUtils
@@ -35,7 +35,7 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class SwitchBetweenSplitPairsBenchmark(override val flicker: FlickerTest) :
+open class SwitchBetweenSplitPairsBenchmark(override val flicker: LegacyFlickerTest) :
SplitScreenBase(flicker) {
protected val thirdApp = SplitScreenUtils.getIme(instrumentation)
protected val fourthApp = SplitScreenUtils.getSendNotification(instrumentation)
@@ -70,8 +70,6 @@
companion object {
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): List<FlickerTest> {
- return FlickerTestFactory.nonRotationTests()
- }
+ fun getParams() = LegacyFlickerTestFactory.nonRotationTests()
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/UnlockKeyguardToSplitScreenBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/UnlockKeyguardToSplitScreenBenchmark.kt
index 5f16e5b..7952b71 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/UnlockKeyguardToSplitScreenBenchmark.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/UnlockKeyguardToSplitScreenBenchmark.kt
@@ -19,8 +19,8 @@
import android.tools.common.NavBar
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import androidx.test.filters.RequiresDevice
import com.android.wm.shell.flicker.splitscreen.SplitScreenBase
import com.android.wm.shell.flicker.splitscreen.SplitScreenUtils
@@ -33,11 +33,11 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class UnlockKeyguardToSplitScreenBenchmark(override val flicker: FlickerTest) :
- SplitScreenBase(flicker) {
+open class UnlockKeyguardToSplitScreenBenchmark(override val flicker: LegacyFlickerTest) :
+ SplitScreenBase(flicker) {
protected val thisTransition: FlickerBuilder.() -> Unit
get() = {
- setup { SplitScreenUtils.enterSplit(wmHelper, tapl, device, primaryApp, secondaryApp) }
+ setup { SplitScreenUtils.enterSplitViaIntent(wmHelper, primaryApp, secondaryApp) }
transitions {
device.sleep()
wmHelper.StateSyncBuilder().withAppTransitionIdle().waitForAndVerify()
@@ -58,10 +58,9 @@
companion object {
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): List<FlickerTest> {
- return FlickerTestFactory.nonRotationTests(
- supportedNavigationModes = listOf(NavBar.MODE_GESTURAL)
+ fun getParams() =
+ LegacyFlickerTestFactory.nonRotationTests(
+ supportedNavigationModes = listOf(NavBar.MODE_GESTURAL)
)
- }
}
-}
\ No newline at end of file
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/BubbleOverflowTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/BubbleOverflowTest.java
index 8278c67..0dc16f4 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/BubbleOverflowTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/BubbleOverflowTest.java
@@ -64,18 +64,27 @@
}
@Test
- public void test_initialize() {
+ public void test_initialize_forStack() {
assertThat(mOverflow.getExpandedView()).isNull();
- mOverflow.initialize(mBubbleController);
+ mOverflow.initialize(mBubbleController, /* forBubbleBar= */ false);
assertThat(mOverflow.getExpandedView()).isNotNull();
assertThat(mOverflow.getExpandedView().getBubbleKey()).isEqualTo(BubbleOverflow.KEY);
+ assertThat(mOverflow.getBubbleBarExpandedView()).isNull();
+ }
+
+ @Test
+ public void test_initialize_forBubbleBar() {
+ mOverflow.initialize(mBubbleController, /* forBubbleBar= */ true);
+
+ assertThat(mOverflow.getBubbleBarExpandedView()).isNotNull();
+ assertThat(mOverflow.getExpandedView()).isNull();
}
@Test
public void test_cleanUpExpandedState() {
- mOverflow.createExpandedView();
+ mOverflow.initialize(mBubbleController, /* forBubbleBar= */ false);
assertThat(mOverflow.getExpandedView()).isNotNull();
mOverflow.cleanUpExpandedState();
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleDataRepositoryTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleDataRepositoryTest.kt
new file mode 100644
index 0000000..6d9d62d
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleDataRepositoryTest.kt
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.bubbles
+
+import android.app.ActivityTaskManager
+import android.content.pm.LauncherApps
+import android.content.pm.ShortcutInfo
+import android.util.SparseArray
+import com.android.wm.shell.ShellTestCase
+import com.android.wm.shell.bubbles.storage.BubbleEntity
+import com.android.wm.shell.bubbles.storage.BubblePersistentRepository
+import com.android.wm.shell.common.ShellExecutor
+import com.google.common.truth.Truth.assertThat
+import org.junit.After
+import org.junit.Before
+import org.junit.Test
+import org.mockito.Mockito.mock
+import org.mockito.Mockito.spy
+
+class BubbleDataRepositoryTest : ShellTestCase() {
+
+ private val user0BubbleEntities = listOf(
+ BubbleEntity(
+ userId = 0,
+ packageName = "com.example.messenger",
+ shortcutId = "shortcut-1",
+ key = "0k1",
+ desiredHeight = 120,
+ desiredHeightResId = 0,
+ title = null,
+ taskId = 1,
+ locus = null,
+ isDismissable = true
+ ),
+ BubbleEntity(
+ userId = 10,
+ packageName = "com.example.chat",
+ shortcutId = "alice and bob",
+ key = "0k2",
+ desiredHeight = 0,
+ desiredHeightResId = 16537428,
+ title = "title",
+ taskId = 2,
+ locus = null
+ ),
+ BubbleEntity(
+ userId = 0,
+ packageName = "com.example.messenger",
+ shortcutId = "shortcut-2",
+ key = "0k3",
+ desiredHeight = 120,
+ desiredHeightResId = 0,
+ title = null,
+ taskId = ActivityTaskManager.INVALID_TASK_ID,
+ locus = null
+ )
+ )
+
+ private val user1BubbleEntities = listOf(
+ BubbleEntity(
+ userId = 1,
+ packageName = "com.example.messenger",
+ shortcutId = "shortcut-1",
+ key = "1k1",
+ desiredHeight = 120,
+ desiredHeightResId = 0,
+ title = null,
+ taskId = 3,
+ locus = null,
+ isDismissable = true
+ ),
+ BubbleEntity(
+ userId = 12,
+ packageName = "com.example.chat",
+ shortcutId = "alice and bob",
+ key = "1k2",
+ desiredHeight = 0,
+ desiredHeightResId = 16537428,
+ title = "title",
+ taskId = 4,
+ locus = null
+ ),
+ BubbleEntity(
+ userId = 1,
+ packageName = "com.example.messenger",
+ shortcutId = "shortcut-2",
+ key = "1k3",
+ desiredHeight = 120,
+ desiredHeightResId = 0,
+ title = null,
+ taskId = ActivityTaskManager.INVALID_TASK_ID,
+ locus = null
+ ),
+ BubbleEntity(
+ userId = 12,
+ packageName = "com.example.chat",
+ shortcutId = "alice",
+ key = "1k4",
+ desiredHeight = 0,
+ desiredHeightResId = 16537428,
+ title = "title",
+ taskId = 5,
+ locus = null
+ )
+ )
+
+ private val mainExecutor = mock(ShellExecutor::class.java)
+ private val launcherApps = mock(LauncherApps::class.java)
+
+ private val persistedBubbles = SparseArray<List<BubbleEntity>>()
+
+ private lateinit var dataRepository: BubbleDataRepository
+ private lateinit var persistentRepository: BubblePersistentRepository
+
+ @Before
+ fun setup() {
+ persistentRepository = spy(BubblePersistentRepository(mContext))
+ dataRepository = BubbleDataRepository(launcherApps, mainExecutor, persistentRepository)
+
+ // Add the bubbles to the persistent repository
+ persistedBubbles.put(0, user0BubbleEntities)
+ persistedBubbles.put(1, user1BubbleEntities)
+ persistentRepository.persistsToDisk(persistedBubbles)
+ }
+
+ @After
+ fun teardown() {
+ // Clean up any persisted bubbles for the next run
+ persistentRepository.persistsToDisk(SparseArray())
+ }
+
+ @Test
+ fun testLoadBubbles_invalidParent() {
+ val activeUserIds = listOf(10, 1, 12) // Missing user 0 in persistedBubbles
+ dataRepository.loadBubbles(1, activeUserIds) {
+ // Verify that user 0 has been removed from the persisted list
+ val entitiesByUser = persistentRepository.readFromDisk()
+ assertThat(entitiesByUser.get(0)).isNull()
+ }
+ }
+
+ @Test
+ fun testLoadBubbles_invalidChild() {
+ val activeUserIds = listOf(0, 10, 1) // Missing user 1's child user 12
+ dataRepository.loadBubbles(1, activeUserIds) {
+ // Build a list to compare against
+ val user1BubblesWithoutUser12 = mutableListOf<Bubble>()
+ val user1EntitiesWithoutUser12 = mutableListOf<BubbleEntity>()
+ for (entity in user1BubbleEntities) {
+ if (entity.userId != 12) {
+ user1BubblesWithoutUser12.add(entity.toBubble())
+ user1EntitiesWithoutUser12.add(entity)
+ }
+ }
+
+ // Verify that user 12 has been removed from the persisted list
+ val entitiesByUser = persistentRepository.readFromDisk()
+ assertThat(entitiesByUser.get(1)).isEqualTo(user1EntitiesWithoutUser12)
+ }
+ }
+
+ private fun BubbleEntity.toBubble(): Bubble {
+ return Bubble(
+ key,
+ mock(ShortcutInfo::class.java),
+ desiredHeight,
+ desiredHeightResId,
+ title,
+ taskId,
+ locus,
+ isDismissable,
+ mainExecutor,
+ mock(Bubbles.BubbleMetadataFlagListener::class.java)
+ )
+ }
+}
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java
index b00a60c..5efd9ad 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java
@@ -76,6 +76,7 @@
import com.android.wm.shell.common.TransactionPool;
import com.android.wm.shell.common.split.SplitDecorManager;
import com.android.wm.shell.common.split.SplitLayout;
+import com.android.wm.shell.transition.DefaultMixedHandler;
import com.android.wm.shell.transition.Transitions;
import com.android.wm.shell.windowdecor.WindowDecorViewModel;
@@ -105,6 +106,7 @@
@Mock private WindowDecorViewModel mWindowDecorViewModel;
@Mock private ShellExecutor mMainExecutor;
@Mock private LaunchAdjacentController mLaunchAdjacentController;
+ @Mock private DefaultMixedHandler mMixedHandler;
private SplitLayout mSplitLayout;
private MainStage mMainStage;
private SideStage mSideStage;
@@ -136,6 +138,7 @@
mDisplayImeController, mDisplayInsetsController, mSplitLayout, mTransitions,
mTransactionPool, mMainExecutor, Optional.empty(),
mLaunchAdjacentController, Optional.empty());
+ mStageCoordinator.setMixedHandler(mMixedHandler);
mSplitScreenTransitions = mStageCoordinator.getSplitTransitions();
doAnswer((Answer<IBinder>) invocation -> mock(IBinder.class))
.when(mTransitions).startTransition(anyInt(), any(), any());
diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp
index db58147..b5e6f94 100644
--- a/libs/hwui/Android.bp
+++ b/libs/hwui/Android.bp
@@ -514,6 +514,7 @@
"canvas/CanvasOpRasterizer.cpp",
"effects/StretchEffect.cpp",
"effects/GainmapRenderer.cpp",
+ "pipeline/skia/BackdropFilterDrawable.cpp",
"pipeline/skia/HolePunch.cpp",
"pipeline/skia/SkiaDisplayList.cpp",
"pipeline/skia/SkiaRecordingCanvas.cpp",
diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp
index 1c39db3..1dd22cf 100644
--- a/libs/hwui/RenderNode.cpp
+++ b/libs/hwui/RenderNode.cpp
@@ -260,6 +260,12 @@
pushStagingDisplayListChanges(observer, info);
}
+ // always damageSelf when filtering backdrop content, or else the BackdropFilterDrawable will
+ // get a wrong snapshot of previous content.
+ if (mProperties.layerProperties().getBackdropImageFilter()) {
+ damageSelf(info);
+ }
+
if (mDisplayList) {
info.out.hasFunctors |= mDisplayList.hasFunctor();
mHasHolePunches = mDisplayList.hasHolePunches();
diff --git a/libs/hwui/RenderProperties.cpp b/libs/hwui/RenderProperties.cpp
index 0589f13..c537123 100644
--- a/libs/hwui/RenderProperties.cpp
+++ b/libs/hwui/RenderProperties.cpp
@@ -55,6 +55,12 @@
return true;
}
+bool LayerProperties::setBackdropImageFilter(SkImageFilter* imageFilter) {
+ if (mBackdropImageFilter.get() == imageFilter) return false;
+ mBackdropImageFilter = sk_ref_sp(imageFilter);
+ return true;
+}
+
bool LayerProperties::setFromPaint(const SkPaint* paint) {
bool changed = false;
changed |= setAlpha(static_cast<uint8_t>(PaintUtils::getAlphaDirect(paint)));
@@ -70,6 +76,7 @@
setXferMode(other.xferMode());
setColorFilter(other.getColorFilter());
setImageFilter(other.getImageFilter());
+ setBackdropImageFilter(other.getBackdropImageFilter());
mStretchEffect = other.mStretchEffect;
return *this;
}
diff --git a/libs/hwui/RenderProperties.h b/libs/hwui/RenderProperties.h
index 064ba7a..e358b57 100644
--- a/libs/hwui/RenderProperties.h
+++ b/libs/hwui/RenderProperties.h
@@ -97,8 +97,12 @@
bool setImageFilter(SkImageFilter* imageFilter);
+ bool setBackdropImageFilter(SkImageFilter* imageFilter);
+
SkImageFilter* getImageFilter() const { return mImageFilter.get(); }
+ SkImageFilter* getBackdropImageFilter() const { return mBackdropImageFilter.get(); }
+
const StretchEffect& getStretchEffect() const { return mStretchEffect; }
StretchEffect& mutableStretchEffect() { return mStretchEffect; }
@@ -129,6 +133,7 @@
SkBlendMode mMode;
sk_sp<SkColorFilter> mColorFilter;
sk_sp<SkImageFilter> mImageFilter;
+ sk_sp<SkImageFilter> mBackdropImageFilter;
StretchEffect mStretchEffect;
};
diff --git a/libs/hwui/jni/BitmapRegionDecoder.cpp b/libs/hwui/jni/BitmapRegionDecoder.cpp
index aeaa171..4c9a23d 100644
--- a/libs/hwui/jni/BitmapRegionDecoder.cpp
+++ b/libs/hwui/jni/BitmapRegionDecoder.cpp
@@ -96,17 +96,33 @@
sk_sp<SkColorSpace> decodeColorSpace =
mGainmapBRD->computeOutputColorSpace(decodeColorType, nullptr);
SkBitmap bm;
- HeapAllocator heapAlloc;
- if (!mGainmapBRD->decodeRegion(&bm, &heapAlloc, desiredSubset, sampleSize, decodeColorType,
- requireUnpremul, decodeColorSpace)) {
- ALOGE("Error decoding Gainmap region");
- return false;
- }
- sk_sp<Bitmap> nativeBitmap(heapAlloc.getStorageObjAndReset());
+ // Because we must match the dimensions of the base bitmap, we always use a
+ // recycling allocator even though we are allocating a new bitmap. This is to ensure
+ // that if a recycled bitmap was used for the base image that we match the relative
+ // dimensions of that base image. The behavior of BRD here is:
+ // if inBitmap is specified -> output dimensions are always equal to the inBitmap's
+ // if no bitmap is reused -> output dimensions are the intersect of the desiredSubset &
+ // the image bounds
+ // The handling of the above conditionals are baked into the desiredSubset, so we
+ // simply need to ensure that the resulting bitmap is the exact same width/height as
+ // the specified desiredSubset regardless of the intersection to the image bounds.
+ // kPremul_SkAlphaType is used just as a placeholder as it doesn't change the underlying
+ // allocation type. RecyclingClippingPixelAllocator will populate this with the
+ // actual alpha type in either allocPixelRef() or copyIfNecessary()
+ sk_sp<Bitmap> nativeBitmap = Bitmap::allocateHeapBitmap(
+ SkImageInfo::Make(desiredSubset.width(), desiredSubset.height(), decodeColorType,
+ kPremul_SkAlphaType, decodeColorSpace));
if (!nativeBitmap) {
ALOGE("OOM allocating Bitmap for Gainmap");
return false;
}
+ RecyclingClippingPixelAllocator allocator(nativeBitmap.get(), false);
+ if (!mGainmapBRD->decodeRegion(&bm, &allocator, desiredSubset, sampleSize, decodeColorType,
+ requireUnpremul, decodeColorSpace)) {
+ ALOGE("Error decoding Gainmap region");
+ return false;
+ }
+ allocator.copyIfNecessary();
auto gainmap = sp<uirenderer::Gainmap>::make();
if (!gainmap) {
ALOGE("OOM allocating Gainmap");
@@ -238,13 +254,11 @@
// Recycle a bitmap if possible.
android::Bitmap* recycledBitmap = nullptr;
- size_t recycledBytes = 0;
if (javaBitmap) {
recycledBitmap = &bitmap::toBitmap(inBitmapHandle);
if (recycledBitmap->isImmutable()) {
ALOGW("Warning: Reusing an immutable bitmap as an image decoder target.");
}
- recycledBytes = recycledBitmap->getAllocationByteCount();
}
auto* brd = reinterpret_cast<BitmapRegionDecoderWrapper*>(brdHandle);
@@ -263,7 +277,7 @@
// Set up the pixel allocator
skia::BRDAllocator* allocator = nullptr;
- RecyclingClippingPixelAllocator recycleAlloc(recycledBitmap, recycledBytes);
+ RecyclingClippingPixelAllocator recycleAlloc(recycledBitmap);
HeapAllocator heapAlloc;
if (javaBitmap) {
allocator = &recycleAlloc;
@@ -277,7 +291,7 @@
decodeColorType, colorSpace);
// Decode the region.
- SkIRect subset = SkIRect::MakeXYWH(inputX, inputY, inputWidth, inputHeight);
+ const SkIRect subset = SkIRect::MakeXYWH(inputX, inputY, inputWidth, inputHeight);
SkBitmap bitmap;
if (!brd->decodeRegion(&bitmap, allocator, subset, sampleSize,
decodeColorType, requireUnpremul, decodeColorSpace)) {
@@ -307,10 +321,27 @@
GraphicsJNI::getColorSpace(env, decodeColorSpace.get(), decodeColorType));
}
+ if (javaBitmap) {
+ recycleAlloc.copyIfNecessary();
+ }
+
sp<uirenderer::Gainmap> gainmap;
bool hasGainmap = brd->hasGainmap();
if (hasGainmap) {
- SkIRect gainmapSubset = brd->calculateGainmapRegion(subset);
+ SkIRect adjustedSubset{};
+ if (javaBitmap) {
+ // Clamp to the width/height of the recycled bitmap in case the reused bitmap
+ // was too small for the specified rectangle, in which case we need to clip
+ adjustedSubset = SkIRect::MakeXYWH(inputX, inputY,
+ std::min(subset.width(), recycledBitmap->width()),
+ std::min(subset.height(), recycledBitmap->height()));
+ } else {
+ // We are not recycling, so use the decoded width/height for calculating the gainmap
+ // subset instead to ensure the gainmap region proportionally matches
+ adjustedSubset = SkIRect::MakeXYWH(std::max(0, inputX), std::max(0, inputY),
+ bitmap.width(), bitmap.height());
+ }
+ SkIRect gainmapSubset = brd->calculateGainmapRegion(adjustedSubset);
if (!brd->decodeGainmapRegion(&gainmap, gainmapSubset, sampleSize, requireUnpremul)) {
// If there is an error decoding Gainmap - we don't fail. We just don't provide Gainmap
hasGainmap = false;
@@ -319,7 +350,6 @@
// If we may have reused a bitmap, we need to indicate that the pixels have changed.
if (javaBitmap) {
- recycleAlloc.copyIfNecessary();
if (hasGainmap) {
recycledBitmap->setGainmap(std::move(gainmap));
}
@@ -331,6 +361,7 @@
if (!requireUnpremul) {
bitmapCreateFlags |= android::bitmap::kBitmapCreateFlag_Premultiplied;
}
+
if (isHardware) {
sk_sp<Bitmap> hardwareBitmap = Bitmap::allocateHardwareBitmap(bitmap);
if (hasGainmap) {
diff --git a/libs/hwui/jni/Graphics.cpp b/libs/hwui/jni/Graphics.cpp
index 914266d..78b4f7b 100644
--- a/libs/hwui/jni/Graphics.cpp
+++ b/libs/hwui/jni/Graphics.cpp
@@ -620,13 +620,13 @@
////////////////////////////////////////////////////////////////////////////////
-RecyclingClippingPixelAllocator::RecyclingClippingPixelAllocator(
- android::Bitmap* recycledBitmap, size_t recycledBytes)
- : mRecycledBitmap(recycledBitmap)
- , mRecycledBytes(recycledBytes)
- , mSkiaBitmap(nullptr)
- , mNeedsCopy(false)
-{}
+RecyclingClippingPixelAllocator::RecyclingClippingPixelAllocator(android::Bitmap* recycledBitmap,
+ bool mustMatchColorType)
+ : mRecycledBitmap(recycledBitmap)
+ , mRecycledBytes(recycledBitmap ? recycledBitmap->getAllocationByteCount() : 0)
+ , mSkiaBitmap(nullptr)
+ , mNeedsCopy(false)
+ , mMustMatchColorType(mustMatchColorType) {}
RecyclingClippingPixelAllocator::~RecyclingClippingPixelAllocator() {}
@@ -637,10 +637,16 @@
LOG_ALWAYS_FATAL_IF(!bitmap);
mSkiaBitmap = bitmap;
- // This behaves differently than the RecyclingPixelAllocator. For backwards
- // compatibility, the original color type of the recycled bitmap must be maintained.
- if (mRecycledBitmap->info().colorType() != bitmap->colorType()) {
- return false;
+ if (mMustMatchColorType) {
+ // This behaves differently than the RecyclingPixelAllocator. For backwards
+ // compatibility, the original color type of the recycled bitmap must be maintained.
+ if (mRecycledBitmap->info().colorType() != bitmap->colorType()) {
+ ALOGW("recycled color type %d != bitmap color type %d",
+ mRecycledBitmap->info().colorType(), bitmap->colorType());
+ return false;
+ }
+ } else {
+ mRecycledBitmap->reconfigure(mRecycledBitmap->info().makeColorType(bitmap->colorType()));
}
// The Skia bitmap specifies the width and height needed by the decoder.
@@ -695,7 +701,7 @@
void RecyclingClippingPixelAllocator::copyIfNecessary() {
if (mNeedsCopy) {
mRecycledBitmap->ref();
- SkPixelRef* recycledPixels = mRecycledBitmap;
+ android::Bitmap* recycledPixels = mRecycledBitmap;
void* dst = recycledPixels->pixels();
const size_t dstRowBytes = mRecycledBitmap->rowBytes();
const size_t bytesToCopy = std::min(mRecycledBitmap->info().minRowBytes(),
@@ -708,6 +714,8 @@
dst = reinterpret_cast<void*>(
reinterpret_cast<uint8_t*>(dst) + dstRowBytes);
}
+ recycledPixels->setAlphaType(mSkiaBitmap->alphaType());
+ recycledPixels->setColorSpace(mSkiaBitmap->refColorSpace());
recycledPixels->notifyPixelsChanged();
recycledPixels->unref();
}
diff --git a/libs/hwui/jni/GraphicsJNI.h b/libs/hwui/jni/GraphicsJNI.h
index 24f9e82..b9fff36 100644
--- a/libs/hwui/jni/GraphicsJNI.h
+++ b/libs/hwui/jni/GraphicsJNI.h
@@ -125,14 +125,6 @@
static jobject createBitmapRegionDecoder(JNIEnv* env,
android::BitmapRegionDecoderWrapper* bitmap);
- /**
- * Given a bitmap we natively allocate a memory block to store the contents
- * of that bitmap. The memory is then attached to the bitmap via an
- * SkPixelRef, which ensures that upon deletion the appropriate caches
- * are notified.
- */
- static bool allocatePixels(JNIEnv* env, SkBitmap* bitmap);
-
/** Copy the colors in colors[] to the bitmap, convert to the correct
format along the way.
Whether to use premultiplied pixels is determined by dstBitmap's alphaType.
@@ -222,9 +214,8 @@
*/
class RecyclingClippingPixelAllocator : public android::skia::BRDAllocator {
public:
-
RecyclingClippingPixelAllocator(android::Bitmap* recycledBitmap,
- size_t recycledBytes);
+ bool mustMatchColorType = true);
~RecyclingClippingPixelAllocator();
@@ -252,6 +243,7 @@
const size_t mRecycledBytes;
SkBitmap* mSkiaBitmap;
bool mNeedsCopy;
+ const bool mMustMatchColorType;
};
class AshmemPixelAllocator : public SkBitmap::Allocator {
diff --git a/libs/hwui/jni/android_graphics_RenderNode.cpp b/libs/hwui/jni/android_graphics_RenderNode.cpp
index 8c7b9a4..2a218a2 100644
--- a/libs/hwui/jni/android_graphics_RenderNode.cpp
+++ b/libs/hwui/jni/android_graphics_RenderNode.cpp
@@ -243,6 +243,13 @@
return SET_AND_DIRTY(mutateLayerProperties().setImageFilter, imageFilter, RenderNode::GENERIC);
}
+static jboolean android_view_RenderNode_setBackdropRenderEffect(
+ CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, jlong renderEffectPtr) {
+ SkImageFilter* imageFilter = reinterpret_cast<SkImageFilter*>(renderEffectPtr);
+ return SET_AND_DIRTY(mutateLayerProperties().setBackdropImageFilter, imageFilter,
+ RenderNode::GENERIC);
+}
+
static jboolean android_view_RenderNode_setHasOverlappingRendering(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,
bool hasOverlappingRendering) {
return SET_AND_DIRTY(setHasOverlappingRendering, hasOverlappingRendering,
@@ -792,6 +799,8 @@
{"nSetAlpha", "(JF)Z", (void*)android_view_RenderNode_setAlpha},
{"nSetRenderEffect", "(JJ)Z", (void*)android_view_RenderNode_setRenderEffect},
+ {"nSetBackdropRenderEffect", "(JJ)Z",
+ (void*)android_view_RenderNode_setBackdropRenderEffect},
{"nSetHasOverlappingRendering", "(JZ)Z",
(void*)android_view_RenderNode_setHasOverlappingRendering},
{"nSetUsageHint", "(JI)V", (void*)android_view_RenderNode_setUsageHint},
diff --git a/libs/hwui/pipeline/skia/BackdropFilterDrawable.cpp b/libs/hwui/pipeline/skia/BackdropFilterDrawable.cpp
new file mode 100644
index 0000000..ffad699
--- /dev/null
+++ b/libs/hwui/pipeline/skia/BackdropFilterDrawable.cpp
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "BackdropFilterDrawable.h"
+
+#include <SkImage.h>
+#include <SkSurface.h>
+
+#include "RenderNode.h"
+#include "RenderNodeDrawable.h"
+
+namespace android {
+namespace uirenderer {
+namespace skiapipeline {
+
+BackdropFilterDrawable::~BackdropFilterDrawable() {}
+
+bool BackdropFilterDrawable::prepareToDraw(SkCanvas* canvas, const RenderProperties& properties,
+ int backdropImageWidth, int backdropImageHeight) {
+ // the drawing bounds for blurred content.
+ mDstBounds.setWH(properties.getWidth(), properties.getHeight());
+
+ float alphaMultiplier = 1.0f;
+ RenderNodeDrawable::setViewProperties(properties, canvas, &alphaMultiplier, true);
+
+ // get proper subset for previous content.
+ canvas->getTotalMatrix().mapRect(&mImageSubset, mDstBounds);
+ SkRect imageSubset(mImageSubset);
+ // ensure the subset is inside bounds of previous content.
+ if (!mImageSubset.intersect(SkRect::MakeWH(backdropImageWidth, backdropImageHeight))) {
+ return false;
+ }
+
+ // correct the drawing bounds if subset was changed.
+ if (mImageSubset != imageSubset) {
+ SkMatrix inverse;
+ if (canvas->getTotalMatrix().invert(&inverse)) {
+ inverse.mapRect(&mDstBounds, mImageSubset);
+ }
+ }
+
+ // follow the alpha from the target RenderNode.
+ mPaint.setAlpha(properties.layerProperties().alpha() * alphaMultiplier);
+ return true;
+}
+
+void BackdropFilterDrawable::onDraw(SkCanvas* canvas) {
+ const RenderProperties& properties = mTargetRenderNode->properties();
+ auto* backdropFilter = properties.layerProperties().getBackdropImageFilter();
+ auto* surface = canvas->getSurface();
+ if (!backdropFilter || !surface) {
+ return;
+ }
+
+ auto backdropImage = surface->makeImageSnapshot();
+ // sync necessary properties from target RenderNode.
+ if (!prepareToDraw(canvas, properties, backdropImage->width(), backdropImage->height())) {
+ return;
+ }
+
+ auto imageSubset = mImageSubset.roundOut();
+ backdropImage =
+ backdropImage->makeWithFilter(canvas->recordingContext(), backdropFilter, imageSubset,
+ imageSubset, &mOutSubset, &mOutOffset);
+ canvas->drawImageRect(backdropImage, SkRect::Make(mOutSubset), mDstBounds,
+ SkSamplingOptions(SkFilterMode::kLinear), &mPaint,
+ SkCanvas::kStrict_SrcRectConstraint);
+}
+
+} // namespace skiapipeline
+} // namespace uirenderer
+} // namespace android
diff --git a/libs/hwui/pipeline/skia/BackdropFilterDrawable.h b/libs/hwui/pipeline/skia/BackdropFilterDrawable.h
new file mode 100644
index 0000000..9e35837
--- /dev/null
+++ b/libs/hwui/pipeline/skia/BackdropFilterDrawable.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <SkCanvas.h>
+#include <SkDrawable.h>
+#include <SkPaint.h>
+
+namespace android {
+namespace uirenderer {
+
+class RenderNode;
+class RenderProperties;
+
+namespace skiapipeline {
+
+/**
+ * This drawable captures it's backdrop content and render it with a
+ * image filter.
+ */
+class BackdropFilterDrawable : public SkDrawable {
+public:
+ BackdropFilterDrawable(RenderNode* renderNode, SkCanvas* canvas)
+ : mTargetRenderNode(renderNode), mBounds(canvas->getLocalClipBounds()) {}
+
+ ~BackdropFilterDrawable();
+
+private:
+ RenderNode* mTargetRenderNode;
+ SkPaint mPaint;
+
+ SkRect mDstBounds;
+ SkRect mImageSubset;
+ SkIRect mOutSubset;
+ SkIPoint mOutOffset;
+
+ /**
+ * Check all necessary properties before actual drawing.
+ * Return true if ready to draw.
+ */
+ bool prepareToDraw(SkCanvas* canvas, const RenderProperties& properties, int backdropImageWidth,
+ int backdropImageHeight);
+
+protected:
+ void onDraw(SkCanvas* canvas) override;
+
+ virtual SkRect onGetBounds() override { return mBounds; }
+ const SkRect mBounds;
+};
+
+} // namespace skiapipeline
+} // namespace uirenderer
+} // namespace android
diff --git a/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp b/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp
index da4f66d..9d72c23 100644
--- a/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp
+++ b/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp
@@ -362,7 +362,7 @@
}
void RenderNodeDrawable::setViewProperties(const RenderProperties& properties, SkCanvas* canvas,
- float* alphaMultiplier) {
+ float* alphaMultiplier, bool ignoreLayer) {
if (properties.getLeft() != 0 || properties.getTop() != 0) {
canvas->translate(properties.getLeft(), properties.getTop());
}
@@ -378,7 +378,8 @@
canvas->concat(*properties.getTransformMatrix());
}
}
- if (Properties::getStretchEffectBehavior() == StretchEffectBehavior::UniformScale) {
+ if (Properties::getStretchEffectBehavior() == StretchEffectBehavior::UniformScale &&
+ !ignoreLayer) {
const StretchEffect& stretch = properties.layerProperties().getStretchEffect();
if (!stretch.isEmpty()) {
canvas->concat(
@@ -388,10 +389,10 @@
const bool isLayer = properties.effectiveLayerType() != LayerType::None;
int clipFlags = properties.getClippingFlags();
if (properties.getAlpha() < 1) {
- if (isLayer) {
+ if (isLayer && !ignoreLayer) {
clipFlags &= ~CLIP_TO_BOUNDS; // bounds clipping done by layer
}
- if (CC_LIKELY(isLayer || !properties.getHasOverlappingRendering())) {
+ if (CC_LIKELY(isLayer || !properties.getHasOverlappingRendering()) || ignoreLayer) {
*alphaMultiplier = properties.getAlpha();
} else {
// savelayer needed to create an offscreen buffer
diff --git a/libs/hwui/pipeline/skia/RenderNodeDrawable.h b/libs/hwui/pipeline/skia/RenderNodeDrawable.h
index c7582e7..818ac45 100644
--- a/libs/hwui/pipeline/skia/RenderNodeDrawable.h
+++ b/libs/hwui/pipeline/skia/RenderNodeDrawable.h
@@ -120,7 +120,7 @@
* Applies the rendering properties of a view onto a SkCanvas.
*/
static void setViewProperties(const RenderProperties& properties, SkCanvas* canvas,
- float* alphaMultiplier);
+ float* alphaMultiplier, bool ignoreLayer = false);
/**
* Stores transform on the canvas at time of recording and is used for
@@ -149,6 +149,11 @@
* display list that is searched for any render nodes with getProjectBackwards==true
*/
SkiaDisplayList* mProjectedDisplayList = nullptr;
+
+ /**
+ * Allow BackdropFilterDrawable to apply same render properties onto SkCanvas.
+ */
+ friend class BackdropFilterDrawable;
};
} // namespace skiapipeline
diff --git a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
index 3ca7eeb..58c14c1 100644
--- a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
+++ b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
@@ -37,6 +37,7 @@
#include "NinePatchUtils.h"
#include "RenderNode.h"
#include "pipeline/skia/AnimatedDrawables.h"
+#include "pipeline/skia/BackdropFilterDrawable.h"
#ifdef __ANDROID__ // Layoutlib does not support GL, Vulcan etc.
#include "pipeline/skia/GLFunctorDrawable.h"
#include "pipeline/skia/VkFunctorDrawable.h"
@@ -168,6 +169,14 @@
// Put Vulkan WebViews with non-rectangular clips in a HW layer
renderNode->mutateStagingProperties().setClipMayBeComplex(mRecorder.isClipMayBeComplex());
}
+
+ // draw backdrop filter drawable if needed.
+ if (renderNode->stagingProperties().layerProperties().getBackdropImageFilter()) {
+ auto* backdropFilterDrawable =
+ mDisplayList->allocateDrawable<BackdropFilterDrawable>(renderNode, asSkCanvas());
+ drawDrawable(backdropFilterDrawable);
+ }
+
drawDrawable(&renderNodeDrawable);
// use staging property, since recording on UI thread
diff --git a/libs/hwui/renderthread/VulkanManager.cpp b/libs/hwui/renderthread/VulkanManager.cpp
index d222531..eb45707 100644
--- a/libs/hwui/renderthread/VulkanManager.cpp
+++ b/libs/hwui/renderthread/VulkanManager.cpp
@@ -659,7 +659,6 @@
if (VK_NULL_HANDLE != mGraphicsQueue) {
mQueueWaitIdle(mGraphicsQueue);
}
- mDeviceWaitIdle(mDevice);
delete surface;
}
diff --git a/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp b/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp
index dd95c4f..1e055c2 100644
--- a/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp
+++ b/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp
@@ -14,20 +14,22 @@
* limitations under the License.
*/
-#include <VectorDrawable.h>
-#include <gtest/gtest.h>
-
#include <SkBlendMode.h>
#include <SkClipStack.h>
#include <SkSurface_Base.h>
+#include <VectorDrawable.h>
+#include <gtest/gtest.h>
+#include <include/effects/SkImageFilters.h>
#include <string.h>
+
#include "AnimationContext.h"
#include "DamageAccumulator.h"
#include "FatalTestCanvas.h"
#include "IContextFactory.h"
-#include "hwui/Paint.h"
#include "RecordingCanvas.h"
#include "SkiaCanvas.h"
+#include "hwui/Paint.h"
+#include "pipeline/skia/BackdropFilterDrawable.h"
#include "pipeline/skia/SkiaDisplayList.h"
#include "pipeline/skia/SkiaOpenGLPipeline.h"
#include "pipeline/skia/SkiaPipeline.h"
@@ -1211,3 +1213,77 @@
canvas.drawDrawable(&drawable);
EXPECT_EQ(2, canvas.mDrawCounter);
}
+
+// Verify drawing logics for BackdropFilterDrawable
+RENDERTHREAD_TEST(BackdropFilterDrawable, drawing) {
+ static const int CANVAS_WIDTH = 100;
+ static const int CANVAS_HEIGHT = 200;
+ class SimpleTestCanvas : public TestCanvasBase {
+ public:
+ SkRect mDstBounds;
+ SimpleTestCanvas() : TestCanvasBase(CANVAS_WIDTH, CANVAS_HEIGHT) {}
+ void onDrawRect(const SkRect& rect, const SkPaint& paint) override {
+ // did nothing.
+ }
+
+ // called when BackdropFilterDrawable is drawn.
+ void onDrawImageRect2(const SkImage*, const SkRect& src, const SkRect& dst,
+ const SkSamplingOptions&, const SkPaint*,
+ SrcRectConstraint) override {
+ mDrawCounter++;
+ mDstBounds = dst;
+ }
+ };
+ class SimpleLayer : public SkSurface_Base {
+ public:
+ SimpleLayer()
+ : SkSurface_Base(SkImageInfo::MakeN32Premul(CANVAS_WIDTH, CANVAS_HEIGHT), nullptr) {
+ }
+ virtual sk_sp<SkImage> onNewImageSnapshot(const SkIRect* bounds) override {
+ SkBitmap bitmap;
+ bitmap.allocN32Pixels(CANVAS_WIDTH, CANVAS_HEIGHT);
+ bitmap.setImmutable();
+ return bitmap.asImage();
+ }
+ SkCanvas* onNewCanvas() override { return new SimpleTestCanvas(); }
+ sk_sp<SkSurface> onNewSurface(const SkImageInfo&) override { return nullptr; }
+ bool onCopyOnWrite(ContentChangeMode) override { return true; }
+ void onWritePixels(const SkPixmap&, int x, int y) {}
+ };
+
+ auto node = TestUtils::createSkiaNode(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT,
+ [](RenderProperties& props, SkiaRecordingCanvas& canvas) {
+ canvas.drawRect(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT,
+ Paint());
+ });
+
+ sk_sp<SkSurface> surface(new SimpleLayer());
+ auto* canvas = reinterpret_cast<SimpleTestCanvas*>(surface->getCanvas());
+ RenderNodeDrawable drawable(node.get(), canvas, true);
+ BackdropFilterDrawable backdropDrawable(node.get(), canvas);
+ canvas->drawDrawable(&drawable);
+ canvas->drawDrawable(&backdropDrawable);
+ // no backdrop filter, skip drawing.
+ EXPECT_EQ(0, canvas->mDrawCounter);
+
+ sk_sp<SkImageFilter> filter(SkImageFilters::Blur(3, 3, nullptr));
+ node->animatorProperties().mutateLayerProperties().setBackdropImageFilter(filter.get());
+ canvas->drawDrawable(&drawable);
+ canvas->drawDrawable(&backdropDrawable);
+ // backdrop filter is set, ok to draw.
+ EXPECT_EQ(1, canvas->mDrawCounter);
+ EXPECT_EQ(SkRect::MakeLTRB(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT), canvas->mDstBounds);
+
+ canvas->translate(30, 30);
+ canvas->drawDrawable(&drawable);
+ canvas->drawDrawable(&backdropDrawable);
+ // the drawable is still visible, ok to draw.
+ EXPECT_EQ(2, canvas->mDrawCounter);
+ EXPECT_EQ(SkRect::MakeLTRB(0, 0, CANVAS_WIDTH - 30, CANVAS_HEIGHT - 30), canvas->mDstBounds);
+
+ canvas->translate(CANVAS_WIDTH, CANVAS_HEIGHT);
+ canvas->drawDrawable(&drawable);
+ canvas->drawDrawable(&backdropDrawable);
+ // the drawable is invisible, skip drawing.
+ EXPECT_EQ(2, canvas->mDrawCounter);
+}
diff --git a/media/java/android/media/MediaRoute2Info.java b/media/java/android/media/MediaRoute2Info.java
index 2075b6c..3def1d0 100644
--- a/media/java/android/media/MediaRoute2Info.java
+++ b/media/java/android/media/MediaRoute2Info.java
@@ -156,6 +156,7 @@
TYPE_REMOTE_GAME_CONSOLE,
TYPE_REMOTE_CAR,
TYPE_REMOTE_SMARTWATCH,
+ TYPE_REMOTE_SMARTPHONE,
TYPE_GROUP
})
@Retention(RetentionPolicy.SOURCE)
@@ -337,6 +338,16 @@
public static final int TYPE_REMOTE_SMARTWATCH = 1009;
/**
+ * Indicates the route is a remote smartphone.
+ *
+ * <p>A remote device uses a routing protocol managed by the application, as opposed to the
+ * routing being done by the system.
+ *
+ * @see #getType
+ */
+ public static final int TYPE_REMOTE_SMARTPHONE = 1010;
+
+ /**
* Indicates the route is a group of devices.
*
* @see #getType
@@ -542,28 +553,6 @@
/**
* Returns the type of this route.
- *
- * @see #TYPE_UNKNOWN
- * @see #TYPE_BUILTIN_SPEAKER
- * @see #TYPE_WIRED_HEADSET
- * @see #TYPE_WIRED_HEADPHONES
- * @see #TYPE_BLUETOOTH_A2DP
- * @see #TYPE_HDMI
- * @see #TYPE_DOCK
- * @see #TYPE_USB_DEVICE
- * @see #TYPE_USB_ACCESSORY
- * @see #TYPE_USB_HEADSET
- * @see #TYPE_HEARING_AID
- * @see #TYPE_REMOTE_TV
- * @see #TYPE_REMOTE_SPEAKER
- * @see #TYPE_REMOTE_AUDIO_VIDEO_RECEIVER
- * @see #TYPE_REMOTE_TABLET
- * @see #TYPE_REMOTE_TABLET_DOCKED
- * @see #TYPE_REMOTE_COMPUTER
- * @see #TYPE_REMOTE_GAME_CONSOLE
- * @see #TYPE_REMOTE_CAR
- * @see #TYPE_REMOTE_SMARTWATCH
- * @see #TYPE_GROUP
*/
@Type
public int getType() {
@@ -946,6 +935,8 @@
return "REMOTE_CAR";
case TYPE_REMOTE_SMARTWATCH:
return "REMOTE_SMARTWATCH";
+ case TYPE_REMOTE_SMARTPHONE:
+ return "REMOTE_SMARTPHONE";
case TYPE_GROUP:
return "GROUP";
case TYPE_UNKNOWN:
diff --git a/media/java/android/media/RoutingSessionInfo.java b/media/java/android/media/RoutingSessionInfo.java
index e1af909..0bc5a60 100644
--- a/media/java/android/media/RoutingSessionInfo.java
+++ b/media/java/android/media/RoutingSessionInfo.java
@@ -100,8 +100,12 @@
boolean volumeAdjustmentForRemoteGroupSessions = Resources.getSystem().getBoolean(
com.android.internal.R.bool.config_volumeAdjustmentForRemoteGroupSessions);
- mVolumeHandling = defineVolumeHandling(builder.mVolumeHandling, mSelectedRoutes,
- volumeAdjustmentForRemoteGroupSessions);
+ mVolumeHandling =
+ defineVolumeHandling(
+ mIsSystemSession,
+ builder.mVolumeHandling,
+ mSelectedRoutes,
+ volumeAdjustmentForRemoteGroupSessions);
mControlHints = updateVolumeHandlingInHints(builder.mControlHints, mVolumeHandling);
}
@@ -150,9 +154,14 @@
return controlHints;
}
- private static int defineVolumeHandling(int volumeHandling, List<String> selectedRoutes,
+ private static int defineVolumeHandling(
+ boolean isSystemSession,
+ int volumeHandling,
+ List<String> selectedRoutes,
boolean volumeAdjustmentForRemoteGroupSessions) {
- if (!volumeAdjustmentForRemoteGroupSessions && selectedRoutes.size() > 1) {
+ if (!isSystemSession
+ && !volumeAdjustmentForRemoteGroupSessions
+ && selectedRoutes.size() > 1) {
return MediaRoute2Info.PLAYBACK_VOLUME_FIXED;
}
return volumeHandling;
diff --git a/media/java/android/media/audiopolicy/AudioPolicy.java b/media/java/android/media/audiopolicy/AudioPolicy.java
index c1ee74a..3e5de82 100644
--- a/media/java/android/media/audiopolicy/AudioPolicy.java
+++ b/media/java/android/media/audiopolicy/AudioPolicy.java
@@ -865,7 +865,7 @@
for (final WeakReference<AudioTrack> weakTrack : mInjectors) {
final AudioTrack track = weakTrack.get();
if (track == null) {
- break;
+ continue;
}
try {
// TODO: add synchronous versions
@@ -876,12 +876,13 @@
// released by the user of the AudioPolicy
}
}
+ mInjectors.clear();
}
if (mCaptors != null) {
for (final WeakReference<AudioRecord> weakRecord : mCaptors) {
final AudioRecord record = weakRecord.get();
if (record == null) {
- break;
+ continue;
}
try {
// TODO: if needed: implement an invalidate method
@@ -891,6 +892,7 @@
// released by the user of the AudioPolicy
}
}
+ mCaptors.clear();
}
}
}
diff --git a/media/java/android/media/projection/MediaProjection.java b/media/java/android/media/projection/MediaProjection.java
index 48367f9..fb72c7b 100644
--- a/media/java/android/media/projection/MediaProjection.java
+++ b/media/java/android/media/projection/MediaProjection.java
@@ -171,25 +171,30 @@
* @param handler The {@link android.os.Handler} on which the callback should be invoked, or
* null if the callback should be invoked on the calling thread's main
* {@link android.os.Looper}.
- * @throws IllegalStateException In the following scenarios, if the target SDK is {@link
- * android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE U} and up:
+ * @throws IllegalStateException If the target SDK is {@link
+ * android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE U} and up, and
+ * if no {@link Callback} is registered.
+ * @throws SecurityException In any of the following scenarios:
* <ol>
- * <li>If no {@link Callback} is registered.</li>
- * <li>If {@link MediaProjectionManager#getMediaProjection}
+ * <li>If attempting to create a new virtual display
+ * associated with this MediaProjection instance after it has
+ * been stopped by invoking {@link #stop()}.
+ * <li>If the target SDK is {@link
+ * android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE U} and up,
+ * and if this instance has already taken a recording through
+ * {@code #createVirtualDisplay}, but {@link #stop()} wasn't
+ * invoked to end the recording.
+ * <li>If the target SDK is {@link
+ * android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE U} and up,
+ * and if {@link MediaProjectionManager#getMediaProjection}
* was invoked more than once to get this
* {@code MediaProjection} instance.
- * <li>If this instance has already taken a recording through
- * {@code #createVirtualDisplay}.
* </ol>
- * However, if the target SDK is less than
- * {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE U}, no
- * exception is thrown. In case 1, recording begins even without
- * the callback. In case 2 & 3, recording doesn't begin
- * until the user re-grants consent in the dialog.
- * @throws SecurityException If attempting to create a new virtual display associated with this
- * MediaProjection instance after it has been stopped by invoking
- * {@link #stop()}.
- *
+ * In cases 2 & 3, no exception is thrown if the target SDK is
+ * less than
+ * {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE U}.
+ * Instead, recording doesn't begin until the user re-grants
+ * consent in the dialog.
* @see VirtualDisplay
* @see VirtualDisplay.Callback
*/
diff --git a/media/java/android/media/session/MediaSession.java b/media/java/android/media/session/MediaSession.java
index 29e8716..af33149 100644
--- a/media/java/android/media/session/MediaSession.java
+++ b/media/java/android/media/session/MediaSession.java
@@ -315,7 +315,7 @@
}
mBinder.setMediaButtonBroadcastReceiver(broadcastReceiver);
} catch (RemoteException e) {
- Log.wtf(TAG, "Failure in setMediaButtonBroadcastReceiver.", e);
+ e.rethrowFromSystemServer();
}
}
diff --git a/mime/java-res/android.mime.types b/mime/java-res/android.mime.types
index cb74cfc..fd785a4 100644
--- a/mime/java-res/android.mime.types
+++ b/mime/java-res/android.mime.types
@@ -52,6 +52,7 @@
?application/sdp sdp
?application/smil+xml smil
?application/ttml+xml ttml dfxp
+?application/vnd.android.haptics.vibration+xml ahv
?application/vnd.android.ota ota
?application/vnd.apple.mpegurl m3u8
?application/vnd.ms-pki.stl stl
diff --git a/packages/CarrierDefaultApp/res/values-ur/strings.xml b/packages/CarrierDefaultApp/res/values-ur/strings.xml
index 0c7cdc5..d6225c2 100644
--- a/packages/CarrierDefaultApp/res/values-ur/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-ur/strings.xml
@@ -16,9 +16,7 @@
<string name="ssl_error_continue" msgid="1138548463994095584">"براؤزر کے ذریعے بہرحال جاری رکھیں"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"پرفارمینس بوسٹ"</string>
<string name="performance_boost_notification_title" msgid="3126203390685781861">"آپ کے کیریئر سے 5G کے اختیارات"</string>
- <!-- String.format failed for translation -->
- <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
- <skip />
+ <string name="performance_boost_notification_detail" msgid="216569851036236346">"اپنی ایپ کے تجربے کے اختیارات دیکھنے کے لیے %s کی ویب سائٹ ملاحظہ کریں"</string>
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"ابھی نہیں"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"نظم کریں"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"پرفارمینس بوسٹ خریدیں۔"</string>
diff --git a/packages/EasterEgg/Android.bp b/packages/EasterEgg/Android.bp
index e88410c..8699f59 100644
--- a/packages/EasterEgg/Android.bp
+++ b/packages/EasterEgg/Android.bp
@@ -26,7 +26,10 @@
android_app {
// the build system in pi-dev can't quite handle R.java in kt
// so we will have a mix of java and kotlin files
- srcs: ["src/**/*.java", "src/**/*.kt"],
+ srcs: [
+ "src/**/*.java",
+ "src/**/*.kt",
+ ],
resource_dirs: ["res"],
@@ -36,17 +39,34 @@
certificate: "platform",
optimize: {
+ enabled: true,
+ optimize: true,
+ shrink: true,
+ shrink_resources: true,
+ proguard_compatibility: false,
proguard_flags_files: ["proguard.flags"],
},
- static_libs: [
- "androidx.core_core",
- "androidx.recyclerview_recyclerview",
+ static_libs: [
+ "androidx.core_core",
"androidx.annotation_annotation",
- "kotlinx-coroutines-android",
- "kotlinx-coroutines-core",
- //"kotlinx-coroutines-reactive",
- ],
+ "androidx.recyclerview_recyclerview",
+ "kotlinx-coroutines-android",
+ "kotlinx-coroutines-core",
+
+ "androidx.core_core-ktx",
+ "androidx.lifecycle_lifecycle-runtime-ktx",
+ "androidx.activity_activity-compose",
+ "androidx.compose.ui_ui",
+ "androidx.compose.ui_ui-util",
+ "androidx.compose.ui_ui-tooling-preview",
+ "androidx.compose.material_material",
+ "androidx.window_window",
+
+ "androidx.compose.runtime_runtime",
+ "androidx.activity_activity-compose",
+ "androidx.compose.ui_ui",
+ ],
manifest: "AndroidManifest.xml",
diff --git a/packages/EasterEgg/AndroidManifest.xml b/packages/EasterEgg/AndroidManifest.xml
index cc7bb4a..d1db237 100644
--- a/packages/EasterEgg/AndroidManifest.xml
+++ b/packages/EasterEgg/AndroidManifest.xml
@@ -1,4 +1,19 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?><!--
+ Copyright (C) 2023 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.egg"
android:versionCode="12"
@@ -18,8 +33,27 @@
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<application
- android:icon="@drawable/icon"
+ android:icon="@drawable/android14_patch_adaptive"
android:label="@string/app_name">
+
+ <!-- Android U easter egg -->
+
+ <activity
+ android:name=".landroid.MainActivity"
+ android:exported="true"
+ android:label="@string/u_egg_name"
+ android:icon="@drawable/android14_patch_adaptive"
+ android:configChanges="orientation|screenLayout|screenSize|density"
+ android:theme="@android:style/Theme.DeviceDefault.NoActionBar.Fullscreen">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.DEFAULT" />
+ <category android:name="com.android.internal.category.PLATLOGO" />
+ </intent-filter>
+ </activity>
+
+
+ <!-- Android Q easter egg -->
<activity
android:name=".quares.QuaresActivity"
android:exported="true"
@@ -69,7 +103,7 @@
android:exported="true"
android:showOnLockScreen="true"
android:theme="@android:style/Theme.Material.Light.Dialog.NoActionBar" />
- <!-- Used to enable easter egg -->
+ <!-- Used to enable easter egg components for earlier easter eggs. -->
<activity
android:name=".ComponentActivationActivity"
android:excludeFromRecents="true"
@@ -79,7 +113,6 @@
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.DEFAULT" />
- <category android:name="com.android.internal.category.PLATLOGO" />
</intent-filter>
</activity>
diff --git a/packages/EasterEgg/res/drawable/android14_patch_adaptive.xml b/packages/EasterEgg/res/drawable/android14_patch_adaptive.xml
new file mode 100644
index 0000000..423e351
--- /dev/null
+++ b/packages/EasterEgg/res/drawable/android14_patch_adaptive.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright (C) 2023 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
+ <background android:drawable="@drawable/android14_patch_adaptive_background"/>
+ <foreground android:drawable="@drawable/android14_patch_adaptive_foreground"/>
+ <monochrome android:drawable="@drawable/android14_patch_monochrome"/>
+</adaptive-icon>
\ No newline at end of file
diff --git a/packages/EasterEgg/res/drawable/android14_patch_adaptive_background.xml b/packages/EasterEgg/res/drawable/android14_patch_adaptive_background.xml
new file mode 100644
index 0000000..c31aa7b
--- /dev/null
+++ b/packages/EasterEgg/res/drawable/android14_patch_adaptive_background.xml
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright (C) 2023 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="108dp"
+ android:height="108dp"
+ android:viewportWidth="108"
+ android:viewportHeight="108">
+ <path
+ android:pathData="M0,0 L108,0 L108,108 L0,108 z"
+ android:fillColor="#FF073042"/>
+ <path
+ android:pathData="M44.51,43.32L44.86,42.27C47.04,54.48 52.81,86.71 52.81,50.14C52.81,49.99 52.92,49.86 53.06,49.86H55.04C55.18,49.86 55.3,49.98 55.3,50.14C55.27,114.18 44.51,43.32 44.51,43.32Z"
+ android:fillColor="#3DDC84"/>
+ <path
+ android:name="planetary head"
+ android:pathData="M38.81,42.23L33.63,51.21C33.33,51.72 33.51,52.38 34.02,52.68C34.54,52.98 35.2,52.8 35.49,52.28L40.74,43.2C49.22,47 58.92,47 67.4,43.2L72.65,52.28C72.96,52.79 73.62,52.96 74.13,52.65C74.62,52.35 74.79,51.71 74.51,51.21L69.33,42.23C78.23,37.39 84.32,28.38 85.21,17.74H22.93C23.82,28.38 29.91,37.39 38.81,42.23Z"
+ android:fillColor="#ffffff"/>
+ <!-- yes it's an easter egg in a vector drawable -->
+ <path
+ android:name="planetary body"
+ android:pathData="M22.9,0 L85.1,0 L85.1,15.5 L22.9,15.5 z"
+ android:fillColor="#ffffff" />
+ <path
+ android:pathData="M54.96,43.32H53.1C52.92,43.32 52.77,43.47 52.77,43.65V48.04C52.77,48.22 52.92,48.37 53.1,48.37H54.96C55.15,48.37 55.3,48.22 55.3,48.04V43.65C55.3,43.47 55.15,43.32 54.96,43.32Z"
+ android:fillColor="#3DDC84"/>
+ <path
+ android:pathData="M54.99,40.61H53.08C52.91,40.61 52.77,40.75 52.77,40.92V41.56C52.77,41.73 52.91,41.87 53.08,41.87H54.99C55.16,41.87 55.3,41.73 55.3,41.56V40.92C55.3,40.75 55.16,40.61 54.99,40.61Z"
+ android:fillColor="#3DDC84"/>
+ <path
+ android:pathData="M41.49,47.88H40.86V48.51H41.49V47.88Z"
+ android:fillColor="#ffffff"/>
+ <path
+ android:pathData="M44.13,57.08H43.5V57.71H44.13V57.08Z"
+ android:fillColor="#ffffff"/>
+ <path
+ android:pathData="M72.29,66.76H71.66V67.39H72.29V66.76Z"
+ android:fillColor="#ffffff"/>
+ <path
+ android:pathData="M59.31,53.41H58.68V54.04H59.31V53.41Z"
+ android:fillColor="#ffffff"/>
+ <path
+ android:pathData="M64.47,48.19H63.84V48.83H64.47V48.19Z"
+ android:fillColor="#ffffff"/>
+ <path
+ android:pathData="M60.58,59.09H59.95V59.72H60.58V59.09Z"
+ android:fillColor="#ffffff"/>
+ <path
+ android:pathData="M66.95,56.7H65.69V57.97H66.95V56.7Z"
+ android:fillColor="#ffffff"/>
+ <path
+ android:pathData="M44.13,60.71H43.5V61.34H44.13V60.71Z"
+ android:fillColor="#ffffff"/>
+ <path
+ android:pathData="M49.66,51.33H48.4V52.6H49.66V51.33Z"
+ android:fillColor="#ffffff"/>
+ <path
+ android:pathData="M57.78,63.83H56.52V65.09H57.78V63.83Z"
+ android:fillColor="#ffffff"/>
+ <path
+ android:pathData="M61.1,68.57H59.83V69.83H61.1V68.57Z"
+ android:fillColor="#ffffff"/>
+ <path
+ android:pathData="M40.43,53.73H39.16V54.99H40.43V53.73Z"
+ android:fillColor="#ffffff"/>
+ <path
+ android:pathData="M74.47,44H73.21V45.26H74.47V44Z"
+ android:fillColor="#ffffff"/>
+ <path
+ android:pathData="M36.8,64.58H35.54V65.84H36.8V64.58Z"
+ android:fillColor="#ffffff"/>
+</vector>
diff --git a/packages/EasterEgg/res/drawable/android14_patch_adaptive_foreground.xml b/packages/EasterEgg/res/drawable/android14_patch_adaptive_foreground.xml
new file mode 100644
index 0000000..391d515
--- /dev/null
+++ b/packages/EasterEgg/res/drawable/android14_patch_adaptive_foreground.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright (C) 2023 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="108dp"
+ android:height="108dp"
+ android:viewportWidth="108"
+ android:viewportHeight="108">
+ <path
+ android:pathData="M54.03,33.03C52.99,33.03 52.14,33.86 52.14,34.87V37.14C52.14,37.34 52.3,37.5 52.5,37.5C52.69,37.5 52.85,37.34 52.85,37.14V36.53C52.85,36.14 53.17,35.82 53.56,35.82H54.51C54.9,35.82 55.22,36.14 55.22,36.53V37.14C55.22,37.34 55.38,37.5 55.57,37.5C55.77,37.5 55.93,37.34 55.93,37.14V34.87C55.93,33.86 55.08,33.03 54.03,33.03H54.03Z"
+ android:fillColor="#3DDC84"/>
+ <path
+ android:pathData="M108,0H0V108H108V0ZM54,80.67C68.73,80.67 80.67,68.73 80.67,54C80.67,39.27 68.73,27.33 54,27.33C39.27,27.33 27.33,39.27 27.33,54C27.33,68.73 39.27,80.67 54,80.67Z"
+ android:fillColor="#F86734"
+ android:fillType="evenOdd"/>
+ <group>
+ <!-- the text doesn't look great everywhere but you can remove the clip to try it out. -->
+ <clip-path />
+ <path
+ android:pathData="M28.58,32.18L29.18,31.5L33.82,33.02L33.12,33.81L32.15,33.48L30.92,34.87L31.37,35.8L30.68,36.58L28.58,32.18L28.58,32.18ZM31.25,33.18L29.87,32.71L30.51,34.02L31.25,33.18V33.18Z"
+ android:fillColor="#ffffff"/>
+ <path
+ android:pathData="M38,29.76L34.61,28.79L36.23,31.04L35.42,31.62L32.8,27.99L33.5,27.48L36.88,28.45L35.26,26.21L36.08,25.62L38.7,29.25L38,29.76Z"
+ android:fillColor="#ffffff"/>
+ <path
+ android:pathData="M39.23,23.87L40.63,23.27C41.79,22.77 43.13,23.28 43.62,24.43C44.11,25.57 43.56,26.89 42.4,27.39L40.99,27.99L39.23,23.87ZM42.03,26.54C42.73,26.24 42.96,25.49 42.68,24.83C42.4,24.17 41.69,23.82 41,24.11L40.51,24.32L41.55,26.75L42.03,26.54Z"
+ android:fillColor="#ffffff"/>
+ <path
+ android:pathData="M45.91,21.43L47.64,21.09C48.47,20.93 49.12,21.41 49.27,22.15C49.38,22.72 49.15,23.14 48.63,23.45L50.57,25.08L49.39,25.31L47.57,23.79L47.41,23.82L47.76,25.63L46.78,25.83L45.91,21.43H45.91ZM47.87,22.86C48.16,22.8 48.34,22.59 48.29,22.34C48.24,22.07 48,21.96 47.71,22.02L47.07,22.14L47.24,22.98L47.87,22.86Z"
+ android:fillColor="#ffffff"/>
+ <path
+ android:pathData="M52.17,22.69C52.19,21.41 53.24,20.39 54.52,20.41C55.8,20.43 56.82,21.49 56.8,22.76C56.78,24.04 55.72,25.06 54.45,25.04C53.17,25.02 52.15,23.96 52.17,22.69ZM55.79,22.75C55.8,22.02 55.23,21.39 54.51,21.38C53.78,21.37 53.19,21.98 53.18,22.7C53.17,23.43 53.73,24.06 54.47,24.07C55.19,24.08 55.78,23.47 55.79,22.75H55.79Z"
+ android:fillColor="#ffffff"/>
+ <path
+ android:pathData="M60,21.01L60.98,21.2L60.12,25.6L59.14,25.41L60,21.01Z"
+ android:fillColor="#ffffff"/>
+ <path
+ android:pathData="M64.3,22.03L65.73,22.58C66.91,23.03 67.51,24.32 67.07,25.49C66.62,26.65 65.31,27.22 64.13,26.77L62.71,26.22L64.3,22.03L64.3,22.03ZM64.46,25.9C65.17,26.17 65.86,25.8 66.12,25.12C66.37,24.45 66.11,23.71 65.4,23.44L64.91,23.25L63.97,25.72L64.46,25.9Z"
+ android:fillColor="#ffffff"/>
+ <path
+ android:pathData="M73.59,27.94L72.94,27.44L73.51,26.69L74.92,27.77L72.2,31.34L71.45,30.76L73.59,27.94Z"
+ android:fillColor="#ffffff"/>
+ <path
+ android:pathData="M76.18,33.75L74.69,32.14L75.25,31.62L78.81,31.42L79.4,32.05L77.47,33.85L77.86,34.27L77.22,34.86L76.83,34.44L76.12,35.11L75.47,34.41L76.18,33.75ZM77.72,32.31L76.12,32.4L76.82,33.15L77.72,32.31Z"
+ android:fillColor="#ffffff"/>
+ </group>
+</vector>
diff --git a/packages/EasterEgg/res/drawable/android14_patch_monochrome.xml b/packages/EasterEgg/res/drawable/android14_patch_monochrome.xml
new file mode 100644
index 0000000..beef85c
--- /dev/null
+++ b/packages/EasterEgg/res/drawable/android14_patch_monochrome.xml
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright (C) 2023 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="108dp"
+ android:height="108dp"
+ android:viewportWidth="108"
+ android:viewportHeight="108">
+ <group>
+ <clip-path
+ android:pathData="M0,0h108v108h-108z"/>
+ <group>
+ <clip-path
+ android:pathData="M22,22h64v64h-64z"/>
+ <path
+ android:pathData="M54,78C67.25,78 78,67.25 78,54C78,40.75 67.25,30 54,30C40.75,30 30,40.75 30,54C30,67.25 40.75,78 54,78Z"
+ android:strokeWidth="5"
+ android:fillColor="#00000000"
+ android:strokeColor="#000000"/>
+ <group>
+ <clip-path
+ android:pathData="M77.5,54C77.5,66.98 66.98,77.5 54,77.5C41.02,77.5 30.5,66.98 30.5,54C30.5,41.02 41.02,30.5 54,30.5C66.98,30.5 77.5,41.02 77.5,54Z"/>
+ <path
+ android:pathData="M61.5,46.06C56.7,47.89 51.4,47.89 46.61,46.06L44.04,50.51C43.49,51.46 42.28,51.79 41.33,51.24C40.39,50.69 40.06,49.48 40.61,48.53L43.06,44.28C37.97,41.03 34.54,35.56 34,29.19L33.88,27.74H74.22L74.1,29.19C73.57,35.56 70.14,41.03 65.04,44.28L67.51,48.56C68.03,49.49 67.71,50.66 66.8,51.21C65.87,51.77 64.65,51.47 64.08,50.54L64.07,50.51L61.5,46.06Z"
+ android:fillColor="#000000"/>
+ </group>
+ <path
+ android:pathData="M51.33,67.33h1.33v1.33h-1.33z"
+ android:fillColor="#000000"/>
+ <path
+ android:pathData="M48.67,62h1.33v1.33h-1.33z"
+ android:fillColor="#000000"/>
+ <path
+ android:pathData="M56.67,70h1.33v1.33h-1.33z"
+ android:fillColor="#000000"/>
+ <path
+ android:pathData="M56.67,62h2.67v2.67h-2.67z"
+ android:fillColor="#000000"/>
+ <path
+ android:pathData="M67.33,62h1.33v1.33h-1.33z"
+ android:fillColor="#000000"/>
+ <path
+ android:pathData="M59.33,51.33h2.67v2.67h-2.67z"
+ android:fillColor="#000000"/>
+ <path
+ android:pathData="M62,59.33h1.33v1.33h-1.33z"
+ android:fillColor="#000000"/>
+ <path
+ android:pathData="M70,54h1.33v1.33h-1.33z"
+ android:fillColor="#000000"/>
+ <path
+ android:pathData="M35.33,56.67h1.33v1.33h-1.33z"
+ android:fillColor="#000000"/>
+ <path
+ android:pathData="M35.33,48.67h1.33v1.33h-1.33z"
+ android:fillColor="#000000"/>
+ <path
+ android:pathData="M40.67,59.33h2.67v2.67h-2.67z"
+ android:fillColor="#000000"/>
+ <path
+ android:pathData="M46,51.33h1.33v1.33h-1.33z"
+ android:fillColor="#000000"/>
+ <path
+ android:pathData="M43.33,67.33h1.33v1.33h-1.33z"
+ android:fillColor="#000000"/>
+ <path
+ android:pathData="M54,54h1.33v1.33h-1.33z"
+ android:fillColor="#000000"/>
+ </group>
+ </group>
+</vector>
diff --git a/packages/EasterEgg/res/values/landroid_strings.xml b/packages/EasterEgg/res/values/landroid_strings.xml
new file mode 100644
index 0000000..1394f2f
--- /dev/null
+++ b/packages/EasterEgg/res/values/landroid_strings.xml
@@ -0,0 +1,371 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ Copyright (C) 2023 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<resources>
+ <string name="u_egg_name" translatable="false">Android 14 Easter Egg</string>
+
+ <string-array name="planet_descriptors" translatable="false">
+ <item>earthy</item>
+ <item>swamp</item>
+ <item>frozen</item>
+ <item>grassy</item>
+ <item>arid</item>
+ <item>crowded</item>
+ <item>ancient</item>
+ <item>lively</item>
+ <item>homey</item>
+ <item>modern</item>
+ <item>boring</item>
+ <item>compact</item>
+ <item>expensive</item>
+ <item>polluted</item>
+ <item>rusty</item>
+ <item>sandy</item>
+ <item>undulating</item>
+ <item>verdant</item>
+ <item>tessellated</item>
+ <item>hollow</item>
+ <item>scalding</item>
+ <item>hemispherical</item>
+ <item>oblong</item>
+ <item>oblate</item>
+ <item>vacuum</item>
+ <item>high-pressure</item>
+ <item>low-pressure</item>
+ <item>plastic</item>
+ <item>metallic</item>
+ <item>burned-out</item>
+ <item>bucolic</item>
+ </string-array>
+
+ <string-array name="life_descriptors" translatable="false">
+ <item>aggressive</item>
+ <item>passive-aggressive</item>
+ <item>shy</item>
+ <item>timid</item>
+ <item>nasty</item>
+ <item>brutish</item>
+ <item>short</item>
+ <item>absent</item>
+ <item>teen-aged</item>
+ <item>confused</item>
+ <item>transparent</item>
+ <item>cubic</item>
+ <item>quadratic</item>
+ <item>higher-order</item>
+ <item>huge</item>
+ <item>tall</item>
+ <item>wary</item>
+ <item>loud</item>
+ <item>yodeling</item>
+ <item>purring</item>
+ <item>slender</item>
+ <item>cats</item>
+ <item>adorable</item>
+ <item>eclectic</item>
+ <item>electric</item>
+ <item>microscopic</item>
+ <item>trunkless</item>
+ <item>myriad</item>
+ <item>cantankerous</item>
+ <item>gargantuan</item>
+ <item>contagious</item>
+ <item>fungal</item>
+ <item>cattywampus</item>
+ <item>spatchcocked</item>
+ <item>rotisserie</item>
+ <item>farm-to-table</item>
+ <item>organic</item>
+ <item>synthetic</item>
+ <item>unfocused</item>
+ <item>focused</item>
+ <item>capitalist</item>
+ <item>communal</item>
+ <item>bossy</item>
+ <item>malicious</item>
+ <item>compliant</item>
+ <item>psychic</item>
+ <item>oblivious</item>
+ <item>passive</item>
+ <item>bonsai</item>
+ </string-array>
+
+ <string-array name="any_descriptors" translatable="false">
+ <item>silly</item>
+ <item>dangerous</item>
+ <item>vast</item>
+ <item>invisible</item>
+ <item>superfluous</item>
+ <item>superconducting</item>
+ <item>superior</item>
+ <item>alien</item>
+ <item>phantom</item>
+ <item>friendly</item>
+ <item>peaceful</item>
+ <item>lonely</item>
+ <item>uncomfortable</item>
+ <item>charming</item>
+ <item>fractal</item>
+ <item>imaginary</item>
+ <item>forgotten</item>
+ <item>tardy</item>
+ <item>gassy</item>
+ <item>fungible</item>
+ <item>bespoke</item>
+ <item>artisanal</item>
+ <item>exceptional</item>
+ <item>puffy</item>
+ <item>rusty</item>
+ <item>fresh</item>
+ <item>crusty</item>
+ <item>glossy</item>
+ <item>lovely</item>
+ <item>processed</item>
+ <item>macabre</item>
+ <item>reticulated</item>
+ <item>shocking</item>
+ <item>void</item>
+ <item>undefined</item>
+ <item>gothic</item>
+ <item>beige</item>
+ <item>mid</item>
+ <item>milquetoast</item>
+ <item>melancholy</item>
+ <item>unnerving</item>
+ <item>cheery</item>
+ <item>vibrant</item>
+ <item>heliotrope</item>
+ <item>psychedelic</item>
+ <item>nondescript</item>
+ <item>indescribable</item>
+ <item>tubular</item>
+ <item>toroidal</item>
+ <item>voxellated</item>
+ <item>low-poly</item>
+ <item>low-carb</item>
+ <item>100% cotton</item>
+ <item>synthetic</item>
+ <item>boot-cut</item>
+ <item>bell-bottom</item>
+ <item>bumpy</item>
+ <item>fluffy</item>
+ <item>sous-vide</item>
+ <item>tepid</item>
+ <item>upcycled</item>
+ <item>sous-vide</item>
+ <item>bedazzled</item>
+ <item>ancient</item>
+ <item>inexplicable</item>
+ <item>sparkling</item>
+ <item>still</item>
+ <item>lemon-scented</item>
+ <item>eccentric</item>
+ <item>tilted</item>
+ <item>pungent</item>
+ <item>pine-scented</item>
+ <item>corduroy</item>
+ <item>overengineered</item>
+ <item>bioengineered</item>
+ <item>impossible</item>
+ </string-array>
+
+ <string-array name="constellations" translatable="false">
+ <item>Aries</item>
+ <item>Taurus</item>
+ <item>Gemini</item>
+ <item>Cancer</item>
+ <item>Leo</item>
+ <item>Virgo</item>
+ <item>Libra</item>
+ <item>Scorpio</item>
+ <item>Sagittarius</item>
+ <item>Capricorn</item>
+ <item>Aquarius</item>
+ <item>Pisces</item>
+ <item>Andromeda</item>
+ <item>Cygnus</item>
+ <item>Draco</item>
+ <item>Alcor</item>
+ <item>Calamari</item>
+ <item>Cuckoo</item>
+ <item>Neko</item>
+ <item>Monoceros</item>
+ <item>Norma</item>
+ <item>Abnorma</item>
+ <item>Morel</item>
+ <item>Redlands</item>
+ <item>Cupcake</item>
+ <item>Donut</item>
+ <item>Eclair</item>
+ <item>Froyo</item>
+ <item>Gingerbread</item>
+ <item>Honeycomb</item>
+ <item>Icecreamsandwich</item>
+ <item>Jellybean</item>
+ <item>Kitkat</item>
+ <item>Lollipop</item>
+ <item>Marshmallow</item>
+ <item>Nougat</item>
+ <item>Oreo</item>
+ <item>Pie</item>
+ <item>Quincetart</item>
+ <item>Redvelvetcake</item>
+ <item>Snowcone</item>
+ <item>Tiramisu</item>
+ <item>Upsidedowncake</item>
+ <item>Vanillaicecream</item>
+ <item>Android</item>
+ <item>Binder</item>
+ <item>Campanile</item>
+ <item>Dread</item>
+ </string-array>
+
+ <!-- prob: 5% -->
+ <string-array name="constellations_rare" translatable="false">
+ <item>Jandycane</item>
+ <item>Zombiegingerbread</item>
+ <item>Astro</item>
+ <item>Bender</item>
+ <item>Flan</item>
+ <item>Untitled-1</item>
+ <item>Expedit</item>
+ <item>Petit Four</item>
+ <item>Worcester</item>
+ <item>Xylophone</item>
+ <item>Yellowpeep</item>
+ <item>Zebraball</item>
+ <item>Hutton</item>
+ <item>Klang</item>
+ <item>Frogblast</item>
+ <item>Exo</item>
+ <item>Keylimepie</item>
+ <item>Nat</item>
+ <item>Nrp</item>
+ </string-array>
+
+ <!-- prob: 75% -->
+ <string-array name="star_suffixes" translatable="false">
+ <item>Alpha</item>
+ <item>Beta</item>
+ <item>Gamma</item>
+ <item>Delta</item>
+ <item>Epsilon</item>
+ <item>Zeta</item>
+ <item>Eta</item>
+ <item>Theta</item>
+ <item>Iota</item>
+ <item>Kappa</item>
+ <item>Lambda</item>
+ <item>Mu</item>
+ <item>Nu</item>
+ <item>Xi</item>
+ <item>Omicron</item>
+ <item>Pi</item>
+ <item>Rho</item>
+ <item>Sigma</item>
+ <item>Tau</item>
+ <item>Upsilon</item>
+ <item>Phi</item>
+ <item>Chi</item>
+ <item>Psi</item>
+ <item>Omega</item>
+
+ <item>Prime</item>
+ <item>Secundo</item>
+ <item>Major</item>
+ <item>Minor</item>
+ <item>Diminished</item>
+ <item>Augmented</item>
+ <item>Ultima</item>
+ <item>Penultima</item>
+ <item>Mid</item>
+
+ <item>Proxima</item>
+ <item>Novis</item>
+
+ <item>Plus</item>
+ </string-array>
+
+ <!-- prob: 5% -->
+ <!-- more than one can be appended, with very low prob -->
+ <string-array name="star_suffixes_rare" translatable="false">
+ <item>Serif</item>
+ <item>Sans</item>
+ <item>Oblique</item>
+ <item>Grotesque</item>
+ <item>Handtooled</item>
+ <item>III “Trey”</item>
+ <item>Alfredo</item>
+ <item>2.0</item>
+ <item>(Final)</item>
+ <item>(Final (Final))</item>
+ <item>(Draft)</item>
+ <item>Con Carne</item>
+ </string-array>
+
+ <string-array name="planet_types" translatable="false">
+ <item>planet</item>
+ <item>planetoid</item>
+ <item>moon</item>
+ <item>moonlet</item>
+ <item>centaur</item>
+ <item>asteroid</item>
+ <item>space garbage</item>
+ <item>detritus</item>
+ <item>satellite</item>
+ <item>core</item>
+ <item>giant</item>
+ <item>body</item>
+ <item>slab</item>
+ <item>rock</item>
+ <item>husk</item>
+ <item>planemo</item>
+ <item>object</item>
+ <item>planetesimal</item>
+ <item>exoplanet</item>
+ <item>ploonet</item>
+ </string-array>
+
+ <string-array name="atmo_descriptors" translatable="false">
+ <item>toxic</item>
+ <item>breathable</item>
+ <item>radioactive</item>
+ <item>clear</item>
+ <item>calm</item>
+ <item>peaceful</item>
+ <item>vacuum</item>
+ <item>stormy</item>
+ <item>freezing</item>
+ <item>burning</item>
+ <item>humid</item>
+ <item>tropical</item>
+ <item>cloudy</item>
+ <item>obscured</item>
+ <item>damp</item>
+ <item>dank</item>
+ <item>clammy</item>
+ <item>frozen</item>
+ <item>contaminated</item>
+ <item>temperate</item>
+ <item>moist</item>
+ <item>minty</item>
+ <item>relaxed</item>
+ <item>skunky</item>
+ <item>breezy</item>
+ <item>soup </item>
+ </string-array>
+
+</resources>
diff --git a/packages/EasterEgg/res/values/q_puzzles.xml b/packages/EasterEgg/res/values/q_puzzles.xml
index 3c9ac0b..bff99d5 100644
--- a/packages/EasterEgg/res/values/q_puzzles.xml
+++ b/packages/EasterEgg/res/values/q_puzzles.xml
@@ -44,7 +44,6 @@
<item>android:drawable/ic_audio_alarm</item>
<item>android:drawable/ic_audio_alarm_mute</item>
- <item>android:drawable/ic_bluetooth_share_icon</item>
<item>android:drawable/ic_bt_headphones_a2dp</item>
<item>android:drawable/ic_bt_headset_hfp</item>
<item>android:drawable/ic_bt_hearing_aid</item>
diff --git a/packages/EasterEgg/res/values/strings.xml b/packages/EasterEgg/res/values/strings.xml
index 743947a..79957df 100644
--- a/packages/EasterEgg/res/values/strings.xml
+++ b/packages/EasterEgg/res/values/strings.xml
@@ -14,7 +14,7 @@
limitations under the License.
-->
<resources xmlns:android="http://schemas.android.com/apk/res/android">
- <string name="app_name" translatable="false">Android S Easter Egg</string>
+ <string name="app_name" translatable="false">Android Easter Egg</string>
<!-- name of the Q easter egg, a nonogram-style icon puzzle -->
<string name="q_egg_name" translatable="false">Icon Quiz</string>
diff --git a/packages/EasterEgg/src/com/android/egg/landroid/Colors.kt b/packages/EasterEgg/src/com/android/egg/landroid/Colors.kt
new file mode 100644
index 0000000..f5657ae
--- /dev/null
+++ b/packages/EasterEgg/src/com/android/egg/landroid/Colors.kt
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.egg.landroid
+
+import androidx.compose.ui.graphics.Color
+
+/** Various UI colors. */
+object Colors {
+ val Eigengrau = Color(0xFF16161D)
+ val Eigengrau2 = Color(0xFF292936)
+ val Eigengrau3 = Color(0xFF3C3C4F)
+ val Eigengrau4 = Color(0xFFA7A7CA)
+
+ val Console = Color(0xFFB7B7FF)
+}
diff --git a/packages/EasterEgg/src/com/android/egg/landroid/ComposeTools.kt b/packages/EasterEgg/src/com/android/egg/landroid/ComposeTools.kt
new file mode 100644
index 0000000..d040fba
--- /dev/null
+++ b/packages/EasterEgg/src/com/android/egg/landroid/ComposeTools.kt
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.egg.landroid
+
+import androidx.compose.animation.core.CubicBezierEasing
+import androidx.compose.animation.core.Easing
+import androidx.compose.animation.core.tween
+import androidx.compose.animation.fadeIn
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.platform.LocalDensity
+import androidx.compose.ui.unit.Dp
+import kotlin.random.Random
+
+@Composable fun Dp.toLocalPx() = with(LocalDensity.current) { this@toLocalPx.toPx() }
+
+operator fun Easing.times(next: Easing) = { x: Float -> next.transform(transform(x)) }
+
+fun flickerFadeEasing(rng: Random) = Easing { frac -> if (rng.nextFloat() < frac) 1f else 0f }
+
+val flickerFadeIn =
+ fadeIn(
+ animationSpec =
+ tween(
+ durationMillis = 1000,
+ easing = CubicBezierEasing(0f, 1f, 1f, 0f) * flickerFadeEasing(Random)
+ )
+ )
diff --git a/packages/EasterEgg/src/com/android/egg/landroid/MainActivity.kt b/packages/EasterEgg/src/com/android/egg/landroid/MainActivity.kt
new file mode 100644
index 0000000..5a9b814
--- /dev/null
+++ b/packages/EasterEgg/src/com/android/egg/landroid/MainActivity.kt
@@ -0,0 +1,543 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.egg.landroid
+
+import android.content.res.Resources
+import android.os.Bundle
+import android.util.Log
+import androidx.activity.ComponentActivity
+import androidx.activity.compose.setContent
+import androidx.compose.animation.AnimatedVisibility
+import androidx.compose.animation.core.CubicBezierEasing
+import androidx.compose.animation.core.animateFloatAsState
+import androidx.compose.animation.core.tween
+import androidx.compose.animation.core.withInfiniteAnimationFrameNanos
+import androidx.compose.animation.fadeIn
+import androidx.compose.foundation.Canvas
+import androidx.compose.foundation.border
+import androidx.compose.foundation.gestures.awaitFirstDown
+import androidx.compose.foundation.gestures.forEachGesture
+import androidx.compose.foundation.gestures.rememberTransformableState
+import androidx.compose.foundation.gestures.transformable
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.ColumnScope
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
+import androidx.compose.material.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.MutableState
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.AbsoluteAlignment.Left
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.drawBehind
+import androidx.compose.ui.geometry.Offset
+import androidx.compose.ui.geometry.Rect
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.PathEffect
+import androidx.compose.ui.graphics.drawscope.Stroke
+import androidx.compose.ui.graphics.drawscope.translate
+import androidx.compose.ui.input.pointer.PointerEvent
+import androidx.compose.ui.input.pointer.pointerInput
+import androidx.compose.ui.text.font.FontFamily
+import androidx.compose.ui.text.font.FontWeight
+import androidx.compose.ui.tooling.preview.Devices
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
+import androidx.core.math.MathUtils.clamp
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.lifecycleScope
+import androidx.lifecycle.repeatOnLifecycle
+import androidx.window.layout.FoldingFeature
+import androidx.window.layout.WindowInfoTracker
+import java.lang.Float.max
+import java.lang.Float.min
+import java.util.Calendar
+import java.util.GregorianCalendar
+import kotlin.math.absoluteValue
+import kotlin.math.floor
+import kotlin.math.sqrt
+import kotlin.random.Random
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.launch
+
+enum class RandomSeedType {
+ Fixed,
+ Daily,
+ Evergreen
+}
+
+const val TEST_UNIVERSE = false
+
+val RANDOM_SEED_TYPE = RandomSeedType.Daily
+
+const val FIXED_RANDOM_SEED = 5038L
+const val DEFAULT_CAMERA_ZOOM = 0.25f
+const val MIN_CAMERA_ZOOM = 250f / UNIVERSE_RANGE // 0.0025f
+const val MAX_CAMERA_ZOOM = 5f
+const val TOUCH_CAMERA_PAN = false
+const val TOUCH_CAMERA_ZOOM = true
+const val DYNAMIC_ZOOM = false // @@@ FIXME
+
+fun dailySeed(): Long {
+ val today = GregorianCalendar()
+ return today.get(Calendar.YEAR) * 10_000L +
+ today.get(Calendar.MONTH) * 100L +
+ today.get(Calendar.DAY_OF_MONTH)
+}
+
+fun randomSeed(): Long {
+ return when (RANDOM_SEED_TYPE) {
+ RandomSeedType.Fixed -> FIXED_RANDOM_SEED
+ RandomSeedType.Daily -> dailySeed()
+ else -> Random.Default.nextLong().mod(10_000_000).toLong()
+ }.absoluteValue
+}
+
+val DEBUG_TEXT = mutableStateOf("Hello Universe")
+const val SHOW_DEBUG_TEXT = false
+
+@Composable
+fun DebugText(text: MutableState<String>) {
+ if (SHOW_DEBUG_TEXT) {
+ Text(
+ modifier = Modifier.fillMaxWidth().border(0.5.dp, color = Color.Yellow).padding(2.dp),
+ fontFamily = FontFamily.Monospace,
+ fontWeight = FontWeight.Medium,
+ fontSize = 9.sp,
+ color = Color.Yellow,
+ text = text.value
+ )
+ }
+}
+
+@Composable
+fun ColumnScope.ConsoleText(
+ modifier: Modifier = Modifier,
+ visible: Boolean = true,
+ random: Random = Random.Default,
+ text: String
+) {
+ AnimatedVisibility(
+ modifier = modifier,
+ visible = visible,
+ enter =
+ fadeIn(
+ animationSpec =
+ tween(
+ durationMillis = 1000,
+ easing = flickerFadeEasing(random) * CubicBezierEasing(0f, 1f, 1f, 0f)
+ )
+ )
+ ) {
+ Text(
+ fontFamily = FontFamily.Monospace,
+ fontWeight = FontWeight.Medium,
+ fontSize = 12.sp,
+ color = Color(0xFFFF8000),
+ text = text
+ )
+ }
+}
+
+@Composable
+fun Telemetry(universe: VisibleUniverse) {
+ var topVisible by remember { mutableStateOf(false) }
+ var bottomVisible by remember { mutableStateOf(false) }
+
+ LaunchedEffect("blah") {
+ delay(1000)
+ bottomVisible = true
+ delay(1000)
+ topVisible = true
+ }
+
+ Column(modifier = Modifier.fillMaxSize().padding(6.dp)) {
+ universe.triggerDraw.value // recompose on every frame
+ val explored = universe.planets.filter { it.explored }
+
+ AnimatedVisibility(modifier = Modifier, visible = topVisible, enter = flickerFadeIn) {
+ Text(
+ fontFamily = FontFamily.Monospace,
+ fontWeight = FontWeight.Medium,
+ fontSize = 12.sp,
+ color = Colors.Console,
+ modifier = Modifier.align(Left),
+ text =
+ with(universe.star) {
+ " STAR: $name (UDC-${universe.randomSeed % 100_000})\n" +
+ " CLASS: ${cls.name}\n" +
+ "RADIUS: ${radius.toInt()}\n" +
+ " MASS: %.3g\n".format(mass) +
+ "BODIES: ${explored.size} / ${universe.planets.size}\n" +
+ "\n"
+ } +
+ explored
+ .map {
+ " BODY: ${it.name}\n" +
+ " TYPE: ${it.description.capitalize()}\n" +
+ " ATMO: ${it.atmosphere.capitalize()}\n" +
+ " FAUNA: ${it.fauna.capitalize()}\n" +
+ " FLORA: ${it.flora.capitalize()}\n"
+ }
+ .joinToString("\n")
+
+ // TODO: different colors, highlight latest discovery
+ )
+ }
+
+ Spacer(modifier = Modifier.weight(1f))
+
+ AnimatedVisibility(modifier = Modifier, visible = bottomVisible, enter = flickerFadeIn) {
+ Text(
+ fontFamily = FontFamily.Monospace,
+ fontWeight = FontWeight.Medium,
+ fontSize = 12.sp,
+ color = Colors.Console,
+ modifier = Modifier.align(Left),
+ text =
+ with(universe.ship) {
+ val closest = universe.closestPlanet()
+ val distToClosest = (closest.pos - pos).mag().toInt()
+ listOfNotNull(
+ landing?.let { "LND: ${it.planet.name}" }
+ ?: if (distToClosest < 10_000) {
+ "ALT: $distToClosest"
+ } else null,
+ if (thrust != Vec2.Zero) "THR: %.0f%%".format(thrust.mag() * 100f)
+ else null,
+ "POS: %s".format(pos.str("%+7.0f")),
+ "VEL: %.0f".format(velocity.mag())
+ )
+ .joinToString("\n")
+ }
+ )
+ }
+ }
+}
+
+class MainActivity : ComponentActivity() {
+ private var foldState = mutableStateOf<FoldingFeature?>(null)
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+
+ onWindowLayoutInfoChange()
+
+ val universe = VisibleUniverse(namer = Namer(resources), randomSeed = randomSeed())
+
+ if (TEST_UNIVERSE) {
+ universe.initTest()
+ } else {
+ universe.initRandom()
+ }
+
+ setContent {
+ Spaaaace(modifier = Modifier.fillMaxSize(), u = universe, foldState = foldState)
+ DebugText(DEBUG_TEXT)
+
+ val minRadius = 50.dp.toLocalPx()
+ val maxRadius = 100.dp.toLocalPx()
+ FlightStick(
+ modifier = Modifier.fillMaxSize(),
+ minRadius = minRadius,
+ maxRadius = maxRadius,
+ color = Color.Green
+ ) { vec ->
+ (universe.follow as? Spacecraft)?.let { ship ->
+ if (vec == Vec2.Zero) {
+ ship.thrust = Vec2.Zero
+ } else {
+ val a = vec.angle()
+ ship.angle = a
+
+ val m = vec.mag()
+ if (m < minRadius) {
+ // within this radius, just reorient
+ ship.thrust = Vec2.Zero
+ } else {
+ ship.thrust =
+ Vec2.makeWithAngleMag(
+ a,
+ lexp(minRadius, maxRadius, m).coerceIn(0f, 1f)
+ )
+ }
+ }
+ }
+ }
+ Telemetry(universe)
+ }
+ }
+
+ private fun onWindowLayoutInfoChange() {
+ val windowInfoTracker = WindowInfoTracker.getOrCreate(this@MainActivity)
+
+ lifecycleScope.launch(Dispatchers.Main) {
+ lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) {
+ windowInfoTracker.windowLayoutInfo(this@MainActivity).collect { layoutInfo ->
+ foldState.value =
+ layoutInfo.displayFeatures.filterIsInstance<FoldingFeature>().firstOrNull()
+ Log.v("Landroid", "fold updated: $foldState")
+ }
+ }
+ }
+ }
+}
+
+@Preview(name = "phone", device = Devices.PHONE)
+@Preview(name = "fold", device = Devices.FOLDABLE)
+@Preview(name = "tablet", device = Devices.TABLET)
+@Composable
+fun MainActivityPreview() {
+ val universe = VisibleUniverse(namer = Namer(Resources.getSystem()), randomSeed = randomSeed())
+
+ universe.initTest()
+
+ Spaaaace(modifier = Modifier.fillMaxSize(), universe)
+ DebugText(DEBUG_TEXT)
+ Telemetry(universe)
+}
+
+@Composable
+fun FlightStick(
+ modifier: Modifier,
+ minRadius: Float = 0f,
+ maxRadius: Float = 1000f,
+ color: Color = Color.Green,
+ onStickChanged: (vector: Vec2) -> Unit
+) {
+ val origin = remember { mutableStateOf(Vec2.Zero) }
+ val target = remember { mutableStateOf(Vec2.Zero) }
+
+ Box(
+ modifier =
+ modifier
+ .pointerInput(Unit) {
+ forEachGesture {
+ awaitPointerEventScope {
+ // ACTION_DOWN
+ val down = awaitFirstDown(requireUnconsumed = false)
+ origin.value = down.position
+ target.value = down.position
+
+ do {
+ // ACTION_MOVE
+ val event: PointerEvent = awaitPointerEvent()
+ target.value = event.changes[0].position
+
+ onStickChanged(target.value - origin.value)
+ } while (
+ !event.changes.any { it.isConsumed } &&
+ event.changes.count { it.pressed } == 1
+ )
+
+ // ACTION_UP / CANCEL
+ target.value = Vec2.Zero
+ origin.value = Vec2.Zero
+
+ onStickChanged(Vec2.Zero)
+ }
+ }
+ }
+ .drawBehind {
+ if (origin.value != Vec2.Zero) {
+ val delta = target.value - origin.value
+ val mag = min(maxRadius, delta.mag())
+ val r = max(minRadius, mag)
+ val a = delta.angle()
+ drawCircle(
+ color = color,
+ center = origin.value,
+ radius = r,
+ style =
+ Stroke(
+ width = 2f,
+ pathEffect =
+ if (mag < minRadius)
+ PathEffect.dashPathEffect(
+ floatArrayOf(this.density * 1f, this.density * 2f)
+ )
+ else null
+ )
+ )
+ drawLine(
+ color = color,
+ start = origin.value,
+ end = origin.value + Vec2.makeWithAngleMag(a, mag),
+ strokeWidth = 2f
+ )
+ }
+ }
+ )
+}
+
+@Composable
+fun Spaaaace(
+ modifier: Modifier,
+ u: VisibleUniverse,
+ foldState: MutableState<FoldingFeature?> = mutableStateOf(null)
+) {
+ LaunchedEffect(u) {
+ while (true) withInfiniteAnimationFrameNanos { frameTimeNanos ->
+ u.simulateAndDrawFrame(frameTimeNanos)
+ }
+ }
+
+ var cameraZoom by remember { mutableStateOf(1f) }
+ var cameraOffset by remember { mutableStateOf(Offset.Zero) }
+
+ val transformableState =
+ rememberTransformableState { zoomChange, offsetChange, rotationChange ->
+ if (TOUCH_CAMERA_PAN) cameraOffset += offsetChange / cameraZoom
+ if (TOUCH_CAMERA_ZOOM)
+ cameraZoom = clamp(cameraZoom * zoomChange, MIN_CAMERA_ZOOM, MAX_CAMERA_ZOOM)
+ }
+
+ var canvasModifier = modifier
+
+ if (TOUCH_CAMERA_PAN || TOUCH_CAMERA_ZOOM) {
+ canvasModifier = canvasModifier.transformable(transformableState)
+ }
+
+ val halfFolded = foldState.value?.let { it.state == FoldingFeature.State.HALF_OPENED } ?: false
+ val horizontalFold =
+ foldState.value?.let { it.orientation == FoldingFeature.Orientation.HORIZONTAL } ?: false
+
+ val centerFracX: Float by
+ animateFloatAsState(if (halfFolded && !horizontalFold) 0.25f else 0.5f, label = "centerX")
+ val centerFracY: Float by
+ animateFloatAsState(if (halfFolded && horizontalFold) 0.25f else 0.5f, label = "centerY")
+
+ Canvas(modifier = canvasModifier) {
+ drawRect(Colors.Eigengrau, Offset.Zero, size)
+
+ val closest = u.closestPlanet()
+ val distToNearestSurf = max(0f, (u.ship.pos - closest.pos).mag() - closest.radius * 1.2f)
+ // val normalizedDist = clamp(distToNearestSurf, 50f, 50_000f) / 50_000f
+ if (DYNAMIC_ZOOM) {
+ // cameraZoom = lerp(0.1f, 5f, smooth(1f-normalizedDist))
+ cameraZoom = clamp(500f / distToNearestSurf, MIN_CAMERA_ZOOM, MAX_CAMERA_ZOOM)
+ } else if (!TOUCH_CAMERA_ZOOM) cameraZoom = DEFAULT_CAMERA_ZOOM
+ if (!TOUCH_CAMERA_PAN) cameraOffset = (u.follow?.pos ?: Vec2.Zero) * -1f
+
+ // cameraZoom: metersToPixels
+ // visibleSpaceSizeMeters: meters
+ // cameraOffset: meters ≈ vector pointing from ship to (0,0) (e.g. -pos)
+ val visibleSpaceSizeMeters = size / cameraZoom // meters x meters
+ val visibleSpaceRectMeters =
+ Rect(
+ -cameraOffset -
+ Offset(
+ visibleSpaceSizeMeters.width * centerFracX,
+ visibleSpaceSizeMeters.height * centerFracY
+ ),
+ visibleSpaceSizeMeters
+ )
+
+ var gridStep = 1000f
+ while (gridStep * cameraZoom < 32.dp.toPx()) gridStep *= 10
+
+ DEBUG_TEXT.value =
+ ("SIMULATION //\n" +
+ // "normalizedDist=${normalizedDist} \n" +
+ "entities: ${u.entities.size} // " +
+ "zoom: ${"%.4f".format(cameraZoom)}x // " +
+ "fps: ${"%3.0f".format(1f / u.dt)} " +
+ "dt: ${u.dt}\n" +
+ ((u.follow as? Spacecraft)?.let {
+ "ship: p=%s v=%7.2f a=%6.3f t=%s\n".format(
+ it.pos.str("%+7.1f"),
+ it.velocity.mag(),
+ it.angle,
+ it.thrust.str("%+5.2f")
+ )
+ }
+ ?: "") +
+ "star: '${u.star.name}' designation=UDC-${u.randomSeed % 100_000} " +
+ "class=${u.star.cls.name} r=${u.star.radius.toInt()} m=${u.star.mass}\n" +
+ "planets: ${u.planets.size}\n" +
+ u.planets.joinToString("\n") {
+ val range = (u.ship.pos - it.pos).mag()
+ val vorbit = sqrt(GRAVITATION * it.mass / range)
+ val vescape = sqrt(2 * GRAVITATION * it.mass / it.radius)
+ " * ${it.name}:\n" +
+ if (it.explored) {
+ " TYPE: ${it.description.capitalize()}\n" +
+ " ATMO: ${it.atmosphere.capitalize()}\n" +
+ " FAUNA: ${it.fauna.capitalize()}\n" +
+ " FLORA: ${it.flora.capitalize()}\n"
+ } else {
+ " (Unexplored)\n"
+ } +
+ " orbit=${(it.pos - it.orbitCenter).mag().toInt()}" +
+ " radius=${it.radius.toInt()}" +
+ " mass=${"%g".format(it.mass)}" +
+ " vel=${(it.speed).toInt()}" +
+ " // range=${"%.0f".format(range)}" +
+ " vorbit=${vorbit.toInt()} vescape=${vescape.toInt()}"
+ })
+
+ zoom(cameraZoom) {
+ // All coordinates are space coordinates now.
+
+ translate(
+ -visibleSpaceRectMeters.center.x + size.width * 0.5f,
+ -visibleSpaceRectMeters.center.y + size.height * 0.5f
+ ) {
+ // debug outer frame
+ // drawRect(
+ // Colors.Eigengrau2,
+ // visibleSpaceRectMeters.topLeft,
+ // visibleSpaceRectMeters.size,
+ // style = Stroke(width = 10f / cameraZoom)
+ // )
+
+ var x = floor(visibleSpaceRectMeters.left / gridStep) * gridStep
+ while (x < visibleSpaceRectMeters.right) {
+ drawLine(
+ color = Colors.Eigengrau2,
+ start = Offset(x, visibleSpaceRectMeters.top),
+ end = Offset(x, visibleSpaceRectMeters.bottom),
+ strokeWidth = (if ((x % (gridStep * 10) == 0f)) 3f else 1.5f) / cameraZoom
+ )
+ x += gridStep
+ }
+
+ var y = floor(visibleSpaceRectMeters.top / gridStep) * gridStep
+ while (y < visibleSpaceRectMeters.bottom) {
+ drawLine(
+ color = Colors.Eigengrau2,
+ start = Offset(visibleSpaceRectMeters.left, y),
+ end = Offset(visibleSpaceRectMeters.right, y),
+ strokeWidth = (if ((y % (gridStep * 10) == 0f)) 3f else 1.5f) / cameraZoom
+ )
+ y += gridStep
+ }
+
+ this@zoom.drawUniverse(u)
+ }
+ }
+ }
+}
diff --git a/packages/EasterEgg/src/com/android/egg/landroid/Maths.kt b/packages/EasterEgg/src/com/android/egg/landroid/Maths.kt
new file mode 100644
index 0000000..fdf29f7
--- /dev/null
+++ b/packages/EasterEgg/src/com/android/egg/landroid/Maths.kt
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.egg.landroid
+
+import kotlin.math.pow
+
+/** smoothstep. Ken Perlin's version */
+fun smooth(x: Float): Float {
+ return x * x * x * (x * (x * 6 - 15) + 10)
+}
+
+/** Kind of like an inverted smoothstep, but */
+fun invsmoothish(x: Float): Float {
+ return 0.25f * ((2f * x - 1f).pow(5f) + 1f) + 0.5f * x
+}
+
+/** Compute the fraction that progress represents between start and end (inverse of lerp). */
+fun lexp(start: Float, end: Float, progress: Float): Float {
+ return (progress - start) / (end - start)
+}
diff --git a/packages/EasterEgg/src/com/android/egg/landroid/Namer.kt b/packages/EasterEgg/src/com/android/egg/landroid/Namer.kt
new file mode 100644
index 0000000..67d536e
--- /dev/null
+++ b/packages/EasterEgg/src/com/android/egg/landroid/Namer.kt
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.egg.landroid
+
+import android.content.res.Resources
+import kotlin.random.Random
+
+import com.android.egg.R
+
+const val SUFFIX_PROB = 0.75f
+const val LETTER_PROB = 0.3f
+const val NUMBER_PROB = 0.3f
+const val RARE_PROB = 0.05f
+
+class Namer(resources: Resources) {
+ private val planetDescriptors = Bag(resources.getStringArray(R.array.planet_descriptors))
+ private val lifeDescriptors = Bag(resources.getStringArray(R.array.life_descriptors))
+ private val anyDescriptors = Bag(resources.getStringArray(R.array.any_descriptors))
+ private val atmoDescriptors = Bag(resources.getStringArray(R.array.atmo_descriptors))
+
+ private val planetTypes = Bag(resources.getStringArray(R.array.planet_types))
+ private val constellations = Bag(resources.getStringArray(R.array.constellations))
+ private val constellationsRare = Bag(resources.getStringArray(R.array.constellations_rare))
+ private val suffixes = Bag(resources.getStringArray(R.array.star_suffixes))
+ private val suffixesRare = Bag(resources.getStringArray(R.array.star_suffixes_rare))
+
+ private val planetTable = RandomTable(0.75f to planetDescriptors, 0.25f to anyDescriptors)
+
+ private var lifeTable = RandomTable(0.75f to lifeDescriptors, 0.25f to anyDescriptors)
+
+ private var constellationsTable =
+ RandomTable(RARE_PROB to constellationsRare, 1f - RARE_PROB to constellations)
+
+ private var suffixesTable = RandomTable(RARE_PROB to suffixesRare, 1f - RARE_PROB to suffixes)
+
+ private var atmoTable = RandomTable(0.75f to atmoDescriptors, 0.25f to anyDescriptors)
+
+ private var delimiterTable =
+ RandomTable(
+ 15f to " ",
+ 3f to "-",
+ 1f to "_",
+ 1f to "/",
+ 1f to ".",
+ 1f to "*",
+ 1f to "^",
+ 1f to "#",
+ 0.1f to "(^*!%@##!!"
+ )
+
+ fun describePlanet(rng: Random): String {
+ return planetTable.roll(rng).pull(rng) + " " + planetTypes.pull(rng)
+ }
+
+ fun describeLife(rng: Random): String {
+ return lifeTable.roll(rng).pull(rng)
+ }
+
+ fun nameSystem(rng: Random): String {
+ val parts = StringBuilder()
+ parts.append(constellationsTable.roll(rng).pull(rng))
+ if (rng.nextFloat() <= SUFFIX_PROB) {
+ parts.append(delimiterTable.roll(rng))
+ parts.append(suffixesTable.roll(rng).pull(rng))
+ if (rng.nextFloat() <= RARE_PROB) parts.append(' ').append(suffixesRare.pull(rng))
+ }
+ if (rng.nextFloat() <= LETTER_PROB) {
+ parts.append(delimiterTable.roll(rng))
+ parts.append('A' + rng.nextInt(0, 26))
+ if (rng.nextFloat() <= RARE_PROB) parts.append(delimiterTable.roll(rng))
+ }
+ if (rng.nextFloat() <= NUMBER_PROB) {
+ parts.append(delimiterTable.roll(rng))
+ parts.append(rng.nextInt(2, 5039))
+ }
+ return parts.toString()
+ }
+
+ fun describeAtmo(rng: Random): String {
+ return atmoTable.roll(rng).pull(rng)
+ }
+}
diff --git a/packages/EasterEgg/src/com/android/egg/landroid/PathTools.kt b/packages/EasterEgg/src/com/android/egg/landroid/PathTools.kt
new file mode 100644
index 0000000..8510640
--- /dev/null
+++ b/packages/EasterEgg/src/com/android/egg/landroid/PathTools.kt
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.egg.landroid
+
+import android.util.Log
+import androidx.compose.ui.graphics.Path
+import kotlin.math.cos
+import kotlin.math.sin
+
+fun createPolygon(radius: Float, sides: Int): Path {
+ return Path().apply {
+ moveTo(radius, 0f)
+ val angleStep = PI2f / sides
+ for (i in 1 until sides) {
+ lineTo(radius * cos(angleStep * i), radius * sin(angleStep * i))
+ }
+ close()
+ }
+}
+
+fun createStar(radius1: Float, radius2: Float, points: Int): Path {
+ return Path().apply {
+ val angleStep = PI2f / points
+ moveTo(radius1, 0f)
+ lineTo(radius2 * cos(angleStep * (0.5f)), radius2 * sin(angleStep * (0.5f)))
+ for (i in 1 until points) {
+ lineTo(radius1 * cos(angleStep * i), radius1 * sin(angleStep * i))
+ lineTo(radius2 * cos(angleStep * (i + 0.5f)), radius2 * sin(angleStep * (i + 0.5f)))
+ }
+ close()
+ }
+}
+
+fun Path.parseSvgPathData(d: String) {
+ Regex("([A-Z])([-.,0-9e ]+)").findAll(d.trim()).forEach {
+ val cmd = it.groups[1]!!.value
+ val args =
+ it.groups[2]?.value?.split(Regex("\\s+"))?.map { v -> v.toFloat() } ?: emptyList()
+ Log.d("Landroid", "cmd = $cmd, args = " + args.joinToString(","))
+ when (cmd) {
+ "M" -> moveTo(args[0], args[1])
+ "C" -> cubicTo(args[0], args[1], args[2], args[3], args[4], args[5])
+ "L" -> lineTo(args[0], args[1])
+ "Z" -> close()
+ else -> Log.v("Landroid", "unsupported SVG command: $cmd")
+ }
+ }
+}
diff --git a/packages/EasterEgg/src/com/android/egg/landroid/Physics.kt b/packages/EasterEgg/src/com/android/egg/landroid/Physics.kt
new file mode 100644
index 0000000..fc66ad6
--- /dev/null
+++ b/packages/EasterEgg/src/com/android/egg/landroid/Physics.kt
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.egg.landroid
+
+import android.util.ArraySet
+import kotlin.random.Random
+
+// artificially speed up or slow down the simulation
+const val TIME_SCALE = 1f
+
+// if it's been over 1 real second since our last timestep, don't simulate that elapsed time.
+// this allows the simulation to "pause" when, for example, the activity pauses
+const val MAX_VALID_DT = 1f
+
+interface Entity {
+ // Integrate.
+ // Compute accelerations from forces, add accelerations to velocity, save old position,
+ // add velocity to position.
+ fun update(sim: Simulator, dt: Float)
+
+ // Post-integration step, after constraints are satisfied.
+ fun postUpdate(sim: Simulator, dt: Float)
+}
+
+open class Body(var name: String = "Unknown") : Entity {
+ var pos = Vec2.Zero
+ var opos = Vec2.Zero
+ var velocity = Vec2.Zero
+
+ var mass = 0f
+ var angle = 0f
+ var radius = 0f
+
+ var collides = true
+
+ var omega: Float
+ get() = angle - oangle
+ set(value) {
+ oangle = angle - value
+ }
+
+ var oangle = 0f
+
+ override fun update(sim: Simulator, dt: Float) {
+ if (dt <= 0) return
+
+ // integrate velocity
+ val vscaled = velocity * dt
+ opos = pos
+ pos += vscaled
+
+ // integrate angular velocity
+ // val wscaled = omega * timescale
+ // oangle = angle
+ // angle = (angle + wscaled) % PI2f
+ }
+
+ override fun postUpdate(sim: Simulator, dt: Float) {
+ if (dt <= 0) return
+ velocity = (pos - opos) / dt
+ }
+}
+
+interface Constraint {
+ // Solve constraints. Pick up objects and put them where they are "supposed" to be.
+ fun solve(sim: Simulator, dt: Float)
+}
+
+open class Container(val radius: Float) : Constraint {
+ private val list = ArraySet<Body>()
+ private val softness = 0.0f
+
+ override fun toString(): String {
+ return "Container($radius)"
+ }
+
+ fun add(p: Body) {
+ list.add(p)
+ }
+
+ fun remove(p: Body) {
+ list.remove(p)
+ }
+
+ override fun solve(sim: Simulator, dt: Float) {
+ for (p in list) {
+ if ((p.pos.mag() + p.radius) > radius) {
+ p.pos =
+ p.pos * (softness) +
+ Vec2.makeWithAngleMag(p.pos.angle(), radius - p.radius) * (1f - softness)
+ }
+ }
+ }
+}
+
+open class Simulator(val randomSeed: Long) {
+ private var wallClockNanos: Long = 0L
+ var now: Float = 0f
+ var dt: Float = 0f
+ val rng = Random(randomSeed)
+ val entities = ArraySet<Entity>(1000)
+ val constraints = ArraySet<Constraint>(100)
+
+ fun add(e: Entity) = entities.add(e)
+ fun remove(e: Entity) = entities.remove(e)
+ fun add(c: Constraint) = constraints.add(c)
+ fun remove(c: Constraint) = constraints.remove(c)
+
+ open fun updateAll(dt: Float, entities: ArraySet<Entity>) {
+ entities.forEach { it.update(this, dt) }
+ }
+
+ open fun solveAll(dt: Float, constraints: ArraySet<Constraint>) {
+ constraints.forEach { it.solve(this, dt) }
+ }
+
+ open fun postUpdateAll(dt: Float, entities: ArraySet<Entity>) {
+ entities.forEach { it.postUpdate(this, dt) }
+ }
+
+ fun step(nanos: Long) {
+ val firstFrame = (wallClockNanos == 0L)
+
+ dt = (nanos - wallClockNanos) / 1_000_000_000f * TIME_SCALE
+ this.wallClockNanos = nanos
+
+ // we start the simulation on the next frame
+ if (firstFrame || dt > MAX_VALID_DT) return
+
+ // simulation is running; we start accumulating simulation time
+ this.now += dt
+
+ val localEntities = ArraySet(entities)
+ val localConstraints = ArraySet(constraints)
+
+ // position-based dynamics approach:
+ // 1. apply acceleration to velocity, save positions, apply velocity to position
+ updateAll(dt, localEntities)
+
+ // 2. solve all constraints
+ solveAll(dt, localConstraints)
+
+ // 3. compute new velocities from updated positions and saved positions
+ postUpdateAll(dt, localEntities)
+ }
+}
diff --git a/packages/EasterEgg/src/com/android/egg/landroid/Randomness.kt b/packages/EasterEgg/src/com/android/egg/landroid/Randomness.kt
new file mode 100644
index 0000000..ebbb2bd
--- /dev/null
+++ b/packages/EasterEgg/src/com/android/egg/landroid/Randomness.kt
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.egg.landroid
+
+import kotlin.random.Random
+
+/**
+ * A bag of stones. Each time you pull one out it is not replaced, preventing duplicates. When the
+ * bag is exhausted, all the stones are replaced and reshuffled.
+ */
+class Bag<T>(items: Array<T>) {
+ private val remaining = items.copyOf()
+ private var next = remaining.size // will cause a shuffle on first pull()
+
+ /** Return the next random item from the bag, without replacing it. */
+ fun pull(rng: Random): T {
+ if (next >= remaining.size) {
+ remaining.shuffle(rng)
+ next = 0
+ }
+ return remaining[next++]
+ }
+}
+
+/**
+ * A loot table. The weight of each possibility is in the first of the pair; the value to be
+ * returned in the second. They need not add up to 1f (we will do that for you, free of charge).
+ */
+class RandomTable<T>(private vararg val pairs: Pair<Float, T>) {
+ private val total = pairs.map { it.first }.sum()
+
+ /** Select a random value from the weighted table. */
+ fun roll(rng: Random): T {
+ var x = rng.nextFloatInRange(0f, total)
+ for ((weight, result) in pairs) {
+ x -= weight
+ if (x < 0f) return result
+ }
+ return pairs.last().second
+ }
+}
+
+/** Return a random float in the range [from, until). */
+fun Random.nextFloatInRange(from: Float, until: Float): Float =
+ from + ((until - from) * nextFloat())
+
+/** Return a random float in the range [start, end). */
+fun Random.nextFloatInRange(fromUntil: ClosedFloatingPointRange<Float>): Float =
+ nextFloatInRange(fromUntil.start, fromUntil.endInclusive)
+/** Return a random float in the range [first, second). */
+fun Random.nextFloatInRange(fromUntil: Pair<Float, Float>): Float =
+ nextFloatInRange(fromUntil.first, fromUntil.second)
+
+/** Choose a random element from an array. */
+fun <T> Random.choose(array: Array<T>) = array[nextInt(array.size)]
diff --git a/packages/EasterEgg/src/com/android/egg/landroid/Universe.kt b/packages/EasterEgg/src/com/android/egg/landroid/Universe.kt
new file mode 100644
index 0000000..fec3ab3
--- /dev/null
+++ b/packages/EasterEgg/src/com/android/egg/landroid/Universe.kt
@@ -0,0 +1,513 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.egg.landroid
+
+import android.util.ArraySet
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.util.lerp
+import kotlin.math.absoluteValue
+import kotlin.math.pow
+import kotlin.math.sqrt
+
+const val UNIVERSE_RANGE = 200_000f
+
+val NUM_PLANETS_RANGE = 1..10
+val STAR_RADIUS_RANGE = (1_000f..8_000f)
+val PLANET_RADIUS_RANGE = (50f..2_000f)
+val PLANET_ORBIT_RANGE = (STAR_RADIUS_RANGE.endInclusive * 2f)..(UNIVERSE_RANGE * 0.75f)
+
+const val GRAVITATION = 1e-2f
+const val KEPLER_CONSTANT = 50f // * 4f * PIf * PIf / GRAVITATION
+
+// m = d * r
+const val PLANETARY_DENSITY = 2.5f
+const val STELLAR_DENSITY = 0.5f
+
+const val SPACECRAFT_MASS = 10f
+
+const val CRAFT_SPEED_LIMIT = 5_000f
+const val MAIN_ENGINE_ACCEL = 1000f // thrust effect, pixels per second squared
+const val LAUNCH_MECO = 2f // how long to suspend gravity when launching
+
+const val SCALED_THRUST = true
+
+interface Removable {
+ fun canBeRemoved(): Boolean
+}
+
+open class Planet(
+ val orbitCenter: Vec2,
+ radius: Float,
+ pos: Vec2,
+ var speed: Float,
+ var color: Color = Color.White
+) : Body() {
+ var atmosphere = ""
+ var description = ""
+ var flora = ""
+ var fauna = ""
+ var explored = false
+ private val orbitRadius: Float
+ init {
+ this.radius = radius
+ this.pos = pos
+ orbitRadius = pos.distance(orbitCenter)
+ mass = 4 / 3 * PIf * radius.pow(3) * PLANETARY_DENSITY
+ }
+
+ override fun update(sim: Simulator, dt: Float) {
+ val orbitAngle = (pos - orbitCenter).angle()
+ // constant linear velocity
+ velocity = Vec2.makeWithAngleMag(orbitAngle + PIf / 2f, speed)
+
+ super.update(sim, dt)
+ }
+
+ override fun postUpdate(sim: Simulator, dt: Float) {
+ // This is kind of like a constraint, but whatever.
+ val orbitAngle = (pos - orbitCenter).angle()
+ pos = orbitCenter + Vec2.makeWithAngleMag(orbitAngle, orbitRadius)
+ super.postUpdate(sim, dt)
+ }
+}
+
+enum class StarClass {
+ O,
+ B,
+ A,
+ F,
+ G,
+ K,
+ M
+}
+
+fun starColor(cls: StarClass) =
+ when (cls) {
+ StarClass.O -> Color(0xFF6666FF)
+ StarClass.B -> Color(0xFFCCCCFF)
+ StarClass.A -> Color(0xFFEEEEFF)
+ StarClass.F -> Color(0xFFFFFFFF)
+ StarClass.G -> Color(0xFFFFFF66)
+ StarClass.K -> Color(0xFFFFCC33)
+ StarClass.M -> Color(0xFFFF8800)
+ }
+
+class Star(val cls: StarClass, radius: Float) :
+ Planet(orbitCenter = Vec2.Zero, radius = radius, pos = Vec2.Zero, speed = 0f) {
+ init {
+ pos = Vec2.Zero
+ mass = 4 / 3 * PIf * radius.pow(3) * STELLAR_DENSITY
+ color = starColor(cls)
+ collides = false
+ }
+ var anim = 0f
+ override fun update(sim: Simulator, dt: Float) {
+ anim += dt
+ }
+}
+
+open class Universe(val namer: Namer, randomSeed: Long) : Simulator(randomSeed) {
+ var latestDiscovery: Planet? = null
+ lateinit var star: Star
+ lateinit var ship: Spacecraft
+ val planets: MutableList<Planet> = mutableListOf()
+ var follow: Body? = null
+ val ringfence = Container(UNIVERSE_RANGE)
+
+ fun initTest() {
+ val systemName = "TEST SYSTEM"
+ star =
+ Star(
+ cls = StarClass.A,
+ radius = STAR_RADIUS_RANGE.endInclusive,
+ )
+ .apply { name = "TEST SYSTEM" }
+
+ repeat(NUM_PLANETS_RANGE.last) {
+ val thisPlanetFrac = it.toFloat() / (NUM_PLANETS_RANGE.last - 1)
+ val radius =
+ lerp(PLANET_RADIUS_RANGE.start, PLANET_RADIUS_RANGE.endInclusive, thisPlanetFrac)
+ val orbitRadius =
+ lerp(PLANET_ORBIT_RANGE.start, PLANET_ORBIT_RANGE.endInclusive, thisPlanetFrac)
+
+ val period = sqrt(orbitRadius.pow(3f) / star.mass) * KEPLER_CONSTANT
+ val speed = 2f * PIf * orbitRadius / period
+
+ val p =
+ Planet(
+ orbitCenter = star.pos,
+ radius = radius,
+ pos = star.pos + Vec2.makeWithAngleMag(thisPlanetFrac * PI2f, orbitRadius),
+ speed = speed,
+ color = Colors.Eigengrau4
+ )
+ android.util.Log.v(
+ "Landroid",
+ "created planet $p with period $period and vel $speed"
+ )
+ val num = it + 1
+ p.description = "TEST PLANET #$num"
+ p.atmosphere = "radius=$radius"
+ p.flora = "mass=${p.mass}"
+ p.fauna = "speed=$speed"
+ planets.add(p)
+ add(p)
+ }
+
+ planets.sortBy { it.pos.distance(star.pos) }
+ planets.forEachIndexed { idx, planet -> planet.name = "$systemName ${idx + 1}" }
+ add(star)
+
+ ship = Spacecraft()
+
+ ship.pos = star.pos + Vec2.makeWithAngleMag(PIf / 4, PLANET_ORBIT_RANGE.start)
+ ship.angle = 0f
+ add(ship)
+
+ ringfence.add(ship)
+ add(ringfence)
+
+ follow = ship
+ }
+
+ fun initRandom() {
+ val systemName = namer.nameSystem(rng)
+ star =
+ Star(
+ cls = rng.choose(StarClass.values()),
+ radius = rng.nextFloatInRange(STAR_RADIUS_RANGE)
+ )
+ star.name = systemName
+ repeat(rng.nextInt(NUM_PLANETS_RANGE.first, NUM_PLANETS_RANGE.last + 1)) {
+ val radius = rng.nextFloatInRange(PLANET_RADIUS_RANGE)
+ val orbitRadius =
+ lerp(
+ PLANET_ORBIT_RANGE.start,
+ PLANET_ORBIT_RANGE.endInclusive,
+ rng.nextFloat().pow(1f)
+ )
+
+ // Kepler's third law
+ val period = sqrt(orbitRadius.pow(3f) / star.mass) * KEPLER_CONSTANT
+ val speed = 2f * PIf * orbitRadius / period
+
+ val p =
+ Planet(
+ orbitCenter = star.pos,
+ radius = radius,
+ pos = star.pos + Vec2.makeWithAngleMag(rng.nextFloat() * PI2f, orbitRadius),
+ speed = speed,
+ color = Colors.Eigengrau4
+ )
+ android.util.Log.v(
+ "Landroid",
+ "created planet $p with period $period and vel $speed"
+ )
+ p.description = namer.describePlanet(rng)
+ p.atmosphere = namer.describeAtmo(rng)
+ p.flora = namer.describeLife(rng)
+ p.fauna = namer.describeLife(rng)
+ planets.add(p)
+ add(p)
+ }
+ planets.sortBy { it.pos.distance(star.pos) }
+ planets.forEachIndexed { idx, planet -> planet.name = "$systemName ${idx + 1}" }
+ add(star)
+
+ ship = Spacecraft()
+
+ ship.pos =
+ star.pos +
+ Vec2.makeWithAngleMag(
+ rng.nextFloat() * PI2f,
+ rng.nextFloatInRange(PLANET_ORBIT_RANGE.start, PLANET_ORBIT_RANGE.endInclusive)
+ )
+ ship.angle = rng.nextFloat() * PI2f
+ add(ship)
+
+ ringfence.add(ship)
+ add(ringfence)
+
+ follow = ship
+ }
+
+ override fun updateAll(dt: Float, entities: ArraySet<Entity>) {
+ // check for passing in front of the sun
+ ship.transit = false
+
+ (planets + star).forEach { planet ->
+ val vector = planet.pos - ship.pos
+ val d = vector.mag()
+ if (d < planet.radius) {
+ if (planet is Star) ship.transit = true
+ } else if (
+ now > ship.launchClock + LAUNCH_MECO
+ ) { // within MECO sec of launch, no gravity at all
+ // simulate gravity: $ f_g = G * m1 * m2 * 1/d^2 $
+ ship.velocity =
+ ship.velocity +
+ Vec2.makeWithAngleMag(
+ vector.angle(),
+ GRAVITATION * (ship.mass * planet.mass) / d.pow(2)
+ ) * dt
+ }
+ }
+
+ super.updateAll(dt, entities)
+ }
+
+ fun closestPlanet(): Planet {
+ val bodiesByDist =
+ (planets + star)
+ .map { planet -> (planet.pos - ship.pos) to planet }
+ .sortedBy { it.first.mag() }
+
+ return bodiesByDist[0].second
+ }
+
+ override fun solveAll(dt: Float, constraints: ArraySet<Constraint>) {
+ if (ship.landing == null) {
+ val planet = closestPlanet()
+
+ if (planet.collides) {
+ val d = (ship.pos - planet.pos).mag() - ship.radius - planet.radius
+ val a = (ship.pos - planet.pos).angle()
+
+ if (d < 0) {
+ // landing, or impact?
+
+ // 1. relative speed
+ val vDiff = (ship.velocity - planet.velocity).mag()
+ // 2. landing angle
+ val aDiff = (ship.angle - a).absoluteValue
+
+ // landing criteria
+ if (aDiff < PIf / 4
+ // &&
+ // vDiff < 100f
+ ) {
+ val landing = Landing(ship, planet, a)
+ ship.landing = landing
+ ship.velocity = planet.velocity
+ add(landing)
+
+ planet.explored = true
+ latestDiscovery = planet
+ } else {
+ val impact = planet.pos + Vec2.makeWithAngleMag(a, planet.radius)
+ ship.pos =
+ planet.pos + Vec2.makeWithAngleMag(a, planet.radius + ship.radius - d)
+
+ // add(Spark(
+ // lifetime = 1f,
+ // style = Spark.Style.DOT,
+ // color = Color.Yellow,
+ // size = 10f
+ // ).apply {
+ // pos = impact
+ // opos = impact
+ // velocity = Vec2.Zero
+ // })
+ //
+ (1..10).forEach {
+ Spark(
+ lifetime = rng.nextFloatInRange(0.5f, 2f),
+ style = Spark.Style.DOT,
+ color = Color.White,
+ size = 1f
+ )
+ .apply {
+ pos =
+ impact +
+ Vec2.makeWithAngleMag(
+ rng.nextFloatInRange(0f, 2 * PIf),
+ rng.nextFloatInRange(0.1f, 0.5f)
+ )
+ opos = pos
+ velocity =
+ ship.velocity * 0.8f +
+ Vec2.makeWithAngleMag(
+ // a +
+ // rng.nextFloatInRange(-PIf, PIf),
+ rng.nextFloatInRange(0f, 2 * PIf),
+ rng.nextFloatInRange(0.1f, 0.5f)
+ )
+ add(this)
+ }
+ }
+ }
+ }
+ }
+ }
+
+ super.solveAll(dt, constraints)
+ }
+
+ override fun postUpdateAll(dt: Float, entities: ArraySet<Entity>) {
+ super.postUpdateAll(dt, entities)
+
+ entities
+ .filterIsInstance<Removable>()
+ .filter(predicate = Removable::canBeRemoved)
+ .filterIsInstance<Entity>()
+ .forEach { remove(it) }
+ }
+}
+
+class Landing(val ship: Spacecraft, val planet: Planet, val angle: Float) : Constraint {
+ private val landingVector = Vec2.makeWithAngleMag(angle, ship.radius + planet.radius)
+ override fun solve(sim: Simulator, dt: Float) {
+ val desiredPos = planet.pos + landingVector
+ ship.pos = (ship.pos * 0.5f) + (desiredPos * 0.5f) // @@@ FIXME
+ ship.angle = angle
+ }
+}
+
+class Spark(
+ var lifetime: Float,
+ collides: Boolean = false,
+ mass: Float = 0f,
+ val style: Style = Style.LINE,
+ val color: Color = Color.Gray,
+ val size: Float = 2f
+) : Removable, Body() {
+ enum class Style {
+ LINE,
+ LINE_ABSOLUTE,
+ DOT,
+ DOT_ABSOLUTE,
+ RING
+ }
+
+ init {
+ this.collides = collides
+ this.mass = mass
+ }
+ override fun update(sim: Simulator, dt: Float) {
+ super.update(sim, dt)
+ lifetime -= dt
+ }
+ override fun canBeRemoved(): Boolean {
+ return lifetime < 0
+ }
+}
+
+const val TRACK_LENGTH = 10_000
+const val SIMPLE_TRACK_DRAWING = true
+
+class Track {
+ val positions = ArrayDeque<Vec2>(TRACK_LENGTH)
+ private val angles = ArrayDeque<Float>(TRACK_LENGTH)
+ fun add(x: Float, y: Float, a: Float) {
+ if (positions.size >= (TRACK_LENGTH - 1)) {
+ positions.removeFirst()
+ angles.removeFirst()
+ positions.removeFirst()
+ angles.removeFirst()
+ }
+ positions.addLast(Vec2(x, y))
+ angles.addLast(a)
+ }
+}
+
+class Spacecraft : Body() {
+ var thrust = Vec2.Zero
+ var launchClock = 0f
+
+ var transit = false
+
+ val track = Track()
+
+ var landing: Landing? = null
+
+ init {
+ mass = SPACECRAFT_MASS
+ radius = 12f
+ }
+
+ override fun update(sim: Simulator, dt: Float) {
+ // check for thrusters
+ val thrustMag = thrust.mag()
+ if (thrustMag > 0) {
+ var deltaV = MAIN_ENGINE_ACCEL * dt
+ if (SCALED_THRUST) deltaV *= thrustMag.coerceIn(0f, 1f)
+
+ if (landing == null) {
+ // we are free in space, so we attempt to pivot toward the desired direction
+ // NOTE: no longer required thanks to FlightStick
+ // angle = thrust.angle()
+ } else
+ landing?.let { landing ->
+ if (launchClock == 0f) launchClock = sim.now + 1f /* @@@ TODO extract */
+
+ if (sim.now > launchClock) {
+ // first-stage to orbit has 1000x power
+ // deltaV *= 1000f
+ sim.remove(landing)
+ this.landing = null
+ } else {
+ deltaV = 0f
+ }
+ }
+
+ // this is it. impart thrust to the ship.
+ // note that we always thrust in the forward direction
+ velocity += Vec2.makeWithAngleMag(angle, deltaV)
+ } else {
+ if (launchClock != 0f) launchClock = 0f
+ }
+
+ // apply global speed limit
+ if (velocity.mag() > CRAFT_SPEED_LIMIT)
+ velocity = Vec2.makeWithAngleMag(velocity.angle(), CRAFT_SPEED_LIMIT)
+
+ super.update(sim, dt)
+ }
+
+ override fun postUpdate(sim: Simulator, dt: Float) {
+ super.postUpdate(sim, dt)
+
+ // special effects all need to be added after the simulation step so they have
+ // the correct position of the ship.
+ track.add(pos.x, pos.y, angle)
+
+ val mag = thrust.mag()
+ if (sim.rng.nextFloat() < mag) {
+ // exhaust
+ sim.add(
+ Spark(
+ lifetime = sim.rng.nextFloatInRange(0.5f, 1f),
+ collides = true,
+ mass = 1f,
+ style = Spark.Style.RING,
+ size = 3f,
+ color = Color(0x40FFFFFF)
+ )
+ .also { spark ->
+ spark.pos = pos
+ spark.opos = pos
+ spark.velocity =
+ velocity +
+ Vec2.makeWithAngleMag(
+ angle + sim.rng.nextFloatInRange(-0.2f, 0.2f),
+ -MAIN_ENGINE_ACCEL * mag * 10f * dt
+ )
+ }
+ )
+ }
+ }
+}
diff --git a/packages/EasterEgg/src/com/android/egg/landroid/Vec2.kt b/packages/EasterEgg/src/com/android/egg/landroid/Vec2.kt
new file mode 100644
index 0000000..82bae75
--- /dev/null
+++ b/packages/EasterEgg/src/com/android/egg/landroid/Vec2.kt
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.egg.landroid
+
+import androidx.compose.ui.geometry.Offset
+import kotlin.math.PI
+import kotlin.math.atan2
+import kotlin.math.cos
+import kotlin.math.sin
+
+const val PIf = PI.toFloat()
+const val PI2f = (2 * PI).toFloat()
+
+typealias Vec2 = Offset
+
+fun Vec2.str(fmt: String = "%+.2f"): String = "<$fmt,$fmt>".format(x, y)
+
+fun Vec2(x: Float, y: Float): Vec2 = Offset(x, y)
+
+fun Vec2.mag(): Float {
+ return getDistance()
+}
+
+fun Vec2.distance(other: Vec2): Float {
+ return (this - other).mag()
+}
+
+fun Vec2.angle(): Float {
+ return atan2(y, x)
+}
+
+fun Vec2.dot(o: Vec2): Float {
+ return x * o.x + y * o.y
+}
+
+fun Vec2.product(f: Float): Vec2 {
+ return Vec2(x * f, y * f)
+}
+
+fun Offset.Companion.makeWithAngleMag(a: Float, m: Float): Vec2 {
+ return Vec2(m * cos(a), m * sin(a))
+}
+
+fun Vec2.rotate(angle: Float, origin: Vec2 = Vec2.Zero): Offset {
+ val translated = this - origin
+ return origin +
+ Offset(
+ (translated.x * cos(angle) - translated.y * sin(angle)),
+ (translated.x * sin(angle) + translated.y * cos(angle))
+ )
+}
diff --git a/packages/EasterEgg/src/com/android/egg/landroid/VisibleUniverse.kt b/packages/EasterEgg/src/com/android/egg/landroid/VisibleUniverse.kt
new file mode 100644
index 0000000..24b9c6a
--- /dev/null
+++ b/packages/EasterEgg/src/com/android/egg/landroid/VisibleUniverse.kt
@@ -0,0 +1,334 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.egg.landroid
+
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.Path
+import androidx.compose.ui.graphics.PathEffect
+import androidx.compose.ui.graphics.PointMode
+import androidx.compose.ui.graphics.drawscope.DrawScope
+import androidx.compose.ui.graphics.drawscope.Stroke
+import androidx.compose.ui.graphics.drawscope.rotateRad
+import androidx.compose.ui.graphics.drawscope.scale
+import androidx.compose.ui.graphics.drawscope.translate
+import androidx.compose.ui.util.lerp
+import androidx.core.math.MathUtils.clamp
+import java.lang.Float.max
+import kotlin.math.sqrt
+
+const val DRAW_ORBITS = true
+const val DRAW_GRAVITATIONAL_FIELDS = true
+const val DRAW_STAR_GRAVITATIONAL_FIELDS = true
+
+val STAR_POINTS = android.os.Build.VERSION.SDK_INT.takeIf { it in 1..99 } ?: 31
+
+/**
+ * A zoomedDrawScope is one that is scaled, but remembers its zoom level, so you can correct for it
+ * if you want to draw single-pixel lines. Which we do.
+ */
+interface ZoomedDrawScope : DrawScope {
+ val zoom: Float
+}
+
+fun DrawScope.zoom(zoom: Float, block: ZoomedDrawScope.() -> Unit) {
+ val ds =
+ object : ZoomedDrawScope, DrawScope by this {
+ override var zoom = zoom
+ }
+ ds.scale(zoom) { block(ds) }
+}
+
+class VisibleUniverse(namer: Namer, randomSeed: Long) : Universe(namer, randomSeed) {
+ // Magic variable. Every time we update it, Compose will notice and redraw the universe.
+ val triggerDraw = mutableStateOf(0L)
+
+ fun simulateAndDrawFrame(nanos: Long) {
+ // By writing this value, Compose will look for functions that read it (like drawZoomed).
+ triggerDraw.value = nanos
+
+ step(nanos)
+ }
+}
+
+fun ZoomedDrawScope.drawUniverse(universe: VisibleUniverse) {
+ with(universe) {
+ triggerDraw.value // Please recompose when this value changes.
+
+ // star.drawZoomed(ds, zoom)
+ // planets.forEach { p ->
+ // p.drawZoomed(ds, zoom)
+ // if (p == follow) {
+ // drawCircle(Color.Red, 20f / zoom, p.pos)
+ // }
+ // }
+ //
+ // ship.drawZoomed(ds, zoom)
+
+ constraints.forEach {
+ when (it) {
+ is Landing -> drawLanding(it)
+ is Container -> drawContainer(it)
+ }
+ }
+ drawStar(star)
+ entities.forEach {
+ if (it === ship || it === star) return@forEach // draw the ship last
+ when (it) {
+ is Spacecraft -> drawSpacecraft(it)
+ is Spark -> drawSpark(it)
+ is Planet -> drawPlanet(it)
+ }
+ }
+ drawSpacecraft(ship)
+ }
+}
+
+fun ZoomedDrawScope.drawContainer(container: Container) {
+ drawCircle(
+ color = Color(0xFF800000),
+ radius = container.radius,
+ center = Vec2.Zero,
+ style =
+ Stroke(
+ width = 1f / zoom,
+ pathEffect = PathEffect.dashPathEffect(floatArrayOf(8f / zoom, 8f / zoom), 0f)
+ )
+ )
+ // val path = Path().apply {
+ // fillType = PathFillType.EvenOdd
+ // addOval(Rect(center = Vec2.Zero, radius = container.radius))
+ // addOval(Rect(center = Vec2.Zero, radius = container.radius + 10_000))
+ // }
+ // drawPath(
+ // path = path,
+ //
+ // )
+}
+
+fun ZoomedDrawScope.drawGravitationalField(planet: Planet) {
+ val rings = 8
+ for (i in 0 until rings) {
+ val force =
+ lerp(
+ 200f,
+ 0.01f,
+ i.toFloat() / rings
+ ) // first rings at force = 1N, dropping off after that
+ val r = sqrt(GRAVITATION * planet.mass * SPACECRAFT_MASS / force)
+ drawCircle(
+ color = Color(1f, 0f, 0f, lerp(0.5f, 0.1f, i.toFloat() / rings)),
+ center = planet.pos,
+ style = Stroke(2f / zoom),
+ radius = r
+ )
+ }
+}
+
+fun ZoomedDrawScope.drawPlanet(planet: Planet) {
+ with(planet) {
+ if (DRAW_ORBITS)
+ drawCircle(
+ color = Color(0x8000FFFF),
+ radius = pos.distance(orbitCenter),
+ center = orbitCenter,
+ style =
+ Stroke(
+ width = 1f / zoom,
+ )
+ )
+
+ if (DRAW_GRAVITATIONAL_FIELDS) {
+ drawGravitationalField(this)
+ }
+
+ drawCircle(color = Colors.Eigengrau, radius = radius, center = pos)
+ drawCircle(color = color, radius = radius, center = pos, style = Stroke(2f / zoom))
+ }
+}
+
+fun ZoomedDrawScope.drawStar(star: Star) {
+ translate(star.pos.x, star.pos.y) {
+ drawCircle(color = star.color, radius = star.radius, center = Vec2.Zero)
+
+ if (DRAW_STAR_GRAVITATIONAL_FIELDS) this@drawStar.drawGravitationalField(star)
+
+ rotateRad(radians = star.anim / 23f * PI2f, pivot = Vec2.Zero) {
+ drawPath(
+ path =
+ createStar(
+ radius1 = star.radius + 80,
+ radius2 = star.radius + 250,
+ points = STAR_POINTS
+ ),
+ color = star.color,
+ style =
+ Stroke(
+ width = 3f / this@drawStar.zoom,
+ pathEffect = PathEffect.cornerPathEffect(radius = 200f)
+ )
+ )
+ }
+ rotateRad(radians = star.anim / -19f * PI2f, pivot = Vec2.Zero) {
+ drawPath(
+ path =
+ createStar(
+ radius1 = star.radius + 20,
+ radius2 = star.radius + 200,
+ points = STAR_POINTS + 1
+ ),
+ color = star.color,
+ style =
+ Stroke(
+ width = 3f / this@drawStar.zoom,
+ pathEffect = PathEffect.cornerPathEffect(radius = 200f)
+ )
+ )
+ }
+ }
+}
+
+val spaceshipPath =
+ Path().apply {
+ parseSvgPathData(
+ """
+M11.853 0
+C11.853 -4.418 8.374 -8 4.083 -8
+L-5.5 -8
+C-6.328 -8 -7 -7.328 -7 -6.5
+C-7 -5.672 -6.328 -5 -5.5 -5
+L-2.917 -5
+C-1.26 -5 0.083 -3.657 0.083 -2
+L0.083 2
+C0.083 3.657 -1.26 5 -2.917 5
+L-5.5 5
+C-6.328 5 -7 5.672 -7 6.5
+C-7 7.328 -6.328 8 -5.5 8
+L4.083 8
+C8.374 8 11.853 4.418 11.853 0
+Z
+"""
+ )
+ }
+val thrustPath = createPolygon(-3f, 3).also { it.translate(Vec2(-4f, 0f)) }
+
+fun ZoomedDrawScope.drawSpacecraft(ship: Spacecraft) {
+ with(ship) {
+ rotateRad(angle, pivot = pos) {
+ translate(pos.x, pos.y) {
+ // drawPath(
+ // path = createStar(200f, 100f, 3),
+ // color = Color.White,
+ // style = Stroke(width = 2f / zoom)
+ // )
+ drawPath(path = spaceshipPath, color = Colors.Eigengrau) // fauxpaque
+ drawPath(
+ path = spaceshipPath,
+ color = if (transit) Color.Black else Color.White,
+ style = Stroke(width = 2f / this@drawSpacecraft.zoom)
+ )
+ if (thrust != Vec2.Zero) {
+ drawPath(
+ path = thrustPath,
+ color = Color(0xFFFF8800),
+ style =
+ Stroke(
+ width = 2f / this@drawSpacecraft.zoom,
+ pathEffect = PathEffect.cornerPathEffect(radius = 1f)
+ )
+ )
+ }
+ // drawRect(
+ // topLeft = Offset(-1f, -1f),
+ // size = Size(2f, 2f),
+ // color = Color.Cyan,
+ // style = Stroke(width = 2f / zoom)
+ // )
+ // drawLine(
+ // start = Vec2.Zero,
+ // end = Vec2(20f, 0f),
+ // color = Color.Cyan,
+ // strokeWidth = 2f / zoom
+ // )
+ }
+ }
+ // // DEBUG: draw velocity vector
+ // drawLine(
+ // start = pos,
+ // end = pos + velocity,
+ // color = Color.Red,
+ // strokeWidth = 3f / zoom
+ // )
+ drawTrack(track)
+ }
+}
+
+fun ZoomedDrawScope.drawLanding(landing: Landing) {
+ val v = landing.planet.pos + Vec2.makeWithAngleMag(landing.angle, landing.planet.radius)
+ drawLine(Color.Red, v + Vec2(-5f, -5f), v + Vec2(5f, 5f), strokeWidth = 1f / zoom)
+ drawLine(Color.Red, v + Vec2(5f, -5f), v + Vec2(-5f, 5f), strokeWidth = 1f / zoom)
+}
+
+fun ZoomedDrawScope.drawSpark(spark: Spark) {
+ with(spark) {
+ if (lifetime < 0) return
+ when (style) {
+ Spark.Style.LINE ->
+ if (opos != Vec2.Zero) drawLine(color, opos, pos, strokeWidth = size)
+ Spark.Style.LINE_ABSOLUTE ->
+ if (opos != Vec2.Zero) drawLine(color, opos, pos, strokeWidth = size / zoom)
+ Spark.Style.DOT -> drawCircle(color, size, pos)
+ Spark.Style.DOT_ABSOLUTE -> drawCircle(color, size, pos / zoom)
+ Spark.Style.RING -> drawCircle(color, size, pos, style = Stroke(width = 1f / zoom))
+ // drawPoints(listOf(pos), PointMode.Points, color, strokeWidth = 2f/zoom)
+ // drawCircle(color, 2f/zoom, pos)
+ }
+ // drawCircle(Color.Gray, center = pos, radius = 1.5f / zoom)
+ }
+}
+
+fun ZoomedDrawScope.drawTrack(track: Track) {
+ with(track) {
+ if (SIMPLE_TRACK_DRAWING) {
+ drawPoints(
+ positions,
+ pointMode = PointMode.Lines,
+ color = Color.Green,
+ strokeWidth = 1f / zoom
+ )
+ // if (positions.size < 2) return
+ // drawPath(Path()
+ // .apply {
+ // val p = positions[positions.size - 1]
+ // moveTo(p.x, p.y)
+ // positions.reversed().subList(1, positions.size).forEach { p ->
+ // lineTo(p.x, p.y)
+ // }
+ // },
+ // color = Color.Green, style = Stroke(1f/zoom))
+ } else {
+ if (positions.size < 2) return
+ var prev: Vec2 = positions[positions.size - 1]
+ var a = 0.5f
+ positions.reversed().subList(1, positions.size).forEach { pos ->
+ drawLine(Color(0f, 1f, 0f, a), prev, pos, strokeWidth = max(1f, 1f / zoom))
+ prev = pos
+ a = clamp((a - 1f / TRACK_LENGTH), 0f, 1f)
+ }
+ }
+ }
+}
diff --git a/packages/PackageInstaller/res/values-am/strings.xml b/packages/PackageInstaller/res/values-am/strings.xml
index cc87288..7b664bc 100644
--- a/packages/PackageInstaller/res/values-am/strings.xml
+++ b/packages/PackageInstaller/res/values-am/strings.xml
@@ -26,12 +26,9 @@
<string name="install_done" msgid="5987363587661783896">"መተግበሪያ ተጭኗል።"</string>
<string name="install_confirm_question" msgid="7663733664476363311">"ይህን መተግበሪያ መጫን ይፈልጋሉ?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"ይህን መተግበሪያ ማዘመን ይፈልጋሉ?"</string>
- <!-- no translation found for install_confirm_question_update_owner_reminder (7994800761970572198) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (2435174886412089791) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (7155138616126795839) -->
- <skip />
+ <string name="install_confirm_question_update_owner_reminder" product="tablet" msgid="7994800761970572198">"<p>ይህን መተግበሪያ <b>ከ<xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>ያዘምኑ?</p><p>ይህ መተግበሪያ በተለምዶ ዝማኔዎችን የሚቀበለው <b>ከ<xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b&gt ነው። ከተለየ ምንጭ በማዘመን በጡባዊዎ ላይ ካለ ማንኛውም ምንጭ የወደፊት ዝማኔዎችን ሊቀበሉ ይችላሉ። የመተግበሪያ ተግባራዊነት ሊቀየር ይችላል።</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="tv" msgid="2435174886412089791">"<p>ይህን መተግበሪያ <b>ከ<xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>ያዘምኑ?</p><p>ይህ መተግበሪያ በተለምዶ ዝማኔዎችን የሚቀበለው <b>ከ<xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b&gt ነው። ከተለየ ምንጭ በማዘመን በቲቪዎ ላይ ካለ ማንኛውም ምንጭ የወደፊት ዝማኔዎችን ሊቀበሉ ይችላሉ። የመተግበሪያ ተግባራዊነት ሊቀየር ይችላል።</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="default" msgid="7155138616126795839">"<p>ይህን መተግበሪያ <b>ከ<xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>ያዘምኑ?</p><p>ይህ መተግበሪያ በተለምዶ ዝማኔዎችን የሚቀበለው <b>ከ<xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b&gt ነው። ከተለየ ምንጭ በማዘመን በስልክዎ ላይ ካለ ማንኛውም ምንጭ የወደፊት ዝማኔዎችን ሊቀበሉ ይችላሉ። የመተግበሪያ ተግባራዊነት ሊቀየር ይችላል።</p>"</string>
<string name="install_failed" msgid="5777824004474125469">"መተግበሪያ አልተጫነም።"</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"ጥቅሉ እንዳይጫን ታግዷል።"</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"እንደ ጥቅል ያልተጫነ መተግበሪያ ከነባር ጥቅል ጋር ይጋጫል።"</string>
diff --git a/packages/PackageInstaller/res/values-ar/strings.xml b/packages/PackageInstaller/res/values-ar/strings.xml
index d501ae6..9a4d7ea 100644
--- a/packages/PackageInstaller/res/values-ar/strings.xml
+++ b/packages/PackageInstaller/res/values-ar/strings.xml
@@ -26,12 +26,9 @@
<string name="install_done" msgid="5987363587661783896">"تم تثبيت التطبيق."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"هل تريد تثبيت هذا التطبيق؟"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"هل تريد تحديث هذا التطبيق؟"</string>
- <!-- no translation found for install_confirm_question_update_owner_reminder (7994800761970572198) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (2435174886412089791) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (7155138616126795839) -->
- <skip />
+ <string name="install_confirm_question_update_owner_reminder" product="tablet" msgid="7994800761970572198">"<p>هل تريد تحديث هذا التطبيق من <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>؟</p><p>يتلقّى هذا التطبيق التحديثات عادةً من <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. من خلال تحديثه من مصدر مختلف، قد يتلقّى تحديثات في المستقبل من أي مصدر على جهازك اللوحي. قد تتغير وظائف التطبيق.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="tv" msgid="2435174886412089791">"<p>هل تريد تحديث هذا التطبيق من <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>؟</p><p>يتلقّى هذا التطبيق التحديثات عادةً من <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. من خلال تحديثه من مصدر مختلف، قد يتلقّى تحديثات في المستقبل من أي مصدر على التلفزيون. قد تتغير وظائف التطبيق.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="default" msgid="7155138616126795839">"<p>هل تريد تحديث هذا التطبيق من <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>؟</p><p>يتلقّى هذا التطبيق التحديثات عادةً من <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. من خلال تحديثه مصدر مختلف، قد تتلقّى تحديثات في المستقبل من أي مصدر على هاتفك. قد تتغير وظائف التطبيق.</p>"</string>
<string name="install_failed" msgid="5777824004474125469">"التطبيق ليس مثبتًا."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"تم حظر تثبيت الحزمة."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"لم يتم تثبيت التطبيق لأن حزمة التثبيت تتعارض مع حزمة حالية."</string>
diff --git a/packages/PackageInstaller/res/values-az/strings.xml b/packages/PackageInstaller/res/values-az/strings.xml
index ca14f0d..cf3ea84 100644
--- a/packages/PackageInstaller/res/values-az/strings.xml
+++ b/packages/PackageInstaller/res/values-az/strings.xml
@@ -26,12 +26,9 @@
<string name="install_done" msgid="5987363587661783896">"Tətbiq quraşdırılıb."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Bu tətbiqi quraşdırmaq istəyirsiniz?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Bu tətbiqi güncəlləmək istəyirsiniz?"</string>
- <!-- no translation found for install_confirm_question_update_owner_reminder (7994800761970572198) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (2435174886412089791) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (7155138616126795839) -->
- <skip />
+ <string name="install_confirm_question_update_owner_reminder" product="tablet" msgid="7994800761970572198">"<p>Bu tətbiq <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b> mənbəyindən güncəllənsin?</p><p>Bu tətbiq adətən <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b> mənbəyindən güncəllənir. Fərqli mənbədən güncəllədikdə gələcəkdə planşetdə istənilən mənbədən güncəlləyə bilərsiniz. Tətbiq funksionallığı dəyişə bilər.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="tv" msgid="2435174886412089791">"<p>Bu tətbiq <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b> mənbəyindən güncəllənsin?</p><p>Bu tətbiq adətən <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b> mənbəyindən güncəllənir. Fərqli mənbədən güncəllədikdə gələcəkdə TV-də istənilən mənbədən güncəlləyə bilərsiniz. Tətbiq funksionallığı dəyişə bilər.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="default" msgid="7155138616126795839">"<p>Bu tətbiq <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b> mənbəyindən güncəllənsin?</p><p>Bu tətbiq adətən <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b> mənbəyindən güncəllənir. Fərqli mənbədən güncəllədikdə gələcəkdə telefonda istənilən mənbədən güncəlləyə bilərsiniz. Tətbiq funksionallığı dəyişə bilər.</p>"</string>
<string name="install_failed" msgid="5777824004474125469">"Tətbiq quraşdırılmayıb."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Paketin quraşdırılması blok edildi."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Bu paketin mövcud paket ilə ziddiyətinə görə tətbiq quraşdırılmadı."</string>
diff --git a/packages/PackageInstaller/res/values-be/strings.xml b/packages/PackageInstaller/res/values-be/strings.xml
index 7b150ae..b10a9e0 100644
--- a/packages/PackageInstaller/res/values-be/strings.xml
+++ b/packages/PackageInstaller/res/values-be/strings.xml
@@ -26,12 +26,9 @@
<string name="install_done" msgid="5987363587661783896">"Праграма ўсталявана."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Усталяваць гэту праграму?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Абнавіць гэту праграму?"</string>
- <!-- no translation found for install_confirm_question_update_owner_reminder (7994800761970572198) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (2435174886412089791) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (7155138616126795839) -->
- <skip />
+ <string name="install_confirm_question_update_owner_reminder" product="tablet" msgid="7994800761970572198">"<p>Абнавіць праграму з <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Звычайна гэта праграма атрымлівае абнаўленні з <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Калі абнавіць праграму з іншай крыніцы, то ў будучыні вы, магчыма, будзеце атрымліваць абнаўленні з любых крыніц на планшэце. Функцыі праграмы могуць змяніцца.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="tv" msgid="2435174886412089791">"<p>Абнавіць праграму з <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Звычайна гэта праграма атрымлівае абнаўленні з <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Калі абнавіць праграму з іншай крыніцы, то ў будучыні вы, магчыма, будзеце атрымліваць абнаўленні з любых крыніц на тэлевізары. Функцыі праграмы могуць змяніцца.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="default" msgid="7155138616126795839">"<p>Абнавіць праграму з <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Звычайна гэта праграма атрымлівае абнаўленні з <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Пры абнаўленні з іншай крыніцы вы, магчыма, будзеце атрымліваць будучыя абнаўленні з любой крыніцы на тэлефоне. Функцыі праграмы могуць змяніцца.</p>"</string>
<string name="install_failed" msgid="5777824004474125469">"Праграма не ўсталявана."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Усталяванне пакета заблакіравана."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Праграма не ўсталявана, таму што пакет канфліктуе з існуючым пакетам."</string>
diff --git a/packages/PackageInstaller/res/values-bg/strings.xml b/packages/PackageInstaller/res/values-bg/strings.xml
index 24ccfcc..8d4739c 100644
--- a/packages/PackageInstaller/res/values-bg/strings.xml
+++ b/packages/PackageInstaller/res/values-bg/strings.xml
@@ -26,12 +26,9 @@
<string name="install_done" msgid="5987363587661783896">"Приложението бе инсталирано."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Искате ли да инсталирате това приложение?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Искате ли да актуализирате това приложение?"</string>
- <!-- no translation found for install_confirm_question_update_owner_reminder (7994800761970572198) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (2435174886412089791) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (7155138616126795839) -->
- <skip />
+ <string name="install_confirm_question_update_owner_reminder" product="tablet" msgid="7994800761970572198">"<p>Това приложение да се актуализира ли от <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Обикновено то получава актуализации от <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Ако инсталирате актуализация от друг източник, може да получавате бъдещи актуализации от който и да е източник на таблета си. Функционалността на приложението може да се промени.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="tv" msgid="2435174886412089791">"<p>Това приложение да се актуализира ли от <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Обикновено то получава актуализации от <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Ако инсталирате актуализация от друг източник, може да получавате бъдещи актуализации от който и да е източник на телевизора си. Функционалността на приложението може да се промени.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="default" msgid="7155138616126795839">"<p>Това приложение да се актуализира ли от <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Обикновено то получава актуализации от <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Ако инсталирате актуализация от друг източник, може да получавате бъдещи актуализации от който и да е източник на телефона си. Функционалността на приложението може да се промени.</p>"</string>
<string name="install_failed" msgid="5777824004474125469">"Приложението не бе инсталирано."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Инсталирането на пакета бе блокирано."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Приложението не бе инсталирано, тъй като пакетът е в конфликт със съществуващ пакет."</string>
diff --git a/packages/PackageInstaller/res/values-bn/strings.xml b/packages/PackageInstaller/res/values-bn/strings.xml
index 36fdbe8..d3c8ad7 100644
--- a/packages/PackageInstaller/res/values-bn/strings.xml
+++ b/packages/PackageInstaller/res/values-bn/strings.xml
@@ -26,12 +26,9 @@
<string name="install_done" msgid="5987363587661783896">"অ্যাপটি ইনস্টল করা হয়ে গেছে।"</string>
<string name="install_confirm_question" msgid="7663733664476363311">"আপনি কি এই অ্যাপটি ইনস্টল করতে চান?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"আপনি কি এই অ্যাপটি আপডেট করতে চান?"</string>
- <!-- no translation found for install_confirm_question_update_owner_reminder (7994800761970572198) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (2435174886412089791) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (7155138616126795839) -->
- <skip />
+ <string name="install_confirm_question_update_owner_reminder" product="tablet" msgid="7994800761970572198">"<xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g><p> থেকে এই অ্যাপ আপডেট করুন <b></b>?</p><p>এই অ্যাপটি সাধারণত <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g> থেকে আপডেট পায়</b>. অন্য কোনও সোর্স থেকে আপডেট করলে, আপনার ট্যাবলেটে ভবিষ্যতে যেকোনও সোর্স থেকে আপডেট পেতে পারেন। অ্যাপের কার্যকারিতা হয়ত পরিবর্তন হবে।</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="tv" msgid="2435174886412089791">"<xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g><p> থেকে এই অ্যাপ আপডেট করুন <b></b>?</p><p>এই অ্যাপটি সাধারণত <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g> থেকে আপডেট পায়</b>. অন্য কোনও সোর্স থেকে আপডেট করলে, আপনার টিভিতে ভবিষ্যতে যেকোনও সোর্স থেকে আপডেট পেতে পারেন। অ্যাপের কার্যকারিতা হয়ত পরিবর্তন হবে।</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="default" msgid="7155138616126795839">"<xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g><p> থেকে এই অ্যাপ আপডেট করুন <b></b>?</p><p>এই অ্যাপটি সাধারণত <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g> থেকে আপডেট পায়</b>. অন্য কোনও সোর্স থেকে আপডেট করলে, আপনার ফোনে ভবিষ্যতে যেকোনও সোর্স থেকে আপডেট পেতে পারেন। অ্যাপের কার্যকারিতা হয়ত পরিবর্তন হবে।</p>"</string>
<string name="install_failed" msgid="5777824004474125469">"অ্যাপটি ইনস্টল করা হয়নি।"</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"ইনস্টল হওয়া থেকে প্যাকেজটিকে ব্লক করা হয়েছে।"</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"আগে থেকেই থাকা একটি প্যাকেজের সাথে প্যাকেজটির সমস্যা সৃষ্টি হওয়ায় অ্যাপটি ইনস্টল করা যায়নি।"</string>
diff --git a/packages/PackageInstaller/res/values-bs/strings.xml b/packages/PackageInstaller/res/values-bs/strings.xml
index db6628c..f93263f0 100644
--- a/packages/PackageInstaller/res/values-bs/strings.xml
+++ b/packages/PackageInstaller/res/values-bs/strings.xml
@@ -26,12 +26,9 @@
<string name="install_done" msgid="5987363587661783896">"Aplikacija je instalirana."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Želite li instalirati ovu aplikaciju?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Želite li ažurirati ovu aplikaciju?"</string>
- <!-- no translation found for install_confirm_question_update_owner_reminder (7994800761970572198) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (2435174886412089791) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (7155138616126795839) -->
- <skip />
+ <string name="install_confirm_question_update_owner_reminder" product="tablet" msgid="7994800761970572198">"<p>Ažurirajte aplikaciju iz izvora <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Aplikacija obično prima ažuriranja iz izvora <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Ako je ažurirate iz drugog izvora, možda ćete primati buduća ažuriranja iz bilo kojeg izvora na tabletu. Funkcionalnost aplikacije se može promijeniti.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="tv" msgid="2435174886412089791">"<p>Ažurirajte aplikaciju iz izvora <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Aplikacija obično prima ažuriranja iz izvora <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Ako je ažurirate iz drugog izvora, možda ćete primati buduća ažuriranja iz bilo kojeg izvora na TV-u. Funkcionalnost aplikacije se može promijeniti.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="default" msgid="7155138616126795839">"<p>Ažurirajte aplikaciju iz izvora <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Aplikacija obično prima ažuriranja iz izvora <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Ako je ažurirate iz drugog izvora, možda ćete primati buduća ažuriranja iz bilo kojeg izvora na telefonu. Funkcionalnost aplikacije se može promijeniti.</p>"</string>
<string name="install_failed" msgid="5777824004474125469">"Aplikacija nije instalirana."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Instaliranje ovog paketa je blokirano."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Aplikacija nije instalirana jer paket nije usaglašen s postojećim paketom."</string>
diff --git a/packages/PackageInstaller/res/values-ca/strings.xml b/packages/PackageInstaller/res/values-ca/strings.xml
index 1750b5e..896b075 100644
--- a/packages/PackageInstaller/res/values-ca/strings.xml
+++ b/packages/PackageInstaller/res/values-ca/strings.xml
@@ -26,12 +26,9 @@
<string name="install_done" msgid="5987363587661783896">"S\'ha instal·lat l\'aplicació."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Vols instal·lar aquesta aplicació?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Vols actualitzar aquesta aplicació?"</string>
- <!-- no translation found for install_confirm_question_update_owner_reminder (7994800761970572198) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (2435174886412089791) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (7155138616126795839) -->
- <skip />
+ <string name="install_confirm_question_update_owner_reminder" product="tablet" msgid="7994800761970572198">"<p>Vols actualitzar l\'aplicació de <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Aquesta aplicació sol rebre actualitzacions de <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Si l\'actualitzes des d\'una font diferent, pot ser que en el futur rebis actualitzacions des de qualsevol font de la teva tauleta. És possible que la funcionalitat de l\'aplicació canviï.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="tv" msgid="2435174886412089791">"<p>Vols actualitzar l\'aplicació de <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Aquesta aplicació sol rebre actualitzacions de <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Si l\'actualitzes des d\'una font diferent, pot ser que en el futur rebis actualitzacions des de qualsevol font del teu televisor. És possible que la funcionalitat de l\'aplicació canviï.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="default" msgid="7155138616126795839">"<p>Vols actualitzar l\'aplicació de <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Aquesta aplicació sol rebre actualitzacions de <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Si l\'actualitzes des d\'una font diferent, pot ser que en el futur rebis actualitzacions des de qualsevol font del teu telèfon. És possible que la funcionalitat de l\'aplicació canviï.</p>"</string>
<string name="install_failed" msgid="5777824004474125469">"No s\'ha instal·lat l\'aplicació."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"El paquet s\'ha bloquejat perquè no es pugui instal·lar."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"L\'aplicació no s\'ha instal·lat perquè el paquet entra en conflicte amb un d\'existent."</string>
diff --git a/packages/PackageInstaller/res/values-cs/strings.xml b/packages/PackageInstaller/res/values-cs/strings.xml
index 47b8703..0874214 100644
--- a/packages/PackageInstaller/res/values-cs/strings.xml
+++ b/packages/PackageInstaller/res/values-cs/strings.xml
@@ -26,12 +26,9 @@
<string name="install_done" msgid="5987363587661783896">"Aplikace je nainstalována."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Chcete tuto aplikaci nainstalovat?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Chcete tuto aplikaci aktualizovat?"</string>
- <!-- no translation found for install_confirm_question_update_owner_reminder (7994800761970572198) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (2435174886412089791) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (7155138616126795839) -->
- <skip />
+ <string name="install_confirm_question_update_owner_reminder" product="tablet" msgid="7994800761970572198">"<p>Aktualizovat tuto aplikaci ze zdroje <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Tato aplikace obvykle dostává aktualizace ze zdroje <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Pokud ji aktualizujete z jiného zdroje, budete v budoucnu do tabletu moci dostávat aktualizace z libovolného zdroje. Funkčnost aplikace se může změnit.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="tv" msgid="2435174886412089791">"<p>Aktualizovat tuto aplikaci ze zdroje <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Tato aplikace obvykle dostává aktualizace ze zdroje <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Pokud ji aktualizujete z jiného zdroje, budete v budoucnu do televize moci dostávat aktualizace z libovolného zdroje. Funkčnost aplikace se může změnit.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="default" msgid="7155138616126795839">"<p>Aktualizovat tuto aplikaci ze zdroje <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Tato aplikace obvykle dostává aktualizace ze zdroje <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Pokud ji aktualizujete z jiného zdroje, budete v budoucnu do telefonu moci dostávat aktualizace z libovolného zdroje. Funkčnost aplikace se může změnit.</p>"</string>
<string name="install_failed" msgid="5777824004474125469">"Aplikaci nelze nainstalovat."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Instalace balíčku byla zablokována."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Aplikaci nelze nainstalovat, protože balíček je v konfliktu se stávajícím balíčkem."</string>
diff --git a/packages/PackageInstaller/res/values-da/strings.xml b/packages/PackageInstaller/res/values-da/strings.xml
index 505afd6..85032c9 100644
--- a/packages/PackageInstaller/res/values-da/strings.xml
+++ b/packages/PackageInstaller/res/values-da/strings.xml
@@ -26,12 +26,9 @@
<string name="install_done" msgid="5987363587661783896">"Appen er installeret."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Vil du installere denne app?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Vil du opdatere denne app?"</string>
- <!-- no translation found for install_confirm_question_update_owner_reminder (7994800761970572198) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (2435174886412089791) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (7155138616126795839) -->
- <skip />
+ <string name="install_confirm_question_update_owner_reminder" product="tablet" msgid="7994800761970572198">"<p>Vil du opdatere denne app via <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Denne app modtager normalt opdateriner fra <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Hvis du opdaterer fra en anden kilde, vil du kunne modtage opdateringer fra en hvilken som helst kilde på din tablet fremover. Dette kan påvirke appfunktionaliteten.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="tv" msgid="2435174886412089791">"<p>Vil du opdatere denne app via <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Denne app modtager normalt opdateriner fra <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Hvis du opdaterer fra en anden kilde, vil du kunne modtage opdateringer fra en hvilken som helst kilde på dit fjernsyn fremover. Dette kan påvirke appfunktionaliteten.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="default" msgid="7155138616126795839">"<p>Vil du opdatere denne app via <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Denne app modtager normalt opdateriner fra <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Hvis du opdaterer fra en anden kilde, vil du kunne modtage opdateringer fra en hvilken som helst kilde på din telefon fremover. Dette kan påvirke appfunktionaliteten.</p>"</string>
<string name="install_failed" msgid="5777824004474125469">"Appen blev ikke installeret."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Pakken blev forhindret i at blive installeret."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Appen blev ikke installeret, da pakken er i strid med en eksisterende pakke."</string>
diff --git a/packages/PackageInstaller/res/values-de/strings.xml b/packages/PackageInstaller/res/values-de/strings.xml
index 5bba467..b638040b 100644
--- a/packages/PackageInstaller/res/values-de/strings.xml
+++ b/packages/PackageInstaller/res/values-de/strings.xml
@@ -26,12 +26,9 @@
<string name="install_done" msgid="5987363587661783896">"App wurde installiert."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Möchtest du diese App installieren?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Möchtest du diese App aktualisieren?"</string>
- <!-- no translation found for install_confirm_question_update_owner_reminder (7994800761970572198) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (2435174886412089791) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (7155138616126795839) -->
- <skip />
+ <string name="install_confirm_question_update_owner_reminder" product="tablet" msgid="7994800761970572198">"<p>Soll diese App von <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b> aktualisiert werden?</p><p>Normalerweise erhält diese App Updates von <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Wenn du ein Update von einer anderen Quelle verwendest, erhältst du künftige Updates auf deinem Tablet möglicherweise aus unklaren Quellen. Der Funktionsumfang der App kann sich dadurch ändern.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="tv" msgid="2435174886412089791">"<p>Soll diese App von <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b> aktualisiert werden?</p><p>Normalerweise erhält diese App Updates von <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Wenn du ein Update von einer anderen Quelle verwendest, erhältst du künftige Updates auf deinem Fernseher möglicherweise aus unklaren Quellen. Der Funktionsumfang der App kann sich dadurch ändern.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="default" msgid="7155138616126795839">"<p>Soll diese App von <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b> aktualisiert werden?</p><p>Normalerweise erhält diese App Updates von <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Wenn du ein Update von einer anderen Quelle verwendest, erhältst du künftige Updates auf deinem Smartphone möglicherweise aus unklaren Quellen. Der Funktionsumfang der App kann sich dadurch ändern.</p>"</string>
<string name="install_failed" msgid="5777824004474125469">"App wurde nicht installiert."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Die Installation des Pakets wurde blockiert."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Die App wurde nicht installiert, da das Paket in Konflikt mit einem bestehenden Paket steht."</string>
diff --git a/packages/PackageInstaller/res/values-el/strings.xml b/packages/PackageInstaller/res/values-el/strings.xml
index 0df682c..43c9b1e 100644
--- a/packages/PackageInstaller/res/values-el/strings.xml
+++ b/packages/PackageInstaller/res/values-el/strings.xml
@@ -26,12 +26,9 @@
<string name="install_done" msgid="5987363587661783896">"Η εφαρμογή εγκαταστάθηκε."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Θέλετε να εγκαταστήσετε αυτήν την εφαρμογή;"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Θέλετε να ενημερώσετε αυτήν την εφαρμογή;"</string>
- <!-- no translation found for install_confirm_question_update_owner_reminder (7994800761970572198) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (2435174886412089791) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (7155138616126795839) -->
- <skip />
+ <string name="install_confirm_question_update_owner_reminder" product="tablet" msgid="7994800761970572198">"<p>Ενημερώστε αυτήν την εφαρμογή από <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Η συγκεκριμένη εφαρμογή λαμβάνει συνήθως ενημερώσεις από <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Αν κάνετε την ενημέρωση από διαφορετική πηγή, μπορεί να λαμβάνετε μελλοντικές ενημερώσεις από οποιαδήποτε πηγή στο tablet σας. Η λειτουργικότητα της εφαρμογής μπορεί να αλλάξει.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="tv" msgid="2435174886412089791">"<p>Ενημερώστε αυτήν την εφαρμογή από <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Η συγκεκριμένη εφαρμογή λαμβάνει συνήθως ενημερώσεις από <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Αν κάνετε την ενημέρωση από διαφορετική πηγή, μπορεί να λαμβάνετε μελλοντικές ενημερώσεις από οποιαδήποτε πηγή στην τηλεόρασή σας. Η λειτουργικότητα της εφαρμογής μπορεί να αλλάξει.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="default" msgid="7155138616126795839">"<p>Ενημερώστε αυτήν την εφαρμογή από <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Η συγκεκριμένη εφαρμογή λαμβάνει συνήθως ενημερώσεις από <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Αν κάνετε την ενημέρωση από διαφορετική πηγή, μπορεί να λαμβάνετε μελλοντικές ενημερώσεις από οποιαδήποτε πηγή στο τηλέφωνό σας. Η λειτουργικότητα της εφαρμογής μπορεί να αλλάξει.</p>"</string>
<string name="install_failed" msgid="5777824004474125469">"Η εφαρμογή δεν εγκαταστάθηκε."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Η εγκατάσταση του πακέτου αποκλείστηκε."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Η εφαρμογή δεν εγκαταστάθηκε, επειδή το πακέτο είναι σε διένεξη με κάποιο υπάρχον πακέτο."</string>
diff --git a/packages/PackageInstaller/res/values-es-rUS/strings.xml b/packages/PackageInstaller/res/values-es-rUS/strings.xml
index cc723e4..3330e5f 100644
--- a/packages/PackageInstaller/res/values-es-rUS/strings.xml
+++ b/packages/PackageInstaller/res/values-es-rUS/strings.xml
@@ -26,12 +26,9 @@
<string name="install_done" msgid="5987363587661783896">"Se instaló la app."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"¿Deseas instalar esta app?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"¿Deseas actualizar esta app?"</string>
- <!-- no translation found for install_confirm_question_update_owner_reminder (7994800761970572198) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (2435174886412089791) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (7155138616126795839) -->
- <skip />
+ <string name="install_confirm_question_update_owner_reminder" product="tablet" msgid="7994800761970572198">"<p>Actualiza esta app desde <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Esta app normalmente recibe actualizaciones desde <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Si actualizas a través de otra fuente, es posible que recibas las próximas actualizaciones de cualquier fuente en la tablet. Las funciones de la app puede cambiar.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="tv" msgid="2435174886412089791">"<p>Actualiza esta app desde <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Esta app normalmente recibe actualizaciones desde <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Si actualizas a través de otra fuente, es posible que recibas las próximas actualizaciones de cualquier fuente en la TV. Las funciones de la app puede cambiar.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="default" msgid="7155138616126795839">"<p>Actualiza esta app desde <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Esta app normalmente recibe actualizaciones desde <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Si actualizas a través de otra fuente, es posible que recibas las próximas actualizaciones de cualquier fuente en el teléfono. Las funciones de la app puede cambiar.</p>"</string>
<string name="install_failed" msgid="5777824004474125469">"No se instaló la app."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Se bloqueó el paquete para impedir la instalación."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"No se instaló la app debido a un conflicto con un paquete."</string>
diff --git a/packages/PackageInstaller/res/values-es/strings.xml b/packages/PackageInstaller/res/values-es/strings.xml
index 0a85d78..c351f15 100644
--- a/packages/PackageInstaller/res/values-es/strings.xml
+++ b/packages/PackageInstaller/res/values-es/strings.xml
@@ -26,12 +26,9 @@
<string name="install_done" msgid="5987363587661783896">"Aplicación instalada."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"¿Quieres instalar esta aplicación?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"¿Quieres actualizar esta aplicación?"</string>
- <!-- no translation found for install_confirm_question_update_owner_reminder (7994800761970572198) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (2435174886412089791) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (7155138616126795839) -->
- <skip />
+ <string name="install_confirm_question_update_owner_reminder" product="tablet" msgid="7994800761970572198">"<p>¿Actualizar esta aplicación con <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Esta aplicación suele recibir actualizaciones de <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Si actualizas a través de otra fuente, puede que recibas futuras actualizaciones de cualquier fuente de tu tablet. La funcionalidad de la aplicación puede cambiar.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="tv" msgid="2435174886412089791">"<p>¿Actualizar esta aplicación con <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Esta aplicación suele recibir actualizaciones de <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Si actualizas a través de otra fuente, puede que recibas futuras actualizaciones de cualquier fuente de tu TV. La funcionalidad de la aplicación puede cambiar.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="default" msgid="7155138616126795839">"<p>¿Actualizar esta aplicación con <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Esta aplicación suele recibir actualizaciones de <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Si actualizas a través de otra fuente, puede que recibas futuras actualizaciones de cualquier fuente de tu teléfono. La funcionalidad de la aplicación puede cambiar.</p>"</string>
<string name="install_failed" msgid="5777824004474125469">"No se ha instalado la aplicación."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Se ha bloqueado la instalación del paquete."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"La aplicación no se ha instalado debido a un conflicto con un paquete."</string>
diff --git a/packages/PackageInstaller/res/values-et/strings.xml b/packages/PackageInstaller/res/values-et/strings.xml
index 9cb4be7..5ecfbf4 100644
--- a/packages/PackageInstaller/res/values-et/strings.xml
+++ b/packages/PackageInstaller/res/values-et/strings.xml
@@ -26,12 +26,9 @@
<string name="install_done" msgid="5987363587661783896">"Rakendus on installitud."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Kas soovite selle rakenduse installida?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Kas soovite seda rakendust värskendada?"</string>
- <!-- no translation found for install_confirm_question_update_owner_reminder (7994800761970572198) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (2435174886412089791) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (7155138616126795839) -->
- <skip />
+ <string name="install_confirm_question_update_owner_reminder" product="tablet" msgid="7994800761970572198">"<p>Update this app from <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>See rakendus saab tavaliselt värskendusi omanikult <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Muust allikast värskendamise korral võite edaspidi saada tahvelarvutis värskendusi mis tahes allikast. Rakenduse funktsioonid võivad muutuda.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="tv" msgid="2435174886412089791">"<p>Update this app from <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>See rakendus saab tavaliselt värskendusi omanikult <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Muust allikast värskendamise korral võite edaspidi saada teleris värskendusi mis tahes allikast. Rakenduse funktsioonid võivad muutuda.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="default" msgid="7155138616126795839">"<p>Update this app from <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>See rakendus saab tavaliselt värskendusi omanikult <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Muust allikast värskendamise korral võite edaspidi saada telefonis värskendusi mis tahes allikast. Rakenduse funktsioonid võivad muutuda.</p>"</string>
<string name="install_failed" msgid="5777824004474125469">"Rakendus pole installitud."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Paketi installimine blokeeriti."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Rakendust ei installitud, kuna pakett on olemasoleva paketiga vastuolus."</string>
diff --git a/packages/PackageInstaller/res/values-eu/strings.xml b/packages/PackageInstaller/res/values-eu/strings.xml
index cd443a7..ec720ac 100644
--- a/packages/PackageInstaller/res/values-eu/strings.xml
+++ b/packages/PackageInstaller/res/values-eu/strings.xml
@@ -26,12 +26,9 @@
<string name="install_done" msgid="5987363587661783896">"Instalatu da aplikazioa."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Aplikazioa instalatu nahi duzu?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Aplikazioa eguneratu nahi duzu?"</string>
- <!-- no translation found for install_confirm_question_update_owner_reminder (7994800761970572198) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (2435174886412089791) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (7155138616126795839) -->
- <skip />
+ <string name="install_confirm_question_update_owner_reminder" product="tablet" msgid="7994800761970572198">"<p>Aplikazioa <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b> iturburutik eguneratu nahi duzu?</p><p>Normalean, <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b> iturburuaren eguneratzeak instalatzen dira aplikazioan. Aplikazioa beste iturburu batetik eguneratuz gero, baliteke aurrerantzeko eguneratzeak tabletako edozein iturburutatik jasotzea. Baliteke aplikazioaren funtzioak aldatzea.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="tv" msgid="2435174886412089791">"<p>Aplikazioa <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b> iturburutik eguneratu nahi duzu?</p><p>Normalean, <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b> iturburuaren eguneratzeak instalatzen dira aplikazioan. Aplikazioa beste iturburu batetik eguneratuz gero, baliteke aurrerantzeko eguneratzeak telebistako edozein iturburutatik jasotzea. Baliteke aplikazioaren funtzioak aldatzea.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="default" msgid="7155138616126795839">"<p>Aplikazioa <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b> iturburutik eguneratu nahi duzu?</p><p>Normalean, <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b> iturburuaren eguneratzeak instalatzen dira aplikazioan. Aplikazioa beste iturburu batetik eguneratuz gero, baliteke aurrerantzeko eguneratzeak telefonoko edozein iturburutatik jasotzea. Baliteke aplikazioaren funtzioak aldatzea.</p>"</string>
<string name="install_failed" msgid="5777824004474125469">"Ez da instalatu aplikazioa."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Paketea instalatzeko aukera blokeatu egin da."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Ez da instalatu aplikazioa, gatazka bat sortu delako lehendik dagoen pakete batekin."</string>
diff --git a/packages/PackageInstaller/res/values-fa/strings.xml b/packages/PackageInstaller/res/values-fa/strings.xml
index bbd984f..7a8b579 100644
--- a/packages/PackageInstaller/res/values-fa/strings.xml
+++ b/packages/PackageInstaller/res/values-fa/strings.xml
@@ -26,12 +26,9 @@
<string name="install_done" msgid="5987363587661783896">"برنامه نصب شد."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"میخواهید این برنامه را نصب کنید؟"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"میخواهید این برنامه را بهروزرسانی کنید؟"</string>
- <!-- no translation found for install_confirm_question_update_owner_reminder (7994800761970572198) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (2435174886412089791) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (7155138616126795839) -->
- <skip />
+ <string name="install_confirm_question_update_owner_reminder" product="tablet" msgid="7994800761970572198">"<p>این برنامه ازطریق <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b> بهروز شود؟</p><p>این برنامه معمولاً بهروزرسانیها را از <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b> دریافت میکند. با بهروزرسانی از منبعی متفاوت، ممکن است بهروزرسانیهای آتی را از هر منبعی در رایانه لوحیتان دریافت کنید. ممکن است قابلیتهای برنامه تغییر کند.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="tv" msgid="2435174886412089791">"<p>این برنامه ازطریق <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b> بهروز شود؟</p><p>این برنامه معمولاً بهروزرسانیها را از <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b> دریافت میکند. با بهروزرسانی از منبعی متفاوت، ممکن است بهروزرسانیهای آتی را از هر منبعی در تلویزیون دریافت کنید. ممکن است قابلیتهای برنامه تغییر کند.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="default" msgid="7155138616126795839">"<p>این برنامه ازطریق <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b> بهروز شود؟</p><p>این برنامه معمولاً بهروزرسانیها را از <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b> دریافت میکند. با بهروزرسانی از منبعی متفاوت، ممکن است بهروزرسانیهای بعدی را از هر منبعی در تلفنتان دریافت کنید. ممکن است قابلیتهای برنامه تغییر کند.</p>"</string>
<string name="install_failed" msgid="5777824004474125469">"برنامه نصب نشد."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"از نصب شدن بسته جلوگیری شد."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"برنامه نصب نشد چون بسته با بسته موجود تداخل دارد."</string>
diff --git a/packages/PackageInstaller/res/values-fi/strings.xml b/packages/PackageInstaller/res/values-fi/strings.xml
index f73fdb2..a9b6984 100644
--- a/packages/PackageInstaller/res/values-fi/strings.xml
+++ b/packages/PackageInstaller/res/values-fi/strings.xml
@@ -26,12 +26,9 @@
<string name="install_done" msgid="5987363587661783896">"Sovellus on asennettu."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Haluatko asentaa tämän sovelluksen?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Haluatko päivittää tämän sovelluksen?"</string>
- <!-- no translation found for install_confirm_question_update_owner_reminder (7994800761970572198) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (2435174886412089791) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (7155138616126795839) -->
- <skip />
+ <string name="install_confirm_question_update_owner_reminder" product="tablet" msgid="7994800761970572198">"<p>Päivitä sovellus täältä: <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Sovellus saa päivitykset yleensä täältä: <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Kun päivität uudesta lähteestä, tulevat päivitykset voivat tulla mistä tahansa tabletilla olevasta lähteestä. Sovelluksen toiminnot voivat muuttua.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="tv" msgid="2435174886412089791">"<p>Päivitä sovellus täältä: <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Sovellus saa päivitykset yleensä täältä: <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Kun päivität uudesta lähteestä, tulevat päivitykset voivat tulla mistä tahansa televisiolla olevasta lähteestä. Sovelluksen toiminnot voivat muuttua.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="default" msgid="7155138616126795839">"<p>Päivitä sovellus täältä: <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Sovellus saa päivitykset yleensä täältä: <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Kun päivität uudesta lähteestä, tulevat päivitykset voivat tulla mistä tahansa puhelimella olevasta lähteestä. Sovelluksen toiminnot voivat muuttua.</p>"</string>
<string name="install_failed" msgid="5777824004474125469">"Sovellusta ei asennettu."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Paketin asennus estettiin."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Sovellusta ei asennettu, koska paketti on ristiriidassa nykyisen paketin kanssa."</string>
diff --git a/packages/PackageInstaller/res/values-fr-rCA/strings.xml b/packages/PackageInstaller/res/values-fr-rCA/strings.xml
index 40c4649..0ef53b9 100644
--- a/packages/PackageInstaller/res/values-fr-rCA/strings.xml
+++ b/packages/PackageInstaller/res/values-fr-rCA/strings.xml
@@ -26,12 +26,9 @@
<string name="install_done" msgid="5987363587661783896">"Application installée."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Voulez-vous installer cette application?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Voulez-vous mettre à jour cette application?"</string>
- <!-- no translation found for install_confirm_question_update_owner_reminder (7994800761970572198) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (2435174886412089791) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (7155138616126795839) -->
- <skip />
+ <string name="install_confirm_question_update_owner_reminder" product="tablet" msgid="7994800761970572198">"<p>Mettre à jour cette application à partir de <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Cette application reçoit normalement des mises à jour de <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. En effectuant une mise à jour à partir d\'une source différente, vous pourriez recevoir des mises à jour futures à partir de n\'importe quelle source sur votre tablette. Le fonctionnement de l\'application peut en être modifié.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="tv" msgid="2435174886412089791">"<p>Mettre à jour cette application à partir de <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Cette application reçoit normalement des mises à jour de <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. En effectuant une mise à jour à partir d\'une source différente, vous pourriez recevoir des mises à jour futures à partir de n\'importe quelle source sur votre téléviseur. Le fonctionnement de l\'application peut en être modifié.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="default" msgid="7155138616126795839">"<p>Mettre à jour cette application à partir de <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Cette application reçoit normalement des mises à jour de <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. En effectuant une mise à jour à partir d\'une source différente, vous pourriez recevoir des mises à jour futures à partir de n\'importe quelle source sur votre téléphone. Le fonctionnement de l\'application peut en être modifié.</p>"</string>
<string name="install_failed" msgid="5777824004474125469">"Application non installée."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"L\'installation du paquet a été bloquée."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"L\'application n\'a pas été installée, car le paquet entre en conflit avec un paquet existant."</string>
diff --git a/packages/PackageInstaller/res/values-fr/strings.xml b/packages/PackageInstaller/res/values-fr/strings.xml
index df2e007..5065a22 100644
--- a/packages/PackageInstaller/res/values-fr/strings.xml
+++ b/packages/PackageInstaller/res/values-fr/strings.xml
@@ -26,12 +26,9 @@
<string name="install_done" msgid="5987363587661783896">"Application installée."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Voulez-vous installer cette appli ?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Voulez-vous mettre à jour cette appli ?"</string>
- <!-- no translation found for install_confirm_question_update_owner_reminder (7994800761970572198) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (2435174886412089791) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (7155138616126795839) -->
- <skip />
+ <string name="install_confirm_question_update_owner_reminder" product="tablet" msgid="7994800761970572198">"<p>Mettez à jour cette appli depuis <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Elle reçoit normalement des mises à jour depuis <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Si vous effectuez la mise à jour à partir d\'une autre source, vous recevrez peut-être les prochaines mises à jour depuis n\'importe quelle source sur votre tablette. Le fonctionnement de l\'application peut changer.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="tv" msgid="2435174886412089791">"<p>Mettez à jour cette appli depuis <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Elle reçoit normalement des mises à jour depuis <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Si vous effectuez la mise à jour à partir d\'une autre source, vous recevrez peut-être les prochaines mises à jour depuis n\'importe quelle source sur votre téléviseur. Le fonctionnement de l\'application peut changer.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="default" msgid="7155138616126795839">"<p>Mettez à jour cette appli depuis <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Elle reçoit normalement des mises à jour depuis <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Si vous effectuez la mise à jour à partir d\'une autre source, vous recevrez peut-être les prochaines mises à jour depuis n\'importe quelle source sur votre téléphone. Le fonctionnement de l\'application peut changer.</p>"</string>
<string name="install_failed" msgid="5777824004474125469">"Application non installée."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"L\'installation du package a été bloquée."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"L\'application n\'a pas été installée, car le package est en conflit avec un package déjà présent."</string>
diff --git a/packages/PackageInstaller/res/values-gl/strings.xml b/packages/PackageInstaller/res/values-gl/strings.xml
index 55512cf..694218d 100644
--- a/packages/PackageInstaller/res/values-gl/strings.xml
+++ b/packages/PackageInstaller/res/values-gl/strings.xml
@@ -26,12 +26,9 @@
<string name="install_done" msgid="5987363587661783896">"Instalouse a aplicación."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Queres instalar esta aplicación?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Queres actualizar esta aplicación?"</string>
- <!-- no translation found for install_confirm_question_update_owner_reminder (7994800761970572198) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (2435174886412089791) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (7155138616126795839) -->
- <skip />
+ <string name="install_confirm_question_update_owner_reminder" product="tablet" msgid="7994800761970572198">"<p>Actualiza esta aplicación desde <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Esta aplicación adoita recibir actualizacións de <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Se actualizas a aplicación desde unha fonte diferente, pode que, a partir de agora, recibas actualizacións de calquera fonte na tableta. As funcións da aplicación poderían variar.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="tv" msgid="2435174886412089791">"<p>Actualiza esta aplicación desde <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Esta aplicación adoita recibir actualizacións de <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Se actualizas a aplicación desde unha fonte diferente, pode que, a partir de agora, recibas actualizacións de calquera fonte na televisión. As funcións da aplicación poderían variar.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="default" msgid="7155138616126795839">"<p>Actualiza esta aplicación desde <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Esta aplicación adoita recibir actualizacións de <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Se actualizas a aplicación desde unha fonte diferente, pode que, a partir de agora, recibas actualizacións de calquera fonte no teléfono. As funcións da aplicación poderían variar.</p>"</string>
<string name="install_failed" msgid="5777824004474125469">"Non se instalou a aplicación"</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Bloqueouse a instalación do paquete."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"A aplicación non se instalou porque o paquete presenta un conflito cun paquete que xa hai."</string>
diff --git a/packages/PackageInstaller/res/values-hi/strings.xml b/packages/PackageInstaller/res/values-hi/strings.xml
index 930757b..ddb16dd 100644
--- a/packages/PackageInstaller/res/values-hi/strings.xml
+++ b/packages/PackageInstaller/res/values-hi/strings.xml
@@ -26,12 +26,9 @@
<string name="install_done" msgid="5987363587661783896">"ऐप्लिकेशन इंस्टॉल हो गया."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"क्या आपको यह ऐप्लिकेशन इंस्टॉल करना है?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"क्या आप इस ऐप्लिकेशन को अपडेट करना चाहते हैं?"</string>
- <!-- no translation found for install_confirm_question_update_owner_reminder (7994800761970572198) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (2435174886412089791) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (7155138616126795839) -->
- <skip />
+ <string name="install_confirm_question_update_owner_reminder" product="tablet" msgid="7994800761970572198">"<p>क्या इस ऐप्लिकेशन को <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b> से अपडेट करना है?</p><p>आम तौर पर, इस ऐप्लिकेशन को <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b> से अपडेट मिलते हैं. किसी दूसरे सोर्स से अपडेट करने पर, आपको आगे से अपने टैबलेट पर किसी भी सोर्स से अपडेट मिल सकते हैं. ऐप्लिकेशन की मुख्य सुविधाएं और उनके काम करने का तरीका बदल सकता है.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="tv" msgid="2435174886412089791">"<p>क्या इस ऐप्लिकेशन को <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b> से अपडेट करना है?</p><p>आम तौर पर, इस ऐप्लिकेशन को <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b> से अपडेट मिलते हैं. किसी दूसरे सोर्स से अपडेट करने पर, आपको आगे से अपने टीवी पर किसी भी सोर्स से अपडेट मिल सकते हैं. ऐप्लिकेशन की मुख्य सुविधाएं और उनके काम करने का तरीका बदल सकता है.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="default" msgid="7155138616126795839">"<p>क्या इस ऐप्लिकेशन को <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b> से अपडेट करना है?</p><p>आम तौर पर, इस ऐप्लिकेशन को <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b> से अपडेट मिलते हैं. किसी दूसरे सोर्स से अपडेट करने पर, आपको आगे से अपने फ़ोन पर किसी भी सोर्स से अपडेट मिल सकते हैं. ऐप्लिकेशन की मुख्य सुविधाएं और उनके काम करने का तरीका बदल सकता है.</p>"</string>
<string name="install_failed" msgid="5777824004474125469">"ऐप्लिकेशन इंस्टॉल नहीं हुआ."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"पैकेज को इंस्टॉल होने से ब्लॉक किया हुआ है."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"ऐप्लिकेशन इंस्टॉल नहीं हुआ क्योंकि पैकेज का किसी मौजूदा पैकेज से विरोध है."</string>
diff --git a/packages/PackageInstaller/res/values-hr/strings.xml b/packages/PackageInstaller/res/values-hr/strings.xml
index 0977745..c758f4f 100644
--- a/packages/PackageInstaller/res/values-hr/strings.xml
+++ b/packages/PackageInstaller/res/values-hr/strings.xml
@@ -26,12 +26,9 @@
<string name="install_done" msgid="5987363587661783896">"Aplikacija je instalirana."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Želite li instalirati ovu aplikaciju?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Želite li ažurirati ovu aplikaciju?"</string>
- <!-- no translation found for install_confirm_question_update_owner_reminder (7994800761970572198) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (2435174886412089791) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (7155138616126795839) -->
- <skip />
+ <string name="install_confirm_question_update_owner_reminder" product="tablet" msgid="7994800761970572198">"<p>Želite li ovu aplikaciju ažurirati sa <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Ova aplikacija uglavnom prima ažuriranja sa <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Ako je ažurirate s nekog drugog izvora, buduća ažuriranja možete primati s bilo kojeg izvora na svojem tabletu. Funkcije aplikacije mogu se promijeniti.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="tv" msgid="2435174886412089791">"<p>Želite li ovu aplikaciju ažurirati sa <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Ova aplikacija uglavnom prima ažuriranja sa <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Ako je ažurirate s nekog drugog izvora, buduća ažuriranja možete primati s bilo kojeg izvora na svojem TV-u. Funkcije aplikacije mogu se promijeniti.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="default" msgid="7155138616126795839">"<p>Želite li ovu aplikaciju ažurirati sa <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Ova aplikacija uglavnom prima ažuriranja sa <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Ako je ažurirate s nekog drugog izvora, buduća ažuriranja možete primati s bilo kojeg izvora na svojem telefonu. Funkcije aplikacije mogu se promijeniti.</p>"</string>
<string name="install_failed" msgid="5777824004474125469">"Aplikacija nije instalirana."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Instaliranje paketa blokirano je."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Aplikacija koja nije instalirana kao paket u sukobu je s postojećim paketom."</string>
diff --git a/packages/PackageInstaller/res/values-hu/strings.xml b/packages/PackageInstaller/res/values-hu/strings.xml
index 022f6456..4fd866d 100644
--- a/packages/PackageInstaller/res/values-hu/strings.xml
+++ b/packages/PackageInstaller/res/values-hu/strings.xml
@@ -26,12 +26,9 @@
<string name="install_done" msgid="5987363587661783896">"Alkalmazás telepítve."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Telepíti ezt az alkalmazást?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Frissíti ezt az alkalmazást?"</string>
- <!-- no translation found for install_confirm_question_update_owner_reminder (7994800761970572198) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (2435174886412089791) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (7155138616126795839) -->
- <skip />
+ <string name="install_confirm_question_update_owner_reminder" product="tablet" msgid="7994800761970572198">"<p>Frissítse ezt az alkalmazást innen: <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Ez az alkalmazás általában a következő forrásból kap frissítéseket: <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Ha másik forrásból frissíti, a későbbiekben bármelyik forrásból kaphat frissítéseket a táblagépén. Emiatt megváltozhat az alkalmazás működése.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="tv" msgid="2435174886412089791">"<p>Frissítse ezt az alkalmazást innen: <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Ez az alkalmazás általában a következő forrásból kap frissítéseket: <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Ha másik forrásból frissíti, a későbbiekben bármelyik forrásból kaphat frissítéseket a tévéjén. Emiatt megváltozhat az alkalmazás működése.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="default" msgid="7155138616126795839">"<p>Frissítse ezt az alkalmazást innen: <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Ez az alkalmazás általában a következő forrásból kap frissítéseket: <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Ha másik forrásból frissíti, a későbbiekben bármelyik forrásból kaphat frissítéseket a telefonján. Emiatt megváltozhat az alkalmazás működése.</p>"</string>
<string name="install_failed" msgid="5777824004474125469">"Az alkalmazás nincs telepítve."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"A csomag telepítését letiltotta a rendszer."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"A nem csomagként telepített alkalmazás ütközik egy már létező csomaggal."</string>
diff --git a/packages/PackageInstaller/res/values-hy/strings.xml b/packages/PackageInstaller/res/values-hy/strings.xml
index 6eba377..e5e7cec 100644
--- a/packages/PackageInstaller/res/values-hy/strings.xml
+++ b/packages/PackageInstaller/res/values-hy/strings.xml
@@ -26,12 +26,9 @@
<string name="install_done" msgid="5987363587661783896">"Հավելվածը տեղադրված է:"</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Տեղադրե՞լ այս հավելվածը:"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Թարմացնե՞լ այս հավելվածը։"</string>
- <!-- no translation found for install_confirm_question_update_owner_reminder (7994800761970572198) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (2435174886412089791) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (7155138616126795839) -->
- <skip />
+ <string name="install_confirm_question_update_owner_reminder" product="tablet" msgid="7994800761970572198">"<p>Թարմացրեք այս հավելվածը <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g>-ից</b>?</p><p>Հավելվածը սովորաբար թարմացումները ստանում է <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g>-ից</b>։ Եթե թարմացնեք այլ աղբյուրից, հետագայում կարող եք ձեր պլանշետում թարմացումներ ստանալ ցանկացած աղբյուրից։ Հավելվածի գործառույթները կարող են փոխվել։</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="tv" msgid="2435174886412089791">"<p>Թարմացրեք այս հավելվածը <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g>-ից</b>?</p><p>Հավելվածը սովորաբար թարմացումները ստանում է <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g>-ից</b>։ Եթե թարմացնեք այլ աղբյուրից, հետագայում կարող եք ձեր հեռուստացույցում թարմացումներ ստանալ ցանկացած աղբյուրից։ Հավելվածի գործառույթները կարող են փոխվել։</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="default" msgid="7155138616126795839">"<p>Թարմացրեք այս հավելվածը <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g>-ից</b>?</p><p>Հավելվածը սովորաբար թարմացումները ստանում է <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g>-ից</b>։ Եթե թարմացնեք այլ աղբյուրից, հետագայում կարող եք ձեր հեռախոսում թարմացումներ ստանալ ցանկացած աղբյուրից։ Հավելվածի գործառույթները կարող են փոխվել։</p>"</string>
<string name="install_failed" msgid="5777824004474125469">"Հավելվածը տեղադրված չէ:"</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Փաթեթի տեղադրումն արգելափակվել է:"</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Հավելվածը չի տեղադրվել, քանի որ տեղադրման փաթեթն ունի հակասություն առկա փաթեթի հետ:"</string>
diff --git a/packages/PackageInstaller/res/values-in/strings.xml b/packages/PackageInstaller/res/values-in/strings.xml
index 726a306..a52b63c 100644
--- a/packages/PackageInstaller/res/values-in/strings.xml
+++ b/packages/PackageInstaller/res/values-in/strings.xml
@@ -26,12 +26,9 @@
<string name="install_done" msgid="5987363587661783896">"Aplikasi terinstal."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Ingin menginstal aplikasi ini?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Ingin mengupdate aplikasi ini?"</string>
- <!-- no translation found for install_confirm_question_update_owner_reminder (7994800761970572198) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (2435174886412089791) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (7155138616126795839) -->
- <skip />
+ <string name="install_confirm_question_update_owner_reminder" product="tablet" msgid="7994800761970572198">"<p>Update aplikasi ini dari <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Aplikasi ini biasanya menerima update dari <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Dengan mengupdate dari sumber yang berbeda, Anda mungkin menerima update berikutnya dari sumber mana pun di tablet. Fungsi aplikasi mungkin berubah.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="tv" msgid="2435174886412089791">"<p>Update aplikasi ini dari <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Aplikasi ini biasanya menerima update dari <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Dengan mengupdate dari sumber yang berbeda, Anda mungkin menerima update berikutnya dari sumber mana pun di TV. Fungsi aplikasi mungkin berubah.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="default" msgid="7155138616126795839">"<p>Update aplikasi ini dari <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Aplikasi ini biasanya menerima update dari <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Dengan mengupdate dari sumber yang berbeda, Anda mungkin menerima update berikutnya dari sumber mana pun di ponsel. Fungsi aplikasi mungkin berubah.</p>"</string>
<string name="install_failed" msgid="5777824004474125469">"Aplikasi tidak terinstal."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Paket diblokir sehingga tidak dapat diinstal."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Aplikasi tidak diinstal karena paket ini bentrok dengan paket yang sudah ada."</string>
diff --git a/packages/PackageInstaller/res/values-is/strings.xml b/packages/PackageInstaller/res/values-is/strings.xml
index 4388f1c..b125da1 100644
--- a/packages/PackageInstaller/res/values-is/strings.xml
+++ b/packages/PackageInstaller/res/values-is/strings.xml
@@ -26,12 +26,9 @@
<string name="install_done" msgid="5987363587661783896">"Forritið er uppsett."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Viltu setja upp þetta forrit?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Viltu uppfæra þetta forrit?"</string>
- <!-- no translation found for install_confirm_question_update_owner_reminder (7994800761970572198) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (2435174886412089791) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (7155138616126795839) -->
- <skip />
+ <string name="install_confirm_question_update_owner_reminder" product="tablet" msgid="7994800761970572198">"<p>Uppfæra þetta forrit frá <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Þetta forrit fær yfirleitt uppfærslur frá <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Með því að uppfæra frá öðrum uppruna gætirðu fengið framtíðaruppfærslur frá hvaða uppruna sem er í spjaldtölvunni. Virkni forrits kann að breytast.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="tv" msgid="2435174886412089791">"<p>Uppfæra þetta forrit frá <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Þetta forrit fær yfirleitt uppfærslur frá <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Með því að uppfæra frá öðrum uppruna gætirðu fengið framtíðaruppfærslur frá hvaða uppruna sem er í sjónvarpinu. Virkni forrits kann að breytast.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="default" msgid="7155138616126795839">"<p>Uppfæra þetta forrit frá <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Þetta forrit fær yfirleitt uppfærslur frá <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Með því að uppfæra frá öðrum uppruna gætirðu fengið framtíðaruppfærslur frá hvaða uppruna sem er í símanum. Virkni forrits kann að breytast.</p>"</string>
<string name="install_failed" msgid="5777824004474125469">"Forritið er ekki uppsett."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Lokað var á uppsetningu pakkans."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Forritið var ekki sett upp vegna árekstra á milli pakkans og annars pakka."</string>
diff --git a/packages/PackageInstaller/res/values-kk/strings.xml b/packages/PackageInstaller/res/values-kk/strings.xml
index 1831b00..1ccac10 100644
--- a/packages/PackageInstaller/res/values-kk/strings.xml
+++ b/packages/PackageInstaller/res/values-kk/strings.xml
@@ -26,12 +26,9 @@
<string name="install_done" msgid="5987363587661783896">"Қолданба орнатылды."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Бұл қолданбаны орнатқыңыз келе ме?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Бұл қолданбаны жаңартқыңыз келе ме?"</string>
- <!-- no translation found for install_confirm_question_update_owner_reminder (7994800761970572198) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (2435174886412089791) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (7155138616126795839) -->
- <skip />
+ <string name="install_confirm_question_update_owner_reminder" product="tablet" msgid="7994800761970572198">"<p>Қолданба <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b> дереккөзінен жаңартылсын ба?</p><p>Бұл қолданба жаңартуды<b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b> дереккөзінен қалыпты түрде алады. Басқа дереккөзден жаңартсаңыз, планшетіңіздегі кез келген дереккөзден алдағы жаңартулар берілуі мүмкін. Қолданба функциялары өзгеруі мүмкін.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="tv" msgid="2435174886412089791">"<p>Қолданба <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b> дереккөзінен жаңартылсын ба?</p><p>Бұл қолданба жаңартуды<b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b> дереккөзінен қалыпты түрде алады. Басқа дереккөзден жаңартсаңыз, теледидарыңыздағы кез келген дереккөзден алдағы жаңартулар берілуі мүмкін. Қолданба функциялары өзгеруі мүмкін.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="default" msgid="7155138616126795839">"<p>Қолданба <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b> дереккөзінен жаңартылсын ба?</p><p>Бұл қолданба жаңартуды<b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b> дереккөзінен қалыпты түрде алады. Басқа дереккөзден жаңартсаңыз, телефоныңыздағы кез келген дереккөзден алдағы жаңартулар берілуі мүмкін. Қолданба функциялары өзгеруі мүмкін.</p>"</string>
<string name="install_failed" msgid="5777824004474125469">"Қолданба орнатылмады."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Пакетті орнатуға тыйым салынды."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Жаңа пакет пен бұрыннан бар пакеттің арасында қайшылық туындағандықтан, қолданба орнатылмады."</string>
diff --git a/packages/PackageInstaller/res/values-kn/strings.xml b/packages/PackageInstaller/res/values-kn/strings.xml
index 2cbbc08..9cfe389 100644
--- a/packages/PackageInstaller/res/values-kn/strings.xml
+++ b/packages/PackageInstaller/res/values-kn/strings.xml
@@ -26,12 +26,9 @@
<string name="install_done" msgid="5987363587661783896">"ಆ್ಯಪ್ ಅನ್ನು ಇನ್ಸ್ಟಾಲ್ ಮಾಡಲಾಗಿದೆ."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"ನೀವು ಈ ಆ್ಯಪ್ ಅನ್ನು ಇನ್ಸ್ಟಾಲ್ ಮಾಡಲು ಬಯಸುವಿರಾ?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"ನೀವು ಈ ಆ್ಯಪ್ ಅನ್ನು ಅಪ್ಡೇಟ್ ಮಾಡಲು ಬಯಸುವಿರಾ?"</string>
- <!-- no translation found for install_confirm_question_update_owner_reminder (7994800761970572198) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (2435174886412089791) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (7155138616126795839) -->
- <skip />
+ <string name="install_confirm_question_update_owner_reminder" product="tablet" msgid="7994800761970572198">"<p>ಈ ಆ್ಯಪ್ ಅನ್ನು <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b> ನಿಂದ ಅಪ್ಡೇಟ್ ಮಾಡಬೇಕೇ?</p><p>ಈ ಆ್ಯಪ್ ಸಾಮಾನ್ಯವಾಗಿ <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b> ನಿಂದ ಅಪ್ಡೇಟ್ಗಳನ್ನು ಸ್ವೀಕರಿಸುತ್ತದೆ. ಬೇರೆ ಮೂಲವೊಂದರಿಂದ ಅಪ್ಡೇಟ್ ಮಾಡುವ ಮೂಲಕ, ನಿಮ್ಮ ಟ್ಯಾಬ್ಲೆಟ್ನಲ್ಲಿರುವ ಯಾವುದೇ ಮೂಲದಿಂದ ನೀವು ಭವಿಷ್ಯದ ಅಪ್ಡೇಟ್ಗಳನ್ನು ಸ್ವೀಕರಿಸಬಹುದು. ಆ್ಯಪ್ನ ಕಾರ್ಯಚಟುವಟಿಕೆಯು ಬದಲಾಗಬಹುದು.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="tv" msgid="2435174886412089791">"<p>ಈ ಆ್ಯಪ್ ಅನ್ನು <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b> ನಿಂದ ಅಪ್ಡೇಟ್ ಮಾಡಬೇಕೇ?</p><p>ಈ ಆ್ಯಪ್ ಸಾಮಾನ್ಯವಾಗಿ <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b> ನಿಂದ ಅಪ್ಡೇಟ್ಗಳನ್ನು ಸ್ವೀಕರಿಸುತ್ತದೆ. ಬೇರೆ ಮೂಲವೊಂದರಿಂದ ಅಪ್ಡೇಟ್ ಮಾಡುವ ಮೂಲಕ, ನಿಮ್ಮ TV ಯಲ್ಲಿರುವ ಯಾವುದೇ ಮೂಲದಿಂದ ನೀವು ಭವಿಷ್ಯದ ಅಪ್ಡೇಟ್ಗಳನ್ನು ಸ್ವೀಕರಿಸಬಹುದು. ಆ್ಯಪ್ನ ಕಾರ್ಯಚಟುವಟಿಕೆಯು ಬದಲಾಗಬಹುದು.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="default" msgid="7155138616126795839">"<p>ಈ ಆ್ಯಪ್ ಅನ್ನು <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b> ನಿಂದ ಅಪ್ಡೇಟ್ ಮಾಡಬೇಕೇ?</p><p>ಈ ಆ್ಯಪ್ ಸಾಮಾನ್ಯವಾಗಿ <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b> ನಿಂದ ಅಪ್ಡೇಟ್ಗಳನ್ನು ಸ್ವೀಕರಿಸುತ್ತದೆ. ಬೇರೆ ಮೂಲವೊಂದರಿಂದ ಅಪ್ಡೇಟ್ ಮಾಡುವ ಮೂಲಕ, ನಿಮ್ಮ ಫೋನ್ನಲ್ಲಿರುವ ಯಾವುದೇ ಮೂಲದಿಂದ ನೀವು ಭವಿಷ್ಯದ ಅಪ್ಡೇಟ್ಗಳನ್ನು ಸ್ವೀಕರಿಸಬಹುದು. ಆ್ಯಪ್ನ ಕಾರ್ಯಚಟುವಟಿಕೆಯು ಬದಲಾಗಬಹುದು.</p>"</string>
<string name="install_failed" msgid="5777824004474125469">"ಆ್ಯಪ್ ಇನ್ಸ್ಟಾಲ್ ಮಾಡಲಾಗಿಲ್ಲ."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"ಇನ್ಸ್ಟಾಲ್ ಮಾಡುವ ಪ್ಯಾಕೇಜ್ ಅನ್ನು ನಿರ್ಬಂಧಿಸಲಾಗಿದೆ."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"ಪ್ಯಾಕೇಜ್ನಂತೆ ಇನ್ಸ್ಟಾಲ್ ಮಾಡಲಾಗಿರುವ ಆ್ಯಪ್ ಅಸ್ತಿತ್ವದಲ್ಲಿರುವ ಪ್ಯಾಕೇಜ್ ಜೊತೆಗೆ ಸಂಘರ್ಷವಾಗುತ್ತದೆ."</string>
diff --git a/packages/PackageInstaller/res/values-ko/strings.xml b/packages/PackageInstaller/res/values-ko/strings.xml
index a36780d..271ec90 100644
--- a/packages/PackageInstaller/res/values-ko/strings.xml
+++ b/packages/PackageInstaller/res/values-ko/strings.xml
@@ -26,12 +26,9 @@
<string name="install_done" msgid="5987363587661783896">"앱이 설치되었습니다."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"이 앱을 설치하시겠습니까?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"이 앱을 업데이트하시겠습니까?"</string>
- <!-- no translation found for install_confirm_question_update_owner_reminder (7994800761970572198) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (2435174886412089791) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (7155138616126795839) -->
- <skip />
+ <string name="install_confirm_question_update_owner_reminder" product="tablet" msgid="7994800761970572198">"<p><b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g>에서</b>?</p><p>이 앱을 업데이트하세요. 이 앱은 보통<b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>에서 업데이트를 받습니다. 다른 출처에서 업데이트를 받으면 향후 태블릿에 있는 어떤 출처에서든지 업데이트를 받을 수 있습니다. 앱 기능이 변경될 수 있습니다.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="tv" msgid="2435174886412089791">"<p><b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g>에서</b>?</p><p>이 앱을 업데이트하세요. 이 앱은 보통<b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>에서 업데이트를 받습니다. 다른 출처에서 앱을 업데이트하면 향후 TV에 있는 어떤 출처에서든지 업데이트를 받을 수 있습니다. 앱 기능이 변경될 수 있습니다.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="default" msgid="7155138616126795839">"<p><b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g>에서</b>?</p><p>이 앱을 업데이트하세요. 이 앱은 보통<b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>에서 업데이트를 받습니다. 다른 출처에서 업데이트를 받으면 향후 휴대전화에 있는 어떤 출처든지 업데이트를 받을 수 있습니다. 앱 기능이 변경될 수 있습니다.</p>"</string>
<string name="install_failed" msgid="5777824004474125469">"앱이 설치되지 않았습니다."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"패키지 설치가 차단되었습니다."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"패키지가 기존 패키지와 충돌하여 앱이 설치되지 않았습니다."</string>
@@ -75,7 +72,7 @@
<string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> 제거 중…"</string>
<string name="uninstall_done" msgid="439354138387969269">"제거를 완료했습니다."</string>
<string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>를 제거했습니다."</string>
- <string name="uninstall_done_clone_app" msgid="5578308154544195413">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> 클론 삭제됨"</string>
+ <string name="uninstall_done_clone_app" msgid="5578308154544195413">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> 복제 삭제됨"</string>
<string name="uninstall_failed" msgid="1847750968168364332">"제거하지 못했습니다."</string>
<string name="uninstall_failed_app" msgid="5506028705017601412">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>을(를) 제거하지 못했습니다."</string>
<string name="uninstalling_cloned_app" msgid="1826380164974984870">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> 클론 삭제 중…"</string>
@@ -99,7 +96,7 @@
<string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"휴대전화와 개인 데이터는 알 수 없는 앱의 공격에 더욱 취약합니다. 이 앱을 설치하면 앱 사용으로 인해 발생할 수 있는 모든 휴대전화 손상이나 데이터 손실에 사용자가 책임을 진다는 것에 동의하게 됩니다."</string>
<string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"태블릿과 개인 데이터는 알 수 없는 앱의 공격에 더욱 취약합니다. 이 앱을 설치하면 앱 사용으로 인해 발생할 수 있는 모든 태블릿 손상이나 데이터 손실에 사용자가 책임을 진다는 것에 동의하게 됩니다."</string>
<string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"TV와 개인 데이터는 알 수 없는 앱의 공격에 더욱 취약합니다. 이 앱을 설치하면 앱 사용으로 인해 발생할 수 있는 모든 TV 손상이나 데이터 손실에 사용자가 책임을 진다는 것에 동의하게 됩니다."</string>
- <string name="cloned_app_label" msgid="7503612829833756160">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> 클론"</string>
+ <string name="cloned_app_label" msgid="7503612829833756160">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> 복제"</string>
<string name="anonymous_source_continue" msgid="4375745439457209366">"계속"</string>
<string name="external_sources_settings" msgid="4046964413071713807">"설정"</string>
<string name="wear_app_channel" msgid="1960809674709107850">"Wear 앱 설치/제거"</string>
diff --git a/packages/PackageInstaller/res/values-ky/strings.xml b/packages/PackageInstaller/res/values-ky/strings.xml
index 5a6ed45..5e9948d 100644
--- a/packages/PackageInstaller/res/values-ky/strings.xml
+++ b/packages/PackageInstaller/res/values-ky/strings.xml
@@ -26,12 +26,9 @@
<string name="install_done" msgid="5987363587661783896">"Колдонмо орнотулду."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Бул колдонмону орнотоюн деп жатасызбы?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Бул колдонмону жаңыртайын деп жатасызбы?"</string>
- <!-- no translation found for install_confirm_question_update_owner_reminder (7994800761970572198) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (2435174886412089791) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (7155138616126795839) -->
- <skip />
+ <string name="install_confirm_question_update_owner_reminder" product="tablet" msgid="7994800761970572198">"<p>Колдонмо <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b> аркылуу жаңыртылсынбы?</p><p>Адатта бул колдонмо <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b> жөнөткөн жаңыртууларды алат. Башка булактан жаңыртcаңыз, кийинки жаңыртуулар планшетиңиздеги ар кандай булактардан алынышы мүмкүн. Колдонмонун функциялары өзгөрүшү мүмкүн.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="tv" msgid="2435174886412089791">"<p>Колдонмо <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b> аркылуу жаңыртылсынбы?</p><p>Адатта бул колдонмо <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b> жөнөткөн жаңыртууларды алат. Башка булактан жаңыртcаңыз, кийинки жаңыртуулар сыналгыңыздагы ар кандай булактардан алынышы мүмкүн. Колдонмонун функциялары өзгөрүшү мүмкүн.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="default" msgid="7155138616126795839">"<p>Колдонмо <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b> аркылуу жаңыртылсынбы?</p><p>Адатта бул колдонмо <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b> жөнөткөн жаңыртууларды алат. Башка булактан жаңыртcаңыз, кийинки жаңыртуулар телефонуңуздагы ар кандай булактардан алынышы мүмкүн. Колдонмонун функциялары өзгөрүшү мүмкүн.</p>"</string>
<string name="install_failed" msgid="5777824004474125469">"Колдонмо орнотулган жок."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Топтомду орнотууга болбойт."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Башка топтом менен дал келбегендиктен колдонмо орнотулган жок."</string>
diff --git a/packages/PackageInstaller/res/values-lo/strings.xml b/packages/PackageInstaller/res/values-lo/strings.xml
index 81f89d9..d12bb4b 100644
--- a/packages/PackageInstaller/res/values-lo/strings.xml
+++ b/packages/PackageInstaller/res/values-lo/strings.xml
@@ -26,12 +26,9 @@
<string name="install_done" msgid="5987363587661783896">"ຕິດຕັ້ງແອັບແລ້ວ."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"ທ່ານຕ້ອງການຕິດຕັ້ງແອັບນີ້ບໍ່?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"ທ່ານຕ້ອງການອັບເດດແອັບນີ້ບໍ່?"</string>
- <!-- no translation found for install_confirm_question_update_owner_reminder (7994800761970572198) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (2435174886412089791) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (7155138616126795839) -->
- <skip />
+ <string name="install_confirm_question_update_owner_reminder" product="tablet" msgid="7994800761970572198">"<p>ອັບເດດແອັບນີ້ຈາກ <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>ໂດຍປົກກະຕິແລ້ວແອັບນີ້ຈະໄດ້ຮັບການອັບເດດຈາກ <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. ການອັບເດດຈາກແຫຼ່ງທີ່ມາອື່ນອາດເຮັດໃຫ້ແທັບເລັດຂອງທ່ານໄດ້ຮັບການອັບເດດຈາກແຫຼ່ງທີ່ມານັ້ນໃນອະນາຄົດ. ເຊິ່ງອາດເຮັດໃຫ້ຟັງຊັນການນຳໃຊ້ແອັບປ່ຽນແປງ.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="tv" msgid="2435174886412089791">"<p>ອັບເດດແອັບນີ້ຈາກ <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>ໂດຍປົກກະຕິແລ້ວແອັບນີ້ຈະໄດ້ຮັບການອັບເດດຈາກ <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. ການອັບເດດຈາກແຫຼ່ງທີ່ມາອື່ນອາດເຮັດໃຫ້ໂທລະທັດຂອງທ່ານໄດ້ຮັບການອັບເດດຈາກແຫຼ່ງທີ່ມານັ້ນໃນອະນາຄົດ. ເຊິ່ງອາດເຮັດໃຫ້ຟັງຊັນການນຳໃຊ້ແອັບປ່ຽນແປງ.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="default" msgid="7155138616126795839">"<p>ອັບເດດແອັບນີ້ຈາກ <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>ໂດຍປົກກະຕິແລ້ວແອັບນີ້ຈະໄດ້ຮັບການອັບເດດຈາກ <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. ການອັບເດດຈາກແຫຼ່ງທີ່ມາອື່ນອາດເຮັດໃຫ້ໂທລະສັບຂອງທ່ານໄດ້ຮັບການອັບເດດຈາກແຫຼ່ງທີ່ມານັ້ນໃນອະນາຄົດ. ເຊິ່ງອາດເຮັດໃຫ້ຟັງຊັນການນຳໃຊ້ແອັບປ່ຽນແປງ.</p>"</string>
<string name="install_failed" msgid="5777824004474125469">"ບໍ່ໄດ້ຕິດຕັ້ງແອັບເທື່ອ."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"ແພັກເກດຖືກບລັອກບໍ່ໃຫ້ໄດ້ຮັບການຕິດຕັ້ງ."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"ບໍ່ໄດ້ຕິດຕັ້ງແອັບເນື່ອງຈາກແພັກເກດຂັດແຍ່ງກັບແພັກເກດທີ່ມີຢູ່ກ່ອນແລ້ວ."</string>
diff --git a/packages/PackageInstaller/res/values-lt/strings.xml b/packages/PackageInstaller/res/values-lt/strings.xml
index 94cf2d8..91ae9d1 100644
--- a/packages/PackageInstaller/res/values-lt/strings.xml
+++ b/packages/PackageInstaller/res/values-lt/strings.xml
@@ -26,12 +26,9 @@
<string name="install_done" msgid="5987363587661783896">"Programa įdiegta."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Ar norite įdiegti šią programą?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Ar norite atnaujinti šią programą?"</string>
- <!-- no translation found for install_confirm_question_update_owner_reminder (7994800761970572198) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (2435174886412089791) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (7155138616126795839) -->
- <skip />
+ <string name="install_confirm_question_update_owner_reminder" product="tablet" msgid="7994800761970572198">"<p>Šią programą atnaujinti iš <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Ši programa paprastai naujinius gauna iš <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Atnaujinę iš kito šaltinio, būsimus naujinius galite gauti iš bet kurio šaltinio planšetiniame kompiuteryje. Programos funkcijos gali pasikeisti.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="tv" msgid="2435174886412089791">"<p>Šią programą atnaujinti iš <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Ši programa paprastai naujinius gauna iš <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Atnaujinę iš kito šaltinio, būsimus naujinius galite gauti iš bet kurio šaltinio televizoriuje. Programos funkcijos gali pasikeisti.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="default" msgid="7155138616126795839">"<p>Šią programą atnaujinti iš <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Ši programa paprastai naujinius gauna iš <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Atnaujinę iš kito šaltinio, būsimus naujinius galite gauti iš bet kurio šaltinio telefone. Programos funkcijos gali pasikeisti.</p>"</string>
<string name="install_failed" msgid="5777824004474125469">"Programa neįdiegta."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Paketas užblokuotas ir negali būti įdiegtas."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Programa neįdiegta, nes paketas nesuderinamas su esamu paketu."</string>
diff --git a/packages/PackageInstaller/res/values-lv/strings.xml b/packages/PackageInstaller/res/values-lv/strings.xml
index e85ac80..c6f9eb4 100644
--- a/packages/PackageInstaller/res/values-lv/strings.xml
+++ b/packages/PackageInstaller/res/values-lv/strings.xml
@@ -26,12 +26,9 @@
<string name="install_done" msgid="5987363587661783896">"Lietotne ir instalēta."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Vai vēlaties instalēt šo lietotni?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Vai vēlaties atjaunināt šo lietotni?"</string>
- <!-- no translation found for install_confirm_question_update_owner_reminder (7994800761970572198) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (2435174886412089791) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (7155138616126795839) -->
- <skip />
+ <string name="install_confirm_question_update_owner_reminder" product="tablet" msgid="7994800761970572198">"<p>Vai atjaunināt šo lietotni, izmantojot <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Šī lietotne parasti saņem atjauninājumus no <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Veicot atjaunināšanu no cita avota, iespējams, turpmāk planšetdatorā saņemsiet atjauninājumus no jebkāda avota. Lietotnes funkcionalitāte var mainīties.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="tv" msgid="2435174886412089791">"<p>Vai atjaunināt šo lietotni, izmantojot <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Šī lietotne parasti saņem atjauninājumus no <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Veicot atjaunināšanu no cita avota, iespējams, turpmāk televizorā saņemsiet atjauninājumus no jebkāda avota. Lietotnes funkcionalitāte var mainīties.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="default" msgid="7155138616126795839">"<p>Vai atjaunināt šo lietotni, izmantojot <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Šī lietotne parasti saņem atjauninājumus no <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Veicot atjaunināšanu no cita avota, iespējams, turpmāk tālrunī saņemsiet atjauninājumus no jebkāda avota. Lietotnes funkcionalitāte var mainīties.</p>"</string>
<string name="install_failed" msgid="5777824004474125469">"Lietotne nav instalēta."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Pakotnes instalēšana tika bloķēta."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Lietotne netika instalēta, jo pastāv pakotnes konflikts ar esošu pakotni."</string>
diff --git a/packages/PackageInstaller/res/values-mk/strings.xml b/packages/PackageInstaller/res/values-mk/strings.xml
index 8273e78..bc5cb90 100644
--- a/packages/PackageInstaller/res/values-mk/strings.xml
+++ b/packages/PackageInstaller/res/values-mk/strings.xml
@@ -26,12 +26,9 @@
<string name="install_done" msgid="5987363587661783896">"Апликацијата е инсталирана."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Дали сакате да ја инсталирате апликацијава?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Дали сакате да ја ажурирате апликацијава?"</string>
- <!-- no translation found for install_confirm_question_update_owner_reminder (7994800761970572198) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (2435174886412089791) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (7155138616126795839) -->
- <skip />
+ <string name="install_confirm_question_update_owner_reminder" product="tablet" msgid="7994800761970572198">"<p>Ажурирајте ја апликацијава од <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Апликацијава вообичаено добива ажурирања од <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Со ажурирање од различен извор, може да добивате идни ажурирања од кој било извор на вашиот таблет. Може да дојде до промени во функционалноста на апликацијата.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="tv" msgid="2435174886412089791">"<p>Ажурирајте ја апликацијава од <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Апликацијава вообичаено добива ажурирања од <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Со ажурирање од различен извор, може да добивате идни ажурирања од кој било извор на вашиот телевизор. Може да дојде до промени во функционалноста на апликацијата.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="default" msgid="7155138616126795839">"<p>Ажурирајте ја апликацијава од <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Апликацијава вообичаено добива ажурирања од <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Со ажурирање од различен извор, може да добивате идни ажурирања од кој било извор на вашиот телефон. Може да дојде до промени во функционалноста на апликацијата.</p>"</string>
<string name="install_failed" msgid="5777824004474125469">"Апликацијата не е инсталирана."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Инсталирањето на пакетот е блокирано."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Апликација што не е инсталирана како пакет е во конфликт со постоечки пакет."</string>
diff --git a/packages/PackageInstaller/res/values-mn/strings.xml b/packages/PackageInstaller/res/values-mn/strings.xml
index 8a86d11..a9365b6 100644
--- a/packages/PackageInstaller/res/values-mn/strings.xml
+++ b/packages/PackageInstaller/res/values-mn/strings.xml
@@ -26,12 +26,9 @@
<string name="install_done" msgid="5987363587661783896">"Аппыг суулгасан."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Та энэ аппыг суулгахыг хүсэж байна уу?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Та энэ аппыг шинэчлэхийг хүсэж байна уу?"</string>
- <!-- no translation found for install_confirm_question_update_owner_reminder (7994800761970572198) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (2435174886412089791) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (7155138616126795839) -->
- <skip />
+ <string name="install_confirm_question_update_owner_reminder" product="tablet" msgid="7994800761970572198">"<p>Энэ аппыг <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g>-с шинэчлэх үү</b>?</p><p>Энэ апп ихэвчлэн <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g>-с шинэчлэлт хүлээн авдаг</b>. Өөр эх сурвалжаас шинэчилснээр та ирээдүйн шинэчлэлтийг таблет дээрх аливаа эх сурвалжаас хүлээн авч магадгүй. Аппын ажиллагаа өөрчлөгдөж магадгүй.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="tv" msgid="2435174886412089791">"<p>Энэ аппыг <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g>-с шинэчлэх үү</b>?</p><p>Энэ апп ихэвчлэн <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g>-с шинэчлэлт хүлээн авдаг</b>. Өөр эх сурвалжаас шинэчилснээр та ирээдүйн шинэчлэлтийг ТВ дээрх аливаа эх сурвалжаас хүлээн авч магадгүй. Аппын ажиллагаа өөрчлөгдөж магадгүй.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="default" msgid="7155138616126795839">"<p>Энэ аппыг <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g>-с шинэчлэх үү</b>?</p><p>Энэ апп ихэвчлэн <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g>-с шинэчлэлт хүлээн авдаг</b>. Өөр эх сурвалжаас шинэчилснээр та ирээдүйн шинэчлэлтийг утсан дээрх аливаа эх сурвалжаас хүлээн авч магадгүй. Аппын ажиллагаа өөрчлөгдөж магадгүй.</p>"</string>
<string name="install_failed" msgid="5777824004474125469">"Аппыг суулгаагүй."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Багц суулгахыг блоклосон байна."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Багц одоо байгаа багцтай тохирохгүй байгаа тул аппыг суулгаж чадсангүй."</string>
diff --git a/packages/PackageInstaller/res/values-mr/strings.xml b/packages/PackageInstaller/res/values-mr/strings.xml
index 81e406c..d6f04b4 100644
--- a/packages/PackageInstaller/res/values-mr/strings.xml
+++ b/packages/PackageInstaller/res/values-mr/strings.xml
@@ -26,12 +26,9 @@
<string name="install_done" msgid="5987363587661783896">"अॅप इंस्टॉल झाले."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"तुम्हाला हे ॲप इंस्टॉल करायचे आहे का?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"तुम्हाला हे ॲप अपडेट करायचे आहे का?"</string>
- <!-- no translation found for install_confirm_question_update_owner_reminder (7994800761970572198) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (2435174886412089791) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (7155138616126795839) -->
- <skip />
+ <string name="install_confirm_question_update_owner_reminder" product="tablet" msgid="7994800761970572198">"<p>हे अॅप<b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>कडून अपडेट करायचे आहे का?</p><p>हे अॅप सामान्यपणे<b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b> कडून अपडेट मिळवते. वेगवेगळ्या स्रोताकडून अपडेट करून, तुम्हाला तुमच्या टॅबलेटवरील कोणत्याही स्रोताकडून भविष्यातील अपडेट मिळू शकतात. अॅपची कार्यक्षमता बदलू शकते.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="tv" msgid="2435174886412089791">"<p>हे अॅप<b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>कडून अपडेट करायचे आहे का?</p><p>हे अॅप सामान्यपणे<b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b> कडून अपडेट मिळवते. वेगवेगळ्या स्रोताकडून अपडेट करून, तुम्हाला तुमच्या टीव्हीवरील कोणत्याही स्रोताकडून भविष्यातील अपडेट मिळू शकतात. अॅपची कार्यक्षमता बदलू शकते.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="default" msgid="7155138616126795839">"<p>हे अॅप<b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>कडून अपडेट करायचे आहे का?</p><p>हे अॅप सामान्यपणे<b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b> कडून अपडेट मिळवते. वेगवेगळ्या स्रोताकडून अपडेट करून, तुम्हाला तुमच्या फोनवरील कोणत्याही स्रोताकडून भविष्यातील अपडेट मिळू शकतात. अॅपची कार्यक्षमता बदलू शकते.</p>"</string>
<string name="install_failed" msgid="5777824004474125469">"अॅप इंस्टॉल झाले नाही."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"पॅकेज इंस्टॉल होण्यापासून ब्लॉक केले होते."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"पॅकेजचा विद्यमान पॅकेजशी विरोध असल्याने अॅप इंस्टॉल झाले नाही."</string>
diff --git a/packages/PackageInstaller/res/values-nb/strings.xml b/packages/PackageInstaller/res/values-nb/strings.xml
index 5919ede..89d9762 100644
--- a/packages/PackageInstaller/res/values-nb/strings.xml
+++ b/packages/PackageInstaller/res/values-nb/strings.xml
@@ -26,12 +26,9 @@
<string name="install_done" msgid="5987363587661783896">"Appen er installert."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Vil du installere denne appen?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Vil du oppdatere denne appen?"</string>
- <!-- no translation found for install_confirm_question_update_owner_reminder (7994800761970572198) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (2435174886412089791) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (7155138616126795839) -->
- <skip />
+ <string name="install_confirm_question_update_owner_reminder" product="tablet" msgid="7994800761970572198">"<p>Vil du oppdatere denne appen fra <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Denne appen mottar vanligvis oppdateringer fra <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Hvis du oppdaterer fra en annen kilde, kan du få fremtidige oppdateringer fra en hvilken som helst kilde på nettbrettet. Appfunksjonaliteten kan endres.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="tv" msgid="2435174886412089791">"<p>Vil du oppdatere denne appen fra <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Denne appen mottar vanligvis oppdateringer fra <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Hvis du oppdaterer fra en annen kilde, kan du få fremtidige oppdateringer fra en hvilken som helst kilde på TV-en. Appfunksjonaliteten kan endres.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="default" msgid="7155138616126795839">"<p>Vil du oppdatere denne appen fra <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Denne appen mottar vanligvis oppdateringer fra <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Hvis du oppdaterer fra en annen kilde, kan du få fremtidige oppdateringer fra en hvilken som helst kilde på telefonen. Appfunksjonaliteten kan endres.</p>"</string>
<string name="install_failed" msgid="5777824004474125469">"Appen ble ikke installert."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Pakken er blokkert fra å bli installert."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Appen ble ikke installert fordi pakken er i konflikt med en eksisterende pakke."</string>
diff --git a/packages/PackageInstaller/res/values-ne/strings.xml b/packages/PackageInstaller/res/values-ne/strings.xml
index 603dfa2..23a689f 100644
--- a/packages/PackageInstaller/res/values-ne/strings.xml
+++ b/packages/PackageInstaller/res/values-ne/strings.xml
@@ -26,12 +26,9 @@
<string name="install_done" msgid="5987363587661783896">"एप इन्स्टल गरियो।"</string>
<string name="install_confirm_question" msgid="7663733664476363311">"तपाईं यो एप इन्स्टल गर्न चाहनुहुन्छ?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"तपाईं यो एप अपडेट गर्न चाहनुहुन्छ?"</string>
- <!-- no translation found for install_confirm_question_update_owner_reminder (7994800761970572198) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (2435174886412089791) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (7155138616126795839) -->
- <skip />
+ <string name="install_confirm_question_update_owner_reminder" product="tablet" msgid="7994800761970572198">"<p><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g> <b>बाट यो एप अपडेट गर्ने हो</b>?</p><p>यो एपले सामान्यतया <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g> बाट अपडेटहरू प्राप्त गर्छ</b>। तपाईंले कुनै फरक स्रोतबाट अपडेट गर्नुभयो भने तपाईं भविष्यमा आफ्नो ट्याब्लेटमा भएको जुनसुकै स्रोतबाट अपडेटहरू प्राप्त गर्न सक्नुहुन्छ। एपका मुख्य सुविधाहरू परिवर्तन हुन सक्छन्।</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="tv" msgid="2435174886412089791">"<p><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g> <b>बाट यो एप अपडेट गर्ने हो</b>?</p><p>यो एपले सामान्यतया <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g> बाट अपडेटहरू प्राप्त गर्छ</b>। तपाईंले कुनै फरक स्रोतबाट अपडेट गर्नुभयो भने तपाईं भविष्यमा आफ्नो टिभीमा भएको जुनसुकै स्रोतबाट अपडेटहरू प्राप्त गर्न सक्नुहुन्छ। एपका मुख्य सुविधाहरू परिवर्तन हुन सक्छन्।</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="default" msgid="7155138616126795839">"<p><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g> <b>बाट यो एप अपडेट गर्ने हो</b>?</p><p>यो एपले सामान्यतया <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g> बाट अपडेटहरू प्राप्त गर्छ</b>। तपाईंले कुनै फरक स्रोतबाट अपडेट गर्नुभयो भने तपाईं भविष्यमा आफ्नो फोनमा भएको जुनसुकै स्रोतबाट अपडेटहरू प्राप्त गर्न सक्नुहुन्छ। एपका मुख्य सुविधाहरू परिवर्तन हुन सक्छन्।</p>"</string>
<string name="install_failed" msgid="5777824004474125469">"एप स्थापना गरिएन।"</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"यो प्याकेज स्थापना गर्ने क्रममा अवरोध गरियो।"</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"प्याकेजका रूपमा स्थापना नगरिएको एप विद्यमान प्याकेजसँग मेल खाँदैन।"</string>
diff --git a/packages/PackageInstaller/res/values-nl/strings.xml b/packages/PackageInstaller/res/values-nl/strings.xml
index d38faaf..731dc48 100644
--- a/packages/PackageInstaller/res/values-nl/strings.xml
+++ b/packages/PackageInstaller/res/values-nl/strings.xml
@@ -26,12 +26,9 @@
<string name="install_done" msgid="5987363587661783896">"App geïnstalleerd."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Wil je deze app installeren?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Wil je deze app updaten?"</string>
- <!-- no translation found for install_confirm_question_update_owner_reminder (7994800761970572198) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (2435174886412089791) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (7155138616126795839) -->
- <skip />
+ <string name="install_confirm_question_update_owner_reminder" product="tablet" msgid="7994800761970572198">"<p>Deze app updaten via <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Deze app krijgt gewoonlijk updates via <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Als je updatet via een andere bron, kun je toekomstige updates via elke bron op je tablet krijgen. De app-functionaliteit kan veranderen.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="tv" msgid="2435174886412089791">"<p>Deze app updaten via <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Deze app krijgt gewoonlijk updates via <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Als je updatet via een andere bron, kun je toekomstige updates via elke bron op je tv krijgen. De app-functionaliteit kan veranderen.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="default" msgid="7155138616126795839">"<p>Deze app updaten via <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Deze app krijgt gewoonlijk updates via <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Als je updatet via een andere bron, kun je toekomstige updates via elke bron op je telefoon krijgen. De app-functionaliteit kan veranderen.</p>"</string>
<string name="install_failed" msgid="5777824004474125469">"App niet geïnstalleerd."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"De installatie van het pakket is geblokkeerd."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"App die niet is geïnstalleerd als pakket conflicteert met een bestaand pakket."</string>
diff --git a/packages/PackageInstaller/res/values-or/strings.xml b/packages/PackageInstaller/res/values-or/strings.xml
index 8eb81e5..331852e1 100644
--- a/packages/PackageInstaller/res/values-or/strings.xml
+++ b/packages/PackageInstaller/res/values-or/strings.xml
@@ -26,12 +26,9 @@
<string name="install_done" msgid="5987363587661783896">"ଆପ ଇନଷ୍ଟଲ ହୋଇଗଲା।"</string>
<string name="install_confirm_question" msgid="7663733664476363311">"ଆପଣ ଏହି ଆପକୁ ଇନଷ୍ଟଲ୍ କରିବା ପାଇଁ ଚାହୁଁଛନ୍ତି କି?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"ଆପଣ ଏହି ଆପକୁ ଅପଡେଟ୍ କରିବା ପାଇଁ ଚାହୁଁଛନ୍ତି କି?"</string>
- <!-- no translation found for install_confirm_question_update_owner_reminder (7994800761970572198) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (2435174886412089791) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (7155138616126795839) -->
- <skip />
+ <string name="install_confirm_question_update_owner_reminder" product="tablet" msgid="7994800761970572198">"<p><b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>ରୁ ଏହି ଆପକୁ ଅପଡେଟ କରିବେ?</p><p>ଏହି ଆପ ସାଧାରଣତଃ <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>ରୁ ଅପଡେଟ ପାଇଥାଏ। ଏକ ଭିନ୍ନ ସୋର୍ସରୁ ଅପଡେଟ କରି ଆପଣ ଆପଣଙ୍କ ଟାବଲେଟରେ ଯେ କୌଣସି ସୋର୍ସରୁ ଭବିଷ୍ୟତର ଅପଡେଟଗୁଡ଼ିକ ପାଇପାରନ୍ତି। ଆପ କାର୍ଯ୍ୟକ୍ଷମତା ପରିବର୍ତ୍ତନ ହୋଇପାରେ।</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="tv" msgid="2435174886412089791">"<p><b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>ରୁ ଏହି ଆପକୁ ଅପଡେଟ କରିବେ?</p><p>ଏହି ଆପ ସାଧାରଣତଃ <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>ରୁ ଅପଡେଟ ପାଇଥାଏ। ଏକ ଭିନ୍ନ ସୋର୍ସରୁ ଅପଡେଟ କରି ଆପଣ ଆପଣଙ୍କ ଟିଭିରେ ଯେ କୌଣସି ସୋର୍ସରୁ ଭବିଷ୍ୟତର ଅପଡେଟଗୁଡ଼ିକ ପାଇପାରନ୍ତି। ଆପ କାର୍ଯ୍ୟକ୍ଷମତା ପରିବର୍ତ୍ତନ ହୋଇପାରେ।</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="default" msgid="7155138616126795839">"<p><b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>ରୁ ଏହି ଆପକୁ ଅପଡେଟ କରିବେ?</p><p>ଏହି ଆପ ସାଧାରଣତଃ <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>ରୁ ଅପଡେଟ ପାଇଥାଏ। ଏକ ଭିନ୍ନ ସୋର୍ସରୁ ଅପଡେଟ କରି ଆପଣ ଆପଣଙ୍କ ଫୋନରେ ଯେ କୌଣସି ସୋର୍ସରୁ ଭବିଷ୍ୟତର ଅପଡେଟଗୁଡ଼ିକ ପାଇପାରନ୍ତି। ଆପ କାର୍ଯ୍ୟକ୍ଷମତା ପରିବର୍ତ୍ତନ ହୋଇପାରେ।</p>"</string>
<string name="install_failed" msgid="5777824004474125469">"ଆପ୍ ଇନଷ୍ଟଲ୍ ହୋଇନାହିଁ।"</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"ଏହି ପ୍ୟାକେଜ୍କୁ ଇନଷ୍ଟଲ୍ କରାଯିବାରୁ ଅବରୋଧ କରାଯାଇଥିଲା।"</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"ପୂର୍ବରୁ ଥିବା ପ୍ୟାକେଜ୍ ସହ ଏହି ପ୍ୟାକେଜ୍ର ସମସ୍ୟା ଉପୁଯିବାରୁ ଆପ୍ ଇନଷ୍ଟଲ୍ ହୋଇପାରିଲା ନାହିଁ।"</string>
diff --git a/packages/PackageInstaller/res/values-pa/strings.xml b/packages/PackageInstaller/res/values-pa/strings.xml
index 78a2342..5bc4624 100644
--- a/packages/PackageInstaller/res/values-pa/strings.xml
+++ b/packages/PackageInstaller/res/values-pa/strings.xml
@@ -26,12 +26,9 @@
<string name="install_done" msgid="5987363587661783896">"ਐਪ ਸਥਾਪਤ ਕੀਤੀ ਗਈ।"</string>
<string name="install_confirm_question" msgid="7663733664476363311">"ਕੀ ਤੁਸੀਂ ਇਸ ਐਪ ਨੂੰ ਸਥਾਪਤ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"ਕੀ ਤੁਸੀਂ ਇਸ ਐਪ ਨੂੰ ਅੱਪਡੇਟ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ?"</string>
- <!-- no translation found for install_confirm_question_update_owner_reminder (7994800761970572198) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (2435174886412089791) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (7155138616126795839) -->
- <skip />
+ <string name="install_confirm_question_update_owner_reminder" product="tablet" msgid="7994800761970572198">"<p>ਕੀ ਇਸ ਐਪ ਨੂੰ <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b> ਤੋਂ ਅੱਪਡੇਟ ਕਰਨਾ ਹੈ?</p><p>ਇਹ ਐਪ ਆਮ ਤੌਰ \'ਤੇ <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b> ਤੋਂ ਅੱਪਡੇਟਾਂ ਪ੍ਰਾਪਤ ਕਰਦੀ ਹੈ। ਕਿਸੇ ਵੱਖਰੇ ਸਰੋਤ ਤੋਂ ਅੱਪਡੇਟ ਕਰ ਕੇ, ਤੁਸੀਂ ਆਪਣੇ ਟੈਬਲੈੱਟ \'ਤੇ ਕਿਸੇ ਵੀ ਸਰੋਤ ਤੋਂ ਭਵਿੱਖੀ ਅੱਪਡੇਟਾਂ ਪ੍ਰਾਪਤ ਕਰ ਸਕਦੇ ਹੋ। ਐਪ ਪ੍ਰਕਾਰਜਾਤਮਕਤਾ ਬਦਲ ਸਕਦੀ ਹੈ।</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="tv" msgid="2435174886412089791">"<p>ਕੀ ਇਸ ਐਪ ਨੂੰ <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b> ਤੋਂ ਅੱਪਡੇਟ ਕਰਨਾ ਹੈ?</p><p>ਇਹ ਐਪ ਆਮ ਤੌਰ \'ਤੇ <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b> ਤੋਂ ਅੱਪਡੇਟਾਂ ਪ੍ਰਾਪਤ ਕਰਦੀ ਹੈ। ਕਿਸੇ ਵੱਖਰੇ ਸਰੋਤ ਤੋਂ ਅੱਪਡੇਟ ਕਰ ਕੇ, ਤੁਸੀਂ ਆਪਣੇ ਟੀਵੀ \'ਤੇ ਕਿਸੇ ਵੀ ਸਰੋਤ ਤੋਂ ਭਵਿੱਖੀ ਅੱਪਡੇਟਾਂ ਪ੍ਰਾਪਤ ਕਰ ਸਕਦੇ ਹੋ। ਐਪ ਪ੍ਰਕਾਰਜਾਤਮਕਤਾ ਬਦਲ ਸਕਦੀ ਹੈ।</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="default" msgid="7155138616126795839">"<p>ਕੀ ਇਸ ਐਪ ਨੂੰ <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b> ਤੋਂ ਅੱਪਡੇਟ ਕਰਨਾ ਹੈ?</p><p>ਇਹ ਐਪ ਆਮ ਤੌਰ \'ਤੇ <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b> ਤੋਂ ਅੱਪਡੇਟਾਂ ਪ੍ਰਾਪਤ ਕਰਦੀ ਹੈ। ਕਿਸੇ ਵੱਖਰੇ ਸਰੋਤ ਤੋਂ ਅੱਪਡੇਟ ਕਰ ਕੇ, ਤੁਸੀਂ ਆਪਣੇ ਫ਼ੋਨ \'ਤੇ ਕਿਸੇ ਵੀ ਸਰੋਤ ਤੋਂ ਭਵਿੱਖੀ ਅੱਪਡੇਟਾਂ ਪ੍ਰਾਪਤ ਕਰ ਸਕਦੇ ਹੋ। ਐਪ ਪ੍ਰਕਾਰਜਾਤਮਕਤਾ ਬਦਲ ਸਕਦੀ ਹੈ।</p>"</string>
<string name="install_failed" msgid="5777824004474125469">"ਐਪ ਸਥਾਪਤ ਨਹੀਂ ਕੀਤੀ ਗਈ।"</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"ਪੈਕੇਜ ਨੂੰ ਸਥਾਪਤ ਹੋਣ ਤੋਂ ਬਲਾਕ ਕੀਤਾ ਗਿਆ ਸੀ।"</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"ਪੈਕੇਜ ਦੇ ਇੱਕ ਮੌਜੂਦਾ ਪੈਕੇਜ ਨਾਲ ਵਿਵਾਦ ਹੋਣ ਕਰਕੇ ਐਪ ਸਥਾਪਤ ਨਹੀਂ ਕੀਤੀ ਗਈ।"</string>
diff --git a/packages/PackageInstaller/res/values-pl/strings.xml b/packages/PackageInstaller/res/values-pl/strings.xml
index 6adb37f..4aa96f7 100644
--- a/packages/PackageInstaller/res/values-pl/strings.xml
+++ b/packages/PackageInstaller/res/values-pl/strings.xml
@@ -26,12 +26,9 @@
<string name="install_done" msgid="5987363587661783896">"Aplikacja została zainstalowana."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Zainstalować tę aplikację?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Zaktualizować tę aplikację?"</string>
- <!-- no translation found for install_confirm_question_update_owner_reminder (7994800761970572198) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (2435174886412089791) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (7155138616126795839) -->
- <skip />
+ <string name="install_confirm_question_update_owner_reminder" product="tablet" msgid="7994800761970572198">"<p>Zaktualizować tę aplikację, korzystając z: <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Aktualizacje tej aplikacji pochodzą zwykle z: <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Jeśli zastosujesz aktualizację pochodzącą z innego źródła, możesz w przyszłości otrzymywać na tablecie aktualizacje z dowolnych źródeł. Funkcje aplikacji mogą ulec zmianie.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="tv" msgid="2435174886412089791">"<p>Zaktualizować tę aplikację, korzystając z: <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Aktualizacje tej aplikacji pochodzą zwykle z: <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Jeśli zastosujesz aktualizację pochodzącą z innego źródła, możesz w przyszłości otrzymywać na telewizorze aktualizacje z dowolnych źródeł. Funkcje aplikacji mogą ulec zmianie.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="default" msgid="7155138616126795839">"<p>Zaktualizować tę aplikację, korzystając z: <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Aktualizacje tej aplikacji pochodzą zwykle z: <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Jeśli zastosujesz aplikację pochodzącą z innego źródła, możesz w przyszłości otrzymywać na telefonie aktualizacje z dowolnych źródeł. Funkcje aplikacji mogą ulec zmianie.</p>"</string>
<string name="install_failed" msgid="5777824004474125469">"Aplikacja nie została zainstalowana."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Instalacja pakietu została zablokowana."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Aplikacja nie została zainstalowana, bo powoduje konflikt z istniejącym pakietem."</string>
diff --git a/packages/PackageInstaller/res/values-pt-rBR/strings.xml b/packages/PackageInstaller/res/values-pt-rBR/strings.xml
index d4aae75..d8713db 100644
--- a/packages/PackageInstaller/res/values-pt-rBR/strings.xml
+++ b/packages/PackageInstaller/res/values-pt-rBR/strings.xml
@@ -26,12 +26,9 @@
<string name="install_done" msgid="5987363587661783896">"App instalado."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Quer instalar esse app?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Quer atualizar esse app?"</string>
- <!-- no translation found for install_confirm_question_update_owner_reminder (7994800761970572198) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (2435174886412089791) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (7155138616126795839) -->
- <skip />
+ <string name="install_confirm_question_update_owner_reminder" product="tablet" msgid="7994800761970572198">"<p>Atualizar este app de <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Este app costuma receber atualizações de <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Ao usar uma fonte diferente, as próximas atualizações poderão ser feitas com qualquer fonte no tablet. A funcionalidade do app pode mudar.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="tv" msgid="2435174886412089791">"<p>Atualizar este app de <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Este app costuma receber atualizações de <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Ao usar uma fonte diferente, as próximas atualizações poderão ser feitas com qualquer fonte na TV. A funcionalidade do app pode mudar.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="default" msgid="7155138616126795839">"<p>Atualizar este app de <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Este app costuma receber atualizações de <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Ao atualizar usando uma origem diferente, as próximas atualizações poderão ser feitas com qualquer origem no seu smartphone. A funcionalidade do app pode mudar.</p>"</string>
<string name="install_failed" msgid="5777824004474125469">"O app não foi instalado."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"A instalação do pacote foi bloqueada."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Como o pacote tem um conflito com um pacote já existente, o app não foi instalado."</string>
diff --git a/packages/PackageInstaller/res/values-pt/strings.xml b/packages/PackageInstaller/res/values-pt/strings.xml
index d4aae75..d8713db 100644
--- a/packages/PackageInstaller/res/values-pt/strings.xml
+++ b/packages/PackageInstaller/res/values-pt/strings.xml
@@ -26,12 +26,9 @@
<string name="install_done" msgid="5987363587661783896">"App instalado."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Quer instalar esse app?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Quer atualizar esse app?"</string>
- <!-- no translation found for install_confirm_question_update_owner_reminder (7994800761970572198) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (2435174886412089791) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (7155138616126795839) -->
- <skip />
+ <string name="install_confirm_question_update_owner_reminder" product="tablet" msgid="7994800761970572198">"<p>Atualizar este app de <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Este app costuma receber atualizações de <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Ao usar uma fonte diferente, as próximas atualizações poderão ser feitas com qualquer fonte no tablet. A funcionalidade do app pode mudar.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="tv" msgid="2435174886412089791">"<p>Atualizar este app de <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Este app costuma receber atualizações de <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Ao usar uma fonte diferente, as próximas atualizações poderão ser feitas com qualquer fonte na TV. A funcionalidade do app pode mudar.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="default" msgid="7155138616126795839">"<p>Atualizar este app de <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Este app costuma receber atualizações de <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Ao atualizar usando uma origem diferente, as próximas atualizações poderão ser feitas com qualquer origem no seu smartphone. A funcionalidade do app pode mudar.</p>"</string>
<string name="install_failed" msgid="5777824004474125469">"O app não foi instalado."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"A instalação do pacote foi bloqueada."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Como o pacote tem um conflito com um pacote já existente, o app não foi instalado."</string>
diff --git a/packages/PackageInstaller/res/values-ru/strings.xml b/packages/PackageInstaller/res/values-ru/strings.xml
index 2c9888b..094a19a 100644
--- a/packages/PackageInstaller/res/values-ru/strings.xml
+++ b/packages/PackageInstaller/res/values-ru/strings.xml
@@ -26,12 +26,9 @@
<string name="install_done" msgid="5987363587661783896">"Приложение установлено."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Установить приложение?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Обновить приложение?"</string>
- <!-- no translation found for install_confirm_question_update_owner_reminder (7994800761970572198) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (2435174886412089791) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (7155138616126795839) -->
- <skip />
+ <string name="install_confirm_question_update_owner_reminder" product="tablet" msgid="7994800761970572198">"<p>Обновить приложение из <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Обычно это приложение получает обновления из <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Если обновить приложение из другого источника, в будущем для обновления могут использоваться любые источники на планшете. Функции приложения могут измениться.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="tv" msgid="2435174886412089791">"<p>Обновить приложение из <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Обычно это приложение получает обновления из <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Если обновить приложение из другого источника, в будущем для обновления могут использоваться любые источники на телевизоре. Функции приложения могут измениться.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="default" msgid="7155138616126795839">"<p>Обновить приложение из <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Обычно это приложение получает обновления из <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Если обновить приложение из другого источника, в будущем для обновления могут использоваться любые источники на телефоне. Функции приложения могут измениться.</p>"</string>
<string name="install_failed" msgid="5777824004474125469">"Приложение не установлено."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Установка пакета заблокирована."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Приложение не установлено, так как оно конфликтует с другим пакетом."</string>
diff --git a/packages/PackageInstaller/res/values-si/strings.xml b/packages/PackageInstaller/res/values-si/strings.xml
index 8486644..afc2195 100644
--- a/packages/PackageInstaller/res/values-si/strings.xml
+++ b/packages/PackageInstaller/res/values-si/strings.xml
@@ -26,12 +26,9 @@
<string name="install_done" msgid="5987363587661783896">"යෙදුම ස්ථාපනය කර ඇත."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"මෙම යෙදුම ස්ථාපනය කිරීමට ඔබට අවශ්යද?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"ඔබට මෙම යෙදුම යාවත්කාලීන කිරීමට අවශ්යද?"</string>
- <!-- no translation found for install_confirm_question_update_owner_reminder (7994800761970572198) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (2435174886412089791) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (7155138616126795839) -->
- <skip />
+ <string name="install_confirm_question_update_owner_reminder" product="tablet" msgid="7994800761970572198">"<p>මෙම යෙදුම <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>වෙතින් යාවත්කාලීන කරන්න ද?</p><p>මෙම යෙදුම සාමාන්යයෙන් <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b> වෙතින් යාවත්කාලීන ලබා ගනී. වෙනස් මූලාශ්රයකින් යාවත්කාලීන කිරීමෙන්, ඔබට ඔබේ ටැබ්ලටයෙහි ඕනෑම මූලාශ්රයකින් අනාගත යාවත්කාලීන ලැබීමට ඉඩ ඇත. යෙදුම් ක්රියාකාරිත්වය වෙනස් විය හැක.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="tv" msgid="2435174886412089791">"<p>මෙම යෙදුම <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>වෙතින් යාවත්කාලීන කරන්න ද?</p><p>මෙම යෙදුම සාමාන්යයෙන් <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b> වෙතින් යාවත්කාලීන ලබා ගනී. වෙනස් මූලාශ්රයකින් යාවත්කාලීන කිරීමෙන්, ඔබට ඔබේ TV මත ඕනෑම මූලාශ්රයකින් අනාගත යාවත්කාලීන ලැබීමට ඉඩ ඇත. යෙදුම් ක්රියාකාරිත්වය වෙනස් විය හැක.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="default" msgid="7155138616126795839">"<p>මෙම යෙදුම <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>වෙතින් යාවත්කාලීන කරන්න ද?</p><p>මෙම යෙදුම සාමාන්යයෙන් <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b> වෙතින් යාවත්කාලීන ලබා ගනී. වෙනස් මූලාශ්රයකින් යාවත්කාලීන කිරීමෙන්, ඔබට ඔබේ දුරකථනයෙහි ඕනෑම මූලාශ්රයකින් අනාගත යාවත්කාලීන ලැබීමට ඉඩ ඇත. යෙදුම් ක්රියාකාරිත්වය වෙනස් විය හැක.</p>"</string>
<string name="install_failed" msgid="5777824004474125469">"යෙදුම ස්ථාපනය කර නැත."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"මෙම පැකේජය ස්ථාපනය කිරීම අවහිර කරන ලදි."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"පැකේජය දැනට පවතින පැකේජයක් සමග ගැටෙන නිසා යෙදුම ස්ථාපනය නොකරන ලදී."</string>
diff --git a/packages/PackageInstaller/res/values-sk/strings.xml b/packages/PackageInstaller/res/values-sk/strings.xml
index ed3ca7e..7a1e70c 100644
--- a/packages/PackageInstaller/res/values-sk/strings.xml
+++ b/packages/PackageInstaller/res/values-sk/strings.xml
@@ -26,12 +26,9 @@
<string name="install_done" msgid="5987363587661783896">"Aplikácia bola nainštalovaná."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Chcete túto aplikáciu nainštalovať?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Chcete túto aplikáciu aktualizovať?"</string>
- <!-- no translation found for install_confirm_question_update_owner_reminder (7994800761970572198) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (2435174886412089791) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (7155138616126795839) -->
- <skip />
+ <string name="install_confirm_question_update_owner_reminder" product="tablet" msgid="7994800761970572198">"<p>Aktualizujte túto aplikáciu zo zdroja <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Obvykle dostáva aktualizácie zo zdroja <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Ak aktualizujete z iného zdroja, môžete v budúcnosti dostávať aktualizácie z ľubovoľného zdroja v tablete. Funkcie aplikácie sa môžu zmeniť.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="tv" msgid="2435174886412089791">"<p>Aktualizujte túto aplikáciu zo zdroja <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Obvykle dostáva aktualizácie zo zdroja <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Ak aktualizujete z iného zdroja, môžete v budúcnosti dostávať aktualizácie z ľubovoľného zdroja v televízore. Funkcie aplikácie sa môžu zmeniť.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="default" msgid="7155138616126795839">"<p>Aktualizujte túto aplikáciu zo zdroja <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Obvykle dostáva aktualizácie zo zdroja <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Ak aktualizujete z iného zdroja, môžete v budúcnosti dostávať aktualizácie z ľubovoľného zdroja v telefóne. Funkcie aplikácie sa môžu zmeniť.</p>"</string>
<string name="install_failed" msgid="5777824004474125469">"Aplikácia nebola nainštalovaná."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Inštalácia balíka bola zablokovaná."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Aplikácia sa nenainštalovala, pretože balík je v konflikte s existujúcim balíkom."</string>
diff --git a/packages/PackageInstaller/res/values-sq/strings.xml b/packages/PackageInstaller/res/values-sq/strings.xml
index ba16e06..566054ed 100644
--- a/packages/PackageInstaller/res/values-sq/strings.xml
+++ b/packages/PackageInstaller/res/values-sq/strings.xml
@@ -26,12 +26,9 @@
<string name="install_done" msgid="5987363587661783896">"Aplikacioni u instalua."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Dëshiron ta instalosh këtë aplikacion?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Dëshiron ta përditësosh këtë aplikacion?"</string>
- <!-- no translation found for install_confirm_question_update_owner_reminder (7994800761970572198) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (2435174886412089791) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (7155138616126795839) -->
- <skip />
+ <string name="install_confirm_question_update_owner_reminder" product="tablet" msgid="7994800761970572198">"<p>Përditëso këtë aplikacion nga <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Ky aplikacion zakonisht merr përditësime nga <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Duke përditësuar nga një burim tjetër, mund të marrësh përditësime të ardhshme nga çdo burim në tabletin tënd. Funksionaliteti i aplikacionit mund të ndryshojë.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="tv" msgid="2435174886412089791">"<p>Përditëso këtë aplikacion nga <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Ky aplikacion zakonisht merr përditësime nga <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Duke përditësuar nga një burim tjetër, mund të marrësh përditësime të ardhshme nga çdo burim në televizorin tënd. Funksionaliteti i aplikacionit mund të ndryshojë.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="default" msgid="7155138616126795839">"<p>Përditëso këtë aplikacion nga <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Ky aplikacion zakonisht merr përditësime nga <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Duke përditësuar nga një burim tjetër, mund të marrësh përditësime të ardhshme nga çdo burim në telefonin tënd. Funksionaliteti i aplikacionit mund të ndryshojë.</p>"</string>
<string name="install_failed" msgid="5777824004474125469">"Aplikacioni nuk u instalua."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Instalimi paketës u bllokua."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Aplikacioni nuk u instalua pasi paketa është në konflikt me një paketë ekzistuese."</string>
diff --git a/packages/PackageInstaller/res/values-sv/strings.xml b/packages/PackageInstaller/res/values-sv/strings.xml
index 524b2c7..79e5738 100644
--- a/packages/PackageInstaller/res/values-sv/strings.xml
+++ b/packages/PackageInstaller/res/values-sv/strings.xml
@@ -26,12 +26,9 @@
<string name="install_done" msgid="5987363587661783896">"Appen har installerats."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Vill du installera den här appen?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Vill du uppdatera den här appen?"</string>
- <!-- no translation found for install_confirm_question_update_owner_reminder (7994800761970572198) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (2435174886412089791) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (7155138616126795839) -->
- <skip />
+ <string name="install_confirm_question_update_owner_reminder" product="tablet" msgid="7994800761970572198">"<p>Uppdatera appen från <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Appen får vanligtvis uppdateringar från <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Om du uppdaterar från en annan källa kanske du får framtida uppdateringar från olika källor på surfplattan. Appfunktionerna kanske ändras.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="tv" msgid="2435174886412089791">"<p>Uppdatera appen från <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Appen får vanligtvis uppdateringar från <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Om du uppdaterar från en annan källa kanske du får framtida uppdateringar från olika källor på tv:n. Appfunktionerna kanske ändras.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="default" msgid="7155138616126795839">"<p>Uppdatera appen från <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Appen får vanligtvis uppdateringar från <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Om du uppdaterar från en annan källa kanske du får framtida uppdateringar från olika källor på telefonen. Appfunktionerna kanske ändras.</p>"</string>
<string name="install_failed" msgid="5777824004474125469">"Appen har inte installerats."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Paketet har blockerats för installation."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Appen har inte installerats på grund av en konflikt mellan detta paket och ett befintligt paket."</string>
diff --git a/packages/PackageInstaller/res/values-sw/strings.xml b/packages/PackageInstaller/res/values-sw/strings.xml
index f51a881..f69d612 100644
--- a/packages/PackageInstaller/res/values-sw/strings.xml
+++ b/packages/PackageInstaller/res/values-sw/strings.xml
@@ -26,12 +26,9 @@
<string name="install_done" msgid="5987363587661783896">"Imesakinisha programu."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Ungependa kusakinisha programu hii?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Ungependa kusasisha programu hii?"</string>
- <!-- no translation found for install_confirm_question_update_owner_reminder (7994800761970572198) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (2435174886412089791) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (7155138616126795839) -->
- <skip />
+ <string name="install_confirm_question_update_owner_reminder" product="tablet" msgid="7994800761970572198">"<p>Sasisha programu hii kutoka kwenye <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Programu hii hupokea masasisho kutoka kwenye <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Kwa kusasisha kutoka kwenye chanzo tofauti, unaweza kupokea masasisho ya baadaye kutoka kwenye chanzo chochote katika kishikwambi chako. Huenda utendaji wa programu ukabadilika.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="tv" msgid="2435174886412089791">"<p>Sasisha programu hii kutoka kwenye <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Programu hii hupokea masasisho kutoka kwenye <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Kwa kusasisha kutoka kwenye chanzo tofauti, unaweza kupokea masasisho ya baadaye kutoka kwenye chanzo chochote katika TV yako. Huenda utendaji wa programu ukabadilika.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="default" msgid="7155138616126795839">"<p>Sasisha programu hii kutoka kwenye <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Programu hii hupokea masasisho kutoka kwenye <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Kwa kusasisha kutoka kwenye chanzo tofauti, unaweza kupokea masasisho ya baadaye kutoka kwenye chanzo chochote katika simu yako. Huenda utendaji wa programu ukabadilika.</p>"</string>
<string name="install_failed" msgid="5777824004474125469">"Imeshindwa kusakinisha programu."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Kifurushi kimezuiwa kisisakinishwe."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Programu haikusakinishwa kwa sababu kifurushi kinakinzana na kifurushi kingine kilichopo."</string>
diff --git a/packages/PackageInstaller/res/values-ta/strings.xml b/packages/PackageInstaller/res/values-ta/strings.xml
index 2a4929c..f2d5463 100644
--- a/packages/PackageInstaller/res/values-ta/strings.xml
+++ b/packages/PackageInstaller/res/values-ta/strings.xml
@@ -26,12 +26,9 @@
<string name="install_done" msgid="5987363587661783896">"ஆப்ஸ் நிறுவப்பட்டது."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"இந்த ஆப்ஸை நிறுவ வேண்டுமா?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"இந்த ஆப்ஸைப் புதுப்பிக்க வேண்டுமா?"</string>
- <!-- no translation found for install_confirm_question_update_owner_reminder (7994800761970572198) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (2435174886412089791) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (7155138616126795839) -->
- <skip />
+ <string name="install_confirm_question_update_owner_reminder" product="tablet" msgid="7994800761970572198">"<p><b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b> இல் இருந்து இந்த ஆப்ஸைப் புதுப்பிக்க வேண்டுமா?</p><p>பொதுவாக இந்த ஆப்ஸ் <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b> இல் இருந்து புதுப்பிப்புகளைப் பெறும். வேறு உரிமையாளர் மூலம் புதுப்பித்தால் எதிர்காலத்தில் டேப்லெட்டில் இடம்பெற்றுள்ள எந்த உரிமையாளரிடம் இருந்தும் புதுப்பிப்புகளைப் பெறக்கூடும். ஆப்ஸ் செயல்பாடுகள் மாறுபடக்கூடும்.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="tv" msgid="2435174886412089791">"<p><b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b> இல் இருந்து இந்த ஆப்ஸைப் புதுப்பிக்க வேண்டுமா?</p><p>பொதுவாக இந்த ஆப்ஸ் <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b> இல் இருந்து புதுப்பிப்புகளைப் பெறும். வேறு உரிமையாளர் மூலம் புதுப்பித்தால் எதிர்காலத்தில் டிவியில் இடம்பெற்றுள்ள எந்த உரிமையாளரிடம் இருந்தும் புதுப்பிப்புகளைப் பெறக்கூடும். ஆப்ஸ் செயல்பாடுகள் மாறுபடக்கூடும்.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="default" msgid="7155138616126795839">"<p><b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b> இல் இருந்து இந்த ஆப்ஸைப் புதுப்பிக்க வேண்டுமா?</p><p>பொதுவாக இந்த ஆப்ஸ் <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b> இல் இருந்து புதுப்பிப்புகளைப் பெறும். வேறு உரிமையாளர் மூலம் புதுப்பித்தால் எதிர்காலத்தில் மொபைலில் இடம்பெற்றுள்ள எந்த உரிமையாளரிடம் இருந்தும் புதுப்பிப்புகளைப் பெறக்கூடும். ஆப்ஸ் செயல்பாடுகள் மாறுபடக்கூடும்.</p>"</string>
<string name="install_failed" msgid="5777824004474125469">"ஆப்ஸ் நிறுவப்படவில்லை."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"இந்தத் தொகுப்பு நிறுவப்படுவதிலிருந்து தடுக்கப்பட்டது."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"இந்தத் தொகுப்பு ஏற்கனவே உள்ள தொகுப்புடன் முரண்படுவதால் ஆப்ஸ் நிறுவப்படவில்லை."</string>
diff --git a/packages/PackageInstaller/res/values-th/strings.xml b/packages/PackageInstaller/res/values-th/strings.xml
index 1206794..35a7611 100644
--- a/packages/PackageInstaller/res/values-th/strings.xml
+++ b/packages/PackageInstaller/res/values-th/strings.xml
@@ -26,12 +26,9 @@
<string name="install_done" msgid="5987363587661783896">"ติดตั้งแอปแล้ว"</string>
<string name="install_confirm_question" msgid="7663733664476363311">"คุณต้องการติดตั้งแอปนี้ไหม"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"คุณต้องการอัปเดตแอปนี้ไหม"</string>
- <!-- no translation found for install_confirm_question_update_owner_reminder (7994800761970572198) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (2435174886412089791) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (7155138616126795839) -->
- <skip />
+ <string name="install_confirm_question_update_owner_reminder" product="tablet" msgid="7994800761970572198">"<p>อัปเดตแอปนี้จาก <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b> ไหม</p><p>โดยปกติแล้ว แอปนี้จะได้รับการอัปเดตจาก <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b> การอัปเดตจากแหล่งที่มาอื่นอาจทำให้แท็บเล็ตของคุณได้รับการอัปเดตจากแหล่งที่มานั้นในอนาคต ซึ่งอาจทำให้ฟังก์ชันการทำงานของแอปเปลี่ยนแปลงไป</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="tv" msgid="2435174886412089791">"<p>อัปเดตแอปนี้จาก <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b> ไหม</p><p>โดยปกติแล้ว แอปนี้จะได้รับการอัปเดตจาก <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b> การอัปเดตจากแหล่งที่มาอื่นอาจทำให้ทีวีของคุณได้รับการอัปเดตจากแหล่งที่มานั้นในอนาคต ซึ่งอาจทำให้ฟังก์ชันการทำงานของแอปเปลี่ยนแปลงไป</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="default" msgid="7155138616126795839">"<p>อัปเดตแอปนี้จาก <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b> ไหม</p><p>โดยปกติแล้ว แอปนี้จะได้รับการอัปเดตจาก <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b> การอัปเดตจากแหล่งที่มาอื่นอาจทำให้โทรศัพท์ของคุณได้รับการอัปเดตจากแหล่งที่มานั้นในอนาคต ซึ่งอาจทำให้ฟังก์ชันการทำงานของแอปเปลี่ยนแปลงไป</p>"</string>
<string name="install_failed" msgid="5777824004474125469">"ไม่ได้ติดตั้งแอป"</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"มีการบล็อกแพ็กเกจไม่ให้ติดตั้ง"</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"ไม่ได้ติดตั้งแอปเพราะแพ็กเกจขัดแย้งกับแพ็กเกจที่มีอยู่"</string>
diff --git a/packages/PackageInstaller/res/values-tl/strings.xml b/packages/PackageInstaller/res/values-tl/strings.xml
index ad8e900..78a1b2b 100644
--- a/packages/PackageInstaller/res/values-tl/strings.xml
+++ b/packages/PackageInstaller/res/values-tl/strings.xml
@@ -26,12 +26,9 @@
<string name="install_done" msgid="5987363587661783896">"Na-install na ang app."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Gusto mo bang i-install ang app na ito?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Gusto mo bang i-update ang app na ito?"</string>
- <!-- no translation found for install_confirm_question_update_owner_reminder (7994800761970572198) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (2435174886412089791) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (7155138616126795839) -->
- <skip />
+ <string name="install_confirm_question_update_owner_reminder" product="tablet" msgid="7994800761970572198">"<p>I-update ang app na ito mula sa <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Karaniwang nakakatanggap ng mga update ang app na ito mula sa <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Sa pamamagitan ng pag-update mula sa ibang source, puwede kang makatanggap ng mga update mula sa anumang source sa iyong tablet sa hinaharap. Posibleng magbago ang functionality ng app.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="tv" msgid="2435174886412089791">"<p>I-update ang app na ito mula sa <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Karaniwang nakakatanggap ng mga update ang app na ito mula sa <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Sa pamamagitan ng pag-update mula sa ibang source, puwede kang makatanggap ng mga update mula sa anumang source sa iyong TV sa hinaharap. Posibleng magbago ang functionality ng app.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="default" msgid="7155138616126795839">"<p>I-update ang app na ito mula sa <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Karaniwang nakakatanggap ng mga update ang app na ito mula sa <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Sa pamamagitan ng pag-update mula sa ibang source, puwede kang makatanggap ng mga update mula sa anumang source sa iyong telepono sa hinaharap. Posibleng magbago ang functionality ng app.</p>"</string>
<string name="install_failed" msgid="5777824004474125469">"Hindi na-install ang app."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Na-block ang pag-install sa package."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Hindi na-install ang app dahil nagkakaproblema ang package sa isang dati nang package."</string>
diff --git a/packages/PackageInstaller/res/values-tr/strings.xml b/packages/PackageInstaller/res/values-tr/strings.xml
index 259b92a..a34765c 100644
--- a/packages/PackageInstaller/res/values-tr/strings.xml
+++ b/packages/PackageInstaller/res/values-tr/strings.xml
@@ -26,12 +26,9 @@
<string name="install_done" msgid="5987363587661783896">"Uygulama yüklendi."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Bu uygulamayı yüklemek istiyor musunuz?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Bu uygulamayı güncellemek istiyor musunuz?"</string>
- <!-- no translation found for install_confirm_question_update_owner_reminder (7994800761970572198) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (2435174886412089791) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (7155138616126795839) -->
- <skip />
+ <string name="install_confirm_question_update_owner_reminder" product="tablet" msgid="7994800761970572198">"<p>Bu uygulama <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b> kaynağından güncellensin mi?</p><p>Bu uygulama genellikle <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b> kaynağından güncelleme alır. Farklı bir kaynaktan güncellerseniz ileride tabletinizde herhangi bir kaynaktan güncelleme alabilirsiniz. Uygulama işlevselliği değişebilir.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="tv" msgid="2435174886412089791">"<p>Bu uygulama <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b> kaynağından güncellensin mi?</p><p>Bu uygulama genellikle <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b> kaynağından güncelleme alır. Farklı bir kaynaktan güncellerseniz ileride televizyonunuzda herhangi bir kaynaktan güncelleme alabilirsiniz. Uygulama işlevselliği değişebilir.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="default" msgid="7155138616126795839">"<p>Bu uygulama <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b> kaynağından güncellensin mi?</p><p>Bu uygulama genellikle <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b> kaynağından güncelleme alır. Farklı bir kaynaktan güncellerseniz ileride telefonunuzda herhangi bir kaynaktan güncelleme alabilirsiniz. Uygulama işlevselliği değişebilir.</p>"</string>
<string name="install_failed" msgid="5777824004474125469">"Uygulama yüklenmedi."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Paketin yüklemesi engellendi."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Paket, mevcut bir paketle çakıştığından uygulama yüklenemedi."</string>
diff --git a/packages/PackageInstaller/res/values-uk/strings.xml b/packages/PackageInstaller/res/values-uk/strings.xml
index e9d1925..76f3372 100644
--- a/packages/PackageInstaller/res/values-uk/strings.xml
+++ b/packages/PackageInstaller/res/values-uk/strings.xml
@@ -26,12 +26,9 @@
<string name="install_done" msgid="5987363587661783896">"Програму встановлено."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Установити цей додаток?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Оновити цей додаток?"</string>
- <!-- no translation found for install_confirm_question_update_owner_reminder (7994800761970572198) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (2435174886412089791) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (7155138616126795839) -->
- <skip />
+ <string name="install_confirm_question_update_owner_reminder" product="tablet" msgid="7994800761970572198">"<p>Оновити цей додаток з <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Зазвичай цей додаток отримує оновлення від <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Якщо встановити оновлення з іншого джерела, надалі на ваш планшет зможуть надходити оновлення з будь-яких джерел. Це може змінити функції додатка.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="tv" msgid="2435174886412089791">"<p>Оновити цей додаток з <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Зазвичай цей додаток отримує оновлення від <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Якщо встановити оновлення з іншого джерела, надалі на ваш телевізор зможуть надходити оновлення з будь-яких джерел. Це може змінити функції додатка.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="default" msgid="7155138616126795839">"<p>Оновити цей додаток з <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Зазвичай цей додаток отримує оновлення від <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Якщо встановити оновлення з іншого джерела, надалі на ваш телефон зможуть надходити оновлення з будь-яких джерел. Це може змінити функції додатка.</p>"</string>
<string name="install_failed" msgid="5777824004474125469">"Програму не встановлено."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Встановлення пакета заблоковано."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Додаток не встановлено, оскільки пакет конфліктує з наявним пакетом."</string>
diff --git a/packages/PackageInstaller/res/values-ur/strings.xml b/packages/PackageInstaller/res/values-ur/strings.xml
index 2bf3ba2f..e621d71 100644
--- a/packages/PackageInstaller/res/values-ur/strings.xml
+++ b/packages/PackageInstaller/res/values-ur/strings.xml
@@ -26,12 +26,9 @@
<string name="install_done" msgid="5987363587661783896">"ایپ انسٹال ہو گئی۔"</string>
<string name="install_confirm_question" msgid="7663733664476363311">"کیا آپ یہ ایپ انسٹال کرنا چاہتے ہیں؟"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"کیا آپ یہ ایپ اپ ڈیٹ کرنا چاہتے ہیں؟"</string>
- <!-- no translation found for install_confirm_question_update_owner_reminder (7994800761970572198) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (2435174886412089791) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (7155138616126795839) -->
- <skip />
+ <string name="install_confirm_question_update_owner_reminder" product="tablet" msgid="7994800761970572198">"<p>اس ایپ کو <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p> سے اپ ڈیٹ کریں یہ ایپ عام طور پر <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b> سے اپ ڈیٹس موصول کرتی ہے۔ کسی مختلف وسیلے سے اپ ڈیٹ کر کے، آپ اپنے ٹیبلیٹ پر کسی بھی وسیلے سے مستقبل کی اپ ڈیٹس حاصل کر سکتے ہیں۔ ایپ کی فعالیت تبدیل ہو سکتی ہے۔</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="tv" msgid="2435174886412089791">"<p>اس ایپ کو <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p> سے اپ ڈیٹ کریں یہ ایپ عام طور پر <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b> سے اپ ڈیٹس موصول کرتی ہے۔ کسی مختلف وسیلے سے اپ ڈیٹ کر کے، آپ اپنے TV پر کسی بھی وسیلے سے مستقبل کی اپ ڈیٹس حاصل کر سکتے ہیں۔ ایپ کی فعالیت تبدیل ہو سکتی ہے۔</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="default" msgid="7155138616126795839">"<p>اس ایپ کو <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p> سے اپ ڈیٹ کریں یہ ایپ عام طور پر <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b> سے اپ ڈیٹس موصول کرتی ہے۔ کسی مختلف ذریعے سے اپ ڈیٹ کر کے، آپ اپنے فون پر کسی بھی ذریعے سے مستقبل کی اپ ڈیٹس حاصل کر سکتے ہیں۔ ایپ کی فعالیت تبدیل ہو سکتی ہے۔</p>"</string>
<string name="install_failed" msgid="5777824004474125469">"ایپ انسٹال نہیں ہوئی۔"</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"پیکج کو انسٹال ہونے سے مسدود کر دیا گیا تھا۔"</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"ایپ انسٹال نہیں ہوئی کیونکہ پیکج ایک موجودہ پیکیج سے متصادم ہے۔"</string>
diff --git a/packages/PackageInstaller/res/values-vi/strings.xml b/packages/PackageInstaller/res/values-vi/strings.xml
index 9af4ac2..53b2a78 100644
--- a/packages/PackageInstaller/res/values-vi/strings.xml
+++ b/packages/PackageInstaller/res/values-vi/strings.xml
@@ -26,12 +26,9 @@
<string name="install_done" msgid="5987363587661783896">"Ứng dụng đã được cài đặt."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Bạn có muốn cài đặt ứng dụng này không?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Bạn có muốn cập nhật ứng dụng này không?"</string>
- <!-- no translation found for install_confirm_question_update_owner_reminder (7994800761970572198) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (2435174886412089791) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (7155138616126795839) -->
- <skip />
+ <string name="install_confirm_question_update_owner_reminder" product="tablet" msgid="7994800761970572198">"<p>Cập nhật ứng dụng này từ <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Ứng dụng này thường nhận các bản cập nhật từ <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Khi cập nhật từ một nguồn khác, bạn có thể nhận các bản cập nhật trong tương lai từ nguồn bất kỳ trên máy tính bảng của mình. Chức năng của ứng dụng có thể thay đổi.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="tv" msgid="2435174886412089791">"<p>Cập nhật ứng dụng này từ <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Ứng dụng này thường nhận các bản cập nhật từ <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Khi cập nhật từ một nguồn khác, bạn có thể nhận các bản cập nhật trong tương lai từ nguồn bất kỳ trên TV của mình. Chức năng của ứng dụng có thể thay đổi.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="default" msgid="7155138616126795839">"<p>Cập nhật ứng dụng này từ <b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Ứng dụng này thường nhận các bản cập nhật từ <b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Khi cập nhật từ một nguồn khác, bạn có thể nhận các bản cập nhật trong tương lai từ nguồn bất kỳ trên điện thoại của mình. Chức năng của ứng dụng có thể thay đổi.</p>"</string>
<string name="install_failed" msgid="5777824004474125469">"Ứng dụng chưa được cài đặt."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Đã chặn cài đặt gói."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Chưa cài đặt được ứng dụng do gói xung đột với một gói hiện có."</string>
diff --git a/packages/PackageInstaller/res/values-zh-rHK/strings.xml b/packages/PackageInstaller/res/values-zh-rHK/strings.xml
index 184aa53..883a6b1 100644
--- a/packages/PackageInstaller/res/values-zh-rHK/strings.xml
+++ b/packages/PackageInstaller/res/values-zh-rHK/strings.xml
@@ -26,9 +26,9 @@
<string name="install_done" msgid="5987363587661783896">"已安裝應用程式。"</string>
<string name="install_confirm_question" msgid="7663733664476363311">"要安裝此應用程式嗎?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"要更新此應用程式嗎?"</string>
- <string name="install_confirm_question_update_owner_reminder" product="tablet" msgid="7994800761970572198">"<p>要透過「<xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g>」<b></b>更新這個應用程式嗎?</p><p>這個應用程式一般是接收「<xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g>」<b></b>的更新。如果透過其他來源更新,平板電腦未來可能會收到任何來源的更新。應用程式功能可能會變動。</p>"</string>
- <string name="install_confirm_question_update_owner_reminder" product="tv" msgid="2435174886412089791">"<p>要透過「<xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g>」<b></b>更新這個應用程式嗎?</p><p>這個應用程式一般是接收「<xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g>」<b></b>的更新。如果透過其他來源更新,TV 裝置未來可能會收到任何來源的更新。應用程式功能可能會變動。</p>"</string>
- <string name="install_confirm_question_update_owner_reminder" product="default" msgid="7155138616126795839">"<p>要透過「<xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g>」<b></b>更新這個應用程式嗎?</p><p>這個應用程式一般是接收「<xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g>」<b></b>的更新。如果透過其他來源更新,手機未來可能會收到任何來源的更新。應用程式功能可能會變動。</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="tablet" msgid="7994800761970572198">"要從「<xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g>」更新此應用程式嗎?在正常情況下,系統會透過「<xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g>」更新此應用程式。如果透過其他來源更新,平板電腦未來可能會收到任何來源的更新。應用程式功能可能會有變動。"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="tv" msgid="2435174886412089791">"要從「<xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g>」更新此應用程式嗎?在正常情況下,系統會透過「<xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g>」更新此應用程式。如果透過其他來源更新,電視未來可能會收到任何來源的更新。應用程式功能可能會有變動。"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="default" msgid="7155138616126795839">"要從「<xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g>」更新此應用程式嗎?在正常情況下,系統會透過「<xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g>」更新此應用程式。如果透過其他來源更新,手機未來可能會收到任何來源的更新。應用程式功能可能會有變動。"</string>
<string name="install_failed" msgid="5777824004474125469">"未安裝應用程式。"</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"套件已遭封鎖,無法安裝。"</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"套件與現有的套件發生衝突,無法安裝應用程式。"</string>
diff --git a/packages/PackageInstaller/res/values-zu/strings.xml b/packages/PackageInstaller/res/values-zu/strings.xml
index f714b38..98c75e8 100644
--- a/packages/PackageInstaller/res/values-zu/strings.xml
+++ b/packages/PackageInstaller/res/values-zu/strings.xml
@@ -26,12 +26,9 @@
<string name="install_done" msgid="5987363587661783896">"Uhlelo lokusebenza olufakiwe."</string>
<string name="install_confirm_question" msgid="7663733664476363311">"Ingabe ufuna ukufaka le app?"</string>
<string name="install_confirm_question_update" msgid="3348888852318388584">"Ingabe ufuna ukubuyekeza le app?"</string>
- <!-- no translation found for install_confirm_question_update_owner_reminder (7994800761970572198) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (2435174886412089791) -->
- <skip />
- <!-- no translation found for install_confirm_question_update_owner_reminder (7155138616126795839) -->
- <skip />
+ <string name="install_confirm_question_update_owner_reminder" product="tablet" msgid="7994800761970572198">"<p>Buyekeza le-app ukusuka ku-<b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Le app ivame ukuthola izibuyekezo ukusuka ku-<b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Ngokubuyekeza ukusuka kumthombo ohlukile, ungase uthole izibuyekezo zesikhathi esizayo ukusuka kunoma yimuphi umthombo kuthebulethi yakho. Ukusebenza ku-app kungashintsha.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="tv" msgid="2435174886412089791">"<p>Buyekeza le-app ukusuka ku-<b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Le app ivame ukuthola izibuyekezo ukusuka ku-<b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Ngokubuyekeza ukusuka kumthombo ohlukile, ungase uthole izibuyekezo zesikhathi esizayo ukusuka kunoma yimuphi umthombo ku-TV yakho. Ukusebenza ku-app kungashintsha.</p>"</string>
+ <string name="install_confirm_question_update_owner_reminder" product="default" msgid="7155138616126795839">"<p>Buyekeza le-app ukusuka ku-<b><xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g></b>?</p><p>Le app ivame ukuthola izibuyekezo ukusuka ku-<b><xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g></b>. Ngokubuyekeza ukusuka kumthombo ohlukile, ungase uthole izibuyekezo zesikhathi esizayo ukusuka kunoma yimuphi umthombo efonini yakho. Ukusebenza ku-app kungashintsha.</p>"</string>
<string name="install_failed" msgid="5777824004474125469">"Uhlelo lokusebenza alufakiwe."</string>
<string name="install_failed_blocked" msgid="8512284352994752094">"Iphakheji livinjiwe kusukela ekufakweni."</string>
<string name="install_failed_conflict" msgid="3493184212162521426">"Uhlelo lokusebenza alufakiwe njengoba ukuphakheja kushayisana nephakheji elikhona."</string>
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java b/packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java
index 229b7a7..1231bb3 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java
@@ -51,7 +51,6 @@
public class InstallStart extends Activity {
private static final String TAG = InstallStart.class.getSimpleName();
- private static final String DOWNLOADS_AUTHORITY = "downloads";
private static final int DLG_INSTALL_APPS_RESTRICTED_FOR_USER = 1;
private static final int DLG_UNKNOWN_SOURCES_RESTRICTED_FOR_USER = 2;
@@ -103,6 +102,8 @@
boolean isDocumentsManager = checkPermission(Manifest.permission.MANAGE_DOCUMENTS,
-1, callingUid) == PackageManager.PERMISSION_GRANTED;
+ boolean isSystemDownloadsProvider = PackageUtil.getSystemDownloadsProviderInfo(
+ mPackageManager, callingUid) != null;
boolean isTrustedSource = false;
if (sourceInfo != null && sourceInfo.isPrivilegedApp()) {
isTrustedSource = intent.getBooleanExtra(Intent.EXTRA_NOT_UNKNOWN_SOURCE, false) || (
@@ -111,7 +112,7 @@
== PackageManager.PERMISSION_GRANTED);
}
- if (!isTrustedSource && !isSystemDownloadsProvider(callingUid) && !isDocumentsManager
+ if (!isTrustedSource && !isSystemDownloadsProvider && !isDocumentsManager
&& originatingUid != Process.INVALID_UID) {
final int targetSdkVersion = getMaxTargetSdkVersionForUid(this, originatingUid);
if (targetSdkVersion < 0) {
@@ -241,17 +242,6 @@
return null;
}
- private boolean isSystemDownloadsProvider(int uid) {
- final ProviderInfo downloadProviderPackage = getPackageManager().resolveContentProvider(
- DOWNLOADS_AUTHORITY, 0);
- if (downloadProviderPackage == null) {
- // There seems to be no currently enabled downloads provider on the system.
- return false;
- }
- final ApplicationInfo appInfo = downloadProviderPackage.applicationInfo;
- return ((appInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0
- && uid == appInfo.uid);
- }
@NonNull
private boolean canPackageQuery(int callingUid, Uri packageUri) {
@@ -266,7 +256,7 @@
if (callingPackages == null) {
return false;
}
- for (String callingPackage: callingPackages) {
+ for (String callingPackage : callingPackages) {
try {
if (mPackageManager.canPackageQuery(callingPackage, targetPackage)) {
return true;
@@ -346,7 +336,6 @@
* Create a new dialog.
*
* @param id The id of the dialog (determines dialog type)
- *
* @return The dialog
*/
private DialogFragment createDialog(int id) {
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java b/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java
index 411f1fa..bc7fa02 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java
@@ -265,6 +265,15 @@
}
private String getPackageNameForUid(int sourceUid) {
+ // If the sourceUid belongs to the system downloads provider, we explicitly return the
+ // name of the Download Manager package. This is because its UID is shared with multiple
+ // packages, resulting in uncertainty about which package will end up first in the list
+ // of packages associated with this UID
+ ApplicationInfo systemDownloadProviderInfo = PackageUtil.getSystemDownloadsProviderInfo(
+ mPm, sourceUid);
+ if (systemDownloadProviderInfo != null) {
+ return systemDownloadProviderInfo.packageName;
+ }
String[] packagesForUid = mPm.getPackagesForUid(sourceUid);
if (packagesForUid == null) {
return null;
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/PackageUtil.java b/packages/PackageInstaller/src/com/android/packageinstaller/PackageUtil.java
index ff0e5fb..c2d4f18 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/PackageUtil.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/PackageUtil.java
@@ -26,6 +26,7 @@
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
+import android.content.pm.ProviderInfo;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
@@ -48,7 +49,7 @@
* used in the package installer application.
*/
public class PackageUtil {
- private static final String LOG_TAG = PackageUtil.class.getSimpleName();
+ private static final String LOG_TAG = "PackageInstaller";
public static final String PREFIX="com.android.packageinstaller.";
public static final String INTENT_ATTR_INSTALL_STATUS = PREFIX+"installStatus";
@@ -56,6 +57,7 @@
public static final String INTENT_ATTR_PERMISSIONS_LIST=PREFIX+"PermissionsList";
//intent attribute strings related to uninstall
public static final String INTENT_ATTR_PACKAGE_NAME=PREFIX+"PackageName";
+ private static final String DOWNLOADS_AUTHORITY = "downloads";
/**
* Utility method to get package information for a given {@link File}
@@ -245,4 +247,26 @@
getActivity().finish();
}
}
+
+ /**
+ * Determines if the UID belongs to the system downloads provider and returns the
+ * {@link ApplicationInfo} of the provider
+ *
+ * @param uid UID of the caller
+ * @return {@link ApplicationInfo} of the provider if a downloads provider exists,
+ * it is a system app, and its UID matches with the passed UID, null otherwise.
+ */
+ public static ApplicationInfo getSystemDownloadsProviderInfo(PackageManager pm, int uid) {
+ final ProviderInfo providerInfo = pm.resolveContentProvider(
+ DOWNLOADS_AUTHORITY, 0);
+ if (providerInfo == null) {
+ // There seems to be no currently enabled downloads provider on the system.
+ return null;
+ }
+ ApplicationInfo appInfo = providerInfo.applicationInfo;
+ if ((appInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0 && uid == appInfo.uid) {
+ return appInfo;
+ }
+ return null;
+ }
}
diff --git a/packages/SettingsLib/Spa/spa/build.gradle.kts b/packages/SettingsLib/Spa/spa/build.gradle.kts
index 5289635..329d80e 100644
--- a/packages/SettingsLib/Spa/spa/build.gradle.kts
+++ b/packages/SettingsLib/Spa/spa/build.gradle.kts
@@ -69,7 +69,6 @@
implementation("com.airbnb.android:lottie-compose:5.2.0")
androidTestImplementation(project(":testutils"))
- androidTestImplementation("androidx.lifecycle:lifecycle-runtime-testing")
androidTestImplementation(libs.dexmaker.mockito)
}
diff --git a/packages/SettingsLib/Spa/tests/Android.bp b/packages/SettingsLib/Spa/tests/Android.bp
index b4c67cc..f9e64ae 100644
--- a/packages/SettingsLib/Spa/tests/Android.bp
+++ b/packages/SettingsLib/Spa/tests/Android.bp
@@ -31,7 +31,6 @@
"SpaLib",
"SpaLibTestUtils",
"androidx.compose.runtime_runtime",
- "androidx.lifecycle_lifecycle-runtime-testing",
"androidx.test.ext.junit",
"androidx.test.runner",
"mockito-target-minus-junit4",
diff --git a/packages/SettingsLib/Spa/testutils/Android.bp b/packages/SettingsLib/Spa/testutils/Android.bp
index 2c1e1c2..e4d56cc 100644
--- a/packages/SettingsLib/Spa/testutils/Android.bp
+++ b/packages/SettingsLib/Spa/testutils/Android.bp
@@ -29,6 +29,7 @@
"androidx.compose.runtime_runtime",
"androidx.compose.ui_ui-test-junit4",
"androidx.compose.ui_ui-test-manifest",
+ "androidx.lifecycle_lifecycle-runtime-testing",
"mockito",
"truth-prebuilt",
],
diff --git a/packages/SettingsLib/Spa/testutils/build.gradle.kts b/packages/SettingsLib/Spa/testutils/build.gradle.kts
index 6df0226..f5a22c9 100644
--- a/packages/SettingsLib/Spa/testutils/build.gradle.kts
+++ b/packages/SettingsLib/Spa/testutils/build.gradle.kts
@@ -26,7 +26,7 @@
sourceSets {
sourceSets.getByName("main") {
- java.setSrcDirs(listOf("src"))
+ kotlin.setSrcDirs(listOf("src"))
manifest.srcFile("AndroidManifest.xml")
}
}
@@ -40,6 +40,7 @@
api("androidx.arch.core:core-testing:2.2.0-alpha01")
api("androidx.compose.ui:ui-test-junit4:$jetpackComposeVersion")
+ api("androidx.lifecycle:lifecycle-runtime-testing")
api(libs.truth)
api("org.mockito:mockito-core:2.21.0")
debugApi("androidx.compose.ui:ui-test-manifest:$jetpackComposeVersion")
diff --git a/packages/SettingsLib/SpaPrivileged/res/values-ko/strings.xml b/packages/SettingsLib/SpaPrivileged/res/values-ko/strings.xml
index ef4ee0d..3e1b837 100644
--- a/packages/SettingsLib/SpaPrivileged/res/values-ko/strings.xml
+++ b/packages/SettingsLib/SpaPrivileged/res/values-ko/strings.xml
@@ -23,5 +23,5 @@
<string name="app_permission_summary_allowed" msgid="6115213465364138103">"허용됨"</string>
<string name="app_permission_summary_not_allowed" msgid="58396132188553920">"허용되지 않음"</string>
<string name="version_text" msgid="4001669804596458577">"버전 <xliff:g id="VERSION_NUM">%1$s</xliff:g>"</string>
- <string name="cloned_app_info_label" msgid="1765651167024478391">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> 클론"</string>
+ <string name="cloned_app_info_label" msgid="1765651167024478391">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> 복제"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-af/arrays.xml b/packages/SettingsLib/res/values-af/arrays.xml
index 41499b0..a96ea0d 100644
--- a/packages/SettingsLib/res/values-af/arrays.xml
+++ b/packages/SettingsLib/res/values-af/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"Oudiobron"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-am/arrays.xml b/packages/SettingsLib/res/values-am/arrays.xml
index 6fb1274..5f7aec2 100644
--- a/packages/SettingsLib/res/values-am/arrays.xml
+++ b/packages/SettingsLib/res/values-am/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"የኦዲዮ ምንጭ"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-ar/arrays.xml b/packages/SettingsLib/res/values-ar/arrays.xml
index cb1ec38..461c637 100644
--- a/packages/SettingsLib/res/values-ar/arrays.xml
+++ b/packages/SettingsLib/res/values-ar/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"مصدر الصوت"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-as/arrays.xml b/packages/SettingsLib/res/values-as/arrays.xml
index 2eaf5fa..7e43ab3 100644
--- a/packages/SettingsLib/res/values-as/arrays.xml
+++ b/packages/SettingsLib/res/values-as/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"ধ্বনিৰ উৎস"</item>
<item msgid="8688681727755534982">"এমআইডিআই"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-az/arrays.xml b/packages/SettingsLib/res/values-az/arrays.xml
index f01def0..357a203 100644
--- a/packages/SettingsLib/res/values-az/arrays.xml
+++ b/packages/SettingsLib/res/values-az/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"Audio Mənbə"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/arrays.xml b/packages/SettingsLib/res/values-b+sr+Latn/arrays.xml
index 772c339..0bcd9bc 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/arrays.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"Izvor zvuka"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-be/arrays.xml b/packages/SettingsLib/res/values-be/arrays.xml
index d253725..3f5da11 100644
--- a/packages/SettingsLib/res/values-be/arrays.xml
+++ b/packages/SettingsLib/res/values-be/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"Крыніца аўдыя"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-bg/arrays.xml b/packages/SettingsLib/res/values-bg/arrays.xml
index 6be8827..b80b5eb 100644
--- a/packages/SettingsLib/res/values-bg/arrays.xml
+++ b/packages/SettingsLib/res/values-bg/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"Аудиоизточник"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-bn/arrays.xml b/packages/SettingsLib/res/values-bn/arrays.xml
index b0a1c29..71228c7 100644
--- a/packages/SettingsLib/res/values-bn/arrays.xml
+++ b/packages/SettingsLib/res/values-bn/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"অডিও উৎস"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-bs/arrays.xml b/packages/SettingsLib/res/values-bs/arrays.xml
index 77d9a20..f664618 100644
--- a/packages/SettingsLib/res/values-bs/arrays.xml
+++ b/packages/SettingsLib/res/values-bs/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"Izvor zvuka"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-ca/arrays.xml b/packages/SettingsLib/res/values-ca/arrays.xml
index 1e333cc..2476141 100644
--- a/packages/SettingsLib/res/values-ca/arrays.xml
+++ b/packages/SettingsLib/res/values-ca/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"Font d\'àudio"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-cs/arrays.xml b/packages/SettingsLib/res/values-cs/arrays.xml
index 034a133..c0b9395 100644
--- a/packages/SettingsLib/res/values-cs/arrays.xml
+++ b/packages/SettingsLib/res/values-cs/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"Zdroj zvuku"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-da/arrays.xml b/packages/SettingsLib/res/values-da/arrays.xml
index 9f3db17..163ee53 100644
--- a/packages/SettingsLib/res/values-da/arrays.xml
+++ b/packages/SettingsLib/res/values-da/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"Lydkilde"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-de/arrays.xml b/packages/SettingsLib/res/values-de/arrays.xml
index 05c4630..5e80e3c 100644
--- a/packages/SettingsLib/res/values-de/arrays.xml
+++ b/packages/SettingsLib/res/values-de/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"Audioquelle"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-el/arrays.xml b/packages/SettingsLib/res/values-el/arrays.xml
index 4e8736c..3d60335 100644
--- a/packages/SettingsLib/res/values-el/arrays.xml
+++ b/packages/SettingsLib/res/values-el/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"Πηγή ήχου"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-en-rAU/arrays.xml b/packages/SettingsLib/res/values-en-rAU/arrays.xml
index df643cd..fa637be 100644
--- a/packages/SettingsLib/res/values-en-rAU/arrays.xml
+++ b/packages/SettingsLib/res/values-en-rAU/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"Audio Source"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-en-rCA/arrays.xml b/packages/SettingsLib/res/values-en-rCA/arrays.xml
index 184d210..ea8f2c5 100644
--- a/packages/SettingsLib/res/values-en-rCA/arrays.xml
+++ b/packages/SettingsLib/res/values-en-rCA/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"Audio Source"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-en-rGB/arrays.xml b/packages/SettingsLib/res/values-en-rGB/arrays.xml
index df643cd..fa637be 100644
--- a/packages/SettingsLib/res/values-en-rGB/arrays.xml
+++ b/packages/SettingsLib/res/values-en-rGB/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"Audio Source"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-en-rIN/arrays.xml b/packages/SettingsLib/res/values-en-rIN/arrays.xml
index df643cd..fa637be 100644
--- a/packages/SettingsLib/res/values-en-rIN/arrays.xml
+++ b/packages/SettingsLib/res/values-en-rIN/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"Audio Source"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-en-rXC/arrays.xml b/packages/SettingsLib/res/values-en-rXC/arrays.xml
index dec70f4..6b404a8 100644
--- a/packages/SettingsLib/res/values-en-rXC/arrays.xml
+++ b/packages/SettingsLib/res/values-en-rXC/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"Audio Source"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-es-rUS/arrays.xml b/packages/SettingsLib/res/values-es-rUS/arrays.xml
index b1b1b2e..27cdeeb 100644
--- a/packages/SettingsLib/res/values-es-rUS/arrays.xml
+++ b/packages/SettingsLib/res/values-es-rUS/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"Fuente de audio"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml
index ae24ff0..39fd341 100644
--- a/packages/SettingsLib/res/values-es-rUS/strings.xml
+++ b/packages/SettingsLib/res/values-es-rUS/strings.xml
@@ -682,7 +682,7 @@
<string name="bt_le_audio_broadcast_dialog_sub_title" msgid="268234802198852753">"Si transmites <xliff:g id="SWITCHAPP">%1$s</xliff:g> o cambias la salida, tu transmisión actual se detendrá"</string>
<string name="bt_le_audio_broadcast_dialog_switch_app" msgid="5749813313369517812">"Transmitir <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
<string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Cambia la salida"</string>
- <string name="back_navigation_animation" msgid="8105467568421689484">"Animaciones de retroceso predictivas"</string>
+ <string name="back_navigation_animation" msgid="8105467568421689484">"Animaciones de gesto predictivo"</string>
<string name="back_navigation_animation_summary" msgid="741292224121599456">"Habilita animaciones del sistema para gestos de retroceso predictivos."</string>
<string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Esta configuración habilita las animaciones del sistema para la animación de gestos predictiva. Se requiere la configuración por app de enableOnBackInvokedCallback en verdadero en el archivo de manifiesto."</string>
<string-array name="udfps_accessibility_touch_hints">
diff --git a/packages/SettingsLib/res/values-es/arrays.xml b/packages/SettingsLib/res/values-es/arrays.xml
index eee7315..a16093a 100644
--- a/packages/SettingsLib/res/values-es/arrays.xml
+++ b/packages/SettingsLib/res/values-es/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"Fuente de audio"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-et/arrays.xml b/packages/SettingsLib/res/values-et/arrays.xml
index 224583f..d686961 100644
--- a/packages/SettingsLib/res/values-et/arrays.xml
+++ b/packages/SettingsLib/res/values-et/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"Heliallikas"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-eu/arrays.xml b/packages/SettingsLib/res/values-eu/arrays.xml
index e2867c2..3b980c5 100644
--- a/packages/SettingsLib/res/values-eu/arrays.xml
+++ b/packages/SettingsLib/res/values-eu/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"Audio-iturburua"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-fa/arrays.xml b/packages/SettingsLib/res/values-fa/arrays.xml
index 7feef70..0eb381f 100644
--- a/packages/SettingsLib/res/values-fa/arrays.xml
+++ b/packages/SettingsLib/res/values-fa/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"منبع صوتی"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml
index 33d262f..9f33fa4 100644
--- a/packages/SettingsLib/res/values-fa/strings.xml
+++ b/packages/SettingsLib/res/values-fa/strings.xml
@@ -86,7 +86,7 @@
<string name="bluetooth_disconnecting" msgid="7638892134401574338">"در حال قطع اتصال..."</string>
<string name="bluetooth_connecting" msgid="5871702668260192755">"در حال اتصال…"</string>
<string name="bluetooth_connected" msgid="8065345572198502293">"متصل<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
- <string name="bluetooth_pairing" msgid="4269046942588193600">"در حال مرتبطسازی..."</string>
+ <string name="bluetooth_pairing" msgid="4269046942588193600">"درحال جفت کردن..."</string>
<string name="bluetooth_connected_no_headset" msgid="2224101138659967604">"متصل (بدون تلفن)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
<string name="bluetooth_connected_no_a2dp" msgid="8566874395813947092">"متصل (بدون رسانه)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
<string name="bluetooth_connected_no_headset_no_a2dp" msgid="2893204819854215433">"متصل (بدون تلفن یا رسانه)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string>
@@ -247,7 +247,7 @@
<string name="adb_pairing_device_dialog_failed_title" msgid="3426758947882091735">"مرتبطسازی ناموفق"</string>
<string name="adb_pairing_device_dialog_failed_msg" msgid="6611097519661997148">"مطمئن شوید که دستگاه به همان شبکه متصل باشد."</string>
<string name="adb_wireless_qrcode_summary" msgid="8051414549011801917">"دستگاه را ازطریق Wi‑Fi و با اسکن کردن رمزینه پاسخسریع مرتبط کنید"</string>
- <string name="adb_wireless_verifying_qrcode_text" msgid="6123192424916029207">"مرتبطسازی دستگاه…"</string>
+ <string name="adb_wireless_verifying_qrcode_text" msgid="6123192424916029207">"جفت کردن دستگاه…"</string>
<string name="adb_qrcode_pairing_device_failed_msg" msgid="6936292092592914132">"جفت کردن دستگاه انجام نشد. یا رمزینه پاسخسریع اشتباه بوده است، یا دستگاه به همان شبکه متصل نیست."</string>
<string name="adb_wireless_ip_addr_preference_title" msgid="8335132107715311730">"نشانی IP و درگاه"</string>
<string name="adb_wireless_qrcode_pairing_title" msgid="1906409667944674707">"اسکن رمزینه پاسخسریع"</string>
diff --git a/packages/SettingsLib/res/values-fi/arrays.xml b/packages/SettingsLib/res/values-fi/arrays.xml
index 5a1dc18..a3cfd15 100644
--- a/packages/SettingsLib/res/values-fi/arrays.xml
+++ b/packages/SettingsLib/res/values-fi/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"Äänilähde"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-fr-rCA/arrays.xml b/packages/SettingsLib/res/values-fr-rCA/arrays.xml
index 06a703f..3fb1833 100644
--- a/packages/SettingsLib/res/values-fr-rCA/arrays.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"Source audio"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-fr/arrays.xml b/packages/SettingsLib/res/values-fr/arrays.xml
index bb650c3..a1a8c99 100644
--- a/packages/SettingsLib/res/values-fr/arrays.xml
+++ b/packages/SettingsLib/res/values-fr/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"Source audio"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-gl/arrays.xml b/packages/SettingsLib/res/values-gl/arrays.xml
index 797f84b..bd88e83 100644
--- a/packages/SettingsLib/res/values-gl/arrays.xml
+++ b/packages/SettingsLib/res/values-gl/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"Fonte de audio"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-gu/arrays.xml b/packages/SettingsLib/res/values-gu/arrays.xml
index 93d3432..e33c759 100644
--- a/packages/SettingsLib/res/values-gu/arrays.xml
+++ b/packages/SettingsLib/res/values-gu/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"ઑડિઓ સ્રોત"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-hi/arrays.xml b/packages/SettingsLib/res/values-hi/arrays.xml
index 4ee7689..2403848 100644
--- a/packages/SettingsLib/res/values-hi/arrays.xml
+++ b/packages/SettingsLib/res/values-hi/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"ऑडियो स्रोत"</item>
<item msgid="8688681727755534982">"एमआईडीआई"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml
index 21936c8..bd508d9 100644
--- a/packages/SettingsLib/res/values-hi/strings.xml
+++ b/packages/SettingsLib/res/values-hi/strings.xml
@@ -355,10 +355,8 @@
<string name="pointer_location_summary" msgid="957120116989798464">"मौजूदा टच डेटा दिखाने वाला स्क्रीन ओवरले"</string>
<string name="show_touches" msgid="8437666942161289025">"टैप दिखाएं"</string>
<string name="show_touches_summary" msgid="3692861665994502193">"टैप के लिए विज़ुअल फ़ीडबैक दिखाएं"</string>
- <!-- no translation found for show_key_presses (6360141722735900214) -->
- <skip />
- <!-- no translation found for show_key_presses_summary (725387457373015024) -->
- <skip />
+ <string name="show_key_presses" msgid="6360141722735900214">"दबाए गए बटन दिखाएं"</string>
+ <string name="show_key_presses_summary" msgid="725387457373015024">"दबाए गए बटन के लिए विज़ुअल फ़ीडबैक दिखाएं"</string>
<string name="show_screen_updates" msgid="2078782895825535494">"सर्फ़ेस अपडेट दिखाएं"</string>
<string name="show_screen_updates_summary" msgid="2126932969682087406">"अपडेट होने पर पूरे विंडो सर्फ़ेस फ़्लैश करें"</string>
<string name="show_hw_screen_updates" msgid="2021286231267747506">"जीपीयू व्यू के अपडेट दिखाएं"</string>
diff --git a/packages/SettingsLib/res/values-hr/arrays.xml b/packages/SettingsLib/res/values-hr/arrays.xml
index 8111b73..3cb64ab 100644
--- a/packages/SettingsLib/res/values-hr/arrays.xml
+++ b/packages/SettingsLib/res/values-hr/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"Audioizvor"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-hu/arrays.xml b/packages/SettingsLib/res/values-hu/arrays.xml
index ee1ace0..f4c1176 100644
--- a/packages/SettingsLib/res/values-hu/arrays.xml
+++ b/packages/SettingsLib/res/values-hu/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"Hangforrás"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-hy/arrays.xml b/packages/SettingsLib/res/values-hy/arrays.xml
index 01b97a8..e9c366d 100644
--- a/packages/SettingsLib/res/values-hy/arrays.xml
+++ b/packages/SettingsLib/res/values-hy/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"Ձայնի աղբյուրը"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-in/arrays.xml b/packages/SettingsLib/res/values-in/arrays.xml
index 8eac267..95aeee7 100644
--- a/packages/SettingsLib/res/values-in/arrays.xml
+++ b/packages/SettingsLib/res/values-in/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"Sumber Audio"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-is/arrays.xml b/packages/SettingsLib/res/values-is/arrays.xml
index 01ce83f..f0ee718 100644
--- a/packages/SettingsLib/res/values-is/arrays.xml
+++ b/packages/SettingsLib/res/values-is/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"Audio Source"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-it/arrays.xml b/packages/SettingsLib/res/values-it/arrays.xml
index be718db..b6b2fdea 100644
--- a/packages/SettingsLib/res/values-it/arrays.xml
+++ b/packages/SettingsLib/res/values-it/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"Sorgente audio"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-iw/arrays.xml b/packages/SettingsLib/res/values-iw/arrays.xml
index 2600d9c..ca3a4dd 100644
--- a/packages/SettingsLib/res/values-iw/arrays.xml
+++ b/packages/SettingsLib/res/values-iw/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"מקור אודיו"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-ja/arrays.xml b/packages/SettingsLib/res/values-ja/arrays.xml
index ab84488..b3267fe 100644
--- a/packages/SettingsLib/res/values-ja/arrays.xml
+++ b/packages/SettingsLib/res/values-ja/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"オーディオソース"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-ka/arrays.xml b/packages/SettingsLib/res/values-ka/arrays.xml
index be44038..ab6acfd 100644
--- a/packages/SettingsLib/res/values-ka/arrays.xml
+++ b/packages/SettingsLib/res/values-ka/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"აუდიო წყარo"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-kk/arrays.xml b/packages/SettingsLib/res/values-kk/arrays.xml
index 7d71699..2b1d700 100644
--- a/packages/SettingsLib/res/values-kk/arrays.xml
+++ b/packages/SettingsLib/res/values-kk/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"Аудио көзі"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-km/arrays.xml b/packages/SettingsLib/res/values-km/arrays.xml
index 548e2d6..0f20bf0 100644
--- a/packages/SettingsLib/res/values-km/arrays.xml
+++ b/packages/SettingsLib/res/values-km/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"ប្រភពអូឌីយ៉ូ"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-kn/arrays.xml b/packages/SettingsLib/res/values-kn/arrays.xml
index aa29850..00e8049 100644
--- a/packages/SettingsLib/res/values-kn/arrays.xml
+++ b/packages/SettingsLib/res/values-kn/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"ಆಡಿಯೊ ಮೂಲ"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-ko/arrays.xml b/packages/SettingsLib/res/values-ko/arrays.xml
index bc739b9..85a0a4a 100644
--- a/packages/SettingsLib/res/values-ko/arrays.xml
+++ b/packages/SettingsLib/res/values-ko/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"오디오 소스"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-ky/arrays.xml b/packages/SettingsLib/res/values-ky/arrays.xml
index 71e10da..eb295ae 100644
--- a/packages/SettingsLib/res/values-ky/arrays.xml
+++ b/packages/SettingsLib/res/values-ky/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"Аудио булак"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-lo/arrays.xml b/packages/SettingsLib/res/values-lo/arrays.xml
index 79cdd6f..ccb777b 100644
--- a/packages/SettingsLib/res/values-lo/arrays.xml
+++ b/packages/SettingsLib/res/values-lo/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"ແຫຼ່ງທີ່ມາຂອງສຽງ"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-lt/arrays.xml b/packages/SettingsLib/res/values-lt/arrays.xml
index d37fb32..010b3b4 100644
--- a/packages/SettingsLib/res/values-lt/arrays.xml
+++ b/packages/SettingsLib/res/values-lt/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"Garso šaltinis"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-lv/arrays.xml b/packages/SettingsLib/res/values-lv/arrays.xml
index af62148..2c7ac98 100644
--- a/packages/SettingsLib/res/values-lv/arrays.xml
+++ b/packages/SettingsLib/res/values-lv/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"Audio avots"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-mk/arrays.xml b/packages/SettingsLib/res/values-mk/arrays.xml
index 6cf933e..a276eb3 100644
--- a/packages/SettingsLib/res/values-mk/arrays.xml
+++ b/packages/SettingsLib/res/values-mk/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"Аудиоизвор"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-ml/arrays.xml b/packages/SettingsLib/res/values-ml/arrays.xml
index 29c4a55..6eb432c 100644
--- a/packages/SettingsLib/res/values-ml/arrays.xml
+++ b/packages/SettingsLib/res/values-ml/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"ഓഡിയോ ഉറവിടം"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-mn/arrays.xml b/packages/SettingsLib/res/values-mn/arrays.xml
index acd5594..925c827 100644
--- a/packages/SettingsLib/res/values-mn/arrays.xml
+++ b/packages/SettingsLib/res/values-mn/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"Аудио эх сурвалж"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-mr/arrays.xml b/packages/SettingsLib/res/values-mr/arrays.xml
index 02dd07c..e3b6ae6 100644
--- a/packages/SettingsLib/res/values-mr/arrays.xml
+++ b/packages/SettingsLib/res/values-mr/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"ऑडिओ स्रोत"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-ms/arrays.xml b/packages/SettingsLib/res/values-ms/arrays.xml
index 3ee7131..6b8bce4 100644
--- a/packages/SettingsLib/res/values-ms/arrays.xml
+++ b/packages/SettingsLib/res/values-ms/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"Sumber Audio"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-my/arrays.xml b/packages/SettingsLib/res/values-my/arrays.xml
index 50be181f..59e1862 100644
--- a/packages/SettingsLib/res/values-my/arrays.xml
+++ b/packages/SettingsLib/res/values-my/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"အသံ ရင်းမြစ်"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-nb/arrays.xml b/packages/SettingsLib/res/values-nb/arrays.xml
index 3029329..c364c58 100644
--- a/packages/SettingsLib/res/values-nb/arrays.xml
+++ b/packages/SettingsLib/res/values-nb/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"Lydkilde"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-ne/arrays.xml b/packages/SettingsLib/res/values-ne/arrays.xml
index f464f31..eaea3ba 100644
--- a/packages/SettingsLib/res/values-ne/arrays.xml
+++ b/packages/SettingsLib/res/values-ne/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"अडियो स्रोत"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-nl/arrays.xml b/packages/SettingsLib/res/values-nl/arrays.xml
index f40eec1..b8e945f 100644
--- a/packages/SettingsLib/res/values-nl/arrays.xml
+++ b/packages/SettingsLib/res/values-nl/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"Audiobron"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-or/arrays.xml b/packages/SettingsLib/res/values-or/arrays.xml
index 8c5589c..d649907 100644
--- a/packages/SettingsLib/res/values-or/arrays.xml
+++ b/packages/SettingsLib/res/values-or/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"ଅଡିଓ ଉତ୍ସ"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-or/strings.xml b/packages/SettingsLib/res/values-or/strings.xml
index 22f923d..bf7470c 100644
--- a/packages/SettingsLib/res/values-or/strings.xml
+++ b/packages/SettingsLib/res/values-or/strings.xml
@@ -577,7 +577,7 @@
<string name="delete_blob_confirmation_text" msgid="7807446938920827280">"ଆପଣ ସେୟାର୍ କରାଯାଇଥିବା ଏହି ଡାଟା ଡିଲିଟ୍ କରିବାକୁ ଚାହୁଁଥିବା ନିଶ୍ଚିତ କି?"</string>
<string name="user_add_user_item_summary" msgid="5748424612724703400">"ଉପଯୋଗକର୍ତ୍ତାମାନଙ୍କ ପାଖରେ ନିଜର ଆପ୍ ଓ କଣ୍ଟେଣ୍ଟ ଅଛି"</string>
<string name="user_add_profile_item_summary" msgid="5418602404308968028">"ନିଜ ଆକାଉଣ୍ଟରୁ ଆପ୍ ତଥା କଣ୍ଟେଣ୍ଟକୁ ଆପଣ ଆକ୍ସେସ୍ ରୋକିପାରିବେ"</string>
- <string name="user_add_user_item_title" msgid="2394272381086965029">"ଉପଯୋଗକର୍ତ୍ତା"</string>
+ <string name="user_add_user_item_title" msgid="2394272381086965029">"ୟୁଜର"</string>
<string name="user_add_profile_item_title" msgid="3111051717414643029">"ସୀମିତ ସୁବିଧା ଥିବା ପ୍ରୋଫାଇଲ୍"</string>
<string name="user_add_user_title" msgid="5457079143694924885">"ନୂଆ ୟୁଜରଙ୍କୁ ଯୋଗ କରିବେ?"</string>
<string name="user_add_user_message_long" msgid="1527434966294733380">"ଅତିରିକ୍ତ ୟୁଜରଙ୍କୁ ଯୋଗ କରି ଆପଣ ଏହି ଡିଭାଇସକୁ ଅନ୍ୟ ଲୋକମାନଙ୍କ ସହିତ ସେୟାର କରିପାରିବେ। ପ୍ରତ୍ୟେକ ୟୁଜରଙ୍କ ନିଜର ସ୍ପେସ ଅଛି ଯାହାକୁ ସେମାନେ ଆପ, ୱାଲପେପର ଓ ଏପରି ଅନେକ କିଛି ସହିତ କଷ୍ଟମାଇଜ କରିପାରିବେ। ୟୁଜର ୱାଇ-ଫାଇ ଭଳି ଡିଭାଇସ ସେଟିଂସକୁ ମଧ୍ୟ ଆଡଜଷ୍ଟ କରିପାରିବେ ଯାହା ସମସ୍ତଙ୍କୁ ପ୍ରଭାବିତ କରିଥାଏ। \n\nଯେତେବେଳେ ଆପଣ ଜଣେ ନୂଆ ୟୁଜରଙ୍କୁ ଯୋଗ କରିବେ, ସେତେବେଳେ ସେହି ବ୍ୟକ୍ତିଙ୍କୁ ନିଜର ସ୍ପେସକୁ ସେଟଅପ କରିବାକୁ ପଡ଼ିବ। \n\nଅନ୍ୟ ୟୁଜରଙ୍କ ପାଇଁ ଯେ କୌଣସି ୟୁଜର ଆପକୁ ଅପଡେଟ କରିପାରିବେ। ଆକ୍ସେସିବିଲିଟୀ ସେଟିଂସ ଏବଂ ସେବାଗୁଡ଼ିକ ନୂଆ ୟୁଜରଙ୍କୁ ସ୍ଥାନାନ୍ତର ହୋଇନପାରେ।"</string>
diff --git a/packages/SettingsLib/res/values-pa/arrays.xml b/packages/SettingsLib/res/values-pa/arrays.xml
index 4225e02..4f58a3c 100644
--- a/packages/SettingsLib/res/values-pa/arrays.xml
+++ b/packages/SettingsLib/res/values-pa/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">" ਆਡੀਓ ਸਰੋਤ"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-pl/arrays.xml b/packages/SettingsLib/res/values-pl/arrays.xml
index 031cd9c..671ae41 100644
--- a/packages/SettingsLib/res/values-pl/arrays.xml
+++ b/packages/SettingsLib/res/values-pl/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"Źródło dźwięku"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-pt-rBR/arrays.xml b/packages/SettingsLib/res/values-pt-rBR/arrays.xml
index 3b61e1a..e3b7701 100644
--- a/packages/SettingsLib/res/values-pt-rBR/arrays.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"Fonte de áudio"</item>
<item msgid="8688681727755534982">"MIDI (som)"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-pt-rPT/arrays.xml b/packages/SettingsLib/res/values-pt-rPT/arrays.xml
index 9b472dd..ba30280 100644
--- a/packages/SettingsLib/res/values-pt-rPT/arrays.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"Fonte de áudio"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-pt/arrays.xml b/packages/SettingsLib/res/values-pt/arrays.xml
index 3b61e1a..e3b7701 100644
--- a/packages/SettingsLib/res/values-pt/arrays.xml
+++ b/packages/SettingsLib/res/values-pt/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"Fonte de áudio"</item>
<item msgid="8688681727755534982">"MIDI (som)"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-ro/arrays.xml b/packages/SettingsLib/res/values-ro/arrays.xml
index f713051..613a631 100644
--- a/packages/SettingsLib/res/values-ro/arrays.xml
+++ b/packages/SettingsLib/res/values-ro/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"Sursă audio"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-ru/arrays.xml b/packages/SettingsLib/res/values-ru/arrays.xml
index 80ae696..c1bb31e 100644
--- a/packages/SettingsLib/res/values-ru/arrays.xml
+++ b/packages/SettingsLib/res/values-ru/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"Источник аудио"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-si/arrays.xml b/packages/SettingsLib/res/values-si/arrays.xml
index 01103f5..0fa1074 100644
--- a/packages/SettingsLib/res/values-si/arrays.xml
+++ b/packages/SettingsLib/res/values-si/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"ශ්රව්ය මූලය"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-sk/arrays.xml b/packages/SettingsLib/res/values-sk/arrays.xml
index 5a6eb99..ecc4afe 100644
--- a/packages/SettingsLib/res/values-sk/arrays.xml
+++ b/packages/SettingsLib/res/values-sk/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"Zdroj zvuku"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-sl/arrays.xml b/packages/SettingsLib/res/values-sl/arrays.xml
index aff47ed..0f2225a 100644
--- a/packages/SettingsLib/res/values-sl/arrays.xml
+++ b/packages/SettingsLib/res/values-sl/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"Vir zvoka"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-sq/arrays.xml b/packages/SettingsLib/res/values-sq/arrays.xml
index 60dba5b..d92ee58 100644
--- a/packages/SettingsLib/res/values-sq/arrays.xml
+++ b/packages/SettingsLib/res/values-sq/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"Burimi i audios"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-sr/arrays.xml b/packages/SettingsLib/res/values-sr/arrays.xml
index d74f55b..69564fa 100644
--- a/packages/SettingsLib/res/values-sr/arrays.xml
+++ b/packages/SettingsLib/res/values-sr/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"Извор звука"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-sv/arrays.xml b/packages/SettingsLib/res/values-sv/arrays.xml
index 5ff90cb..daaa138 100644
--- a/packages/SettingsLib/res/values-sv/arrays.xml
+++ b/packages/SettingsLib/res/values-sv/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"Ljudkälla"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-sw/arrays.xml b/packages/SettingsLib/res/values-sw/arrays.xml
index 30cc69f..a555596 100644
--- a/packages/SettingsLib/res/values-sw/arrays.xml
+++ b/packages/SettingsLib/res/values-sw/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"Chanzo cha Sauti"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-ta/arrays.xml b/packages/SettingsLib/res/values-ta/arrays.xml
index 5774bf9..6195e3c 100644
--- a/packages/SettingsLib/res/values-ta/arrays.xml
+++ b/packages/SettingsLib/res/values-ta/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"ஆடியோ மூலம்"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-te/arrays.xml b/packages/SettingsLib/res/values-te/arrays.xml
index d250352..2a31c0d 100644
--- a/packages/SettingsLib/res/values-te/arrays.xml
+++ b/packages/SettingsLib/res/values-te/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"ఆడియో మూలం"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml
index 32738bb..ae1b251 100644
--- a/packages/SettingsLib/res/values-te/strings.xml
+++ b/packages/SettingsLib/res/values-te/strings.xml
@@ -378,7 +378,7 @@
<string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"నావిగేషన్ బార్ బ్యాక్గ్రౌండ్ రంగును ఆటోమేటిక్గా పారదర్శకంగా చేయండి"</string>
<string name="window_blurs" msgid="6831008984828425106">"విండో-స్థాయి బ్లర్ అనుమతించండి"</string>
<string name="force_msaa" msgid="4081288296137775550">"4x MSAA అమలు తప్పనిసరి"</string>
- <string name="force_msaa_summary" msgid="9070437493586769500">"OpenGL ES 2.0 యాప్లలో 4x MSAAను ప్రారంభించండి"</string>
+ <string name="force_msaa_summary" msgid="9070437493586769500">"OpenGL ES 2.0 యాప్లలో 4x MSAAను ఎనేబుల్ చేయండి"</string>
<string name="show_non_rect_clip" msgid="7499758654867881817">"దీర్ఘ చతురస్రం కాని క్లిప్ ఆపరేషన్స్ను డీబగ్ చేయండి"</string>
<string name="track_frame_time" msgid="522674651937771106">"ప్రొఫైల్ HWUI రెండరింగ్"</string>
<string name="enable_gpu_debug_layers" msgid="4986675516188740397">"GPU డీబగ్ లేయర్లను ప్రారంభించండి"</string>
diff --git a/packages/SettingsLib/res/values-th/arrays.xml b/packages/SettingsLib/res/values-th/arrays.xml
index bf6bf17..b66fe5c 100644
--- a/packages/SettingsLib/res/values-th/arrays.xml
+++ b/packages/SettingsLib/res/values-th/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"แหล่งที่มาของเสียง"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-tl/arrays.xml b/packages/SettingsLib/res/values-tl/arrays.xml
index 9af30d6..d9fee74 100644
--- a/packages/SettingsLib/res/values-tl/arrays.xml
+++ b/packages/SettingsLib/res/values-tl/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"Pinagmulan ng Audio"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-tr/arrays.xml b/packages/SettingsLib/res/values-tr/arrays.xml
index 6d8821e..e22ad90 100644
--- a/packages/SettingsLib/res/values-tr/arrays.xml
+++ b/packages/SettingsLib/res/values-tr/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"Ses Kaynağı"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-uk/arrays.xml b/packages/SettingsLib/res/values-uk/arrays.xml
index b606d07..dc02eeb 100644
--- a/packages/SettingsLib/res/values-uk/arrays.xml
+++ b/packages/SettingsLib/res/values-uk/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"Джерело аудіо"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-ur/arrays.xml b/packages/SettingsLib/res/values-ur/arrays.xml
index 6d4062d..be76762 100644
--- a/packages/SettingsLib/res/values-ur/arrays.xml
+++ b/packages/SettingsLib/res/values-ur/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"آڈیو ماخذ"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-uz/arrays.xml b/packages/SettingsLib/res/values-uz/arrays.xml
index da14d78..860761e0 100644
--- a/packages/SettingsLib/res/values-uz/arrays.xml
+++ b/packages/SettingsLib/res/values-uz/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"Audio manbasi"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-vi/arrays.xml b/packages/SettingsLib/res/values-vi/arrays.xml
index 29858bd..4c6392b 100644
--- a/packages/SettingsLib/res/values-vi/arrays.xml
+++ b/packages/SettingsLib/res/values-vi/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"Nguồn âm thanh"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-zh-rCN/arrays.xml b/packages/SettingsLib/res/values-zh-rCN/arrays.xml
index 1eb597a..679098a 100644
--- a/packages/SettingsLib/res/values-zh-rCN/arrays.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"音频来源"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-zh-rHK/arrays.xml b/packages/SettingsLib/res/values-zh-rHK/arrays.xml
index e14f719..746ac68 100644
--- a/packages/SettingsLib/res/values-zh-rHK/arrays.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"音效檔案來源"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-zh-rTW/arrays.xml b/packages/SettingsLib/res/values-zh-rTW/arrays.xml
index 16890be..b7fb99b 100644
--- a/packages/SettingsLib/res/values-zh-rTW/arrays.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"音訊來源"</item>
<item msgid="8688681727755534982">"MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/res/values-zu/arrays.xml b/packages/SettingsLib/res/values-zu/arrays.xml
index d20c7db..63b19e2 100644
--- a/packages/SettingsLib/res/values-zu/arrays.xml
+++ b/packages/SettingsLib/res/values-zu/arrays.xml
@@ -282,6 +282,4 @@
<item msgid="8828567335701536560">"Umthombo Womsindo"</item>
<item msgid="8688681727755534982">"I-MIDI"</item>
</string-array>
- <string-array name="avatar_image_descriptions">
- </string-array>
</resources>
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcast.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcast.java
index 79fb566..a05a6e9 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcast.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcast.java
@@ -237,7 +237,8 @@
"startBroadcast: language = " + language + " ,programInfo = " + programInfo);
}
buildContentMetadata(language, programInfo);
- mService.startBroadcast(mBluetoothLeAudioContentMetadata, mBroadcastCode);
+ mService.startBroadcast(mBluetoothLeAudioContentMetadata,
+ (mBroadcastCode != null && mBroadcastCode.length > 0) ? mBroadcastCode : null);
}
public String getProgramInfo() {
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaDevice.java b/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaDevice.java
index 632120e..b10d794 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaDevice.java
@@ -19,6 +19,7 @@
import static android.media.MediaRoute2Info.TYPE_REMOTE_CAR;
import static android.media.MediaRoute2Info.TYPE_REMOTE_COMPUTER;
import static android.media.MediaRoute2Info.TYPE_REMOTE_GAME_CONSOLE;
+import static android.media.MediaRoute2Info.TYPE_REMOTE_SMARTPHONE;
import static android.media.MediaRoute2Info.TYPE_REMOTE_SMARTWATCH;
import static android.media.MediaRoute2Info.TYPE_REMOTE_SPEAKER;
import static android.media.MediaRoute2Info.TYPE_REMOTE_TABLET;
@@ -103,6 +104,9 @@
case TYPE_REMOTE_SMARTWATCH:
resId = R.drawable.ic_media_smartwatch;
break;
+ case TYPE_REMOTE_SMARTPHONE:
+ resId = R.drawable.ic_smartphone;
+ break;
case TYPE_REMOTE_SPEAKER:
default:
resId = R.drawable.ic_media_speaker_device;
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java b/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java
index 0bd9384..a1beed8 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java
@@ -26,6 +26,7 @@
import static android.media.MediaRoute2Info.TYPE_REMOTE_CAR;
import static android.media.MediaRoute2Info.TYPE_REMOTE_COMPUTER;
import static android.media.MediaRoute2Info.TYPE_REMOTE_GAME_CONSOLE;
+import static android.media.MediaRoute2Info.TYPE_REMOTE_SMARTPHONE;
import static android.media.MediaRoute2Info.TYPE_REMOTE_SMARTWATCH;
import static android.media.MediaRoute2Info.TYPE_REMOTE_SPEAKER;
import static android.media.MediaRoute2Info.TYPE_REMOTE_TABLET;
@@ -566,8 +567,8 @@
case TYPE_REMOTE_GAME_CONSOLE:
case TYPE_REMOTE_CAR:
case TYPE_REMOTE_SMARTWATCH:
- mediaDevice =
- createInfoMediaDevice(route, mPreferenceItemMap.get(route.getId()));
+ case TYPE_REMOTE_SMARTPHONE:
+ mediaDevice = createInfoMediaDevice(route, mPreferenceItemMap.get(route.getId()));
break;
case TYPE_BUILTIN_SPEAKER:
case TYPE_USB_DEVICE:
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InfoMediaDeviceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InfoMediaDeviceTest.java
index 67a045e..19a3db2 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InfoMediaDeviceTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InfoMediaDeviceTest.java
@@ -20,6 +20,7 @@
import static android.media.MediaRoute2Info.TYPE_REMOTE_CAR;
import static android.media.MediaRoute2Info.TYPE_REMOTE_COMPUTER;
import static android.media.MediaRoute2Info.TYPE_REMOTE_GAME_CONSOLE;
+import static android.media.MediaRoute2Info.TYPE_REMOTE_SMARTPHONE;
import static android.media.MediaRoute2Info.TYPE_REMOTE_SMARTWATCH;
import static android.media.MediaRoute2Info.TYPE_REMOTE_SPEAKER;
import static android.media.MediaRoute2Info.TYPE_REMOTE_TABLET;
@@ -143,5 +144,9 @@
assertThat(mInfoMediaDevice.getDrawableResIdByType()).isEqualTo(
R.drawable.ic_media_smartwatch);
+
+ when(mRouteInfo.getType()).thenReturn(TYPE_REMOTE_SMARTPHONE);
+
+ assertThat(mInfoMediaDevice.getDrawableResIdByType()).isEqualTo(R.drawable.ic_smartphone);
}
}
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index 3a38b69..9c70a70 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -3558,11 +3558,11 @@
if (isSecureSettingsKey(key)) {
maybeNotifyProfiles(getTypeFromKey(key), userId, uri, name,
sSecureCloneToManagedSettings);
- maybeNotifyProfiles(SETTINGS_TYPE_SYSTEM, userId, uri, name,
- sSystemCloneFromParentOnDependency.values());
} else if (isSystemSettingsKey(key)) {
maybeNotifyProfiles(getTypeFromKey(key), userId, uri, name,
sSystemCloneToManagedSettings);
+ maybeNotifyProfiles(SETTINGS_TYPE_SYSTEM, userId, uri, name,
+ sSystemCloneFromParentOnDependency.keySet());
}
}
@@ -5118,14 +5118,15 @@
Secure.ACCESSIBILITY_MAGNIFICATION_CAPABILITY);
final boolean supportMagnificationArea = getContext().getResources().getBoolean(
com.android.internal.R.bool.config_magnification_area);
- final int capability = supportMagnificationArea
- ? R.integer.def_accessibility_magnification_capabilities
- : Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN;
final String supportShowPrompt = supportMagnificationArea ? "1" : "0";
if (magnificationCapabilities.isNull()) {
+ final int capability = supportMagnificationArea
+ ? getContext().getResources().getInteger(
+ R.integer.def_accessibility_magnification_capabilities)
+ : Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN;
secureSettings.insertSettingLocked(
Secure.ACCESSIBILITY_MAGNIFICATION_CAPABILITY,
- String.valueOf(getContext().getResources().getInteger(capability)),
+ String.valueOf(capability),
null, true, SettingsState.SYSTEM_PACKAGE_NAME);
if (isMagnificationSettingsOn(secureSettings)) {
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-be/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-be/strings.xml
index 572d25c..db1e8b5 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/res/values-be/strings.xml
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-be/strings.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="accessibility_menu_service_name" msgid="730136711554740131">"Спецыяльныя магчымасці"</string>
+ <string name="accessibility_menu_service_name" msgid="730136711554740131">"Меню спецыяльных магчымасцей"</string>
<string name="accessibility_menu_intro" msgid="3164193281544042394">"Меню спецыяльных магчымасцей – гэта вялікае экраннае меню для кіравання прыладай. Вы можаце блакіраваць прыладу, рэгуляваць гучнасць і яркасць, рабіць здымкі экрана і выконваць іншыя дзеянні."</string>
<string name="assistant_label" msgid="6796392082252272356">"Памочнік"</string>
<string name="assistant_utterance" msgid="65509599221141377">"Памочнік"</string>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-el/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-el/strings.xml
index 60e49ae..c51c9af 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/res/values-el/strings.xml
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-el/strings.xml
@@ -5,7 +5,7 @@
<string name="accessibility_menu_intro" msgid="3164193281544042394">"Το μενού προσβασιμότητας παρέχει ένα μεγάλο μενού στην οθόνη για να ελέγχετε τη συσκευή σας. Μπορείτε να κλειδώνετε τη συσκευή, να ελέγχετε την ένταση ήχου και τη φωτεινότητα, να λαμβάνετε στιγμιότυπα οθόνης και άλλα."</string>
<string name="assistant_label" msgid="6796392082252272356">"Βοηθός"</string>
<string name="assistant_utterance" msgid="65509599221141377">"Βοηθός"</string>
- <string name="a11y_settings_label" msgid="3977714687248445050">"Ρυθμίσεις προσβU+00ADασιμότητας"</string>
+ <string name="a11y_settings_label" msgid="3977714687248445050">"Ρυθμίσεις προσβασιμότητας"</string>
<string name="power_label" msgid="7699720321491287839">"Κουμπί λειτουργίας"</string>
<string name="power_utterance" msgid="7444296686402104807">"Επιλογές λειτουργίας"</string>
<string name="recent_apps_label" msgid="6583276995616385847">"Πρόσφατες εφαρμογές"</string>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/view/A11yMenuAdapter.java b/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/view/A11yMenuAdapter.java
index 6ae65cb..c64ec6f 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/view/A11yMenuAdapter.java
+++ b/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/view/A11yMenuAdapter.java
@@ -16,6 +16,7 @@
package com.android.systemui.accessibility.accessibilitymenu.view;
+import android.content.Context;
import android.graphics.Rect;
import android.view.LayoutInflater;
import android.view.TouchDelegate;
@@ -47,10 +48,11 @@
private final ShortcutDrawableUtils mShortcutDrawableUtils;
public A11yMenuAdapter(
- AccessibilityMenuService service, List<A11yMenuShortcut> shortcutDataList) {
+ AccessibilityMenuService service,
+ Context displayContext, List<A11yMenuShortcut> shortcutDataList) {
this.mService = service;
this.mShortcutDataList = shortcutDataList;
- mInflater = LayoutInflater.from(service);
+ mInflater = LayoutInflater.from(displayContext);
mShortcutDrawableUtils = new ShortcutDrawableUtils(service);
@@ -75,7 +77,9 @@
@Override
public View getView(int position, View convertView, ViewGroup parent) {
- convertView = mInflater.inflate(R.layout.grid_item, null);
+ if (convertView == null) {
+ convertView = mInflater.inflate(R.layout.grid_item, parent, false);
+ }
A11yMenuShortcut shortcutItem = (A11yMenuShortcut) getItem(position);
// Sets shortcut icon and label resource.
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/view/A11yMenuOverlayLayout.java b/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/view/A11yMenuOverlayLayout.java
index 5b7bbe8..edd6a48 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/view/A11yMenuOverlayLayout.java
+++ b/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/view/A11yMenuOverlayLayout.java
@@ -17,11 +17,13 @@
package com.android.systemui.accessibility.accessibilitymenu.view;
import static android.view.Display.DEFAULT_DISPLAY;
+import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY;
import static java.lang.Math.max;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
+import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Insets;
import android.graphics.PixelFormat;
@@ -135,15 +137,13 @@
initLayoutParams();
}
- final Display display = mService.getSystemService(
- DisplayManager.class).getDisplay(DEFAULT_DISPLAY);
-
- mLayout = new FrameLayout(
- mService.createDisplayContext(display).createWindowContext(
- WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY, null));
+ final Display display = mDisplayManager.getDisplay(DEFAULT_DISPLAY);
+ final Context context = mService.createDisplayContext(display).createWindowContext(
+ TYPE_ACCESSIBILITY_OVERLAY, null);
+ mLayout = new FrameLayout(context);
updateLayoutPosition();
- inflateLayoutAndSetOnTouchListener(mLayout);
- mA11yMenuViewPager = new A11yMenuViewPager(mService);
+ inflateLayoutAndSetOnTouchListener(mLayout, context);
+ mA11yMenuViewPager = new A11yMenuViewPager(mService, context);
mA11yMenuViewPager.configureViewPagerAndFooter(mLayout, createShortcutList(), pageIndex);
mWindowManager.addView(mLayout, mLayoutParameter);
mLayout.setVisibility(lastVisibilityState);
@@ -169,8 +169,8 @@
mLayoutParameter.setTitle(mService.getString(R.string.accessibility_menu_service_name));
}
- private void inflateLayoutAndSetOnTouchListener(ViewGroup view) {
- LayoutInflater inflater = LayoutInflater.from(mService);
+ private void inflateLayoutAndSetOnTouchListener(ViewGroup view, Context displayContext) {
+ LayoutInflater inflater = LayoutInflater.from(displayContext);
inflater.inflate(R.layout.paged_menu, view);
view.setOnTouchListener(mService);
}
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/view/A11yMenuViewPager.java b/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/view/A11yMenuViewPager.java
index 0a349e5..b969017 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/view/A11yMenuViewPager.java
+++ b/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/view/A11yMenuViewPager.java
@@ -147,8 +147,12 @@
/** The container layout for a11y menu. */
private ViewGroup mA11yMenuLayout;
- public A11yMenuViewPager(AccessibilityMenuService service) {
+ /** Display context for inflating views. */
+ private Context mDisplayContext;
+
+ public A11yMenuViewPager(AccessibilityMenuService service, Context displayContext) {
this.mService = service;
+ this.mDisplayContext = displayContext;
}
/**
@@ -213,10 +217,11 @@
}
private void addGridPage(List<A11yMenuShortcut> shortcutDataListInPage) {
- LayoutInflater inflater = LayoutInflater.from(mService);
+ LayoutInflater inflater = LayoutInflater.from(mDisplayContext);
View view = inflater.inflate(R.layout.grid_view, null);
GridView gridView = view.findViewById(R.id.gridview);
- A11yMenuAdapter adapter = new A11yMenuAdapter(mService, shortcutDataListInPage);
+ A11yMenuAdapter adapter = new A11yMenuAdapter(
+ mService, mDisplayContext, shortcutDataListInPage);
gridView.setNumColumns(GridViewParams.getGridColumnCount(mService));
gridView.setAdapter(adapter);
mGridPageList.add(gridView);
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewLaunchAnimatorController.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewLaunchAnimatorController.kt
index 23e3a01..1a03ede 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewLaunchAnimatorController.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewLaunchAnimatorController.kt
@@ -34,7 +34,6 @@
import android.view.ViewGroupOverlay
import android.widget.FrameLayout
import com.android.internal.jank.InteractionJankMonitor
-import java.lang.IllegalArgumentException
import java.util.LinkedList
import kotlin.math.min
import kotlin.math.roundToInt
@@ -240,7 +239,7 @@
val ghostView = this.ghostView ?: return
val backgroundView = this.backgroundView!!
- if (!state.visible) {
+ if (!state.visible || !ghostedView.isAttachedToWindow) {
if (ghostView.visibility == View.VISIBLE) {
// Making the ghost view invisible will make the ghosted view visible, so order is
// important here.
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PinBouncer.kt b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PinBouncer.kt
index f801434..323fed0 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PinBouncer.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PinBouncer.kt
@@ -21,11 +21,14 @@
import android.view.HapticFeedbackConstants
import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.animation.animateColorAsState
+import androidx.compose.animation.core.Animatable
import androidx.compose.animation.core.AnimationSpec
+import androidx.compose.animation.core.AnimationVector1D
import androidx.compose.animation.core.MutableTransitionState
import androidx.compose.animation.core.Transition
import androidx.compose.animation.core.animateDp
import androidx.compose.animation.core.animateDpAsState
+import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.core.keyframes
import androidx.compose.animation.core.snap
import androidx.compose.animation.core.tween
@@ -58,6 +61,7 @@
import androidx.compose.ui.draw.drawBehind
import androidx.compose.ui.geometry.CornerRadius
import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.layout.Layout
import androidx.compose.ui.platform.LocalView
@@ -67,6 +71,7 @@
import com.android.compose.animation.Easings
import com.android.compose.grid.VerticalGrid
import com.android.systemui.R
+import com.android.systemui.bouncer.ui.viewmodel.ActionButtonAppearance
import com.android.systemui.bouncer.ui.viewmodel.EnteredKey
import com.android.systemui.bouncer.ui.viewmodel.PinBouncerViewModel
import com.android.systemui.common.shared.model.ContentDescription
@@ -76,6 +81,7 @@
import kotlin.time.Duration.Companion.milliseconds
import kotlin.time.DurationUnit
import kotlinx.coroutines.async
+import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
@@ -87,78 +93,13 @@
// Report that the UI is shown to let the view-model run some logic.
LaunchedEffect(Unit) { viewModel.onShown() }
- val isInputEnabled: Boolean by viewModel.isInputEnabled.collectAsState()
- val animateFailure: Boolean by viewModel.animateFailure.collectAsState()
-
- // Show the failure animation if the user entered the wrong input.
- LaunchedEffect(animateFailure) {
- if (animateFailure) {
- showFailureAnimation()
- viewModel.onFailureAnimationShown()
- }
- }
-
Column(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = modifier,
) {
PinInputDisplay(viewModel)
-
Spacer(Modifier.height(100.dp))
-
- VerticalGrid(
- columns = 3,
- verticalSpacing = 12.dp,
- horizontalSpacing = 20.dp,
- ) {
- repeat(9) { index ->
- val digit = index + 1
- PinButton(
- onClicked = { viewModel.onPinButtonClicked(digit) },
- isEnabled = isInputEnabled,
- ) { contentColor ->
- PinDigit(digit, contentColor)
- }
- }
-
- PinButton(
- onClicked = { viewModel.onBackspaceButtonClicked() },
- onLongPressed = { viewModel.onBackspaceButtonLongPressed() },
- isEnabled = isInputEnabled,
- isIconButton = true,
- ) { contentColor ->
- PinIcon(
- Icon.Resource(
- res = R.drawable.ic_backspace_24dp,
- contentDescription =
- ContentDescription.Resource(R.string.keyboardview_keycode_delete),
- ),
- contentColor,
- )
- }
-
- PinButton(
- onClicked = { viewModel.onPinButtonClicked(0) },
- isEnabled = isInputEnabled,
- ) { contentColor ->
- PinDigit(0, contentColor)
- }
-
- PinButton(
- onClicked = { viewModel.onAuthenticateButtonClicked() },
- isEnabled = isInputEnabled,
- isIconButton = true,
- ) { contentColor ->
- PinIcon(
- Icon.Resource(
- res = R.drawable.ic_keyboard_tab_36dp,
- contentDescription =
- ContentDescription.Resource(R.string.keyboardview_keycode_enter),
- ),
- contentColor,
- )
- }
- }
+ PinPad(viewModel)
}
}
@@ -305,38 +246,153 @@
}
@Composable
-private fun PinDigit(
+private fun PinPad(viewModel: PinBouncerViewModel) {
+ val isInputEnabled: Boolean by viewModel.isInputEnabled.collectAsState()
+ val backspaceButtonAppearance by viewModel.backspaceButtonAppearance.collectAsState()
+ val confirmButtonAppearance by viewModel.confirmButtonAppearance.collectAsState()
+ val animateFailure: Boolean by viewModel.animateFailure.collectAsState()
+
+ val buttonScaleAnimatables = remember { List(12) { Animatable(1f) } }
+ LaunchedEffect(animateFailure) {
+ // Show the failure animation if the user entered the wrong input.
+ if (animateFailure) {
+ showFailureAnimation(buttonScaleAnimatables)
+ viewModel.onFailureAnimationShown()
+ }
+ }
+
+ VerticalGrid(
+ columns = 3,
+ verticalSpacing = 12.dp,
+ horizontalSpacing = 20.dp,
+ ) {
+ repeat(9) { index ->
+ DigitButton(
+ index + 1,
+ isInputEnabled,
+ viewModel::onPinButtonClicked,
+ buttonScaleAnimatables[index]::value,
+ )
+ }
+
+ ActionButton(
+ icon =
+ Icon.Resource(
+ res = R.drawable.ic_backspace_24dp,
+ contentDescription =
+ ContentDescription.Resource(R.string.keyboardview_keycode_delete),
+ ),
+ isInputEnabled = isInputEnabled,
+ onClicked = viewModel::onBackspaceButtonClicked,
+ onLongPressed = viewModel::onBackspaceButtonLongPressed,
+ appearance = backspaceButtonAppearance,
+ scaling = buttonScaleAnimatables[9]::value,
+ )
+
+ DigitButton(
+ 0,
+ isInputEnabled,
+ viewModel::onPinButtonClicked,
+ buttonScaleAnimatables[10]::value,
+ )
+
+ ActionButton(
+ icon =
+ Icon.Resource(
+ res = R.drawable.ic_keyboard_tab_36dp,
+ contentDescription =
+ ContentDescription.Resource(R.string.keyboardview_keycode_enter),
+ ),
+ isInputEnabled = isInputEnabled,
+ onClicked = viewModel::onAuthenticateButtonClicked,
+ appearance = confirmButtonAppearance,
+ scaling = buttonScaleAnimatables[11]::value,
+ )
+ }
+}
+
+@Composable
+private fun DigitButton(
digit: Int,
- contentColor: Color,
+ isInputEnabled: Boolean,
+ onClicked: (Int) -> Unit,
+ scaling: () -> Float,
) {
- // TODO(b/281878426): once "color: () -> Color" (added to BasicText in aosp/2568972) makes it
- // into Text, use that here, to animate more efficiently.
- Text(
- text = digit.toString(),
- style = MaterialTheme.typography.headlineLarge,
- color = contentColor,
- )
+ PinPadButton(
+ onClicked = { onClicked(digit) },
+ isEnabled = isInputEnabled,
+ backgroundColor = MaterialTheme.colorScheme.surfaceVariant,
+ foregroundColor = MaterialTheme.colorScheme.onSurfaceVariant,
+ modifier =
+ Modifier.graphicsLayer {
+ val scale = scaling()
+ scaleX = scale
+ scaleY = scale
+ }
+ ) { contentColor ->
+ // TODO(b/281878426): once "color: () -> Color" (added to BasicText in aosp/2568972) makes
+ // it into Text, use that here, to animate more efficiently.
+ Text(
+ text = digit.toString(),
+ style = MaterialTheme.typography.headlineLarge,
+ color = contentColor(),
+ )
+ }
}
@Composable
-private fun PinIcon(
+private fun ActionButton(
icon: Icon,
- contentColor: Color,
+ isInputEnabled: Boolean,
+ onClicked: () -> Unit,
+ onLongPressed: (() -> Unit)? = null,
+ appearance: ActionButtonAppearance,
+ scaling: () -> Float,
) {
- Icon(
- icon = icon,
- tint = contentColor,
- )
+ val isHidden = appearance == ActionButtonAppearance.Hidden
+ val hiddenAlpha by animateFloatAsState(if (isHidden) 0f else 1f, label = "Action button alpha")
+
+ val foregroundColor =
+ when (appearance) {
+ ActionButtonAppearance.Shown -> MaterialTheme.colorScheme.onSecondaryContainer
+ else -> MaterialTheme.colorScheme.onSurface
+ }
+ val backgroundColor =
+ when (appearance) {
+ ActionButtonAppearance.Shown -> MaterialTheme.colorScheme.secondaryContainer
+ else -> MaterialTheme.colorScheme.surface
+ }
+
+ PinPadButton(
+ onClicked = onClicked,
+ onLongPressed = onLongPressed,
+ isEnabled = isInputEnabled && !isHidden,
+ backgroundColor = backgroundColor,
+ foregroundColor = foregroundColor,
+ modifier =
+ Modifier.graphicsLayer {
+ alpha = hiddenAlpha
+ val scale = scaling()
+ scaleX = scale
+ scaleY = scale
+ }
+ ) { contentColor ->
+ Icon(
+ icon = icon,
+ tint = contentColor(),
+ )
+ }
}
@Composable
-private fun PinButton(
+private fun PinPadButton(
onClicked: () -> Unit,
isEnabled: Boolean,
+ backgroundColor: Color,
+ foregroundColor: Color,
modifier: Modifier = Modifier,
onLongPressed: (() -> Unit)? = null,
- isIconButton: Boolean = false,
- content: @Composable (contentColor: Color) -> Unit,
+ content: @Composable (contentColor: () -> Color) -> Unit,
) {
var isPressed: Boolean by remember { mutableStateOf(false) }
@@ -370,18 +426,16 @@
animateColorAsState(
when {
isPressed -> MaterialTheme.colorScheme.primary
- isIconButton -> MaterialTheme.colorScheme.secondaryContainer
- else -> MaterialTheme.colorScheme.surfaceVariant
+ else -> backgroundColor
},
label = "Pin button container color",
animationSpec = colorAnimationSpec
)
- val contentColor: Color by
+ val contentColor =
animateColorAsState(
when {
isPressed -> MaterialTheme.colorScheme.onPrimary
- isIconButton -> MaterialTheme.colorScheme.onSecondaryContainer
- else -> MaterialTheme.colorScheme.onSurfaceVariant
+ else -> foregroundColor
},
label = "Pin button container color",
animationSpec = colorAnimationSpec
@@ -420,17 +474,46 @@
}
},
) {
- content(contentColor)
+ content(contentColor::value)
}
}
-private fun showFailureAnimation() {
- // TODO(b/282730134): implement.
+private suspend fun showFailureAnimation(
+ buttonScaleAnimatables: List<Animatable<Float, AnimationVector1D>>
+) {
+ coroutineScope {
+ buttonScaleAnimatables.forEachIndexed { index, animatable ->
+ launch {
+ animatable.animateTo(
+ targetValue = pinButtonErrorShrinkFactor,
+ animationSpec =
+ tween(
+ durationMillis = pinButtonErrorShrinkMs,
+ delayMillis = index * pinButtonErrorStaggerDelayMs,
+ easing = Easings.Linear,
+ ),
+ )
+
+ animatable.animateTo(
+ targetValue = 1f,
+ animationSpec =
+ tween(
+ durationMillis = pinButtonErrorRevertMs,
+ easing = Easings.Legacy,
+ ),
+ )
+ }
+ }
+ }
}
private val entryShapeSize = 16.dp
private val pinButtonSize = 84.dp
+private val pinButtonErrorShrinkFactor = 67.dp / pinButtonSize
+private const val pinButtonErrorShrinkMs = 50
+private const val pinButtonErrorStaggerDelayMs = 33
+private const val pinButtonErrorRevertMs = 617
// Pin button motion spec: http://shortn/_9TTIG6SoEa
private val pinButtonPressedDuration = 100.milliseconds
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockRegistry.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockRegistry.kt
index 702cc05..1443465 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockRegistry.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockRegistry.kt
@@ -56,6 +56,7 @@
"com.android.systemui.falcon.four" to listOf(ClockMetadata("DIGITAL_CLOCK_GROWTH")),
"com.android.systemui.falcon.five" to listOf(ClockMetadata("DIGITAL_CLOCK_HANDWRITTEN")),
"com.android.systemui.falcon.six" to listOf(ClockMetadata("DIGITAL_CLOCK_INFLATE")),
+ "com.android.systemui.falcon.seven" to listOf(ClockMetadata("DIGITAL_CLOCK_METRO")),
"com.android.systemui.falcon.eight" to listOf(ClockMetadata("DIGITAL_CLOCK_NUMBEROVERLAP")),
"com.android.systemui.falcon.nine" to listOf(ClockMetadata("DIGITAL_CLOCK_WEATHER")),
)
@@ -112,6 +113,7 @@
val logBuffer: LogBuffer? = null,
val keepAllLoaded: Boolean,
subTag: String,
+ var isTransitClockEnabled: Boolean = false,
) {
private val TAG = "${ClockRegistry::class.simpleName} ($subTag)"
interface ClockChangeListener {
@@ -203,6 +205,10 @@
var isClockListChanged = false
for (clock in plugin.getClocks()) {
val id = clock.clockId
+ if (!isTransitClockEnabled && id == "DIGITAL_CLOCK_METRO") {
+ continue
+ }
+
val info =
availableClocks.concurrentGetOrPut(id, ClockInfo(clock, plugin, manager)) {
isClockListChanged = true
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/customization/data/content/CustomizationProviderContract.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/customization/data/content/CustomizationProviderContract.kt
index b6d5ef3..95a9ce9 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/customization/data/content/CustomizationProviderContract.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/customization/data/content/CustomizationProviderContract.kt
@@ -184,6 +184,9 @@
/** Flag denoting AI Wallpapers are enabled in wallpaper picker. */
const val FLAG_NAME_WALLPAPER_PICKER_UI_FOR_AIWP = "wallpaper_picker_ui_for_aiwp"
+ /** Flag denoting transit clock are enabled in wallpaper picker. */
+ const val FLAG_NAME_TRANSIT_CLOCK = "lockscreen_custom_transit_clock"
+
object Columns {
/** String. Unique ID for the flag. */
const val NAME = "name"
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/WeatherData.kt b/packages/SystemUI/plugin/src/com/android/systemui/plugins/WeatherData.kt
index a4b1cee..f83fa33 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/WeatherData.kt
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/WeatherData.kt
@@ -2,14 +2,18 @@
import android.os.Bundle
import android.util.Log
+import android.view.View
import androidx.annotation.VisibleForTesting
+typealias WeatherTouchAction = (View) -> Unit
+
class WeatherData
constructor(
val description: String,
val state: WeatherStateIcon,
val useCelsius: Boolean,
val temperature: Int,
+ val touchAction: WeatherTouchAction? = null,
) {
companion object {
const val DEBUG = true
@@ -20,7 +24,7 @@
@VisibleForTesting const val TEMPERATURE_KEY = "temperature"
private const val INVALID_WEATHER_ICON_STATE = -1
- fun fromBundle(extras: Bundle): WeatherData? {
+ fun fromBundle(extras: Bundle, touchAction: WeatherTouchAction? = null): WeatherData? {
val description = extras.getString(DESCRIPTION_KEY)
val state =
WeatherStateIcon.fromInt(extras.getInt(STATE_KEY, INVALID_WEATHER_ICON_STATE))
@@ -41,7 +45,8 @@
description = description,
state = state,
useCelsius = extras.getBoolean(USE_CELSIUS_KEY),
- temperature = temperature
+ temperature = temperature,
+ touchAction = touchAction
)
if (DEBUG) {
Log.i(TAG, "Weather data parsed $result from $extras")
diff --git a/packages/SystemUI/res-keyguard/values-af/strings.xml b/packages/SystemUI/res-keyguard/values-af/strings.xml
index 39b4183..4bd19465 100644
--- a/packages/SystemUI/res-keyguard/values-af/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-af/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"Borrel"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"Analoog"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"Ontsluit jou toestel om voort te gaan"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"Voer PIN in om opdatering later te installeer"</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"Voer wagwoord in om opdatering later te installeer"</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"Teken patroon om opdatering later te installeer"</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"Toestel is opgedateer. Voer PIN in om voort te gaan."</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"Toestel is opgedateer. Voer wagwoord in om voort te gaan."</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"Toestel is opgedateer. Teken patroon om voort te gaan."</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-am/strings.xml b/packages/SystemUI/res-keyguard/values-am/strings.xml
index e175007..daa25e7 100644
--- a/packages/SystemUI/res-keyguard/values-am/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-am/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"አረፋ"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"አናሎግ"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"ለመቀጠል መሣሪያዎን ይክፈቱ"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"ዝማኔን በኋላ ላይ ለመጫን ፒን ያስገቡ"</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"ዝማኔን በኋላ ላይ ለመጫን የይለፍ ቃል ያስገቡ"</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"ዝማኔን በኋላ ላይ ለመጫን ስርዓተ ጥለት ይሳሉ"</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"መሣሪያ ዘምኗል። ለመቀጠል ፒን ያስገቡ።"</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"መሣሪያ ዘምኗል። ለመቀጠል የይለፍ ቃል ያስገቡ።"</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"መሣሪያ ዘምኗል። ለመቀጠል ሥርዓተ ጥለት ይሳሉ።"</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-ar/strings.xml b/packages/SystemUI/res-keyguard/values-ar/strings.xml
index fa0fb44..1215c34 100644
--- a/packages/SystemUI/res-keyguard/values-ar/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ar/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"فقاعة"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"ساعة تقليدية"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"يجب فتح قفل الجهاز للمتابعة"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"أدخِل رقم التعريف الشخصي لتثبيت التحديث لاحقًا."</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"أدخِل كلمة المرور لتثبيت التحديث لاحقًا."</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"ارسم النقش لتثبيت التحديث لاحقًا."</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"تم تحديث الجهاز. أدخِل رقم التعريف الشخصي للمتابعة."</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"تم تحديث الجهاز. أدخِل كلمة المرور للمتابعة."</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"تم تحديث الجهاز. ارسم النقش للمتابعة."</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-as/strings.xml b/packages/SystemUI/res-keyguard/values-as/strings.xml
index 5ecf15a..7e43a29 100644
--- a/packages/SystemUI/res-keyguard/values-as/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-as/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"বাবল"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"এনাল’গ"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"অব্যাহত ৰাখিবলৈ আপোনাৰ ডিভাইচটো আনলক কৰক"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"আপডে’ট পাছত ইনষ্টল কৰিবলৈ পিন দিয়ক"</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"আপডে’ট পাছত ইনষ্টল কৰিবলৈ পাছৱৰ্ড দিয়ক"</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"আপডে’ট পাছত ইনষ্টল কৰিবলৈ আৰ্হি আঁকক"</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"ডিভাইচ আপডে’ট কৰা হ’ল। অব্যাহত ৰাখিবলৈ পিন দিয়ক।"</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"ডিভাইচ আপডে’ট কৰা হ’ল। অব্যাহত ৰাখিবলৈ পাছৱৰ্ড দিয়ক।"</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"ডিভাইচ আপডে’ট কৰা হ’ল। অব্যাহত ৰাখিবলৈ আৰ্হি আঁকক।"</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-az/strings.xml b/packages/SystemUI/res-keyguard/values-az/strings.xml
index 6eb36bd..37d9f0e 100644
--- a/packages/SystemUI/res-keyguard/values-az/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-az/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"Qabarcıq"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"Analoq"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"Davam etmək üçün cihazınızın kilidini açın"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"Güncəllənməni sonra quraşdırmaq üçün PIN daxil edin"</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"Güncəllənməni sonra quraşdırmaq üçün parol daxil edin"</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"Güncəllənməni sonra quraşdırmaq üçün model çəkin"</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"Cihaz güncəlləndi. Davam etmək üçün PIN daxil edin."</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"Cihaz güncəlləndi. Davam etmək üçün parol daxil edin."</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"Cihaz güncəlləndi. Davam etmək üçün model çəkin."</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-b+sr+Latn/strings.xml b/packages/SystemUI/res-keyguard/values-b+sr+Latn/strings.xml
index fb18f1a..d8de1ef 100644
--- a/packages/SystemUI/res-keyguard/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-b+sr+Latn/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"Mehurići"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"Analogni"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"Otključajte uređaj da biste nastavili"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"Unesite PIN da biste kasnije istalirali ažuriranje"</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"Unesite lozinku da biste kasnije instalirali ažuriranje"</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"Nacrtajte šablon da biste kasnije instalirali ažuriranje"</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"Uređaj je ažuriran. Unesite PIN da biste nastavili."</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"Uređaj je ažuriran. Unesite lozinku da biste nastavili."</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"Uređaj je ažuriran. Nacrtajte šablon da biste nastavili."</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-be/strings.xml b/packages/SystemUI/res-keyguard/values-be/strings.xml
index 4781c3a..f66ccc7 100644
--- a/packages/SystemUI/res-keyguard/values-be/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-be/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"Бурбалкі"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"Са стрэлкамі"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"Каб працягнуць, разблакіруйце прыладу"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"Увядзіце PIN-код, каб усталяваць абнаўленне пазней"</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"Увядзіце пароль, каб усталяваць абнаўленне пазней"</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"Увядзіце ўзор разблакіроўкі, каб усталяваць абнаўленне пазней"</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"Прылада абноўлена. Каб працягнуць, увядзіце PIN-код."</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"Прылада абноўлена. Каб працягнуць, увядзіце пароль."</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"Прылада абноўлена. Каб працягнуць, увядзіце ўзор разблакіроўкі."</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-bg/strings.xml b/packages/SystemUI/res-keyguard/values-bg/strings.xml
index da1c52b..646f7f9 100644
--- a/packages/SystemUI/res-keyguard/values-bg/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-bg/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"Балонен"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"Аналогов"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"Отключете устройството, за да продължите"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"Въведете ПИН код, за да инсталирате актуализацията по-късно"</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"Въведете парола, за да инсталирате актуализацията по-късно"</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"Начертайте фигура, за да инсталирате актуализацията по-късно"</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"Устройството е актуализирано. Въведете ПИН код, за да продължите."</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"Устройството е актуализирано. Въведете парола, за да продължите."</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"Устройството е актуализирано. Начертайте фигура, за да продължите."</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-bn/strings.xml b/packages/SystemUI/res-keyguard/values-bn/strings.xml
index 4dcceab..23eb418 100644
--- a/packages/SystemUI/res-keyguard/values-bn/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-bn/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"বাবল"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"অ্যানালগ"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"চালিয়ে যেতে আপনার ডিভাইস আনলক করুন"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"পরে ইনস্টল আপডেট করতে পিন লিখুন"</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"পরে আপডেট ইনস্টল করতে পাসওয়ার্ড লিখুন"</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"পরে আপডেট ইনস্টল করতে প্যাটার্ন আঁকুন"</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"ডিভাইস আপডেট করা হয়েছে। চালিয়ে যেতে পিন লিখুন।"</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"ডিভাইস আপডেট করা হয়েছে। চালিয়ে যেতে পাসওয়ার্ড লিখুন।"</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"ডিভাইস আপডেট করা হয়েছে। চালিয়ে যেতে প্যাটার্ন আঁকুন।"</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-bs/strings.xml b/packages/SystemUI/res-keyguard/values-bs/strings.xml
index 5d8c508..3ed0958 100644
--- a/packages/SystemUI/res-keyguard/values-bs/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-bs/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"Mjehurići"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"Analogni"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"Otključajte uređaj da nastavite"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"Unesite PIN da kasnije instalirate ažuriranje"</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"Unesite lozinku da kasnije instalirate ažuriranje"</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"Unesite uzorak da kasnije instalirate ažuriranje"</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"Uređaj je ažuriran. Unesite PIN da nastavite."</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"Uređaj je ažuriran. Unesite lozinku da nastavite."</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"Uređaj je ažuriran. Unesite uzorak da nastavite."</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-ca/strings.xml b/packages/SystemUI/res-keyguard/values-ca/strings.xml
index 04b6a3d..bd1e4a1 100644
--- a/packages/SystemUI/res-keyguard/values-ca/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ca/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"Bombolla"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"Analògica"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"Desbloqueja el dispositiu per continuar"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"Introdueix el PIN per instal·lar l\'actualització més tard"</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"Introdueix la contrasenya per instal·lar l\'actualització més tard"</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"Dibuixa el patró per instal·lar l\'actualització més tard"</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"Dispositiu actualitzat. Introdueix el PIN per continuar."</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"Dispositiu actualitzat. Introdueix la contrasenya per continuar."</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"Dispositiu actualitzat. Dibuixa el patró per continuar."</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-cs/strings.xml b/packages/SystemUI/res-keyguard/values-cs/strings.xml
index 22f46a0..88890bb 100644
--- a/packages/SystemUI/res-keyguard/values-cs/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-cs/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"Bublina"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"Analogové"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"Pokud chcete pokračovat, odemkněte zařízení"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"Pokud aktualizaci chcete nainstalovat později, zadejte PIN"</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"Pokud aktualizaci chcete nainstalovat později, zadejte heslo"</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"Pokud aktualizaci chcete nainstalovat později, zadejte gesto"</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"Zařízení bylo aktualizováno. Pokud chcete pokračovat, zadejte PIN."</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"Zařízení bylo aktualizováno. Pokud chcete pokračovat, zadejte heslo."</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"Zařízení bylo aktualizováno. Pokud chcete pokračovat, zadejte gesto."</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-da/strings.xml b/packages/SystemUI/res-keyguard/values-da/strings.xml
index 5f3c2e7..c4ea98a 100644
--- a/packages/SystemUI/res-keyguard/values-da/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-da/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"Boble"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"Analog"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"Lås din enhed op for at fortsætte"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"Angiv din pinkode for at installere opdateringen senere"</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"Angiv din adgangskode for at installere opdateringen senere"</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"Tegn dit mønster for at installere opdateringen senere"</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"Enheden er opdateret. Angiv din pinkode for at fortsætte."</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"Enheden er opdateret. Angiv din adgangskode for at fortsætte."</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"Enheden er opdateret. Tegn dit mønster for at fortsætte."</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-de/strings.xml b/packages/SystemUI/res-keyguard/values-de/strings.xml
index 05fcced..223e74c7 100644
--- a/packages/SystemUI/res-keyguard/values-de/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-de/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"Bubble"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"Analog"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"Gerät entsperren, um fortzufahren"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"Gib deine PIN ein, um das Update später zu installieren"</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"Gib dein Passwort ein, um das Update später zu installieren"</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"Zeichne dein Muster, um das Update später zu installieren"</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"Gerät aktualisiert. Gib deine PIN ein, um fortzufahren."</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"Gerät aktualisiert. Gib dein Passwort ein, um fortzufahren."</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"Gerät aktualisiert. Zeichne dein Muster, um fortzufahren."</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-el/strings.xml b/packages/SystemUI/res-keyguard/values-el/strings.xml
index d042b78..6ee323a 100644
--- a/packages/SystemUI/res-keyguard/values-el/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-el/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"Συννεφάκι"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"Αναλογικό"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"Ξεκλειδώστε τη συσκευή σας για να συνεχίσετε"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"Εισαγάγετε το PIN για να εγκαταστήσετε την ενημέρωση αργότερα"</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"Εισαγ. τον κωδ. πρόσβασης για να εγκαταστήσετε την ενημέρωση αργότερα"</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"Σχεδιάστε το μοτίβο για να εγκαταστήσετε την ενημέρωση αργότερα"</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"Η συσκευή ενημερώθηκε. Εισαγάγετε το PIN για να συνεχίσετε."</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"Η συσκευή ενημερώθηκε. Εισαγάγ. τον κωδ. πρόσβασης για να συνεχίσετε."</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"Η συσκευή ενημερώθηκε. Σχεδιάστε το μοτίβο για να συνεχίσετε."</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-en-rAU/strings.xml b/packages/SystemUI/res-keyguard/values-en-rAU/strings.xml
index 10b82a4..5130670 100644
--- a/packages/SystemUI/res-keyguard/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-en-rAU/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"Bubble"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"Analogue"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"Unlock your device to continue"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"Enter PIN to install update later"</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"Enter password to install update later"</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"Draw pattern to install update later"</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"Device updated Enter PIN to continue."</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"Device updated Enter password to continue."</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"Device updated Draw pattern to continue."</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-en-rCA/strings.xml b/packages/SystemUI/res-keyguard/values-en-rCA/strings.xml
index e134d9e..9457489 100644
--- a/packages/SystemUI/res-keyguard/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-en-rCA/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"Bubble"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"Analog"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"Unlock your device to continue"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"Enter PIN to install update later"</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"Enter password to install update later"</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"Draw pattern to install update later"</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"Device updated. Enter PIN to continue."</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"Device updated. Enter password to continue."</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"Device updated. Draw pattern to continue."</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-en-rGB/strings.xml b/packages/SystemUI/res-keyguard/values-en-rGB/strings.xml
index 10b82a4..5130670 100644
--- a/packages/SystemUI/res-keyguard/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-en-rGB/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"Bubble"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"Analogue"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"Unlock your device to continue"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"Enter PIN to install update later"</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"Enter password to install update later"</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"Draw pattern to install update later"</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"Device updated Enter PIN to continue."</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"Device updated Enter password to continue."</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"Device updated Draw pattern to continue."</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-en-rIN/strings.xml b/packages/SystemUI/res-keyguard/values-en-rIN/strings.xml
index 10b82a4..5130670 100644
--- a/packages/SystemUI/res-keyguard/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-en-rIN/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"Bubble"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"Analogue"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"Unlock your device to continue"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"Enter PIN to install update later"</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"Enter password to install update later"</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"Draw pattern to install update later"</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"Device updated Enter PIN to continue."</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"Device updated Enter password to continue."</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"Device updated Draw pattern to continue."</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-en-rXC/strings.xml b/packages/SystemUI/res-keyguard/values-en-rXC/strings.xml
index ff9d4f3..b2520d79 100644
--- a/packages/SystemUI/res-keyguard/values-en-rXC/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-en-rXC/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"Bubble"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"Analog"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"Unlock your device to continue"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"Enter PIN to install update later"</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"Enter password to install update later"</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"Draw pattern to install update later"</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"Device updated. Enter PIN to continue."</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"Device updated. Enter password to continue."</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"Device updated. Draw pattern to continue."</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-es-rUS/strings.xml b/packages/SystemUI/res-keyguard/values-es-rUS/strings.xml
index be1c44f..8c5b7bc 100644
--- a/packages/SystemUI/res-keyguard/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-es-rUS/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"Burbuja"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"Analógico"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"Desbloquea tu dispositivo para continuar"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"Ingresa el PIN para instalar la actualización más tarde."</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"Ingresa la contraseña para instalar la actualización más tarde."</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"Dibuja el patrón para instalar la actualización más tarde."</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"Dispositivo actualizado. Ingresa el PIN para continuar."</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"Dispositivo actualizado. Ingresa la contraseña para continuar."</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"Dispositivo actualizado. Dibuja el patrón para continuar."</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-es/strings.xml b/packages/SystemUI/res-keyguard/values-es/strings.xml
index aa09cf9..811e33a 100644
--- a/packages/SystemUI/res-keyguard/values-es/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-es/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"Burbuja"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"Analógico"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"Desbloquea tu dispositivo para continuar"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"Introduce el PIN para instalar la actualización más tarde"</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"Introduce la contraseña para instalar la actualización más tarde"</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"Dibuja el patrón para instalar la actualización más tarde"</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"Dispositivo actualizado. Introduce el PIN para continuar."</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"Dispositivo actualizado. Introduce la contraseña para continuar."</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"Dispositivo actualizado. Dibuja el patrón para continuar."</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-et/strings.xml b/packages/SystemUI/res-keyguard/values-et/strings.xml
index d6c7f3f..4846412 100644
--- a/packages/SystemUI/res-keyguard/values-et/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-et/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"Mull"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"Analoog"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"Jätkamiseks avage oma seade"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"Sisestage PIN-kood, et värskendus hiljem installida"</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"Sisestage parool, et värskendus hiljem installida"</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"Joonistage muster, et värskendus hiljem installida"</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"Seadet värskendati. Jätkamiseks sisestage PIN-kood."</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"Seadet värskendati. Jätkamiseks sisestage parool."</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"Seadet värskendati. Jätkamiseks joonistage muster."</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-eu/strings.xml b/packages/SystemUI/res-keyguard/values-eu/strings.xml
index 4d4c3f9..351bada 100644
--- a/packages/SystemUI/res-keyguard/values-eu/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-eu/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"Puxikak"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"Analogikoa"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"Aurrera egiteko, desblokeatu gailua"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"Eguneratzea geroago instalatzeko, idatzi PINa"</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"Eguneratzea geroago instalatzeko, idatzi pasahitza"</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"Eguneratzea geroago instalatzeko, marraztu eredua"</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"Eguneratu egin da gailua. Aurrera egiteko, idatzi PINa."</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"Eguneratu egin da gailua. Aurrera egiteko, idatzi pasahitza."</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"Eguneratu egin da gailua. Aurrera egiteko, marraztu eredua."</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-fa/strings.xml b/packages/SystemUI/res-keyguard/values-fa/strings.xml
index 91a15a4..8063873 100644
--- a/packages/SystemUI/res-keyguard/values-fa/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-fa/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"حباب"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"آنالوگ"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"برای ادامه، قفل دستگاهتان را باز کنید"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"برای نصب بهروزرسانی در فرصتی دیگر، پین را وارد کنید"</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"برای نصب بهروزرسانی در فرصتی دیگر، گذرواژه را وارد کنید"</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"برای نصب بهروزرسانی در فرصتی دیگر، الگو را وارد کنید"</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"دستگاه بهروز شد. برای ادامه، پین را وارد کنید."</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"دستگاه بهروز شد. برای ادامه، گذرواژه را وارد کنید."</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"دستگاه بهروز شد. برای ادامه، الگو را وارد کنید."</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-fi/strings.xml b/packages/SystemUI/res-keyguard/values-fi/strings.xml
index 7db4fea..f96f61f 100644
--- a/packages/SystemUI/res-keyguard/values-fi/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-fi/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"Kupla"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"Analoginen"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"Jatka avaamalla laitteen lukitus"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"Jos haluat asentaa päivityksen myöhemmin, lisää PIN-koodi"</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"Jos haluat asentaa päivityksen myöhemmin, lisää salasana"</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"Jos haluat asentaa päivityksen myöhemmin, piirrä kuvio"</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"Laite päivitetty. Jatka lisäämällä PIN-koodi."</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"Laite päivitetty. Jatka lisäämällä salasana."</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"Laite päivitetty. Jatka piirtämällä kuvio."</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-fr-rCA/strings.xml b/packages/SystemUI/res-keyguard/values-fr-rCA/strings.xml
index a1dbb9f..e880c1e 100644
--- a/packages/SystemUI/res-keyguard/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-fr-rCA/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"Bulle"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"Analogique"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"Déverrouillez votre appareil pour continuer"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"Entrez le NIP pour installer la mise à jour plus tard"</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"Entrez le mot de passe pour installer la mise à jour plus tard"</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"Dessinez le schéma pour installer la mise à jour plus tard"</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"Appareil mis à jour. Entrez le NIP pour continuer."</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"Appareil mis à jour. Entrez le mot de passe pour continuer."</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"Appareil mis à jour. Dessinez le schéma pour continuer."</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-fr/strings.xml b/packages/SystemUI/res-keyguard/values-fr/strings.xml
index f746db0..f2f037f 100644
--- a/packages/SystemUI/res-keyguard/values-fr/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-fr/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"Bulle"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"Analogique"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"Déverrouillez votre appareil pour continuer"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"Saisissez le code pour installer la mise à jour plus tard"</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"Saisissez le mot de passe pour installer la mise à jour plus tard"</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"Dessinez le schéma pour installer la mise à jour plus tard"</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"Appareil mis à jour. Saisissez le code pour continuer."</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"Appareil mis à jour. Saisissez le mot de passe pour continuer."</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"Appareil mis à jour. Dessinez le schéma pour continuer."</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-gl/strings.xml b/packages/SystemUI/res-keyguard/values-gl/strings.xml
index 6f4b667..2cc2ec2 100644
--- a/packages/SystemUI/res-keyguard/values-gl/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-gl/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"Burbulla"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"Analóxico"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"Desbloquea o dispositivo para continuar"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"Mete o PIN para instalar a actualización máis tarde"</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"Mete o contrasinal para instalar a actualización máis tarde"</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"Debuxa o padrón para instalar a actualización máis tarde"</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"Actualizouse o dispositivo. Mete o PIN para continuar."</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"Actualizouse o dispositivo. Mete o contrasinal para continuar."</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"Actualizouse o dispositivo. Debuxa o padrón para continuar."</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-gu/strings.xml b/packages/SystemUI/res-keyguard/values-gu/strings.xml
index 5c2d09b..c574e4f 100644
--- a/packages/SystemUI/res-keyguard/values-gu/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-gu/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"બબલ"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"એનાલોગ"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"ચાલુ રાખવા માટે તમારા ડિવાઇસને અનલૉક કરો"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"પછીથી અપડેટ ઇન્સ્ટૉલ કરવા માટે પિન દાખલ કરો"</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"પછીથી અપડેટ ઇન્સ્ટૉલ કરવા માટે પાસવર્ડ દાખલ કરો"</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"પછીથી અપડેટ ઇન્સ્ટૉલ કરવા માટે પૅટર્ન દોરો"</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"ડિવાઇસ અપડેટ કર્યું. ચાલુ રાખવા માટે પિન દાખલ કરો."</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"ડિવાઇસ અપડેટ કર્યું. ચાલુ રાખવા માટે પાસવર્ડ દાખલ કરો."</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"ડિવાઇસ અપડેટ કર્યું. ચાલુ રાખવા માટે પૅટર્ન દોરો."</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-hi/strings.xml b/packages/SystemUI/res-keyguard/values-hi/strings.xml
index 10c7aaf..5d43c32 100644
--- a/packages/SystemUI/res-keyguard/values-hi/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-hi/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"बबल"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"एनालॉग"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"जारी रखने के लिए डिवाइस अनलॉक करें"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"अपडेट को बाद में इंस्टॉल करने के लिए पिन डालें"</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"अपडेट को बाद में इंस्टॉल करने के लिए पासवर्ड डालें"</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"अपडेट को बाद में इंस्टॉल करने के लिए पैटर्न ड्रॉ करें"</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"डिवाइस अपडेट किया गया. जारी रखने के लिए पिन डालें."</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"डिवाइस अपडेट किया गया. जारी रखने के लिए पासवर्ड डालें."</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"डिवाइस अपडेट किया गया. जारी रखने के लिए पैटर्न ड्रॉ करें."</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-hr/strings.xml b/packages/SystemUI/res-keyguard/values-hr/strings.xml
index 045c904..6d65df6 100644
--- a/packages/SystemUI/res-keyguard/values-hr/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-hr/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"Mjehurić"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"Analogni"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"Otključajte uređaj da biste nastavili"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"Unesite PIN da biste ažuriranje instalirali kasnije"</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"Unesite zaporku da biste ažuriranje instalirali kasnije"</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"Nacrtajte uzorak da biste ažuriranje instalirali kasnije"</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"Uređaj je ažuriran. Unesite PIN da biste nastavili."</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"Uređaj je ažuriran. Unesite zaporku da biste nastavili."</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"Uređaj je ažuriran. Nacrtajte uzorak da biste nastavili."</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-hu/strings.xml b/packages/SystemUI/res-keyguard/values-hu/strings.xml
index a98408c..f1183af 100644
--- a/packages/SystemUI/res-keyguard/values-hu/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-hu/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"Buborék"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"Analóg"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"A folytatáshoz oldja fel az eszközét"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"A frissítés később történő telepítéséhez adja meg a PIN-kódot"</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"A frissítés később történő telepítéséhez adja meg a jelszót"</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"A frissítés később történő telepítéséhez rajzolja le a mintát"</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"Eszköz frissítve. A folytatáshoz adja meg a PIN-kódot."</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"Eszköz frissítve. A folytatáshoz adja meg a jelszót."</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"Eszköz frissítve. A folytatáshoz rajzolja le a mintát."</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-hy/strings.xml b/packages/SystemUI/res-keyguard/values-hy/strings.xml
index 985f77ac..bbff378 100644
--- a/packages/SystemUI/res-keyguard/values-hy/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-hy/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"Պղպջակ"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"Անալոգային"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"Շարունակելու համար ապակողպեք սարքը"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"Թարմացումն ավելի ուշ տեղադրելու համար մուտքագրեք PIN կոդը"</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"Թարմացումն ավելի ուշ տեղադրելու համար մուտքագրեք գաղտնաբառը"</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"Թարմացումն ավելի ուշ տեղադրելու համար գծեք նախշը"</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"Սարքը թարմացվեց։ Շարունակելու համար մուտքագրեք PIN կոդը։"</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"Սարքը թարմացվեց։ Շարունակելու համար մուտքագրեք գաղտնաբառը։"</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"Սարքը թարմացվեց։ Շարունակելու համար գծեք նախշը։"</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-in/strings.xml b/packages/SystemUI/res-keyguard/values-in/strings.xml
index 1ba3278..46390bf 100644
--- a/packages/SystemUI/res-keyguard/values-in/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-in/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"Balon"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"Analog"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"Buka kunci perangkat untuk melanjutkan"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"Masukkan PIN untuk menginstal update nanti"</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"Masukkan sandi untuk menginstal update nanti"</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"Gambar pola untuk menginstal update nanti"</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"Perangkat diupdate. Masukkan PIN untuk melanjutkan."</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"Perangkat diupdate. Masukkan sandi untuk melanjutkan."</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"Perangkat diupdate. Gambar pola untuk melanjutkan."</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-is/strings.xml b/packages/SystemUI/res-keyguard/values-is/strings.xml
index 1f8687f..4099241 100644
--- a/packages/SystemUI/res-keyguard/values-is/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-is/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"Blaðra"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"Með vísum"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"Taktu tækið úr lás til að halda áfram"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"Sláðu inn PIN-númer til að setja uppfærsluna upp síðar"</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"Sláðu inn aðgangsorð til að setja uppfærsluna upp síðar"</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"Teiknaðu mynstur til að setja uppfærsluna upp síðar"</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"Tæki uppfært. Sláðu inn PIN-númer til að halda áfram."</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"Tæki uppfært. Sláðu inn aðgangsorð til að halda áfram."</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"Tæki uppfært. Teiknaðu mynstur til að halda áfram."</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-it/strings.xml b/packages/SystemUI/res-keyguard/values-it/strings.xml
index bdfeda7..bc1922f 100644
--- a/packages/SystemUI/res-keyguard/values-it/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-it/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"Bolla"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"Analogico"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"Sblocca il dispositivo per continuare"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"Inserisci il PIN per installare l\'aggiornamento più tardi"</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"Inserisci la password per installare l\'aggiornamento più tardi"</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"Inserisci la sequenza per installare l\'aggiornamento più tardi"</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"Dispositivo aggiornato. Inserisci il PIN per continuare."</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"Dispositivo aggiornato. Inserisci la password per continuare."</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"Dispositivo aggiornato. Inserisci la sequenza per continuare."</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-iw/strings.xml b/packages/SystemUI/res-keyguard/values-iw/strings.xml
index 08cdd79..7b641dc 100644
--- a/packages/SystemUI/res-keyguard/values-iw/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-iw/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"בועה"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"אנלוגי"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"צריך לבטל את הנעילה של המכשיר כדי להמשיך"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"צריך להזין את קוד האימות כדי להתקין את העדכון מאוחר יותר"</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"צריך להזין את הסיסמה כדי להתקין את העדכון מאוחר יותר"</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"צריך למתוח את קו ביטול הנעילה כדי להתקין את העדכון מאוחר יותר"</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"המכשיר עודכן. צריך להזין את קוד האימות כדי להמשיך."</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"המכשיר עודכן. צריך להזין את הסיסמה כדי להמשיך."</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"המכשיר עודכן. צריך למתוח את קו ביטול הנעילה כדי להמשיך."</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-ja/strings.xml b/packages/SystemUI/res-keyguard/values-ja/strings.xml
index 666f9b1..6babdd7 100644
--- a/packages/SystemUI/res-keyguard/values-ja/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ja/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"バブル"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"アナログ"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"続行するにはデバイスのロックを解除します"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"アップデートを後でインストールするには、PIN を入力してください"</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"アップデートを後でインストールするには、パスワードを入力してください"</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"アップデートを後でインストールするには、パターンを入力してください"</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"デバイスの更新が完了しました。PIN を入力して続行してください。"</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"デバイスの更新が完了しました。パスワードを入力して続行してください。"</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"デバイスの更新が完了しました。パターンを入力して続行してください。"</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-ka/strings.xml b/packages/SystemUI/res-keyguard/values-ka/strings.xml
index c979641..c2d22f7 100644
--- a/packages/SystemUI/res-keyguard/values-ka/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ka/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"ბუშტი"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"ანალოგური"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"გასაგრძელებლად განბლოკეთ მოწყობილობა"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"განახლების მოგვიანებით ინსტალაციისთვის PIN-კოდი შეიყვანეთ"</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"განახლების მოგვიანებით ინსტალაციისთვის პაროლი შეიყვანეთ"</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"განახლების მოგვიანებით ინსტალაციისთვის ნიმუში დახაზეთ"</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"მოწყობილობა განახლებულია. გასაგრძელებლად PIN-კოდი შეიყვანეთ."</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"მოწყობილობა განახლებულია. გასაგრძელებლად პაროლი შეიყვანეთ."</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"მოწყობილობა განახლებულია. გასაგრძელებლად ნიმუში დახაზეთ."</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-kk/strings.xml b/packages/SystemUI/res-keyguard/values-kk/strings.xml
index 97658c1..d922b23 100644
--- a/packages/SystemUI/res-keyguard/values-kk/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-kk/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"Көпіршік"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"Аналогтық"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"Жалғастыру үшін құлыпты ашыңыз"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"Жаңа нұсқаны кейінірек орнату үшін PIN кодын енгізіңіз"</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"Жаңа нұсқаны кейінірек орнату үшін құпия сөзді енгізіңіз"</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"Жаңа нұсқаны кейінірек орнату үшін өрнекті салыңыз"</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"Құрылғы жаңартылды. Жалғастыру үшін PIN кодын енгізіңіз."</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"Құрылғы жаңартылды. Жалғастыру үшін құпия сөзді енгізіңіз."</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"Құрылғы жаңартылды. Жалғастыру үшін өрнекті салыңыз."</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-km/strings.xml b/packages/SystemUI/res-keyguard/values-km/strings.xml
index 4aa4798..dac9002 100644
--- a/packages/SystemUI/res-keyguard/values-km/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-km/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"ពពុះ"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"អាណាឡូក"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"ដោះសោឧបករណ៍របស់អ្នកដើម្បីបន្ត"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"បញ្ចូលកូដ PIN ដើម្បីដំឡើងកំណែថ្មីនៅពេលក្រោយ"</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"បញ្ចូលពាក្យសម្ងាត់ ដើម្បីដំឡើងកំណែថ្មីនៅពេលក្រោយ"</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"គូរលំនាំ ដើម្បីដំឡើងកំណែថ្មីនៅពេលក្រោយ"</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"ឧបករណ៍ត្រូវបានដំឡើងកំណែ។ សូមបញ្ចូលកូដ PIN ដើម្បីបន្ត។"</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"ឧបករណ៍ត្រូវបានដំឡើងកំណែ។ សូមបញ្ចូលពាក្យសម្ងាត់ដើម្បីបន្ត។"</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"ឧបករណ៍ត្រូវបានដំឡើងកំណែ។ សូមគូរលំនាំដើម្បីបន្ត។"</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-kn/strings.xml b/packages/SystemUI/res-keyguard/values-kn/strings.xml
index 8b0d60c..7303585 100644
--- a/packages/SystemUI/res-keyguard/values-kn/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-kn/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"ಬಬಲ್"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"ಅನಲಾಗ್"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"ಮುಂದುವರಿಸಲು, ನಿಮ್ಮ ಸಾಧನವನ್ನು ಅನ್ಲಾಕ್ ಮಾಡಿ"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"ಅಪ್ಡೇಟ್ ಅನ್ನು ಆನಂತರ ಇನ್ಸ್ಟಾಲ್ ಮಾಡಲು ಪಿನ್ ಅನ್ನು ನಮೂದಿಸಿ"</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"ಅಪ್ಡೇಟ್ ಅನ್ನು ಆನಂತರ ಇನ್ಸ್ಟಾಲ್ ಮಾಡಲು ಪಾಸ್ವರ್ಡ್ ನಮೂದಿಸಿ"</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"ಅಪ್ಡೇಟ್ ಅನ್ನು ಆನಂತರ ಇನ್ಸ್ಟಾಲ್ ಮಾಡಲು ಪ್ಯಾಟರ್ನ್ ಅನ್ನು ಬಿಡಿಸಿ"</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"ಸಾಧನವನ್ನು ಅಪ್ಡೇಟ್ ಮಾಡಲಾಗಿದೆ. ಮುಂದುವರಿಸಲು ಪಿನ್ ಅನ್ನು ನಮೂದಿಸಿ."</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"ಸಾಧನವನ್ನು ಅಪ್ಡೇಟ್ ಮಾಡಲಾಗಿದೆ. ಮುಂದುವರಿಸಲು ಪಾಸ್ವರ್ಡ್ ನಮೂದಿಸಿ."</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"ಸಾಧನವನ್ನು ಅಪ್ಡೇಟ್ ಮಾಡಲಾಗಿದೆ. ಮುಂದುವರಿಸಲು ಪ್ಯಾಟರ್ನ್ ಅನ್ನು ಬಿಡಿಸಿ."</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-ko/strings.xml b/packages/SystemUI/res-keyguard/values-ko/strings.xml
index cfd053c..5787258 100644
--- a/packages/SystemUI/res-keyguard/values-ko/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ko/strings.xml
@@ -61,7 +61,7 @@
<string name="kg_wrong_pin" msgid="4160978845968732624">"잘못된 PIN"</string>
<string name="kg_wrong_pin_try_again" msgid="3129729383303430190">"잘못된 PIN입니다. 다시 시도해 주세요."</string>
<string name="kg_wrong_input_try_fp_suggestion" msgid="3143861542242024833">"또는 지문으로 잠금 해제하세요."</string>
- <string name="kg_fp_not_recognized" msgid="5183108260932029241">"지문이 인식되지 않았습니다."</string>
+ <string name="kg_fp_not_recognized" msgid="5183108260932029241">"지문이 인식되지 않았습니다"</string>
<string name="bouncer_face_not_recognized" msgid="1666128054475597485">"얼굴을 인식할 수 없습니다."</string>
<string name="kg_bio_try_again_or_pin" msgid="4752168242723808390">"다시 시도하거나 PIN을 입력하세요."</string>
<string name="kg_bio_try_again_or_password" msgid="1473132729225398039">"다시 시도하거나 비밀번호를 입력하세요."</string>
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"버블"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"아날로그"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"계속하려면 기기 잠금 해제"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"나중에 업데이트를 설치하려면 PIN을 입력하세요."</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"나중에 업데이트를 설치하려면 비밀번호를 입력하세요."</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"나중에 업데이트를 설치하려면 패턴을 그리세요."</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"기기가 업데이트되었습니다. 계속하려면 PIN을 입력하세요."</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"기기가 업데이트되었습니다. 계속 진행하려면 비밀번호를 입력하세요."</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"기기가 업데이트되었습니다. 계속하려면 패턴을 그리세요."</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-ky/strings.xml b/packages/SystemUI/res-keyguard/values-ky/strings.xml
index f32d27f..9e5c7ab 100644
--- a/packages/SystemUI/res-keyguard/values-ky/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ky/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"Көбүк"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"Аналог"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"Улантуу үчүн түзмөгүңүздүн кулпусун ачыңыз"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"Кийинчерээк жаңыртуу үчүн PIN кодду териңиз"</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"Кийинчерээк жаңыртуу үчүн сырсөздү териңиз"</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"Кийинчерээк жаңыртуу үчүн графикалык ачкычты тартыңыз"</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"Түзмөк жаңырды. Улантуу үчүн PIN кодду териңиз."</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"Түзмөк жаңырды. Улантуу үчүн сырсөздү териңиз."</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"Түзмөк жаңырды. Улантуу үчүн графикалык ачкычты тартыңыз."</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-lo/strings.xml b/packages/SystemUI/res-keyguard/values-lo/strings.xml
index deb6a15..ac766e5 100644
--- a/packages/SystemUI/res-keyguard/values-lo/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-lo/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"ຟອງ"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"ໂມງເຂັມ"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"ປົດລັອກອຸປະກອນຂອງທ່ານເພື່ອສືບຕໍ່"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"ໃສ່ PIN ເພື່ອຕິດຕັ້ງອັບເດດໃນພາຍຫຼັງ"</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"ໃສ່ລະຫັດຜ່ານເພື່ອຕິດຕັ້ງອັບເດດໃນພາຍຫຼັງ"</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"ແຕ້ມຮູບແບບເພື່ອຕິດຕັ້ງອັບເດດໃນພາຍຫຼັງ"</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"ອັບເດດອຸປະກອນແລ້ວ. ໃສ່ PIN ເພື່ອສືບຕໍ່."</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"ອັບເດດອຸປະກອນແລ້ວ. ໃສ່ລະຫັດຜ່ານເພື່ອສືບຕໍ່."</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"ອັບເດດອຸປະກອນແລ້ວ. ແຕ້ມຮູບແບບເພື່ອສືບຕໍ່."</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-lt/strings.xml b/packages/SystemUI/res-keyguard/values-lt/strings.xml
index 4e154b0..5e47622 100644
--- a/packages/SystemUI/res-keyguard/values-lt/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-lt/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"Debesėlis"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"Analoginis"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"Atrakinkite įrenginį norėdami tęsti"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"Įveskite PIN kodą, kad įdiegtumėte naujinį vėliau"</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"Įveskite slaptažodį, kad įdiegtumėte naujinį vėliau"</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"Nubrėžkite atrakinimo piešinį, kad įdiegtumėte naujinį vėliau"</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"Įrenginys atnaujintas. Įveskite PIN kodą, kad galėtumėte tęsti."</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"Įrenginys atnaujintas. Įveskite slaptažodį, kad galėtumėte tęsti."</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"Įrenginys atnaujintas. Nubrėžkite atrakinimo piešinį, kad gal. tęsti."</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-lv/strings.xml b/packages/SystemUI/res-keyguard/values-lv/strings.xml
index 5d992f8..5277671 100644
--- a/packages/SystemUI/res-keyguard/values-lv/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-lv/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"Burbuļi"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"Analogais"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"Lai turpinātu, atbloķējiet ierīci"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"Ievadiet PIN, lai instalētu atjauninājumu vēlāk."</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"Ievadiet paroli, lai instalētu atjauninājumu vēlāk."</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"Zīmējiet kombināciju, lai instalētu atjauninājumu vēlāk."</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"Ierīce ir atjaunināta. Ievadiet PIN, lai turpinātu."</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"Ierīce ir atjaunināta. Ievadiet paroli, lai turpinātu."</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"Ierīce ir atjaunināta. Zīmējiet kombināciju, lai turpinātu."</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-mk/strings.xml b/packages/SystemUI/res-keyguard/values-mk/strings.xml
index e39cc95..5a35808 100644
--- a/packages/SystemUI/res-keyguard/values-mk/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-mk/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"Балонче"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"Аналоген"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"Отклучете го уредот за да продолжите"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"Внесете PIN за да го инсталирате ажурирањето подоцна"</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"Внесете ја лозинката за да го инсталирате ажурирањето подоцна"</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"Нацртајте ја шемата за да го инсталирате ажурирањето подоцна"</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"Уредот е ажуриран. Внесете PIN за да продолжите."</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"Уредот е ажуриран. Внесете лозинка за да продолжите."</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"Уредот е ажуриран. Нацртајте ја шемата за да продолжите."</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-ml/strings.xml b/packages/SystemUI/res-keyguard/values-ml/strings.xml
index 8181357..20f5b4d 100644
--- a/packages/SystemUI/res-keyguard/values-ml/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ml/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"ബബിൾ"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"അനലോഗ്"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"തുടരാൻ നിങ്ങളുടെ ഉപകരണം അൺലോക്ക് ചെയ്യുക"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"അപ്ഡേറ്റ് പിന്നീട് ഇൻസ്റ്റാൾ ചെയ്യാൻ പിൻ നൽകുക"</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"അപ്ഡേറ്റ് പിന്നീട് ഇൻസ്റ്റാൾ ചെയ്യാൻ പാസ്വേഡ് നൽകുക"</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"അപ്ഡേറ്റ് പിന്നീട് ഇൻസ്റ്റാൾ ചെയ്യാൻ പാറ്റേൺ വരയ്ക്കുക"</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"ഉപകരണം അപ്ഡേറ്റ് ചെയ്തു. തുടരുന്നതിന് പിൻ നൽകുക."</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"ഉപകരണം അപ്ഡേറ്റ് ചെയ്തു. തുടരുന്നതിന് പാസ്വേഡ് നൽകുക."</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"ഉപകരണം അപ്ഡേറ്റ് ചെയ്തു. തുടരുന്നതിന് പാറ്റേൺ വരയ്ക്കുക."</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-mn/strings.xml b/packages/SystemUI/res-keyguard/values-mn/strings.xml
index 54def0c..b326d3ed 100644
--- a/packages/SystemUI/res-keyguard/values-mn/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-mn/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"Бөмбөлөг"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"Aналог"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"Үргэлжлүүлэхийн тулд төхөөрөмжийнхөө түгжээг тайлна уу"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"Дараа шинэчлэлт суулгахын тулд ПИН оруулна уу"</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"Дараа шинэчлэлт суулгахын тулд нууц үг оруулна уу"</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"Дараа шинэчлэлт суулгахын тулд хээ зурна уу"</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"Төхөөрөмжийг шинэчилсэн. Үргэлжлүүлэхийн тулд ПИН оруулна уу."</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"Төхөөрөмжийг шинэчилсэн. Үргэлжлүүлэхийн тулд нууц үг оруулна уу."</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"Төхөөрөмжийг шинэчилсэн. Үргэлжлүүлэхийн тулд хээ зурна уу."</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-mr/strings.xml b/packages/SystemUI/res-keyguard/values-mr/strings.xml
index 206bdf2..1e25e17 100644
--- a/packages/SystemUI/res-keyguard/values-mr/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-mr/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"बबल"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"अॅनालॉग"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"पुढे सुरू ठेवण्यासाठी तुमचे डिव्हाइस अनलॉक करा"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"नंतर अपडेट इंस्टॉल करण्यासाठी पिन एंटर करा"</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"नंतर अपडेट इंस्टॉल करण्यासाठी पासवर्ड एंटर करा"</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"नंतर अपडेट इंस्टॉल करण्यासाठी पॅटर्न ड्रॉ करा"</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"डिव्हाइस अपडेट केले आहे. पुढे सुरू ठेवण्यासाठी पिन एंटर करा."</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"डिव्हाइस अपडेट केले आहे. पुढे सुरू ठेवण्यासाठी पासवर्ड एंटर करा."</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"डिव्हाइस अपडेट केले आहे. पुढे सुरू ठेवण्यासाठी पॅटर्न ड्रॉ करा."</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-ms/strings.xml b/packages/SystemUI/res-keyguard/values-ms/strings.xml
index 2c42f2b..3942dbb 100644
--- a/packages/SystemUI/res-keyguard/values-ms/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ms/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"Gelembung"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"Analog"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"Buka kunci peranti untuk meneruskan"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"Masukkan PIN untuk memasang kemaskinian kemudian"</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"Masukkan kata laluan untuk memasang kemaskinian kemudian"</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"Lukis corak untuk memasang kemaskinian kemudian"</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"Peranti dikemaskinikan. Masukkan PIN untuk meneruskan."</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"Peranti dikemaskinikan. Masukkan kata laluan untuk meneruskan."</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"Peranti dikemaskinikan. Lukis corak untuk meneruskan."</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-my/strings.xml b/packages/SystemUI/res-keyguard/values-my/strings.xml
index a2c4aae..311e072 100644
--- a/packages/SystemUI/res-keyguard/values-my/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-my/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"ပူဖောင်းကွက်"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"ရိုးရိုး"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"ရှေ့ဆက်ရန် သင့်စက်ကိုဖွင့်ပါ"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"နောက်ပိုင်းတွင် အပ်ဒိတ်ထည့်သွင်းရန် ပင်နံပါတ်ထည့်ပါ"</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"နောက်ပိုင်းတွင် အပ်ဒိတ်ထည့်သွင်းရန် စကားဝှက်ထည့်ပါ"</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"နောက်ပိုင်းတွင် အပ်ဒိတ်ထည့်သွင်းရန် ပုံဖော်ရေးဆွဲပါ"</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"စက်ပစ္စည်း အပ်ဒိတ်လုပ်ထားသည်။ ရှေ့ဆက်ရန် ပင်နံပါတ်ထည့်ပါ။"</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"စက်ပစ္စည်း အပ်ဒိတ်လုပ်ထားသည်။ ရှေ့ဆက်ရန် စကားဝှက်ထည့်ပါ။"</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"စက်ပစ္စည်း အပ်ဒိတ်လုပ်ထားသည်။ ရှေ့ဆက်ရန် ပုံဖော်ရေးဆွဲပါ။"</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-nb/strings.xml b/packages/SystemUI/res-keyguard/values-nb/strings.xml
index 501d836..94a6340 100644
--- a/packages/SystemUI/res-keyguard/values-nb/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-nb/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"Boble"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"Analog"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"Lås opp enheten for å fortsette"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"Oppgi PIN-koden for å installere oppdateringen senere"</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"Oppgi passordet for å installere oppdateringen senere"</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"Tegn mønsteret for å installere oppdateringen senere"</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"Enheten er oppdatert. Oppgi PIN-koden for å fortsette."</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"Enheten er oppdatert. Oppgi passordet for å fortsette."</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"Enheten er oppdatert. Tegn mønsteret for å fortsette."</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-ne/strings.xml b/packages/SystemUI/res-keyguard/values-ne/strings.xml
index c89855d..0b4a4a5 100644
--- a/packages/SystemUI/res-keyguard/values-ne/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ne/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"बबल"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"एनालग"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"आफ्नो डिभाइस अनलक गरी जारी राख्नुहोस्"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"पछि अपडेट इन्स्टल गर्न PIN हाल्नुहोस्"</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"पछि अपडेट इन्स्टल गर्न पासवर्ड हाल्नुहोस्"</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"पछि अपडेट इन्स्टल गर्न प्याटर्न बनाउनुहोस्"</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"डिभाइस अपडेट गरिएको छ। जारी राख्न PIN हाल्नुहोस्।"</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"डिभाइस अपडेट गरिएको छ। जारी राख्न पासवर्ड हाल्नुहोस्।"</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"डिभाइस अपडेट गरिएको छ। जारी राख्न प्याटर्न बनाउनुहोस्।"</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-nl/strings.xml b/packages/SystemUI/res-keyguard/values-nl/strings.xml
index 9b8b72d..c394fb6 100644
--- a/packages/SystemUI/res-keyguard/values-nl/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-nl/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"Bel"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"Analoog"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"Ontgrendel je apparaat om door te gaan"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"Voer de pincode in om de update later te installeren"</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"Voer het wachtwoord in om de update later te installeren"</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"Teken het patroon om de update later te installeren"</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"Apparaat geüpdatet. Voer de pincode in om door te gaan."</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"Apparaat geüpdatet. Voer het wachtwoord in om door te gaan."</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"Apparaat geüpdatet. Teken het patroon om door te gaan."</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-or/strings.xml b/packages/SystemUI/res-keyguard/values-or/strings.xml
index bcf5984..666dab5 100644
--- a/packages/SystemUI/res-keyguard/values-or/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-or/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"ବବଲ୍"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"ଆନାଲଗ୍"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"ଜାରି ରଖିବା ପାଇଁ ଆପଣଙ୍କ ଡିଭାଇସକୁ ଅନଲକ କରନ୍ତୁ"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"ପରେ ଅପଡେଟ ଇନଷ୍ଟଲ କରିବାକୁ PIN ଲେଖନ୍ତୁ"</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"ପରେ ଅପଡେଟ ଇନଷ୍ଟଲ କରିବାକୁ ପାସୱାର୍ଡ ଲେଖନ୍ତୁ"</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"ପରେ ଅପଡେଟ ଇନଷ୍ଟଲ କରିବାକୁ ପାଟର୍ନ ଡ୍ର କରନ୍ତୁ"</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"ଡିଭାଇସ ଅପଡେଟ କରାଯାଇଛି। ଜାରି ରଖିବାକୁ PIN ଲେଖନ୍ତୁ।"</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"ଡିଭାଇସ ଅପଡେଟ କରାଯାଇଛି। ଜାରି ରଖିବାକୁ ପାସୱାର୍ଡ ଲେଖନ୍ତୁ।"</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"ଡିଭାଇସ ଅପଡେଟ କରାଯାଇଛି। ଜାରି ରଖିବାକୁ ପାଟର୍ନ ଡ୍ର କରନ୍ତୁ।"</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-pa/strings.xml b/packages/SystemUI/res-keyguard/values-pa/strings.xml
index 67ba3ef..321c99f 100644
--- a/packages/SystemUI/res-keyguard/values-pa/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-pa/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"ਬੁਲਬੁਲਾ"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"ਐਨਾਲੌਗ"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"ਜਾਰੀ ਰੱਖਣ ਲਈ ਆਪਣੇ ਡੀਵਾਈਸ ਨੂੰ ਅਣਲਾਕ ਕਰੋ"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"ਅੱਪਡੇਟ ਨੂੰ ਬਾਅਦ ਵਿੱਚ ਸਥਾਪਤ ਕਰਨ ਲਈ ਪਿੰਨ ਦਾਖਲ ਕਰੋ"</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"ਅੱਪਡੇਟ ਨੂੰ ਬਾਅਦ ਵਿੱਚ ਸਥਾਪਤ ਕਰਨ ਲਈ ਪਾਸਵਰਡ ਦਾਖਲ ਕਰੋ"</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"ਅੱਪਡੇਟ ਨੂੰ ਬਾਅਦ ਵਿੱਚ ਸਥਾਪਤ ਕਰਨ ਲਈ ਪੈਟਰਨ ਬਣਾਓ"</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"ਡੀਵਾਈਸ ਅੱਪਡੇਟ ਹੋ ਗਿਆ। ਜਾਰੀ ਰੱਖਣ ਲਈ ਪਿੰਨ ਦਾਖਲ ਕਰੋ।"</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"ਡੀਵਾਈਸ ਅੱਪਡੇਟ ਹੋ ਗਿਆ। ਜਾਰੀ ਰੱਖਣ ਲਈ ਪਾਸਵਰਡ ਦਾਖਲ ਕਰੋ।"</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"ਡੀਵਾਈਸ ਅੱਪਡੇਟ ਹੋ ਗਿਆ। ਜਾਰੀ ਰੱਖਣ ਲਈ ਪੈਟਰਨ ਬਣਾਓ।"</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-pl/strings.xml b/packages/SystemUI/res-keyguard/values-pl/strings.xml
index 868bf22..1a38896 100644
--- a/packages/SystemUI/res-keyguard/values-pl/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-pl/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"Bąbelkowy"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"Analogowy"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"Aby przejść dalej, odblokuj urządzenie"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"Podaj kod PIN, żeby zainstalować aktualizację później"</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"Wpisz hasło, żeby zainstalować aktualizację później"</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"Narysuj wzór, żeby zainstalować aktualizację później"</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"Urządzenie zostało zaktualizowane. Podaj kod PIN, aby kontynuować."</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"Urządzenie zostało zaktualizowane. Wpisz hasło, aby kontynuować."</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"Urządzenie zostało zaktualizowane. Narysuj wzór, aby kontynuować."</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-pt-rBR/strings.xml b/packages/SystemUI/res-keyguard/values-pt-rBR/strings.xml
index 15b3fc0..962f1e6 100644
--- a/packages/SystemUI/res-keyguard/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-pt-rBR/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"Bolha"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"Analógico"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"Desbloqueie o dispositivo para continuar"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"Digite o PIN para instalar a atualização mais tarde"</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"Digite a senha para instalar a atualização mais tarde"</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"Desenhe o padrão para instalar a atualização mais tarde"</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"Dispositivo atualizado. Digite o PIN para continuar."</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"Dispositivo atualizado. Digite a senha para continuar."</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"Dispositivo atualizado. Desenhe o padrão para continuar."</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml b/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml
index e1a0c43..afec176 100644
--- a/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"Balão"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"Analógico"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"Desbloqueie o dispositivo para continuar"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"Introduza o PIN para instalar a atualização mais tarde"</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"Introduza a palavra-passe para instalar a atualização mais tarde"</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"Desenhe o padrão para instalar a atualização mais tarde"</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"Dispositivo atualizado. Introduza o PIN para continuar."</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"Dispositivo atualizado. Introduza a palavra-passe para continuar."</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"Dispositivo atualizado. Desenhe o padrão para continuar."</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-pt/strings.xml b/packages/SystemUI/res-keyguard/values-pt/strings.xml
index 15b3fc0..962f1e6 100644
--- a/packages/SystemUI/res-keyguard/values-pt/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-pt/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"Bolha"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"Analógico"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"Desbloqueie o dispositivo para continuar"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"Digite o PIN para instalar a atualização mais tarde"</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"Digite a senha para instalar a atualização mais tarde"</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"Desenhe o padrão para instalar a atualização mais tarde"</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"Dispositivo atualizado. Digite o PIN para continuar."</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"Dispositivo atualizado. Digite a senha para continuar."</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"Dispositivo atualizado. Desenhe o padrão para continuar."</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-ro/strings.xml b/packages/SystemUI/res-keyguard/values-ro/strings.xml
index 9f568cc..caa3d83 100644
--- a/packages/SystemUI/res-keyguard/values-ro/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ro/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"Balon"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"Analogic"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"Deblochează dispozitivul pentru a continua"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"Introdu codul PIN pentru a instala actualizarea mai târziu"</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"Introdu parola pentru a instala actualizarea mai târziu"</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"Desenează modelul pentru a instala actualizarea mai târziu"</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"Dispozitivul s-a actualizat. Introdu codul PIN pentru a continua."</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"Dispozitivul s-a actualizat. Introdu parola pentru a continua."</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"Dispozitivul s-a actualizat. Desenează modelul pentru a continua."</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-ru/strings.xml b/packages/SystemUI/res-keyguard/values-ru/strings.xml
index bae5255..bd52b7d 100644
--- a/packages/SystemUI/res-keyguard/values-ru/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ru/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"Пузырь"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"Стрелки"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"Чтобы продолжить, разблокируйте устройство"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"Введите PIN-код, чтобы установить обновление позже."</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"Введите пароль, чтобы установить обновление позже."</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"Введите графический ключ, чтобы установить обновление позже."</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"Устройство обновлено. Введите PIN-код."</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"Устройство обновлено. Введите пароль."</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"Устройство обновлено. Введите графический ключ."</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-si/strings.xml b/packages/SystemUI/res-keyguard/values-si/strings.xml
index 4bb8aeb..0dfc8d9 100644
--- a/packages/SystemUI/res-keyguard/values-si/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-si/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"බුබුළ"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"ප්රතිසමය"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"ඉදිරියට යාමට ඔබේ උපාංගය අගුළු හරින්න"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"පසුව යාවත්කාලීනය ස්ථාපනය කිරීමට PIN ඇතුළු කරන්න"</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"පසුව යාවත්කාලීනය ස්ථාපනය කිරීමට මුරපදය ඇතුළු කරන්න"</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"පසුව යාවත්කාලීනය ස්ථාපනය කිරීමට රටාව අඳින්න"</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"උපාංගය යාවත්කාලීන කරන ලදි. ඉදිරියට යාමට PIN ඇතුළු කරන්න."</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"උපාංගය යාවත්කාලීන කරන ලදි. ඉදිරියට යාමට මුරපදය ඇතුළු කරන්න."</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"උපාංගය යාවත්කාලීන කරන ලදි. ඉදිරියට යාමට රටාව අඳින්න."</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-sk/strings.xml b/packages/SystemUI/res-keyguard/values-sk/strings.xml
index 08bf30d..5f10287 100644
--- a/packages/SystemUI/res-keyguard/values-sk/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-sk/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"Bublina"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"Analógový"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"Ak chcete pokračovať, odomknite zariadenie"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"Zadajte PIN, aby sa aktualizácia nainštalovala neskôr"</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"Zadajte heslo, aby sa aktualizácia nainštalovala neskôr"</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"Nakreslite vzor, aby sa aktualizácia nainštalovala neskôr"</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"Zariadenie bolo aktualizované. Pokračujte zadaním kódu PIN."</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"Zariadenie bolo aktualizované. Pokračujte zadaním hesla."</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"Zariadenie bolo aktualizované. Pokračujte nakreslením vzoru."</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-sl/strings.xml b/packages/SystemUI/res-keyguard/values-sl/strings.xml
index 3f29688..26d4951 100644
--- a/packages/SystemUI/res-keyguard/values-sl/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-sl/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"Mehurček"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"Analogno"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"Za nadaljevanje odklenite napravo"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"Vnesite kodo PIN, če želite posodobitev namestiti pozneje"</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"Vnesite geslo, če želite posodobitev namestiti pozneje"</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"Narišite vzorec, če želite posodobitev namestiti pozneje"</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"Naprava je posodobljena. Vnesite kodo PIN za nadaljevanje."</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"Naprava je posodobljena. Vnesite geslo za nadaljevanje."</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"Naprava je posodobljena. Narišite vzorec za nadaljevanje."</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-sq/strings.xml b/packages/SystemUI/res-keyguard/values-sq/strings.xml
index 149207c..ef4e566 100644
--- a/packages/SystemUI/res-keyguard/values-sq/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-sq/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"Flluskë"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"Analoge"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"Shkyç pajisjen tënde për të vazhduar"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"Fut kodin PIN për ta instaluar përditësimin më vonë"</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"Fut fjalëkalimin për ta instaluar përditësimin më vonë"</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"Vizato motivin për ta instaluar përditësimin më vonë"</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"Pajisja u përditësua. Fut kodin PIN për të vazhduar."</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"Pajisja u përditësua. Fut fjalëkalimin për të vazhduar."</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"Pajisja u përditësua. Vizato motivin për të vazhduar."</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-sr/strings.xml b/packages/SystemUI/res-keyguard/values-sr/strings.xml
index cabf94f..5ed152f 100644
--- a/packages/SystemUI/res-keyguard/values-sr/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-sr/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"Мехурићи"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"Аналогни"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"Откључајте уређај да бисте наставили"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"Унесите PIN да бисте касније исталирали ажурирање"</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"Унесите лозинку да бисте касније инсталирали ажурирање"</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"Нацртајте шаблон да бисте касније инсталирали ажурирање"</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"Уређај је ажуриран. Унесите PIN да бисте наставили."</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"Уређај је ажуриран. Унесите лозинку да бисте наставили."</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"Уређај је ажуриран. Нацртајте шаблон да бисте наставили."</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-sv/strings.xml b/packages/SystemUI/res-keyguard/values-sv/strings.xml
index c11e0f1..abd677a 100644
--- a/packages/SystemUI/res-keyguard/values-sv/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-sv/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"Bubbla"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"Analog"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"Lås upp enheten för att fortsätta"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"Ange pinkoden för att installera uppdateringen senare"</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"Ange lösenordet för att installera uppdateringen senare"</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"Rita mönstret för att installera uppdateringen senare"</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"Enheten har uppdaterats. Ange pinkoden för att fortsätta."</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"Enheten har uppdaterats. Ange lösenordet för att fortsätta."</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"Enheten har uppdaterats. Rita mönstret för att fortsätta."</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-sw/strings.xml b/packages/SystemUI/res-keyguard/values-sw/strings.xml
index 943c76b..7516d90 100644
--- a/packages/SystemUI/res-keyguard/values-sw/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-sw/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"Kiputo"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"Analogi"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"Fungua kifaa chako ili uendelee"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"Weka PIN ili usakinishe sasisho baadaye"</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"Weka nenosiri ili usakinishe sasisho baadaye"</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"Chora mchoro ili usakinishe sasisho baadaye"</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"Kifaa kimesasishwa. Weka PIN ili uendelee."</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"Kifaa kimesasishwa. Weka nenosiri ili uendelee."</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"Kifaa kimesasishwa. Chora mchoro ili uendelee."</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-ta/strings.xml b/packages/SystemUI/res-keyguard/values-ta/strings.xml
index 3e64755..92dfc18 100644
--- a/packages/SystemUI/res-keyguard/values-ta/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ta/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"பபிள்"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"அனலாக்"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"தொடர, சாதனத்தை அன்லாக் செய்யுங்கள்"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"புதுப்பிப்பைப் பின்னர் நிறுவ பின்னை உள்ளிடவும்"</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"புதுப்பிப்பைப் பின்னர் நிறுவ கடவுச்சொல்லை உள்ளிடவும்"</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"புதுப்பிப்பைப் பின்னர் நிறுவ பேட்டர்னை வரையவும்"</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"சாதனம் புதுப்பிக்கப்பட்டது. தொடர பின்னை உள்ளிடவும்."</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"சாதனம் புதுப்பிக்கப்பட்டது. தொடர கடவுச்சொல்லை உள்ளிடவும்."</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"சாதனம் புதுப்பிக்கப்பட்டது. தொடர பேட்டர்னை வரையவும்."</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-te/strings.xml b/packages/SystemUI/res-keyguard/values-te/strings.xml
index f8bf307..a12d6ec 100644
--- a/packages/SystemUI/res-keyguard/values-te/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-te/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"బబుల్"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"ఎనలాగ్"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"కొనసాగించడానికి మీ పరికరాన్ని అన్లాక్ చేయండి"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"అప్డేట్ను తర్వాత ఇన్స్టాల్ చేయడానికి PINను ఎంటర్ చేయండి"</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"అప్డేట్ను తర్వాత ఇన్స్టాల్ చేయడానికి పాస్వర్డ్ను ఎంటర్ చేయండి"</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"అప్డేట్ను తర్వాత ఇన్స్టాల్ చేయడానికి ఆకృతిని గీయండి"</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"పరికరం అప్డేట్ అయింది. కొనసాగడానికి PINను ఎంటర్ చేయండి."</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"పరికరం అప్డేట్ అయింది. కొనసాగడానికి పాస్వర్డ్ను ఎంటర్ చేయండి."</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"పరికరం అప్డేట్ అయింది. కొనసాగడానికి ఆకృతిని గీయండి."</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-th/strings.xml b/packages/SystemUI/res-keyguard/values-th/strings.xml
index 4df30dc..bcd097d 100644
--- a/packages/SystemUI/res-keyguard/values-th/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-th/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"บับเบิล"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"แอนะล็อก"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"ปลดล็อกอุปกรณ์ของคุณเพื่อดำเนินการต่อ"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"ป้อน PIN เพื่อติดตั้งอัปเดตในภายหลัง"</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"ป้อนรหัสผ่านเพื่อติดตั้งอัปเดตในภายหลัง"</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"วาดรูปแบบเพื่อติดตั้งอัปเดตในภายหลัง"</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"อัปเดตอุปกรณ์แล้ว ป้อน PIN เพื่อดำเนินการต่อ"</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"อัปเดตอุปกรณ์แล้ว ป้อนรหัสผ่านเพื่อดำเนินการต่อ"</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"อัปเดตอุปกรณ์แล้ว วาดรูปแบบเพื่อดำเนินการต่อ"</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-tl/strings.xml b/packages/SystemUI/res-keyguard/values-tl/strings.xml
index 7032886..a968cb0 100644
--- a/packages/SystemUI/res-keyguard/values-tl/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-tl/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"Bubble"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"Analog"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"I-unlock ang iyong device para magpatuloy"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"Ilagay ang PIN para i-install ang update sa ibang pagkakataon"</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"Ilagay ang password para i-install ang update sa ibang pagkakataon"</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"Iguhit ang pattern para i-install ang update sa ibang pagkakataon"</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"Na-update na ang device. Ilagay ang PIN para magpatuloy."</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"Na-update na ang device. Ilagay ang password para magpatuloy."</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"Na-update na ang device. Iguhit ang pattern para magpatuloy."</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-tr/strings.xml b/packages/SystemUI/res-keyguard/values-tr/strings.xml
index ff0bc9a..1aad78c 100644
--- a/packages/SystemUI/res-keyguard/values-tr/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-tr/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"Baloncuk"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"Analog"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"Devam etmek için cihazınızın kilidini açın"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"Güncellemeyi daha sonra yüklemek için PIN girin."</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"Güncellemeyi daha sonra yüklemek için şifre girin."</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"Güncellemeyi daha sonra yüklemek için desen çizin."</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"Cihaz güncellendi. Devam etmek için PIN girin."</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"Cihaz güncellendi. Devam etmek için şifre girin."</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"Cihaz güncellendi. Devam etmek için desen çizin."</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-uk/strings.xml b/packages/SystemUI/res-keyguard/values-uk/strings.xml
index 2fd1934..a147d07 100644
--- a/packages/SystemUI/res-keyguard/values-uk/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-uk/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"Бульбашковий"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"Аналоговий"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"Розблокуйте пристрій, щоб продовжити"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"Щоб установити оновлення пізніше, введіть PIN-код"</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"Щоб установити оновлення пізніше, введіть пароль"</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"Щоб установити оновлення пізніше, намалюйте ключ"</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"Пристрій оновлено. Щоб продовжити, введіть PIN-код."</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"Пристрій оновлено. Щоб продовжити, введіть пароль."</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"Пристрій оновлено. Щоб продовжити, намалюйте ключ."</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-ur/strings.xml b/packages/SystemUI/res-keyguard/values-ur/strings.xml
index dc6ef4d..5c9e6b0 100644
--- a/packages/SystemUI/res-keyguard/values-ur/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ur/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"بلبلہ"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"اینالاگ"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"جاری رکھنے کے لئے اپنا آلہ غیر مقفل کریں"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"بعد میں اپ ڈیٹ انسٹال کرنے کیلئے PIN درج کریں"</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"بعد میں اپ ڈیٹ انسٹال کرنے کیلئے پاس ورڈ درج کریں"</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"بعد میں اپ ڈیٹ انسٹال کرنے کیلئے پیٹرن ڈرا کریں"</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"آلہ اپ ڈیٹ ہو گیا۔ جاری رکھنے کیلئے PIN درج کریں۔"</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"آلہ اپ ڈیٹ ہو گیا۔ جاری رکھنے کیلئے پاس ورڈ درج کریں۔"</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"آلہ اپ ڈیٹ ہو گیا۔ جاری رکھنے کیلئے پیٹرن ڈرا کریں۔"</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-uz/strings.xml b/packages/SystemUI/res-keyguard/values-uz/strings.xml
index 0e2a6cf..53c2a2c 100644
--- a/packages/SystemUI/res-keyguard/values-uz/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-uz/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"Pufaklar"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"Analog"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"Davom etish uchun qurilmangizni qulfdan chiqaring"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"Yangilanishni keyinroq oʻrnatish uchun PIN kodni kiriting"</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"Yangilanishni keyinroq oʻrnatish uchun parolni kiriting"</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"Yangilanishni keyinroq oʻrnatish uchun grafik kalitni chizing"</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"Qurilma yangilandi. Davom etish uchun PIN kodni kiriting."</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"Qurilma yangilandi. Davom etish uchun parolni kiriting."</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"Qurilma yangilandi. Davom etish uchun grafik kalitni chizing."</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-vi/strings.xml b/packages/SystemUI/res-keyguard/values-vi/strings.xml
index e2d2525..b81e147 100644
--- a/packages/SystemUI/res-keyguard/values-vi/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-vi/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"Bong bóng"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"Đồng hồ kim"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"Mở khoá thiết bị của bạn để tiếp tục"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"Hãy nhập mã PIN để cài đặt bản cập nhật vào lúc khác"</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"Hãy nhập mật khẩu để cài đặt bản cập nhật vào lúc khác"</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"Hãy vẽ hình mở khoá để cài đặt bản cập nhật vào lúc khác"</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"Đã cập nhật thiết bị. Hãy nhập mã PIN để tiếp tục."</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"Đã cập nhật thiết bị. Hãy nhập mật khẩu để tiếp tục."</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"Đã cập nhật thiết bị. Hãy vẽ hình mở khoá để tiếp tục."</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-zh-rCN/strings.xml b/packages/SystemUI/res-keyguard/values-zh-rCN/strings.xml
index 2888c37..0f0feb5 100644
--- a/packages/SystemUI/res-keyguard/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-zh-rCN/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"泡泡"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"指针"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"解锁设备才能继续操作"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"需要输入 PIN 码才能稍后安装更新"</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"需要输入密码才能稍后安装更新"</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"需要绘制解锁图案才能稍后安装更新"</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"设备已更新。您需要输入 PIN 码才能继续。"</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"设备已更新。您需要输入密码才能继续。"</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"设备已更新。您需要绘制解锁图案才能继续。"</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-zh-rHK/strings.xml b/packages/SystemUI/res-keyguard/values-zh-rHK/strings.xml
index ba40a65..701100f 100644
--- a/packages/SystemUI/res-keyguard/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-zh-rHK/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"泡泡"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"指針"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"解鎖裝置以繼續"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"輸入 PIN 即可在稍後安裝更新"</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"輸入密碼即可在稍後安裝更新"</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"畫出解鎖圖案即可在稍後安裝更新"</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"裝置已更新。輸入 PIN 即可繼續。"</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"裝置已更新。輸入密碼即可繼續。"</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"裝置已更新。畫出解鎖圖案即可繼續。"</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-zh-rTW/strings.xml b/packages/SystemUI/res-keyguard/values-zh-rTW/strings.xml
index b73e803c..4ac27f2 100644
--- a/packages/SystemUI/res-keyguard/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-zh-rTW/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"泡泡"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"類比"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"解鎖裝置才能繼續操作"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"請輸入 PIN 碼,系統稍後會安裝更新"</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"請輸入密碼,系統稍後會安裝更新"</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"請畫出解鎖圖案,系統稍後會安裝更新"</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"裝置已更新。如要繼續操作,請輸入 PIN 碼。"</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"裝置已更新。如要繼續操作,請輸入密碼。"</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"裝置已更新。如要繼續操作,請畫出解鎖圖案。"</string>
</resources>
diff --git a/packages/SystemUI/res-keyguard/values-zu/strings.xml b/packages/SystemUI/res-keyguard/values-zu/strings.xml
index 6a2d368..e4a4503 100644
--- a/packages/SystemUI/res-keyguard/values-zu/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-zu/strings.xml
@@ -125,4 +125,10 @@
<string name="clock_title_bubble" msgid="2204559396790593213">"Ibhamuza"</string>
<string name="clock_title_analog" msgid="8409262532900918273">"I-Analog"</string>
<string name="keyguard_unlock_to_continue" msgid="7509503484250597743">"Vula idivayisi yakho ukuze uqhubeke"</string>
+ <string name="kg_prompt_unattended_update_pin" msgid="5979434876768801873">"Faka Iphinikhodi ukuze ufake isibuyekezo kamuva"</string>
+ <string name="kg_prompt_unattended_update_password" msgid="8805664437604967210">"Faka iphasiwedi ukuze ufake isibuyekezo kamuva"</string>
+ <string name="kg_prompt_unattended_update_pattern" msgid="8580479377489546091">"Dweba iphethini ukuze ufake isibuyekezo kamuva"</string>
+ <string name="kg_prompt_after_update_pin" msgid="7051709651908643013">"Idivayisi ibuyekeziwe. Faka Iphinikhodi ukuze uqhubeke."</string>
+ <string name="kg_prompt_after_update_password" msgid="153703052501352094">"Idivayisi ibuyekeziwe. Faka iphasiwedi ukuze uqhubeke."</string>
+ <string name="kg_prompt_after_update_pattern" msgid="1484084551298241992">"Idivayisi ibuyekeziwe. Dweba iphethini ukuze uqhubeke."</string>
</resources>
diff --git a/packages/SystemUI/res-product/values-it/strings.xml b/packages/SystemUI/res-product/values-it/strings.xml
index 5964af8..0b3bb3d 100644
--- a/packages/SystemUI/res-product/values-it/strings.xml
+++ b/packages/SystemUI/res-product/values-it/strings.xml
@@ -42,7 +42,7 @@
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"<xliff:g id="NUMBER_0">%1$d</xliff:g> tentativi errati di inserimento della sequenza di sblocco. Dopo altri <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativi falliti, ti verrà chiesto di sbloccare il telefono con un account email.\n\n Riprova tra <xliff:g id="NUMBER_2">%3$d</xliff:g> secondi."</string>
<string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Il sensore di impronte digitali si trova sul tasto di accensione. Si tratta del tasto piatto accanto al tasto del volume in rilievo sul bordo del tablet."</string>
<string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Il sensore di impronte digitali si trova sul tasto di accensione. Si tratta del tasto piatto accanto al tasto del volume in rilievo sulla parte laterale del dispositivo."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Il sensore di impronte digitali si trova sul tasto di accensione. Si tratta del tasto piatto accanto al tasto del volume in rilievo sulla parte laterale del telefono."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Il sensore di impronte digitali si trova sul tasto di accensione. Si tratta del tasto piatto accanto al tasto del volume in rilievo sulla parte laterale dello smartphone."</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Sblocca il telefono per visualizzare altre opzioni"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Sblocca il tablet per visualizzare altre opzioni"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Sblocca il dispositivo per visualizzare altre opzioni"</string>
diff --git a/packages/SystemUI/res/layout/battery_percentage_view.xml b/packages/SystemUI/res/layout/battery_percentage_view.xml
index b9b1bb1..82facd0 100644
--- a/packages/SystemUI/res/layout/battery_percentage_view.xml
+++ b/packages/SystemUI/res/layout/battery_percentage_view.xml
@@ -20,7 +20,7 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/battery_percentage_view"
android:layout_width="wrap_content"
- android:layout_height="match_parent"
+ android:layout_height="wrap_content"
android:singleLine="true"
android:textAppearance="@style/TextAppearance.StatusBar.Clock"
android:textColor="?android:attr/textColorPrimary"
diff --git a/packages/SystemUI/res/layout/combined_qs_header.xml b/packages/SystemUI/res/layout/combined_qs_header.xml
index 386c9d6..665c612 100644
--- a/packages/SystemUI/res/layout/combined_qs_header.xml
+++ b/packages/SystemUI/res/layout/combined_qs_header.xml
@@ -74,7 +74,7 @@
android:layout_height="wrap_content"
android:id="@+id/barrier"
app:barrierDirection="start"
- app:constraint_referenced_ids="statusIcons,privacy_container" />
+ app:constraint_referenced_ids="shade_header_system_icons,privacy_container" />
<com.android.systemui.statusbar.policy.Clock
android:id="@+id/clock"
@@ -108,46 +108,39 @@
<include
android:id="@+id/carrier_group"
layout="@layout/shade_carrier_group"
- app:layout_constraintHeight_min="@dimen/large_screen_shade_header_min_height"
- android:minHeight="@dimen/large_screen_shade_header_min_height"
- app:layout_constraintWidth_min="48dp"
android:layout_width="0dp"
android:layout_height="0dp"
- app:layout_constrainedWidth="true"
android:layout_gravity="end|center_vertical"
android:layout_marginStart="8dp"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toStartOf="@id/shade_header_system_icons"
+ app:layout_constraintHorizontal_bias="1"
app:layout_constraintStart_toEndOf="@id/date"
- app:layout_constraintEnd_toStartOf="@id/statusIcons"
- app:layout_constraintTop_toTopOf="@id/clock"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintHorizontal_bias="1"
- />
+ app:layout_constraintTop_toTopOf="@id/clock" />
- <com.android.systemui.statusbar.phone.StatusIconContainer
- android:id="@+id/statusIcons"
- app:layout_constraintHeight_min="@dimen/large_screen_shade_header_min_height"
- android:paddingEnd="@dimen/signal_cluster_battery_padding"
+ <LinearLayout
+ android:id="@+id/shade_header_system_icons"
android:layout_width="wrap_content"
+ app:layout_constraintHeight_min="@dimen/large_screen_shade_header_min_height"
android:layout_height="@dimen/large_screen_shade_header_min_height"
- app:layout_constraintStart_toEndOf="@id/carrier_group"
- app:layout_constraintEnd_toStartOf="@id/batteryRemainingIcon"
- app:layout_constraintTop_toTopOf="@id/clock"
+ android:clickable="true"
+ android:orientation="horizontal"
app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintHorizontal_bias="1"
- />
+ app:layout_constraintEnd_toEndOf="@id/privacy_container"
+ app:layout_constraintTop_toTopOf="@id/clock">
- <com.android.systemui.battery.BatteryMeterView
- android:id="@+id/batteryRemainingIcon"
- android:layout_width="wrap_content"
- android:layout_height="@dimen/large_screen_shade_header_min_height"
- app:layout_constraintHeight_min="@dimen/large_screen_shade_header_min_height"
- app:layout_constrainedWidth="true"
- app:textAppearance="@style/TextAppearance.QS.Status"
- app:layout_constraintStart_toEndOf="@id/statusIcons"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintTop_toTopOf="@id/clock"
- app:layout_constraintBottom_toBottomOf="parent"
- />
+ <com.android.systemui.statusbar.phone.StatusIconContainer
+ android:id="@+id/statusIcons"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:paddingEnd="@dimen/signal_cluster_battery_padding" />
+
+ <com.android.systemui.battery.BatteryMeterView
+ android:id="@+id/batteryRemainingIcon"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ app:textAppearance="@style/TextAppearance.QS.Status" />
+ </LinearLayout>
<FrameLayout
android:id="@+id/privacy_container"
diff --git a/packages/SystemUI/res/layout/keyguard_status_bar.xml b/packages/SystemUI/res/layout/keyguard_status_bar.xml
index 64c4eff..fc0bf24 100644
--- a/packages/SystemUI/res/layout/keyguard_status_bar.xml
+++ b/packages/SystemUI/res/layout/keyguard_status_bar.xml
@@ -47,7 +47,10 @@
android:layout_height="match_parent"
android:layout_marginEnd="@dimen/status_bar_padding_end"
android:gravity="center_vertical|end">
- <include layout="@layout/system_icons" />
+ <include layout="@layout/system_icons"
+ android:layout_gravity="center_vertical"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
</FrameLayout>
<ImageView android:id="@+id/multi_user_avatar"
diff --git a/packages/SystemUI/res/layout/status_bar_expanded.xml b/packages/SystemUI/res/layout/status_bar_expanded.xml
index d710676..e214666 100644
--- a/packages/SystemUI/res/layout/status_bar_expanded.xml
+++ b/packages/SystemUI/res/layout/status_bar_expanded.xml
@@ -132,21 +132,6 @@
android:id="@+id/lock_icon_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
- <!-- Background protection -->
- <ImageView
- android:id="@+id/lock_icon_bg"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:src="@drawable/fingerprint_bg"
- android:visibility="invisible"/>
-
- <ImageView
- android:id="@+id/lock_icon"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_gravity="center"
- android:scaleType="centerCrop"/>
-
</com.android.keyguard.LockIconView>
<include
diff --git a/packages/SystemUI/res/layout/super_notification_shade.xml b/packages/SystemUI/res/layout/super_notification_shade.xml
index 6601e63..2fde947 100644
--- a/packages/SystemUI/res/layout/super_notification_shade.xml
+++ b/packages/SystemUI/res/layout/super_notification_shade.xml
@@ -65,17 +65,17 @@
android:layout_width="match_parent"
android:layout_height="match_parent" />
- <include layout="@layout/status_bar_expanded"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:visibility="invisible" />
-
<!-- Root for all keyguard content. It was previously located within the shade. -->
<com.android.systemui.keyguard.ui.view.KeyguardRootView
android:id="@id/keyguard_root_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
+ <include layout="@layout/status_bar_expanded"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:visibility="invisible" />
+
<include layout="@layout/brightness_mirror_container" />
<com.android.systemui.scrim.ScrimView
diff --git a/packages/SystemUI/res/layout/system_icons.xml b/packages/SystemUI/res/layout/system_icons.xml
index 816dfd3..6a14c21 100644
--- a/packages/SystemUI/res/layout/system_icons.xml
+++ b/packages/SystemUI/res/layout/system_icons.xml
@@ -18,20 +18,23 @@
xmlns:systemui="http://schemas.android.com/apk/res-auto"
android:id="@+id/system_icons"
android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:layout_gravity="center_vertical|end"
+ android:layout_height="wrap_content"
+ android:paddingBottom="@dimen/status_bar_icons_padding_bottom"
+ android:paddingTop="@dimen/status_bar_icons_padding_top"
+ android:paddingStart="@dimen/status_bar_icons_padding_start"
+ android:paddingEnd="@dimen/status_bar_icons_padding_end"
android:gravity="center_vertical">
<com.android.systemui.statusbar.phone.StatusIconContainer android:id="@+id/statusIcons"
android:layout_width="0dp"
android:layout_weight="1"
- android:layout_height="match_parent"
+ android:layout_height="wrap_content"
android:paddingEnd="@dimen/signal_cluster_battery_padding"
android:gravity="center_vertical"
android:orientation="horizontal"/>
<com.android.systemui.battery.BatteryMeterView android:id="@+id/battery"
- android:layout_height="match_parent"
+ android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:clipToPadding="false"
android:clipChildren="false"
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 71b02bf..2fa9711 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -1046,8 +1046,7 @@
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Kon nie jou batterymeter lees nie"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Tik vir meer inligting"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Geen wekker nie"</string>
- <!-- no translation found for accessibility_bouncer (5896923685673320070) -->
- <skip />
+ <string name="accessibility_bouncer" msgid="5896923685673320070">"voer skermslot in"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Vingerafdruksensor"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"staaf"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"gaan by toestel in"</string>
@@ -1127,18 +1126,12 @@
<string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Kom meer te wete"</string>
<string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Kom meer te wete by <xliff:g id="URL">%s</xliff:g>"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Maak <xliff:g id="APPNAME">%1$s</xliff:g> oop"</string>
- <!-- no translation found for wallet_quick_affordance_unavailable_install_the_app (7298552910007208368) -->
- <skip />
- <!-- no translation found for wallet_quick_affordance_unavailable_configure_the_app (4387433357429873258) -->
- <skip />
- <!-- no translation found for qr_scanner_quick_affordance_unavailable_explanation (3049582306241150946) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_install_the_app (6187820778998446168) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_configure_the_app (7953595390775156839) -->
- <skip />
- <!-- no translation found for notes_app_quick_affordance_unavailable_explanation (4796955161600178530) -->
- <skip />
+ <string name="wallet_quick_affordance_unavailable_install_the_app" msgid="7298552910007208368">"Om die Wallet-app as ’n kortpad by te voeg, moet jy seker maak dat die app geïnstalleer is"</string>
+ <string name="wallet_quick_affordance_unavailable_configure_the_app" msgid="4387433357429873258">"Om die Wallet-app as ’n kortpad by te voeg, moet jy seker maak dat minstens een kaart bygevoeg is"</string>
+ <string name="qr_scanner_quick_affordance_unavailable_explanation" msgid="3049582306241150946">"Om die QR-kodeskandeerder as ’n kortpad by te voeg, moet jy seker maak dat ’n kamera-app geïnstalleer is"</string>
+ <string name="home_quick_affordance_unavailable_install_the_app" msgid="6187820778998446168">"Om die Home-app as ’n kortpad by te voeg, moet jy seker maak dat die app geïnstalleer is"</string>
+ <string name="home_quick_affordance_unavailable_configure_the_app" msgid="7953595390775156839">"• Minstens een toestel beskikbaar is"</string>
+ <string name="notes_app_quick_affordance_unavailable_explanation" msgid="4796955161600178530">"Kies ’n versteknotasapp om die notaneemkortpad te gebruik"</string>
<string name="keyguard_affordance_enablement_dialog_notes_app_action" msgid="6821710209675089470">"Kies app"</string>
<string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Raak en hou kortpad"</string>
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Kanselleer"</string>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index e2038fb..6d6b435 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -1046,8 +1046,7 @@
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"የባትሪ መለኪያዎን የማንበብ ችግር"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"ለበለጠ መረጃ መታ ያድርጉ"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"ምንም ማንቂያ አልተቀናበረም"</string>
- <!-- no translation found for accessibility_bouncer (5896923685673320070) -->
- <skip />
+ <string name="accessibility_bouncer" msgid="5896923685673320070">"ማያ ገጽ መቆለፊያ ያስገቡ"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"የጣት አሻራ ዳሳሽ"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"ያረጋግጡ"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"መሣሪያን ያስገቡ"</string>
@@ -1127,18 +1126,12 @@
<string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"የበለጠ ለመረዳት"</string>
<string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"<xliff:g id="URL">%s</xliff:g> ላይ የበለጠ ይወቁ"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> ይክፈቱ"</string>
- <!-- no translation found for wallet_quick_affordance_unavailable_install_the_app (7298552910007208368) -->
- <skip />
- <!-- no translation found for wallet_quick_affordance_unavailable_configure_the_app (4387433357429873258) -->
- <skip />
- <!-- no translation found for qr_scanner_quick_affordance_unavailable_explanation (3049582306241150946) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_install_the_app (6187820778998446168) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_configure_the_app (7953595390775156839) -->
- <skip />
- <!-- no translation found for notes_app_quick_affordance_unavailable_explanation (4796955161600178530) -->
- <skip />
+ <string name="wallet_quick_affordance_unavailable_install_the_app" msgid="7298552910007208368">"የWallet መተግበሪያን እንደ አቋራጭ ለማከል መተግበሪያው መጫኑን ያረጋግጡ"</string>
+ <string name="wallet_quick_affordance_unavailable_configure_the_app" msgid="4387433357429873258">"የWallet መተግበሪያን እንደ አቋራጭ ለማከል ቢያንስ አንድ ካርድ መታከሉን ያረጋግጡ"</string>
+ <string name="qr_scanner_quick_affordance_unavailable_explanation" msgid="3049582306241150946">"የQR ኮድ መቃኛውን እንደ አቋራጭ ለማከል የካሜራ መተግበሪያ መጫኑን ያረጋግጡ"</string>
+ <string name="home_quick_affordance_unavailable_install_the_app" msgid="6187820778998446168">"የHome መተግበሪያውን እንደ አቋራጭ ለማከል መተግበሪያው እንደተጫነ ያረጋግጡ"</string>
+ <string name="home_quick_affordance_unavailable_configure_the_app" msgid="7953595390775156839">"• ቢያንስ አንድ መሣሪያ ይገኛል"</string>
+ <string name="notes_app_quick_affordance_unavailable_explanation" msgid="4796955161600178530">"የማስታወሻ አያያዝ አቋራጭን ለመጠቀም ነባሪ የማስታወሻ መተግበሪያ ይምረጡ"</string>
<string name="keyguard_affordance_enablement_dialog_notes_app_action" msgid="6821710209675089470">"መተግበሪያ ይምረጡ"</string>
<string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"የይንኩ እና ይያዙ አቋራጭ"</string>
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"ይቅር"</string>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 4d4ee94..614b968 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -399,7 +399,7 @@
<string name="media_projection_sys_service_dialog_warning" msgid="2443872865267330320">"ستتمكن الخدمة التي تقدّم هذه الوظيفة من الوصول إلى كل المحتوى المعروض على شاشتك أو الذي يتم تشغيله على جهازك أثناء التسجيل أو البثّ. ويشمل ذلك معلومات، مثل كلمات المرور وتفاصيل الدفع والصور والرسائل والمقاطع الصوتية التي تشغِّلها."</string>
<string name="screen_share_permission_dialog_option_entire_screen" msgid="3131200488455089620">"الشاشة بالكامل"</string>
<string name="screen_share_permission_dialog_option_single_app" msgid="4350961814397220929">"تطبيق واحد"</string>
- <string name="screen_share_permission_app_selector_title" msgid="1404878013670347899">"مشاركة محتوى تطبيق أو تسجيله"</string>
+ <string name="screen_share_permission_app_selector_title" msgid="1404878013670347899">"مشاركة أو تسجيل محتوى تطبيق محدّد"</string>
<string name="media_projection_entry_app_permission_dialog_title" msgid="9155535851866407199">"هل تريد بدء التسجيل أو البثّ باستخدام \"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>\"؟"</string>
<string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"أثناء المشاركة أو التسجيل أو البثّ، يمكن لتطبيق \"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>\" الوصول إلى كل المحتوى المعروض على شاشتك أو الذي يتم تشغيله على جهاز، لذا يُرجى توخي الحذر بشأن المعلومات، مثل كلمات المرور وتفاصيل الدفع والرسائل والصور وملفات الصوت والفيديو."</string>
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"أثناء مشاركة محتوى تطبيق أو تسجيله أو بثّه، يمكن لتطبيق \"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>\" الوصول إلى كل المحتوى المعروض أو الذي يتم تشغيله في ذلك التطبيق، لذا يُرجى توخي الحذر بشأن المعلومات، مثل كلمات المرور وتفاصيل الدفع والرسائل والصور وملفات الصوت والفيديو."</string>
@@ -1046,8 +1046,7 @@
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"حدثت مشكلة أثناء قراءة مقياس مستوى شحن البطارية."</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"انقر للحصول على مزيد من المعلومات."</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"لم يتم ضبط منبّه."</string>
- <!-- no translation found for accessibility_bouncer (5896923685673320070) -->
- <skip />
+ <string name="accessibility_bouncer" msgid="5896923685673320070">"إدخال الرمز لفتح القفل"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"مستشعر بصمات الإصبع"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"المصادقة"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"الدخول إلى الجهاز"</string>
@@ -1127,18 +1126,12 @@
<string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"مزيد من المعلومات"</string>
<string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"مزيد من المعلومات على <xliff:g id="URL">%s</xliff:g>"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"فتح \"<xliff:g id="APPNAME">%1$s</xliff:g>\""</string>
- <!-- no translation found for wallet_quick_affordance_unavailable_install_the_app (7298552910007208368) -->
- <skip />
- <!-- no translation found for wallet_quick_affordance_unavailable_configure_the_app (4387433357429873258) -->
- <skip />
- <!-- no translation found for qr_scanner_quick_affordance_unavailable_explanation (3049582306241150946) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_install_the_app (6187820778998446168) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_configure_the_app (7953595390775156839) -->
- <skip />
- <!-- no translation found for notes_app_quick_affordance_unavailable_explanation (4796955161600178530) -->
- <skip />
+ <string name="wallet_quick_affordance_unavailable_install_the_app" msgid="7298552910007208368">"لإضافة تطبيق \"محفظة Google\" كاختصار، تأكَّد من أنّ التطبيق مثبَّت."</string>
+ <string name="wallet_quick_affordance_unavailable_configure_the_app" msgid="4387433357429873258">"لإضافة تطبيق \"محفظة Google\" كاختصار، تأكَّد من إضافة بطاقة واحدة على الأقل."</string>
+ <string name="qr_scanner_quick_affordance_unavailable_explanation" msgid="3049582306241150946">"لإضافة تطبيق الماسح الضوئي لرمز الاستجابة السريعة كاختصار، تأكَّد من أنّ تطبيق الكاميرا مثبَّت."</string>
+ <string name="home_quick_affordance_unavailable_install_the_app" msgid="6187820778998446168">"لإضافة تطبيق Home كاختصار، تأكَّد من أنّ التطبيق مثبَّت."</string>
+ <string name="home_quick_affordance_unavailable_configure_the_app" msgid="7953595390775156839">"• توفُّر جهاز واحد على الأقل"</string>
+ <string name="notes_app_quick_affordance_unavailable_explanation" msgid="4796955161600178530">"اختَر تطبيقًا تلقائيًا لتدوين الملاحظات لاستخدام اختصار تدوين الملاحظات."</string>
<string name="keyguard_affordance_enablement_dialog_notes_app_action" msgid="6821710209675089470">"اختيار تطبيق"</string>
<string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"انقر مع الاستمرار على الاختصار."</string>
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"إلغاء"</string>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index eb07ee3..06c9f53d 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -1046,8 +1046,7 @@
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"আপোনাৰ বেটাৰী মিটাৰ পঢ়োঁতে সমস্যা হৈছে"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"অধিক তথ্যৰ বাবে টিপক"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"কোনো এলাৰ্ম ছেট কৰা হোৱা নাই"</string>
- <!-- no translation found for accessibility_bouncer (5896923685673320070) -->
- <skip />
+ <string name="accessibility_bouncer" msgid="5896923685673320070">"স্ক্ৰীন লকটো দিয়ক"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"ফিংগাৰপ্ৰিণ্ট ছেন্সৰ"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"বিশ্বাসযোগ্যতা প্ৰমাণ কৰক"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"ডিভাইচ আনলক কৰক"</string>
@@ -1127,18 +1126,12 @@
<string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"অধিক জানক"</string>
<string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"<xliff:g id="URL">%s</xliff:g>ত অধিক জানক"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> খোলক"</string>
- <!-- no translation found for wallet_quick_affordance_unavailable_install_the_app (7298552910007208368) -->
- <skip />
- <!-- no translation found for wallet_quick_affordance_unavailable_configure_the_app (4387433357429873258) -->
- <skip />
- <!-- no translation found for qr_scanner_quick_affordance_unavailable_explanation (3049582306241150946) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_install_the_app (6187820778998446168) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_configure_the_app (7953595390775156839) -->
- <skip />
- <!-- no translation found for notes_app_quick_affordance_unavailable_explanation (4796955161600178530) -->
- <skip />
+ <string name="wallet_quick_affordance_unavailable_install_the_app" msgid="7298552910007208368">"Wallet এপ্টোক এটা শ্বৰ্টকাট হিচাপে যোগ দিবলৈ, এপ্টো ইনষ্টল কৰি থোৱাটো নিশ্চিত কৰক"</string>
+ <string name="wallet_quick_affordance_unavailable_configure_the_app" msgid="4387433357429873258">"Wallet এপ্টোক এটা শ্বৰ্টকাট হিচাপে যোগ দিবলৈ, কমেও এখন কাৰ্ড যোগ দিয়াটো নিশ্চিত কৰক"</string>
+ <string name="qr_scanner_quick_affordance_unavailable_explanation" msgid="3049582306241150946">"কিউআৰ ক’ড স্কেনাৰক এটা শ্বৰ্টকাট হিচাপে যোগ দিবলৈ, কেমেৰা এপ্টো ইনষ্টল কৰি থোৱাটো নিশ্চিত কৰক"</string>
+ <string name="home_quick_affordance_unavailable_install_the_app" msgid="6187820778998446168">"Home এপ্টোক এটা শ্বৰ্টকাট হিচাপে যোগ দিবলৈ, এপ্টো ইনষ্টল কৰি থোৱাটো নিশ্চিত কৰক"</string>
+ <string name="home_quick_affordance_unavailable_configure_the_app" msgid="7953595390775156839">"• অতি কমেও এটা ডিভাইচ উপলব্ধ"</string>
+ <string name="notes_app_quick_affordance_unavailable_explanation" msgid="4796955161600178530">"টোকা গ্ৰহণৰ শ্বৰ্টকাটটো ব্যৱহাৰ কৰিবলৈ এটা ডিফ’ল্ট টোকা গ্ৰহণৰ এপ্ বাছনি কৰক"</string>
<string name="keyguard_affordance_enablement_dialog_notes_app_action" msgid="6821710209675089470">"এপ্ বাছনি কৰক"</string>
<string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"শ্বৰ্টকাটটোত স্পৰ্শ কৰি ধৰি ৰাখক"</string>
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"বাতিল কৰক"</string>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index a99ea62..a413e6b 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -1046,8 +1046,7 @@
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Batareya ölçüsünü oxuyarkən problem yarandı"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Ətraflı məlumat üçün toxunun"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Siqnal ayarlanmayıb"</string>
- <!-- no translation found for accessibility_bouncer (5896923685673320070) -->
- <skip />
+ <string name="accessibility_bouncer" msgid="5896923685673320070">"ekran kilidi daxil edin"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Barmaq izi sensoru"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"doğrulayın"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"cihaz daxil edin"</string>
@@ -1127,18 +1126,12 @@
<string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Ətraflı məlumat"</string>
<string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Ətraflı məlumat: <xliff:g id="URL">%s</xliff:g>"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> tətbiqini açın"</string>
- <!-- no translation found for wallet_quick_affordance_unavailable_install_the_app (7298552910007208368) -->
- <skip />
- <!-- no translation found for wallet_quick_affordance_unavailable_configure_the_app (4387433357429873258) -->
- <skip />
- <!-- no translation found for qr_scanner_quick_affordance_unavailable_explanation (3049582306241150946) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_install_the_app (6187820778998446168) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_configure_the_app (7953595390775156839) -->
- <skip />
- <!-- no translation found for notes_app_quick_affordance_unavailable_explanation (4796955161600178530) -->
- <skip />
+ <string name="wallet_quick_affordance_unavailable_install_the_app" msgid="7298552910007208368">"Pulqabı tətbiqini qısayol kimi əlavə etmək üçün tətbiq quraşdırılmalıdır"</string>
+ <string name="wallet_quick_affordance_unavailable_configure_the_app" msgid="4387433357429873258">"Pulqabı tətbiqini qısayol kimi əlavə etmək üçün kart əlavə edilməlidir"</string>
+ <string name="qr_scanner_quick_affordance_unavailable_explanation" msgid="3049582306241150946">"QR kod skanerini qısayol kimi əlavə etmək üçün kamera tətbiqi quraşdırılmalıdır"</string>
+ <string name="home_quick_affordance_unavailable_install_the_app" msgid="6187820778998446168">"Home tətbiqini qısayol kimi əlavə etmək üçün tətbiq quraşdırılmalıdır"</string>
+ <string name="home_quick_affordance_unavailable_configure_the_app" msgid="7953595390775156839">"• Ən azı bir cihaz əlçatandır"</string>
+ <string name="notes_app_quick_affordance_unavailable_explanation" msgid="4796955161600178530">"Qeydgötürmə qısayolu üçün defolt qeyd tətbiqi seçin"</string>
<string name="keyguard_affordance_enablement_dialog_notes_app_action" msgid="6821710209675089470">"Tətbiq seçin"</string>
<string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Qısayola toxunub saxlayın"</string>
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Ləğv edin"</string>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index 1dfdde3..3d52d51 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -1046,8 +1046,7 @@
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problem sa očitavanjem merača baterije"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Dodirnite za više informacija"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Nije podešen"</string>
- <!-- no translation found for accessibility_bouncer (5896923685673320070) -->
- <skip />
+ <string name="accessibility_bouncer" msgid="5896923685673320070">"unesite zaključavanje ekrana"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Senzor za otisak prsta"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"potvrdite identitet"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"unesite uređaj"</string>
@@ -1127,18 +1126,12 @@
<string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Saznajte više"</string>
<string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Saznajte više na <xliff:g id="URL">%s</xliff:g>"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Otvorite: <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <!-- no translation found for wallet_quick_affordance_unavailable_install_the_app (7298552910007208368) -->
- <skip />
- <!-- no translation found for wallet_quick_affordance_unavailable_configure_the_app (4387433357429873258) -->
- <skip />
- <!-- no translation found for qr_scanner_quick_affordance_unavailable_explanation (3049582306241150946) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_install_the_app (6187820778998446168) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_configure_the_app (7953595390775156839) -->
- <skip />
- <!-- no translation found for notes_app_quick_affordance_unavailable_explanation (4796955161600178530) -->
- <skip />
+ <string name="wallet_quick_affordance_unavailable_install_the_app" msgid="7298552910007208368">"Da biste dodali aplikaciju Novčanik kao prečicu, uverite se da je aplikacija instalirana"</string>
+ <string name="wallet_quick_affordance_unavailable_configure_the_app" msgid="4387433357429873258">"Da biste dodali aplikaciju Novčanik kao prečicu, uverite se da je dodata bar jedna kartica"</string>
+ <string name="qr_scanner_quick_affordance_unavailable_explanation" msgid="3049582306241150946">"Da biste dodali Skener QR koda kao prečicu, uverite se da je aplikacija za kameru instalirana"</string>
+ <string name="home_quick_affordance_unavailable_install_the_app" msgid="6187820778998446168">"Da biste dodali aplikaciju Home kao prečicu, uverite se da je aplikacija instalirana"</string>
+ <string name="home_quick_affordance_unavailable_configure_the_app" msgid="7953595390775156839">"• Dostupan je bar jedan uređaj"</string>
+ <string name="notes_app_quick_affordance_unavailable_explanation" msgid="4796955161600178530">"Izaberite podrazumevanu aplikaciju za beleške da biste koristili prečicu za pravljenje beleški"</string>
<string name="keyguard_affordance_enablement_dialog_notes_app_action" msgid="6821710209675089470">"Izaberi aplikaciju"</string>
<string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Dodirnite i zadržite prečicu"</string>
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Otkaži"</string>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index 05841dc..5f2d7b5 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -1046,8 +1046,7 @@
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Праблема з чытаннем індыкатара зараду акумулятара"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Націсніце, каб убачыць больш"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Няма будзільнікаў"</string>
- <!-- no translation found for accessibility_bouncer (5896923685673320070) -->
- <skip />
+ <string name="accessibility_bouncer" msgid="5896923685673320070">"прыступіць да разблакіроўкі экрана"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Сканер адбіткаў пальцаў"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"правесці аўтэнтыфікацыю"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"адкрыць галоўны экран прылады"</string>
@@ -1127,18 +1126,12 @@
<string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Даведацца больш"</string>
<string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Даведайцеся больш на старонцы <xliff:g id="URL">%s</xliff:g>"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Адкрыць праграму \"<xliff:g id="APPNAME">%1$s</xliff:g>\""</string>
- <!-- no translation found for wallet_quick_affordance_unavailable_install_the_app (7298552910007208368) -->
- <skip />
- <!-- no translation found for wallet_quick_affordance_unavailable_configure_the_app (4387433357429873258) -->
- <skip />
- <!-- no translation found for qr_scanner_quick_affordance_unavailable_explanation (3049582306241150946) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_install_the_app (6187820778998446168) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_configure_the_app (7953595390775156839) -->
- <skip />
- <!-- no translation found for notes_app_quick_affordance_unavailable_explanation (4796955161600178530) -->
- <skip />
+ <string name="wallet_quick_affordance_unavailable_install_the_app" msgid="7298552910007208368">"Вы можаце дадаць ярлык праграмы \"Кашалёк\", толькі калі яна ўсталявана"</string>
+ <string name="wallet_quick_affordance_unavailable_configure_the_app" msgid="4387433357429873258">"Вы можаце дадаць ярлык праграмы \"Кашалёк\", толькі калі дададзена хаця б адна картка"</string>
+ <string name="qr_scanner_quick_affordance_unavailable_explanation" msgid="3049582306241150946">"Вы можаце дадаць ярлык сканера QR-кодаў, толькі калі ўсталявана праграма камеры"</string>
+ <string name="home_quick_affordance_unavailable_install_the_app" msgid="6187820778998446168">"Вы можаце дадаць ярлык праграмы Home, толькі калі яна ўсталявана"</string>
+ <string name="home_quick_affordance_unavailable_configure_the_app" msgid="7953595390775156839">"• Даступная хаця б адна прылада"</string>
+ <string name="notes_app_quick_affordance_unavailable_explanation" msgid="4796955161600178530">"Выберыце стандартную праграму для нататак, якая будзе адкрывацца пры націсканні на ярлык"</string>
<string name="keyguard_affordance_enablement_dialog_notes_app_action" msgid="6821710209675089470">"Выберыце праграму"</string>
<string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Дакраніцеся і ўтрымлівайце ярлык"</string>
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Скасаваць"</string>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index 0345471..9201f40 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -1046,8 +1046,7 @@
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Възникна проблем при четенето на данните за нивото на батерията"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Докоснете за още информация"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Няма зададен будилник"</string>
- <!-- no translation found for accessibility_bouncer (5896923685673320070) -->
- <skip />
+ <string name="accessibility_bouncer" msgid="5896923685673320070">"въведете опция за заключване на екрана"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Сензор за отпечатъци"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"удостоверяване"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"вход в устройството"</string>
@@ -1127,18 +1126,12 @@
<string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Научете повече"</string>
<string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Научете повече на адрес <xliff:g id="URL">%s</xliff:g>"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Отваряне на <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <!-- no translation found for wallet_quick_affordance_unavailable_install_the_app (7298552910007208368) -->
- <skip />
- <!-- no translation found for wallet_quick_affordance_unavailable_configure_the_app (4387433357429873258) -->
- <skip />
- <!-- no translation found for qr_scanner_quick_affordance_unavailable_explanation (3049582306241150946) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_install_the_app (6187820778998446168) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_configure_the_app (7953595390775156839) -->
- <skip />
- <!-- no translation found for notes_app_quick_affordance_unavailable_explanation (4796955161600178530) -->
- <skip />
+ <string name="wallet_quick_affordance_unavailable_install_the_app" msgid="7298552910007208368">"За да добавите пряк път към приложението Wallet, уверете се, че то е инсталирано"</string>
+ <string name="wallet_quick_affordance_unavailable_configure_the_app" msgid="4387433357429873258">"За да добавите пряк път към приложението Wallet, уверете се, че е добавена поне една карта"</string>
+ <string name="qr_scanner_quick_affordance_unavailable_explanation" msgid="3049582306241150946">"За да добавите пряк път към скенера за QR кодове, уверете се, че е инсталирано приложение за камера"</string>
+ <string name="home_quick_affordance_unavailable_install_the_app" msgid="6187820778998446168">"За да добавите пряк път към приложението Home, уверете се, че то е инсталирано"</string>
+ <string name="home_quick_affordance_unavailable_configure_the_app" msgid="7953595390775156839">"• Налице е поне едно устройство."</string>
+ <string name="notes_app_quick_affordance_unavailable_explanation" msgid="4796955161600178530">"Изберете стандартно приложение за бележки, за да използвате прекия път за водене на бележки"</string>
<string name="keyguard_affordance_enablement_dialog_notes_app_action" msgid="6821710209675089470">"Избиране на приложение"</string>
<string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Докоснете и задръжте прекия път"</string>
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Отказ"</string>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index 2d0388d..d8cb70d 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -399,7 +399,7 @@
<string name="media_projection_sys_service_dialog_warning" msgid="2443872865267330320">"যে পরিষেবা এই ফাংশন প্রদান করছে, সেটি রেকর্ড বা কাস্ট করার সময় আপনার স্ক্রিনে দৃশ্যমান বা ডিভাইসে চালানো হয়েছে এমন সব তথ্য অ্যাক্সেস করতে পারবে। এর মধ্যে আপনার পাসওয়ার্ড, পেমেন্টের বিবরণ, ফটো, মেসেজ এবং আপনার চালানো অডিও সম্পর্কিত তথ্য রয়েছে।"</string>
<string name="screen_share_permission_dialog_option_entire_screen" msgid="3131200488455089620">"পুরো স্ক্রিন"</string>
<string name="screen_share_permission_dialog_option_single_app" msgid="4350961814397220929">"একটি অ্যাপ"</string>
- <string name="screen_share_permission_app_selector_title" msgid="1404878013670347899">"অ্যাপ শেয়ার বা এর মাধ্যমে রেকর্ড করুন"</string>
+ <string name="screen_share_permission_app_selector_title" msgid="1404878013670347899">"অ্যাপ শেয়ার বা রেকর্ড করুন"</string>
<string name="media_projection_entry_app_permission_dialog_title" msgid="9155535851866407199">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ব্যবহার করে রেকর্ডিং বা কাস্টিং শুরু করবেন?"</string>
<string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"আপনি শেয়ার, রেকর্ড বা কাস্ট করার সময়, স্ক্রিনে দৃশ্যমান বা ডিভাইসে চালানো সব কিছুই <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> অ্যাক্সেস করতে পারবে। তাই পাসওয়ার্ড, পেমেন্টের বিবরণ, মেসেজ, ফটো এবং অডিও ও ভিডিওর মতো বিষয়ে সতর্ক থাকুন।"</string>
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"আপনি কোনও অ্যাপ শেয়ার, রেকর্ড বা কাস্ট করার সময়, সেই অ্যাপে দেখা যায় বা চালানো হয় এমন সব কিছু <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> অ্যাক্সেস করতে পারবে। তাই পাসওয়ার্ড, পেমেন্টের বিবরণ, মেসেজ, ফটো এবং অডিও ও ভিডিওর মতো বিষয়ে সতর্ক থাকুন।"</string>
@@ -415,7 +415,7 @@
<string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"আপনার আইটি অ্যাডমিন ব্লক করেছেন"</string>
<string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"ডিভাইস নীতির কারণে স্ক্রিন ক্যাপচার করার প্রসেস বন্ধ করা আছে"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"সব মুছে দিন"</string>
- <string name="manage_notifications_text" msgid="6885645344647733116">"পরিচালনা করুন"</string>
+ <string name="manage_notifications_text" msgid="6885645344647733116">"ম্যানেজ করুন"</string>
<string name="manage_notifications_history_text" msgid="57055985396576230">"ইতিহাস"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"নতুন"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"আওয়াজ করবে না"</string>
@@ -1046,8 +1046,7 @@
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"ব্যাটারির মিটারের রিডিং নেওয়ার সময় সমস্যা হয়েছে"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"আরও তথ্যের জন্য ট্যাপ করুন"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"কোনও অ্যালার্ম সেট করা নেই"</string>
- <!-- no translation found for accessibility_bouncer (5896923685673320070) -->
- <skip />
+ <string name="accessibility_bouncer" msgid="5896923685673320070">"স্ক্রিন লক খুলুন"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"ফিঙ্গারপ্রিন্ট সেন্সর"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"যাচাই করিয়ে নিন"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"ডিভাইস আনলক করুন"</string>
@@ -1127,18 +1126,12 @@
<string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"আরও জানুন"</string>
<string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"আরও জানতে <xliff:g id="URL">%s</xliff:g>-এ যান"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> খুলুন"</string>
- <!-- no translation found for wallet_quick_affordance_unavailable_install_the_app (7298552910007208368) -->
- <skip />
- <!-- no translation found for wallet_quick_affordance_unavailable_configure_the_app (4387433357429873258) -->
- <skip />
- <!-- no translation found for qr_scanner_quick_affordance_unavailable_explanation (3049582306241150946) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_install_the_app (6187820778998446168) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_configure_the_app (7953595390775156839) -->
- <skip />
- <!-- no translation found for notes_app_quick_affordance_unavailable_explanation (4796955161600178530) -->
- <skip />
+ <string name="wallet_quick_affordance_unavailable_install_the_app" msgid="7298552910007208368">"Wallet অ্যাপ, শর্টকাট হিসেবে যোগ করতে, অ্যাপ ইনস্টল করা আছে কিনা তা ভালভাবে দেখে নিন"</string>
+ <string name="wallet_quick_affordance_unavailable_configure_the_app" msgid="4387433357429873258">"Wallet অ্যাপ, শর্টকাট হিসেবে যোগ করতে, অন্তত একটি কার্ড যোগ করা হয়েছে কিনা তা ভালভাবে দেখে নিন"</string>
+ <string name="qr_scanner_quick_affordance_unavailable_explanation" msgid="3049582306241150946">"QR কোড স্ক্যানার, শর্টকাট হিসেবে যোগ করতে, ক্যামেরা অ্যাপ ইনস্টল করা আছে কিনা তা ভালভাবে দেখে নিন"</string>
+ <string name="home_quick_affordance_unavailable_install_the_app" msgid="6187820778998446168">"Home অ্যাপ, শর্টকাট হিসেবে যোগ করতে, অ্যাপ ইনস্টল করা আছে কিনা তা ভালভাবে দেখে নিন"</string>
+ <string name="home_quick_affordance_unavailable_configure_the_app" msgid="7953595390775156839">"• অন্তত একটি ডিভাইস উপলভ্য আছে"</string>
+ <string name="notes_app_quick_affordance_unavailable_explanation" msgid="4796955161600178530">"নোট নেওয়ার শর্টকাট ব্যবহার করতে, ডিফল্ট কোনও নোট অ্যাপ বেছে নিন"</string>
<string name="keyguard_affordance_enablement_dialog_notes_app_action" msgid="6821710209675089470">"অ্যাপ বেছে নিন"</string>
<string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"শর্টকাট টাচ করে ধরে রাখুন"</string>
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"বাতিল করুন"</string>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index 8e8fb8b..89c964d 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -1046,8 +1046,7 @@
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Došlo je do problema prilikom očitavanja mjerača stanja baterije"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Dodirnite za više informacija"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Nema nijednog alarma"</string>
- <!-- no translation found for accessibility_bouncer (5896923685673320070) -->
- <skip />
+ <string name="accessibility_bouncer" msgid="5896923685673320070">"unos zaključavanja ekrana"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Senzor za otisak prsta"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"autentificiranje"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"pristup uređaju"</string>
@@ -1127,12 +1126,12 @@
<string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Saznajte više"</string>
<string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Saznajte više na <xliff:g id="URL">%s</xliff:g>"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Otvori aplikaciju <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <string name="wallet_quick_affordance_unavailable_install_the_app" msgid="7298552910007208368">"Za dodavanje aplikacije Wallet kao prečaca provjerite je li instalirana"</string>
- <string name="wallet_quick_affordance_unavailable_configure_the_app" msgid="4387433357429873258">"Provjerite je li dodana barem jedna kartica kako biste dodali aplikaciju Wallet kao prečac"</string>
- <string name="qr_scanner_quick_affordance_unavailable_explanation" msgid="3049582306241150946">"Provjerite je li instalirana aplikacija kamere kako biste dodali čitač QR koda kao prečac"</string>
- <string name="home_quick_affordance_unavailable_install_the_app" msgid="6187820778998446168">"Provjerite je li aplikacija Home instalirana kako biste je dodali kao prečac"</string>
+ <string name="wallet_quick_affordance_unavailable_install_the_app" msgid="7298552910007208368">"Da dodate aplikaciju Novčanik kao prečicu, instalirajte aplikaciju"</string>
+ <string name="wallet_quick_affordance_unavailable_configure_the_app" msgid="4387433357429873258">"Da dodate aplikaciju Novčanik kao prečicu, dodajte barem jednu karticu"</string>
+ <string name="qr_scanner_quick_affordance_unavailable_explanation" msgid="3049582306241150946">"Da dodate skener QR koda kao prečicu, instalirajte aplikaciju kamere"</string>
+ <string name="home_quick_affordance_unavailable_install_the_app" msgid="6187820778998446168">"Da dodate aplikaciju Home kao prečicu, instalirajte aplikaciju"</string>
<string name="home_quick_affordance_unavailable_configure_the_app" msgid="7953595390775156839">"• Dostupan je najmanje jedan uređaj"</string>
- <string name="notes_app_quick_affordance_unavailable_explanation" msgid="4796955161600178530">"Odaberite zadanu aplikaciju za bilješke da biste koristili prečac za pisanje bilježaka"</string>
+ <string name="notes_app_quick_affordance_unavailable_explanation" msgid="4796955161600178530">"Odaberite zadanu aplikaciju za bilješke da koristite prečicu za zapisivanje bilješki"</string>
<string name="keyguard_affordance_enablement_dialog_notes_app_action" msgid="6821710209675089470">"Odaberi aplikaciju"</string>
<string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Dodirnite i zadržite prečicu"</string>
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Otkaži"</string>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 530482f..e0e78ae 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -1046,8 +1046,7 @@
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Hi ha hagut un problema en llegir el mesurador de la bateria"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Toca per obtenir més informació"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Cap alarma definida"</string>
- <!-- no translation found for accessibility_bouncer (5896923685673320070) -->
- <skip />
+ <string name="accessibility_bouncer" msgid="5896923685673320070">"utilitza el bloqueig de pantalla"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Sensor d\'empremtes digitals"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"autenticar"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"accedir al dispositiu"</string>
@@ -1127,18 +1126,12 @@
<string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Més informació"</string>
<string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Més informació a <xliff:g id="URL">%s</xliff:g>"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Obre <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <!-- no translation found for wallet_quick_affordance_unavailable_install_the_app (7298552910007208368) -->
- <skip />
- <!-- no translation found for wallet_quick_affordance_unavailable_configure_the_app (4387433357429873258) -->
- <skip />
- <!-- no translation found for qr_scanner_quick_affordance_unavailable_explanation (3049582306241150946) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_install_the_app (6187820778998446168) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_configure_the_app (7953595390775156839) -->
- <skip />
- <!-- no translation found for notes_app_quick_affordance_unavailable_explanation (4796955161600178530) -->
- <skip />
+ <string name="wallet_quick_affordance_unavailable_install_the_app" msgid="7298552910007208368">"Per afegir l\'aplicació Wallet com a drecera, assegura\'t que estigui instal·lada"</string>
+ <string name="wallet_quick_affordance_unavailable_configure_the_app" msgid="4387433357429873258">"Per afegir l\'aplicació Wallet com a drecera, assegura\'t que s\'hagi afegit almenys una targeta"</string>
+ <string name="qr_scanner_quick_affordance_unavailable_explanation" msgid="3049582306241150946">"Per afegir l\'escàner de codis QR com a drecera, assegura\'t que hi hagi una aplicació de càmera instal·lada"</string>
+ <string name="home_quick_affordance_unavailable_install_the_app" msgid="6187820778998446168">"Per afegir l\'aplicació Home com a drecera, assegura\'t que estigui instal·lada"</string>
+ <string name="home_quick_affordance_unavailable_configure_the_app" msgid="7953595390775156839">"• Almenys un dispositiu està disponible."</string>
+ <string name="notes_app_quick_affordance_unavailable_explanation" msgid="4796955161600178530">"Selecciona una aplicació de notes predeterminada per utilitzar la drecera de presa de notes"</string>
<string name="keyguard_affordance_enablement_dialog_notes_app_action" msgid="6821710209675089470">"Selecciona una aplicació"</string>
<string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Mantén premuda la drecera"</string>
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Cancel·la"</string>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index fba856d..522300b 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -1046,8 +1046,7 @@
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problém s načtením měřiče baterie"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Klepnutím zobrazíte další informace"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Budík nenastaven"</string>
- <!-- no translation found for accessibility_bouncer (5896923685673320070) -->
- <skip />
+ <string name="accessibility_bouncer" msgid="5896923685673320070">"zadejte zámek obrazovky"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Snímač otisků prstů"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"ověříte"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"zadáte zařízení"</string>
@@ -1127,18 +1126,12 @@
<string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Další informace"</string>
<string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Další informace najdete na adrese <xliff:g id="URL">%s</xliff:g>."</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Otevřít <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <!-- no translation found for wallet_quick_affordance_unavailable_install_the_app (7298552910007208368) -->
- <skip />
- <!-- no translation found for wallet_quick_affordance_unavailable_configure_the_app (4387433357429873258) -->
- <skip />
- <!-- no translation found for qr_scanner_quick_affordance_unavailable_explanation (3049582306241150946) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_install_the_app (6187820778998446168) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_configure_the_app (7953595390775156839) -->
- <skip />
- <!-- no translation found for notes_app_quick_affordance_unavailable_explanation (4796955161600178530) -->
- <skip />
+ <string name="wallet_quick_affordance_unavailable_install_the_app" msgid="7298552910007208368">"Pokud chcete přidat aplikaci Peněženka jako zkratku, nainstalujte ji"</string>
+ <string name="wallet_quick_affordance_unavailable_configure_the_app" msgid="4387433357429873258">"Pokud chcete přidat aplikaci Peněženka jako zkratku, přidejte alespoň jednu kartu"</string>
+ <string name="qr_scanner_quick_affordance_unavailable_explanation" msgid="3049582306241150946">"Pokud chcete přidat skener QR kódů jako zkratku, ujistěte se, že je nainstalována aplikace k focení a natáčení"</string>
+ <string name="home_quick_affordance_unavailable_install_the_app" msgid="6187820778998446168">"Pokud chcete přidat aplikaci Home jako zkratku, nainstalujte ji"</string>
+ <string name="home_quick_affordance_unavailable_configure_the_app" msgid="7953595390775156839">"• Je k dispozici alespoň jedno zařízení"</string>
+ <string name="notes_app_quick_affordance_unavailable_explanation" msgid="4796955161600178530">"Vyberte výchozí aplikaci k psaní poznámek, ke které přidružíte zkratku pro poznámky"</string>
<string name="keyguard_affordance_enablement_dialog_notes_app_action" msgid="6821710209675089470">"Vyberte aplikaci"</string>
<string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Podržte zkratku"</string>
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Zrušit"</string>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 386f809..e9a522f 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -1046,8 +1046,7 @@
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Der er problemer med at læse dit batteriniveau"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Tryk for at få flere oplysninger"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Ingen alarm er indstillet"</string>
- <!-- no translation found for accessibility_bouncer (5896923685673320070) -->
- <skip />
+ <string name="accessibility_bouncer" msgid="5896923685673320070">"angiv skærmlås"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Fingeraftrykssensor"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"godkende"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"få adgang til enheden"</string>
@@ -1127,18 +1126,12 @@
<string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Få flere oplysninger"</string>
<string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Få flere oplysninger på <xliff:g id="URL">%s</xliff:g>"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Åbn <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <!-- no translation found for wallet_quick_affordance_unavailable_install_the_app (7298552910007208368) -->
- <skip />
- <!-- no translation found for wallet_quick_affordance_unavailable_configure_the_app (4387433357429873258) -->
- <skip />
- <!-- no translation found for qr_scanner_quick_affordance_unavailable_explanation (3049582306241150946) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_install_the_app (6187820778998446168) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_configure_the_app (7953595390775156839) -->
- <skip />
- <!-- no translation found for notes_app_quick_affordance_unavailable_explanation (4796955161600178530) -->
- <skip />
+ <string name="wallet_quick_affordance_unavailable_install_the_app" msgid="7298552910007208368">"Hvis du vil tilføje en genvej til Wallet-appen, skal du sørge for, at appen er installeret"</string>
+ <string name="wallet_quick_affordance_unavailable_configure_the_app" msgid="4387433357429873258">"Hvis du vil tilføje en genvej til Wallet-appen, skal du sørge for, at du har tilføjet mindst ét kort"</string>
+ <string name="qr_scanner_quick_affordance_unavailable_explanation" msgid="3049582306241150946">"Hvis du vil tilføje en genvej til QR-kodescanneren, skal du sørge for, at kameraappen er installeret"</string>
+ <string name="home_quick_affordance_unavailable_install_the_app" msgid="6187820778998446168">"Hvis du vil tilføje en genvej til Home-appen, skal du sørge for, at appen er installeret"</string>
+ <string name="home_quick_affordance_unavailable_configure_the_app" msgid="7953595390775156839">"• Mindst én enhed er tilgængelig"</string>
+ <string name="notes_app_quick_affordance_unavailable_explanation" msgid="4796955161600178530">"Vælg en standardapp til noter for at bruge genvejen til notetagning"</string>
<string name="keyguard_affordance_enablement_dialog_notes_app_action" msgid="6821710209675089470">"Vælg app"</string>
<string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Hold fingeren på genvejen"</string>
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Annuller"</string>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index b57f023..dc06ee1 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -1046,8 +1046,7 @@
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problem beim Lesen des Akkustands"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Für weitere Informationen tippen"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Kein Wecker gestellt"</string>
- <!-- no translation found for accessibility_bouncer (5896923685673320070) -->
- <skip />
+ <string name="accessibility_bouncer" msgid="5896923685673320070">"Displaysperre-Anmeldedaten eingeben"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Fingerabdrucksensor"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"Authentifizieren"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"Eingeben des Geräts"</string>
@@ -1127,26 +1126,20 @@
<string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Weitere Informationen"</string>
<string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Weitere Informationen unter <xliff:g id="URL">%s</xliff:g>"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> öffnen"</string>
- <!-- no translation found for wallet_quick_affordance_unavailable_install_the_app (7298552910007208368) -->
- <skip />
- <!-- no translation found for wallet_quick_affordance_unavailable_configure_the_app (4387433357429873258) -->
- <skip />
- <!-- no translation found for qr_scanner_quick_affordance_unavailable_explanation (3049582306241150946) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_install_the_app (6187820778998446168) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_configure_the_app (7953595390775156839) -->
- <skip />
- <!-- no translation found for notes_app_quick_affordance_unavailable_explanation (4796955161600178530) -->
- <skip />
+ <string name="wallet_quick_affordance_unavailable_install_the_app" msgid="7298552910007208368">"Damit du die Wallet App als Verknüpfung hinzufügen kannst, muss die App installiert sein"</string>
+ <string name="wallet_quick_affordance_unavailable_configure_the_app" msgid="4387433357429873258">"Damit du die Wallet App als Verknüpfung hinzufügen kannst, muss mindestens eine Karte hinzugefügt sein"</string>
+ <string name="qr_scanner_quick_affordance_unavailable_explanation" msgid="3049582306241150946">"Damit du den QR-Code-Scanner als Verknüpfung hinzufügen kannst, muss eine Kamera-App installiert sein"</string>
+ <string name="home_quick_affordance_unavailable_install_the_app" msgid="6187820778998446168">"Damit du die Home App als Verknüpfung hinzufügen kannst, muss die App installiert sein"</string>
+ <string name="home_quick_affordance_unavailable_configure_the_app" msgid="7953595390775156839">"• Mindestens ein Gerät ist verfügbar"</string>
+ <string name="notes_app_quick_affordance_unavailable_explanation" msgid="4796955161600178530">"Wähle eine Standard-App für Notizen aus, die du für die Verknüpfung verwenden möchtest"</string>
<string name="keyguard_affordance_enablement_dialog_notes_app_action" msgid="6821710209675089470">"App wählen"</string>
<string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Verknüpfung berühren & halten"</string>
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Abbrechen"</string>
- <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"Bildschirm jetzt wechseln"</string>
+ <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"Jetzt umdrehen"</string>
<string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"Smartphone auffalten"</string>
<string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"Bildschirm wechseln?"</string>
<string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"Mit der Rückkamera lassen sich Fotos mit höherer Auflösung aufnehmen"</string>
- <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Smartphone umdrehen, um Fotos mit höherer Auflösung aufzunehmen"</string>
+ <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Für höhere Auflösung Smartphone umdrehen"</string>
<string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"Faltbares Gerät wird geöffnet"</string>
<string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"Faltbares Gerät wird umgeklappt"</string>
<string name="stylus_battery_low_percentage" msgid="1620068112350141558">"Akku bei <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 421307ee..08d5b4b 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -1046,8 +1046,7 @@
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Υπάρχει κάποιο πρόβλημα με την ανάγνωση του μετρητή μπαταρίας"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Πατήστε για περισσότερες πληροφορίες."</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Δεν ορίστηκε ξυπνητ."</string>
- <!-- no translation found for accessibility_bouncer (5896923685673320070) -->
- <skip />
+ <string name="accessibility_bouncer" msgid="5896923685673320070">"εισαγωγή κλειδώματος οθόνης"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Αισθητήρας δακτυλικών αποτυπωμάτων"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"έλεγχος ταυτότητας"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"εισαγωγή συσκευής"</string>
@@ -1127,18 +1126,12 @@
<string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Μάθετε περισσότερα"</string>
<string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Μάθετε περισσότερα στο <xliff:g id="URL">%s</xliff:g>."</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Άνοιγμα <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <!-- no translation found for wallet_quick_affordance_unavailable_install_the_app (7298552910007208368) -->
- <skip />
- <!-- no translation found for wallet_quick_affordance_unavailable_configure_the_app (4387433357429873258) -->
- <skip />
- <!-- no translation found for qr_scanner_quick_affordance_unavailable_explanation (3049582306241150946) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_install_the_app (6187820778998446168) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_configure_the_app (7953595390775156839) -->
- <skip />
- <!-- no translation found for notes_app_quick_affordance_unavailable_explanation (4796955161600178530) -->
- <skip />
+ <string name="wallet_quick_affordance_unavailable_install_the_app" msgid="7298552910007208368">"Για να προσθέσετε ως συντόμευση την εφαρμογή Πορτοφόλι, βεβαιωθείτε ότι έχει εγκατασταθεί η εφαρμογή"</string>
+ <string name="wallet_quick_affordance_unavailable_configure_the_app" msgid="4387433357429873258">"Για να προσθέσετε ως συντόμευση την εφαρμογή Πορτοφόλι, βεβαιωθείτε ότι έχει προστεθεί τουλάχιστον μία κάρτα"</string>
+ <string name="qr_scanner_quick_affordance_unavailable_explanation" msgid="3049582306241150946">"Για να προσθέσετε ως συντόμευση τη Σάρωση κωδικών QR, βεβαιωθείτε ότι η εφαρμογή κάμερας είναι εγκατεστημένη"</string>
+ <string name="home_quick_affordance_unavailable_install_the_app" msgid="6187820778998446168">"Για να προσθέσετε την εφαρμογή Home ως συντόμευση, βεβαιωθείτε ότι η εφαρμογή είναι εγκατεστημένη"</string>
+ <string name="home_quick_affordance_unavailable_configure_the_app" msgid="7953595390775156839">"• Είναι διαθέσιμη τουλάχιστον μία συσκευή"</string>
+ <string name="notes_app_quick_affordance_unavailable_explanation" msgid="4796955161600178530">"Επιλέξτε μια προεπιλεγμένη εφαρμογή σημειώσεων για να χρησιμοποιήσετε τη συντόμευση δημιουργίας σημειώσεων"</string>
<string name="keyguard_affordance_enablement_dialog_notes_app_action" msgid="6821710209675089470">"Επιλογή εφαρμογής"</string>
<string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Παρατεταμένο άγγιγμα συντόμευσης"</string>
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Ακύρωση"</string>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index eb4ccf5..e4719e4 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -1046,8 +1046,7 @@
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problem reading your battery meter"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Tap for more information"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"No alarm set"</string>
- <!-- no translation found for accessibility_bouncer (5896923685673320070) -->
- <skip />
+ <string name="accessibility_bouncer" msgid="5896923685673320070">"enter screen lock"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Fingerprint sensor"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"Authenticate"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"enter device"</string>
@@ -1127,18 +1126,12 @@
<string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Learn more"</string>
<string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Learn more at <xliff:g id="URL">%s</xliff:g>"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Open <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <!-- no translation found for wallet_quick_affordance_unavailable_install_the_app (7298552910007208368) -->
- <skip />
- <!-- no translation found for wallet_quick_affordance_unavailable_configure_the_app (4387433357429873258) -->
- <skip />
- <!-- no translation found for qr_scanner_quick_affordance_unavailable_explanation (3049582306241150946) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_install_the_app (6187820778998446168) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_configure_the_app (7953595390775156839) -->
- <skip />
- <!-- no translation found for notes_app_quick_affordance_unavailable_explanation (4796955161600178530) -->
- <skip />
+ <string name="wallet_quick_affordance_unavailable_install_the_app" msgid="7298552910007208368">"To add the Wallet app as a shortcut, make sure that the app is installed"</string>
+ <string name="wallet_quick_affordance_unavailable_configure_the_app" msgid="4387433357429873258">"To add the Wallet app as a shortcut, make sure that at least one card has been added"</string>
+ <string name="qr_scanner_quick_affordance_unavailable_explanation" msgid="3049582306241150946">"To add the QR code scanner as a shortcut, make sure that a camera app is installed"</string>
+ <string name="home_quick_affordance_unavailable_install_the_app" msgid="6187820778998446168">"To add the Home app as a shortcut, make sure that the app is installed"</string>
+ <string name="home_quick_affordance_unavailable_configure_the_app" msgid="7953595390775156839">"• At least one device is available"</string>
+ <string name="notes_app_quick_affordance_unavailable_explanation" msgid="4796955161600178530">"Select a default notes app to use the note-taking shortcut"</string>
<string name="keyguard_affordance_enablement_dialog_notes_app_action" msgid="6821710209675089470">"Select app"</string>
<string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Touch & hold shortcut"</string>
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Cancel"</string>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index eb4ccf5..e4719e4 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -1046,8 +1046,7 @@
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problem reading your battery meter"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Tap for more information"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"No alarm set"</string>
- <!-- no translation found for accessibility_bouncer (5896923685673320070) -->
- <skip />
+ <string name="accessibility_bouncer" msgid="5896923685673320070">"enter screen lock"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Fingerprint sensor"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"Authenticate"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"enter device"</string>
@@ -1127,18 +1126,12 @@
<string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Learn more"</string>
<string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Learn more at <xliff:g id="URL">%s</xliff:g>"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Open <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <!-- no translation found for wallet_quick_affordance_unavailable_install_the_app (7298552910007208368) -->
- <skip />
- <!-- no translation found for wallet_quick_affordance_unavailable_configure_the_app (4387433357429873258) -->
- <skip />
- <!-- no translation found for qr_scanner_quick_affordance_unavailable_explanation (3049582306241150946) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_install_the_app (6187820778998446168) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_configure_the_app (7953595390775156839) -->
- <skip />
- <!-- no translation found for notes_app_quick_affordance_unavailable_explanation (4796955161600178530) -->
- <skip />
+ <string name="wallet_quick_affordance_unavailable_install_the_app" msgid="7298552910007208368">"To add the Wallet app as a shortcut, make sure that the app is installed"</string>
+ <string name="wallet_quick_affordance_unavailable_configure_the_app" msgid="4387433357429873258">"To add the Wallet app as a shortcut, make sure that at least one card has been added"</string>
+ <string name="qr_scanner_quick_affordance_unavailable_explanation" msgid="3049582306241150946">"To add the QR code scanner as a shortcut, make sure that a camera app is installed"</string>
+ <string name="home_quick_affordance_unavailable_install_the_app" msgid="6187820778998446168">"To add the Home app as a shortcut, make sure that the app is installed"</string>
+ <string name="home_quick_affordance_unavailable_configure_the_app" msgid="7953595390775156839">"• At least one device is available"</string>
+ <string name="notes_app_quick_affordance_unavailable_explanation" msgid="4796955161600178530">"Select a default notes app to use the note-taking shortcut"</string>
<string name="keyguard_affordance_enablement_dialog_notes_app_action" msgid="6821710209675089470">"Select app"</string>
<string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Touch & hold shortcut"</string>
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Cancel"</string>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index eb4ccf5..e4719e4 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -1046,8 +1046,7 @@
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problem reading your battery meter"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Tap for more information"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"No alarm set"</string>
- <!-- no translation found for accessibility_bouncer (5896923685673320070) -->
- <skip />
+ <string name="accessibility_bouncer" msgid="5896923685673320070">"enter screen lock"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Fingerprint sensor"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"Authenticate"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"enter device"</string>
@@ -1127,18 +1126,12 @@
<string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Learn more"</string>
<string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Learn more at <xliff:g id="URL">%s</xliff:g>"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Open <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <!-- no translation found for wallet_quick_affordance_unavailable_install_the_app (7298552910007208368) -->
- <skip />
- <!-- no translation found for wallet_quick_affordance_unavailable_configure_the_app (4387433357429873258) -->
- <skip />
- <!-- no translation found for qr_scanner_quick_affordance_unavailable_explanation (3049582306241150946) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_install_the_app (6187820778998446168) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_configure_the_app (7953595390775156839) -->
- <skip />
- <!-- no translation found for notes_app_quick_affordance_unavailable_explanation (4796955161600178530) -->
- <skip />
+ <string name="wallet_quick_affordance_unavailable_install_the_app" msgid="7298552910007208368">"To add the Wallet app as a shortcut, make sure that the app is installed"</string>
+ <string name="wallet_quick_affordance_unavailable_configure_the_app" msgid="4387433357429873258">"To add the Wallet app as a shortcut, make sure that at least one card has been added"</string>
+ <string name="qr_scanner_quick_affordance_unavailable_explanation" msgid="3049582306241150946">"To add the QR code scanner as a shortcut, make sure that a camera app is installed"</string>
+ <string name="home_quick_affordance_unavailable_install_the_app" msgid="6187820778998446168">"To add the Home app as a shortcut, make sure that the app is installed"</string>
+ <string name="home_quick_affordance_unavailable_configure_the_app" msgid="7953595390775156839">"• At least one device is available"</string>
+ <string name="notes_app_quick_affordance_unavailable_explanation" msgid="4796955161600178530">"Select a default notes app to use the note-taking shortcut"</string>
<string name="keyguard_affordance_enablement_dialog_notes_app_action" msgid="6821710209675089470">"Select app"</string>
<string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Touch & hold shortcut"</string>
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Cancel"</string>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 5358a26..0678e68 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -1046,8 +1046,7 @@
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problema al leer el medidor de batería"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Presiona para obtener más información"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"No establecida"</string>
- <!-- no translation found for accessibility_bouncer (5896923685673320070) -->
- <skip />
+ <string name="accessibility_bouncer" msgid="5896923685673320070">"ingresa el bloqueo pantalla"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Sensor de huellas dactilares"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"autenticar"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"ingresar al dispositivo"</string>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 42e390d..0dfd63c 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -412,7 +412,7 @@
<string name="media_projection_entry_generic_permission_dialog_warning_entire_screen" msgid="5407906851409410209">"Cuando compartes, grabas o envías contenido, Android puede acceder a todo lo que se muestre en la pantalla o se reproduzca en tu dispositivo. Debes tener cuidado con elementos como contraseñas, detalles de pagos, mensajes, fotos, audio y vídeo."</string>
<string name="media_projection_entry_generic_permission_dialog_warning_single_app" msgid="3454859977888159495">"Cuando compartes, grabas o envías una aplicación, Android puede acceder a todo lo que se muestre o se reproduzca en ella. Debes tener cuidado con elementos como contraseñas, detalles de pagos, mensajes, fotos, audio y vídeo."</string>
<string name="media_projection_entry_generic_permission_dialog_continue" msgid="8640381403048097116">"Empezar"</string>
- <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"Bloqueadas por tu administrador de TI"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"Bloqueado por tu administrador de TI"</string>
<string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"Las capturas de pantalla están inhabilitadas debido a la política de dispositivos"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"Borrar todo"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Gestionar"</string>
@@ -1046,8 +1046,7 @@
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"No se ha podido leer el indicador de batería"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Toca la pantalla para consultar más información"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Ninguna alarma puesta"</string>
- <!-- no translation found for accessibility_bouncer (5896923685673320070) -->
- <skip />
+ <string name="accessibility_bouncer" msgid="5896923685673320070">"Poner bloqueo de pantalla"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Sensor de huellas digitales"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"autenticarte"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"acceder al dispositivo"</string>
@@ -1127,18 +1126,12 @@
<string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Más información"</string>
<string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Más información en <xliff:g id="URL">%s</xliff:g>"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Abrir <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <!-- no translation found for wallet_quick_affordance_unavailable_install_the_app (7298552910007208368) -->
- <skip />
- <!-- no translation found for wallet_quick_affordance_unavailable_configure_the_app (4387433357429873258) -->
- <skip />
- <!-- no translation found for qr_scanner_quick_affordance_unavailable_explanation (3049582306241150946) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_install_the_app (6187820778998446168) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_configure_the_app (7953595390775156839) -->
- <skip />
- <!-- no translation found for notes_app_quick_affordance_unavailable_explanation (4796955161600178530) -->
- <skip />
+ <string name="wallet_quick_affordance_unavailable_install_the_app" msgid="7298552910007208368">"Para añadir la aplicación Wallet como acceso directo, asegúrate de que está instalada"</string>
+ <string name="wallet_quick_affordance_unavailable_configure_the_app" msgid="4387433357429873258">"Para añadir la aplicación Wallet como acceso directo, asegúrate de haber añadido al menos una tarjeta"</string>
+ <string name="qr_scanner_quick_affordance_unavailable_explanation" msgid="3049582306241150946">"Para añadir el escáner de códigos QR como acceso directo, asegúrate de que hay instalada una aplicación de cámara"</string>
+ <string name="home_quick_affordance_unavailable_install_the_app" msgid="6187820778998446168">"Para añadir la aplicación Home como acceso directo, asegúrate de que está instalada"</string>
+ <string name="home_quick_affordance_unavailable_configure_the_app" msgid="7953595390775156839">"• Al menos un dispositivo debe estar disponible"</string>
+ <string name="notes_app_quick_affordance_unavailable_explanation" msgid="4796955161600178530">"Selecciona una aplicación de notas predeterminada para usar el acceso directo de toma de notas"</string>
<string name="keyguard_affordance_enablement_dialog_notes_app_action" msgid="6821710209675089470">"Seleccionar aplicación"</string>
<string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Mantén pulsado el acceso directo"</string>
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Cancelar"</string>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index cd6b47c..ae75d09 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -1046,8 +1046,7 @@
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Probleem akumõõdiku lugemisel"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Puudutage lisateabe saamiseks"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Äratust pole"</string>
- <!-- no translation found for accessibility_bouncer (5896923685673320070) -->
- <skip />
+ <string name="accessibility_bouncer" msgid="5896923685673320070">"sisesta ekraanilukk"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Sõrmejäljeandur"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"autentimiseks"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"seadmesse sisenemiseks"</string>
@@ -1127,18 +1126,12 @@
<string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Lisateave"</string>
<string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Lisateave: <xliff:g id="URL">%s</xliff:g>"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Ava <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <!-- no translation found for wallet_quick_affordance_unavailable_install_the_app (7298552910007208368) -->
- <skip />
- <!-- no translation found for wallet_quick_affordance_unavailable_configure_the_app (4387433357429873258) -->
- <skip />
- <!-- no translation found for qr_scanner_quick_affordance_unavailable_explanation (3049582306241150946) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_install_the_app (6187820778998446168) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_configure_the_app (7953595390775156839) -->
- <skip />
- <!-- no translation found for notes_app_quick_affordance_unavailable_explanation (4796955161600178530) -->
- <skip />
+ <string name="wallet_quick_affordance_unavailable_install_the_app" msgid="7298552910007208368">"Rahakotirakenduse otsetee lisamiseks veenduge, et rakendus oleks installitud"</string>
+ <string name="wallet_quick_affordance_unavailable_configure_the_app" msgid="4387433357429873258">"Rahakotirakenduse otsetee lisamiseks veenduge, et vähemalt üks kaart oleks lisatud"</string>
+ <string name="qr_scanner_quick_affordance_unavailable_explanation" msgid="3049582306241150946">"QR-koodi skanneri otsetee lisamiseks veenduge, et kaamerarakendus oleks installitud"</string>
+ <string name="home_quick_affordance_unavailable_install_the_app" msgid="6187820778998446168">"Rakenduse Home otsetee lisamiseks veenduge, et rakendus oleks installitud"</string>
+ <string name="home_quick_affordance_unavailable_configure_the_app" msgid="7953595390775156839">"• Vähemalt üks seade on saadaval"</string>
+ <string name="notes_app_quick_affordance_unavailable_explanation" msgid="4796955161600178530">"Valige märkmete tegemise vaikerakendus, et kasutada märkmete tegemise otseteed"</string>
<string name="keyguard_affordance_enablement_dialog_notes_app_action" msgid="6821710209675089470">"Valige rakendus"</string>
<string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Pikalt puudutamise otsetee"</string>
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Tühista"</string>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index a670166..ff78952 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -1046,8 +1046,7 @@
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Arazo bat izan da bateria-neurgailua irakurtzean"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Informazio gehiago lortzeko, sakatu hau"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Ez da ezarri alarmarik"</string>
- <!-- no translation found for accessibility_bouncer (5896923685673320070) -->
- <skip />
+ <string name="accessibility_bouncer" msgid="5896923685673320070">"erabili pantailaren blokeoa"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Hatz-marken sentsorea"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"autentifikatu"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"sartu gailuan"</string>
@@ -1127,18 +1126,12 @@
<string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Lortu informazio gehiago"</string>
<string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Lortu informazio gehiago <xliff:g id="URL">%s</xliff:g> helbidean"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Ireki <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <!-- no translation found for wallet_quick_affordance_unavailable_install_the_app (7298552910007208368) -->
- <skip />
- <!-- no translation found for wallet_quick_affordance_unavailable_configure_the_app (4387433357429873258) -->
- <skip />
- <!-- no translation found for qr_scanner_quick_affordance_unavailable_explanation (3049582306241150946) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_install_the_app (6187820778998446168) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_configure_the_app (7953595390775156839) -->
- <skip />
- <!-- no translation found for notes_app_quick_affordance_unavailable_explanation (4796955161600178530) -->
- <skip />
+ <string name="wallet_quick_affordance_unavailable_install_the_app" msgid="7298552910007208368">"Diru-zorroa aplikazioa lasterbide gisa gehitzeko, ziurtatu aplikazioa instalatuta dagoela."</string>
+ <string name="wallet_quick_affordance_unavailable_configure_the_app" msgid="4387433357429873258">"Diru-zorroa aplikazioa lasterbide gisa gehitzeko, ziurtatu gutxienez txartel bat gehitu dela."</string>
+ <string name="qr_scanner_quick_affordance_unavailable_explanation" msgid="3049582306241150946">"QR kodeen eskanerra lasterbide gisa gehitzeko, ziurtatu kameraren aplikazioa instalatuta dagoela."</string>
+ <string name="home_quick_affordance_unavailable_install_the_app" msgid="6187820778998446168">"Home aplikazioa lasterbide gisa gehitzeko, ziurtatu aplikazioa instalatuta dagoela."</string>
+ <string name="home_quick_affordance_unavailable_configure_the_app" msgid="7953595390775156839">"• Gutxienez gailu bat erabilgarri dago."</string>
+ <string name="notes_app_quick_affordance_unavailable_explanation" msgid="4796955161600178530">"Oharrak idazteko lasterbidea erabiltzeko, hautatu oharretarako aplikazio lehenetsia."</string>
<string name="keyguard_affordance_enablement_dialog_notes_app_action" msgid="6821710209675089470">"Hautatu aplikazioa"</string>
<string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Eduki sakatuta lasterbidea"</string>
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Utzi"</string>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index dc24a3d..cc26355 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -1046,8 +1046,7 @@
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"مشکلی در خواندن میزان باتری وجود دارد"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"برای اطلاعات بیشتر ضربه بزنید"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"هشداری تنظیم نشده"</string>
- <!-- no translation found for accessibility_bouncer (5896923685673320070) -->
- <skip />
+ <string name="accessibility_bouncer" msgid="5896923685673320070">"وارد کردن قفل صفحه"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"حسگر اثرانگشت"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"اصالتسنجی کردن"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"وارد شدن به دستگاه"</string>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index b6303da..2b93430 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -1046,8 +1046,7 @@
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Ongelma akkumittarin lukemisessa"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Saat lisätietoja napauttamalla"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Ei herätyksiä"</string>
- <!-- no translation found for accessibility_bouncer (5896923685673320070) -->
- <skip />
+ <string name="accessibility_bouncer" msgid="5896923685673320070">"käytä näytön lukitustapaa"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Sormenjälkitunnistin"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"todentaaksesi"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"avataksesi laitteen"</string>
@@ -1127,18 +1126,12 @@
<string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Lue lisää"</string>
<string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Lue lisää: <xliff:g id="URL">%s</xliff:g>"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Avaa <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <!-- no translation found for wallet_quick_affordance_unavailable_install_the_app (7298552910007208368) -->
- <skip />
- <!-- no translation found for wallet_quick_affordance_unavailable_configure_the_app (4387433357429873258) -->
- <skip />
- <!-- no translation found for qr_scanner_quick_affordance_unavailable_explanation (3049582306241150946) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_install_the_app (6187820778998446168) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_configure_the_app (7953595390775156839) -->
- <skip />
- <!-- no translation found for notes_app_quick_affordance_unavailable_explanation (4796955161600178530) -->
- <skip />
+ <string name="wallet_quick_affordance_unavailable_install_the_app" msgid="7298552910007208368">"Jos haluat lisätä Wallet-sovelluksen pikakuvakkeena, varmista, että se on asennettuna"</string>
+ <string name="wallet_quick_affordance_unavailable_configure_the_app" msgid="4387433357429873258">"Jos haluat lisätä Wallet-sovelluksen pikakuvakkeena, varmista, että lisättynä on vähintään yksi kortti"</string>
+ <string name="qr_scanner_quick_affordance_unavailable_explanation" msgid="3049582306241150946">"Jos haluat lisätä QR-koodiskannerin pikakuvakkeena, varmista, että kamerasovellus on asennettuna"</string>
+ <string name="home_quick_affordance_unavailable_install_the_app" msgid="6187820778998446168">"Jos haluat lisätä Home-sovelluksen pikakuvakkeena, varmista, että se on asennettuna"</string>
+ <string name="home_quick_affordance_unavailable_configure_the_app" msgid="7953595390775156839">"• Ainakin yksi laite on käytettävissä"</string>
+ <string name="notes_app_quick_affordance_unavailable_explanation" msgid="4796955161600178530">"Valitse muistiinpanojen tekemisen oletussovellus, jota käytetään pikakuvakkeen avulla"</string>
<string name="keyguard_affordance_enablement_dialog_notes_app_action" msgid="6821710209675089470">"Valitse sovellus"</string>
<string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Kosketa pikakuvaketta pitkään"</string>
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Peru"</string>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index d88c9e0..2ac7309 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -249,7 +249,7 @@
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Rotation automatique de l\'écran"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Localisation"</string>
<string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Écran de veille"</string>
- <string name="quick_settings_camera_label" msgid="5612076679385269339">"Accès à l\'appareil photo"</string>
+ <string name="quick_settings_camera_label" msgid="5612076679385269339">"Accès à la caméra"</string>
<string name="quick_settings_mic_label" msgid="8392773746295266375">"Accès au micro"</string>
<string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Accessible"</string>
<string name="quick_settings_camera_mic_blocked" msgid="4710884905006788281">"Bloqué"</string>
@@ -1046,8 +1046,7 @@
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Un problème est survenu lors de la lecture du niveau de charge de la pile"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Touchez pour en savoir plus"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Aucune alarme définie"</string>
- <!-- no translation found for accessibility_bouncer (5896923685673320070) -->
- <skip />
+ <string name="accessibility_bouncer" msgid="5896923685673320070">"entrer verrouillage de l\'écran"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Capteur d\'empreintes digitales"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"authentifier"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"accéder à l\'appareil"</string>
@@ -1127,18 +1126,12 @@
<string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"En savoir plus"</string>
<string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"En savoir plus : <xliff:g id="URL">%s</xliff:g>"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Ouvrir <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <!-- no translation found for wallet_quick_affordance_unavailable_install_the_app (7298552910007208368) -->
- <skip />
- <!-- no translation found for wallet_quick_affordance_unavailable_configure_the_app (4387433357429873258) -->
- <skip />
- <!-- no translation found for qr_scanner_quick_affordance_unavailable_explanation (3049582306241150946) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_install_the_app (6187820778998446168) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_configure_the_app (7953595390775156839) -->
- <skip />
- <!-- no translation found for notes_app_quick_affordance_unavailable_explanation (4796955161600178530) -->
- <skip />
+ <string name="wallet_quick_affordance_unavailable_install_the_app" msgid="7298552910007208368">"Pour ajouter l\'application portefeuille sous forme de raccourci, assurez-vous que l\'application est installée"</string>
+ <string name="wallet_quick_affordance_unavailable_configure_the_app" msgid="4387433357429873258">"Pour ajouter l\'application Portefeuille sous forme de raccourci, assurez-vous qu\'au moins une carte a été ajoutée"</string>
+ <string name="qr_scanner_quick_affordance_unavailable_explanation" msgid="3049582306241150946">"Pour ajouter le numériseur de code QR sous forme de raccourci, assurez-vous qu\'une application d\'appareil photo est installée"</string>
+ <string name="home_quick_affordance_unavailable_install_the_app" msgid="6187820778998446168">"Pour ajouter l\'application Home sous forme de raccourci, assurez-vous que l\'application est installée"</string>
+ <string name="home_quick_affordance_unavailable_configure_the_app" msgid="7953595390775156839">"• qu\'au moins un appareil est utilisable;"</string>
+ <string name="notes_app_quick_affordance_unavailable_explanation" msgid="4796955161600178530">"Sélectionnez une application de prise de notes par défaut pour utiliser le raccourci de prise de notes"</string>
<string name="keyguard_affordance_enablement_dialog_notes_app_action" msgid="6821710209675089470">"Sélectionner l\'application"</string>
<string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Maintenir le doigt sur raccourci"</string>
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Annuler"</string>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index b4cfb34..7646a88 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -412,7 +412,7 @@
<string name="media_projection_entry_generic_permission_dialog_warning_entire_screen" msgid="5407906851409410209">"Lorsque vous partagez, enregistrez ou castez, Android a accès à tout ce qui est visible sur votre écran ou lu sur votre appareil. Faites donc attention aux éléments tels que les mots de passe, détails de mode de paiement, messages, photos et contenus audio et vidéo."</string>
<string name="media_projection_entry_generic_permission_dialog_warning_single_app" msgid="3454859977888159495">"Lorsque vous partagez, enregistrez ou castez une appli, Android a accès à tout ce qui est visible sur votre écran ou lu sur votre appareil. Faites donc attention aux éléments tels que les mots de passe, détails de mode de paiement, messages et contenus audio et vidéo."</string>
<string name="media_projection_entry_generic_permission_dialog_continue" msgid="8640381403048097116">"Commencer"</string>
- <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"Bloquée par votre administrateur informatique"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"Bloqué par votre administrateur informatique"</string>
<string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"La capture d\'écran est désactivée conformément aux règles relatives à l\'appareil"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"Tout effacer"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"Gérer"</string>
@@ -1046,8 +1046,7 @@
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Un problème est survenu au niveau de la lecture de votre outil de mesure de batterie"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Appuyer pour en savoir plus"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Pas d\'alarme définie"</string>
- <!-- no translation found for accessibility_bouncer (5896923685673320070) -->
- <skip />
+ <string name="accessibility_bouncer" msgid="5896923685673320070">"accéder au verrouillage de l\'écran"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Lecteur d\'empreinte digitale"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"s\'authentifier"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"accéder à l\'appareil"</string>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index 014d8ba..cb2375f 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -1046,8 +1046,7 @@
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Produciuse un problema ao ler o medidor da batería"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Toca para obter máis información"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Sen alarmas postas"</string>
- <!-- no translation found for accessibility_bouncer (5896923685673320070) -->
- <skip />
+ <string name="accessibility_bouncer" msgid="5896923685673320070">"introducir bloqueo de pantalla"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Sensor de impresión dixital"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"autenticar"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"poñer o dispositivo"</string>
@@ -1127,18 +1126,12 @@
<string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Máis información"</string>
<string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Máis información en <xliff:g id="URL">%s</xliff:g>"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Abrir <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <!-- no translation found for wallet_quick_affordance_unavailable_install_the_app (7298552910007208368) -->
- <skip />
- <!-- no translation found for wallet_quick_affordance_unavailable_configure_the_app (4387433357429873258) -->
- <skip />
- <!-- no translation found for qr_scanner_quick_affordance_unavailable_explanation (3049582306241150946) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_install_the_app (6187820778998446168) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_configure_the_app (7953595390775156839) -->
- <skip />
- <!-- no translation found for notes_app_quick_affordance_unavailable_explanation (4796955161600178530) -->
- <skip />
+ <string name="wallet_quick_affordance_unavailable_install_the_app" msgid="7298552910007208368">"Para engadir a aplicación Wallet como atallo, asegúrate de que estea instalada"</string>
+ <string name="wallet_quick_affordance_unavailable_configure_the_app" msgid="4387433357429873258">"Para engadir a aplicación Wallet como atallo, asegúrate de que se incluíse polo menos unha tarxeta"</string>
+ <string name="qr_scanner_quick_affordance_unavailable_explanation" msgid="3049582306241150946">"Para engadir o escáner de códigos QR como atallo, asegúrate de que a aplicación de cámara estea instalada"</string>
+ <string name="home_quick_affordance_unavailable_install_the_app" msgid="6187820778998446168">"Para engadir a aplicación Google Home como atallo, asegúrate de que estea instalada"</string>
+ <string name="home_quick_affordance_unavailable_configure_the_app" msgid="7953595390775156839">"• Ten que haber polo menos un dispositivo dispoñible"</string>
+ <string name="notes_app_quick_affordance_unavailable_explanation" msgid="4796955161600178530">"Selecciona unha aplicación de notas predeterminada para usar o atallo de tomar notas"</string>
<string name="keyguard_affordance_enablement_dialog_notes_app_action" msgid="6821710209675089470">"Seleccionar aplicación"</string>
<string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Mantén premido o atallo"</string>
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Cancelar"</string>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index cd264e2..c3be28c 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -1046,8 +1046,7 @@
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"તમારું બૅટરી મીટર વાંચવામાં સમસ્યા આવી"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"વધુ માહિતી માટે ટૅપ કરો"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"કોઈ અલાર્મ સેટ નથી"</string>
- <!-- no translation found for accessibility_bouncer (5896923685673320070) -->
- <skip />
+ <string name="accessibility_bouncer" msgid="5896923685673320070">"સ્ક્રીન લૉક દાખલ કરો"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"ફિંગરપ્રિન્ટ સેન્સર"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"ખાતરી કરો"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"ડિવાઇસ અનલૉક કરો"</string>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index e5c798b..60fd680 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -142,8 +142,7 @@
<string name="biometric_dialog_face_icon_description_authenticated" msgid="2242167416140740920">"चेहरे की पुष्टि हो गई"</string>
<string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"पुष्टि हो गई"</string>
<string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"\'पुष्टि करें\' पर टैप करके पूरा करें"</string>
- <!-- no translation found for biometric_dialog_tap_confirm_with_face (2378151312221818694) -->
- <skip />
+ <string name="biometric_dialog_tap_confirm_with_face" msgid="2378151312221818694">"चेहरे से अनलॉक किया गया"</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"चेहरे से अनलॉक किया गया. जारी रखने के लिए टैप करें."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"चेहरे की पहचान हो गई. जारी रखने के लिए टैप करें."</string>
<string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"चेहरे की पहचान हो गई. जारी रखने के लिए अनलॉक आइकॉन को टैप करें."</string>
@@ -1047,8 +1046,7 @@
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"आपके डिवाइस के बैटरी मीटर की रीडिंग लेने में समस्या आ रही है"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"ज़्यादा जानकारी के लिए टैप करें"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"कोई अलार्म सेट नहीं है"</string>
- <!-- no translation found for accessibility_bouncer (5896923685673320070) -->
- <skip />
+ <string name="accessibility_bouncer" msgid="5896923685673320070">"स्क्रीन लॉक डालें"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"फ़िंगरप्रिंट सेंसर"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"पुष्टि करें"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"डिवाइस की होम स्क्रीन पर जाएं"</string>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index e921679..02c1be7 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -399,7 +399,7 @@
<string name="media_projection_sys_service_dialog_warning" msgid="2443872865267330320">"Usluga koja pruža ovu funkciju imat će pristup svim podacima koji su vidljivi na vašem zaslonu ili koji se reproduciraju s vašeg uređaja tijekom snimanja ili emitiranja. To uključuje podatke kao što su zaporke, podaci o plaćanju, fotografije, poruke i audiozapisi koje reproducirate."</string>
<string name="screen_share_permission_dialog_option_entire_screen" msgid="3131200488455089620">"Cijeli zaslon"</string>
<string name="screen_share_permission_dialog_option_single_app" msgid="4350961814397220929">"Jedna aplikacija"</string>
- <string name="screen_share_permission_app_selector_title" msgid="1404878013670347899">"Dijeljenje ili snimanje pomoću aplikacije"</string>
+ <string name="screen_share_permission_app_selector_title" msgid="1404878013670347899">"Dijeljenje ili snimanje aplikacije"</string>
<string name="media_projection_entry_app_permission_dialog_title" msgid="9155535851866407199">"Želite li započeti snimanje ili emitiranje pomoću aplikacije <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>?"</string>
<string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"Kad dijelite, snimate ili emitirate, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ima pristup svemu što je vidljivo na vašem zaslonu ili se reproducira na vašem uređaju. Stoga pazite na stvari kao što su zaporke, podaci o plaćanju, poruke, fotografije te audio i videozapisi."</string>
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"Kad dijelite, snimate ili emitirate aplikaciju, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ima pristup svemu što se prikazuje ili reproducira u toj aplikaciji. Stoga pazite na stvari kao što su zaporke, podaci o plaćanju, poruke, fotografije te audio i videozapisi."</string>
@@ -1046,8 +1046,7 @@
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problem s očitavanjem mjerača baterije"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Dodirnite za više informacija"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Nema nijednog alarma"</string>
- <!-- no translation found for accessibility_bouncer (5896923685673320070) -->
- <skip />
+ <string name="accessibility_bouncer" msgid="5896923685673320070">"unesite zaključavanje zaslona"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Senzor otiska prsta"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"autentificirali"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"pristupili uređaju"</string>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index b0050cf..b5081d0 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -1046,8 +1046,7 @@
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Probléma merült fel az akkumulátor-töltésmérő olvasásakor"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Koppintással további információkat érhet el."</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Nincs ébresztés"</string>
- <!-- no translation found for accessibility_bouncer (5896923685673320070) -->
- <skip />
+ <string name="accessibility_bouncer" msgid="5896923685673320070">"képernyőzár megadása"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Ujjlenyomat-érzékelő"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"a hitelesítéshez"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"eszköz megadásához"</string>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index 59ec076..cfc92a4 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -1046,8 +1046,7 @@
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Մարտկոցի ցուցիչի ցուցմունքը կարդալու հետ կապված խնդիր կա"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Հպեք՝ ավելին իմանալու համար"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Զարթուցիչ դրված չէ"</string>
- <!-- no translation found for accessibility_bouncer (5896923685673320070) -->
- <skip />
+ <string name="accessibility_bouncer" msgid="5896923685673320070">"ապակողպել էկրանը"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Մատնահետքի սկաներ"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"նույնականացնել"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"նշել սարքը"</string>
@@ -1127,18 +1126,12 @@
<string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Իմանալ ավելին"</string>
<string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Իմացեք ավելին <xliff:g id="URL">%s</xliff:g> էջում"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Բացել <xliff:g id="APPNAME">%1$s</xliff:g> հավելվածը"</string>
- <!-- no translation found for wallet_quick_affordance_unavailable_install_the_app (7298552910007208368) -->
- <skip />
- <!-- no translation found for wallet_quick_affordance_unavailable_configure_the_app (4387433357429873258) -->
- <skip />
- <!-- no translation found for qr_scanner_quick_affordance_unavailable_explanation (3049582306241150946) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_install_the_app (6187820778998446168) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_configure_the_app (7953595390775156839) -->
- <skip />
- <!-- no translation found for notes_app_quick_affordance_unavailable_explanation (4796955161600178530) -->
- <skip />
+ <string name="wallet_quick_affordance_unavailable_install_the_app" msgid="7298552910007208368">"Wallet հավելվածի դյուրանցումն ավելացնելու համար համոզվեք, որ հավելվածը տեղադրված է"</string>
+ <string name="wallet_quick_affordance_unavailable_configure_the_app" msgid="4387433357429873258">"Wallet հավելվածի դյուրանցումն ավելացնելու համար համոզվեք, որ առնվազն մեկ քարտ ավելացված է"</string>
+ <string name="qr_scanner_quick_affordance_unavailable_explanation" msgid="3049582306241150946">"QR կոդերի սկաների դյուրանցումն ավելացնելու համար համոզվեք, որ տեսախցիկի հավելվածը տեղադրված է"</string>
+ <string name="home_quick_affordance_unavailable_install_the_app" msgid="6187820778998446168">"Home հավելվածի դյուրանցումն ավելացնելու համար համոզվեք, որ հավելվածը տեղադրված է"</string>
+ <string name="home_quick_affordance_unavailable_configure_the_app" msgid="7953595390775156839">"• Հասանելի է առնվազն մեկ սարք"</string>
+ <string name="notes_app_quick_affordance_unavailable_explanation" msgid="4796955161600178530">"Ընտրեք նշումների կանխադրված հավելված՝ նշումների ստեղծման դյուրանցումն օգտագործելու համար"</string>
<string name="keyguard_affordance_enablement_dialog_notes_app_action" msgid="6821710209675089470">"Ընտրել հավելված"</string>
<string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Հպեք դյուրանցմանը և պահեք"</string>
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Չեղարկել"</string>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 7b3feaa..515f80f 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -1046,8 +1046,7 @@
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Terjadi error saat membaca indikator baterai"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Ketuk untuk informasi selengkapnya"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Alarm tidak disetel"</string>
- <!-- no translation found for accessibility_bouncer (5896923685673320070) -->
- <skip />
+ <string name="accessibility_bouncer" msgid="5896923685673320070">"masukkan kunci layar"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Sensor sidik jari"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"autentikasi"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"masukkan perangkat"</string>
@@ -1127,18 +1126,12 @@
<string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Pelajari lebih lanjut"</string>
<string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Pelajari lebih lanjut di <xliff:g id="URL">%s</xliff:g>"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Buka <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <!-- no translation found for wallet_quick_affordance_unavailable_install_the_app (7298552910007208368) -->
- <skip />
- <!-- no translation found for wallet_quick_affordance_unavailable_configure_the_app (4387433357429873258) -->
- <skip />
- <!-- no translation found for qr_scanner_quick_affordance_unavailable_explanation (3049582306241150946) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_install_the_app (6187820778998446168) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_configure_the_app (7953595390775156839) -->
- <skip />
- <!-- no translation found for notes_app_quick_affordance_unavailable_explanation (4796955161600178530) -->
- <skip />
+ <string name="wallet_quick_affordance_unavailable_install_the_app" msgid="7298552910007208368">"Untuk menambahkan aplikasi Wallet sebagai pintasan, pastikan aplikasi sudah diinstal"</string>
+ <string name="wallet_quick_affordance_unavailable_configure_the_app" msgid="4387433357429873258">"Untuk menambahkan aplikasi Wallet sebagai pintasan, pastikan minimal satu kartu telah ditambahkan"</string>
+ <string name="qr_scanner_quick_affordance_unavailable_explanation" msgid="3049582306241150946">"Untuk menambahkan pemindai kode QR sebagai pintasan, pastikan aplikasi kamera sudah diinstal"</string>
+ <string name="home_quick_affordance_unavailable_install_the_app" msgid="6187820778998446168">"Untuk menambahkan aplikasi Home sebagai pintasan, pastikan aplikasi sudah diinstal"</string>
+ <string name="home_quick_affordance_unavailable_configure_the_app" msgid="7953595390775156839">"• Tersedia minimal satu perangkat"</string>
+ <string name="notes_app_quick_affordance_unavailable_explanation" msgid="4796955161600178530">"Pilih aplikasi catatan default untuk menggunakan pintasan pembuatan catatan"</string>
<string name="keyguard_affordance_enablement_dialog_notes_app_action" msgid="6821710209675089470">"Pilih aplikasi"</string>
<string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Sentuh lama pintasan"</string>
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Batal"</string>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index 7883207..fb73c0b 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -1046,8 +1046,7 @@
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Vandamál við að lesa stöðu rafhlöðu"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Ýttu til að fá frekari upplýsingar"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Enginn vekjari"</string>
- <!-- no translation found for accessibility_bouncer (5896923685673320070) -->
- <skip />
+ <string name="accessibility_bouncer" msgid="5896923685673320070">"sláðu inn skjálás"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Fingrafaralesari"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"auðkenna"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"opna tæki"</string>
@@ -1127,18 +1126,12 @@
<string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Nánar"</string>
<string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Nánar á <xliff:g id="URL">%s</xliff:g>"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Opna <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <!-- no translation found for wallet_quick_affordance_unavailable_install_the_app (7298552910007208368) -->
- <skip />
- <!-- no translation found for wallet_quick_affordance_unavailable_configure_the_app (4387433357429873258) -->
- <skip />
- <!-- no translation found for qr_scanner_quick_affordance_unavailable_explanation (3049582306241150946) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_install_the_app (6187820778998446168) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_configure_the_app (7953595390775156839) -->
- <skip />
- <!-- no translation found for notes_app_quick_affordance_unavailable_explanation (4796955161600178530) -->
- <skip />
+ <string name="wallet_quick_affordance_unavailable_install_the_app" msgid="7298552910007208368">"Til að bæta Veskisforritinu við sem flýtileið skaltu ganga úr skugga um að forritið sé uppsett"</string>
+ <string name="wallet_quick_affordance_unavailable_configure_the_app" msgid="4387433357429873258">"Til að bæta Veskisforritinu við sem flýtileið skaltu ganga úr skugga um að hafa bætt að minnsta kosti einu korti við"</string>
+ <string name="qr_scanner_quick_affordance_unavailable_explanation" msgid="3049582306241150946">"Til að bæta QR-kóðaskanna við sem flýtileið skaltu ganga úr skugga um að myndavélarforrit sé uppsett"</string>
+ <string name="home_quick_affordance_unavailable_install_the_app" msgid="6187820778998446168">"Til að bæta Home-forritinu við sem flýtileið skaltu ganga úr skugga um að forritið sé uppsett"</string>
+ <string name="home_quick_affordance_unavailable_configure_the_app" msgid="7953595390775156839">"• Að minnsta kosti eitt tæki er tiltækt"</string>
+ <string name="notes_app_quick_affordance_unavailable_explanation" msgid="4796955161600178530">"Veldu sjálfgefið glósuforrit til að nota flýtileið fyrir glósugerð"</string>
<string name="keyguard_affordance_enablement_dialog_notes_app_action" msgid="6821710209675089470">"Velja forrit"</string>
<string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Haltu flýtilyklinum inni"</string>
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Hætta við"</string>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index fef0fe5..62d5a46 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -1046,8 +1046,7 @@
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problema durante la lettura dell\'indicatore di livello della batteria"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Tocca per ulteriori informazioni"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Nessuna"</string>
- <!-- no translation found for accessibility_bouncer (5896923685673320070) -->
- <skip />
+ <string name="accessibility_bouncer" msgid="5896923685673320070">"inserisci blocco schermo"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Sensore di impronte digitali"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"effettuare l\'autenticazione"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"accedere al dispositivo"</string>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 255c1da..7497bd4 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -412,7 +412,7 @@
<string name="media_projection_entry_generic_permission_dialog_warning_entire_screen" msgid="5407906851409410209">"בזמן שיתוף, הקלטה או העברה (cast) תהיה ל-Android גישה לכל הפרטים שגלויים במסך שלך או מופעלים מהמכשיר שלך. מומלץ להיזהר עם סיסמאות, פרטי תשלום, הודעות, תמונות, אודיו וסרטונים."</string>
<string name="media_projection_entry_generic_permission_dialog_warning_single_app" msgid="3454859977888159495">"בזמן שיתוף, הקלטה או העברה (cast) של אפליקציה, תהיה ל-Android גישה לכל מה שגלוי באפליקציה או מופעל מהאפליקציה. מומלץ להיזהר עם סיסמאות, פרטי תשלום, הודעות, תמונות, אודיו וסרטונים."</string>
<string name="media_projection_entry_generic_permission_dialog_continue" msgid="8640381403048097116">"התחלה"</string>
- <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"נחסם על ידי מנהל ה-IT"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"האפשרות נחסמה על ידי אדמין ב-IT"</string>
<string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"צילום המסך מושבת בגלל מדיניות המכשיר"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"ניקוי הכול"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"ניהול"</string>
@@ -1046,8 +1046,7 @@
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"בעיה בקריאת מדדי הסוללה"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"יש להקיש כדי להציג מידע נוסף"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"לא הוגדרה"</string>
- <!-- no translation found for accessibility_bouncer (5896923685673320070) -->
- <skip />
+ <string name="accessibility_bouncer" msgid="5896923685673320070">"הזנת קוד נעילת המסך"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"חיישן טביעות אצבע"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"אימות"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"הזנת מכשיר"</string>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index 053989e..8662f98 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -1046,8 +1046,7 @@
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"თქვენი ბატარეის მზომის წაკითხვასთან დაკავშირებით პრობლემა დაფიქსირდა"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"შეეხეთ მეტი ინფორმაციისთვის"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"მაღვიძარა არ არის"</string>
- <!-- no translation found for accessibility_bouncer (5896923685673320070) -->
- <skip />
+ <string name="accessibility_bouncer" msgid="5896923685673320070">"ეკრანის დაბლოკვის შეყვანა"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"თითის ანაბეჭდის სენსორი"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"ავტორიზაცია"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"მოწყობილობის შეყვანა"</string>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index ef1a4d3..4fd3242 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -135,7 +135,7 @@
<string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Жіберу"</string>
<string name="cancel" msgid="1089011503403416730">"Бас тарту"</string>
<string name="biometric_dialog_confirm" msgid="2005978443007344895">"Растау"</string>
- <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Қайталап көріңіз"</string>
+ <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Қайта көру"</string>
<string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"Аутентификациядан бас тарту үшін түртіңіз."</string>
<string name="biometric_dialog_face_icon_description_idle" msgid="4351777022315116816">"Қайталап көріңіз."</string>
<string name="biometric_dialog_face_icon_description_authenticating" msgid="3401633342366146535">"Құрылғы бетіңізді талдап жатыр."</string>
@@ -1046,8 +1046,7 @@
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Батарея зарядының дерегі алынбай жатыр"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Толығырақ ақпарат алу үшін түртіңіз."</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Оятқыш орнатылмаған."</string>
- <!-- no translation found for accessibility_bouncer (5896923685673320070) -->
- <skip />
+ <string name="accessibility_bouncer" msgid="5896923685673320070">"экран құлпын енгізу"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Саусақ ізін оқу сканері"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"аутентификациялау"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"құрылғыны енгізу"</string>
@@ -1127,18 +1126,12 @@
<string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Толық ақпарат"</string>
<string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Толық ақпарат: <xliff:g id="URL">%s</xliff:g>"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> ашу"</string>
- <!-- no translation found for wallet_quick_affordance_unavailable_install_the_app (7298552910007208368) -->
- <skip />
- <!-- no translation found for wallet_quick_affordance_unavailable_configure_the_app (4387433357429873258) -->
- <skip />
- <!-- no translation found for qr_scanner_quick_affordance_unavailable_explanation (3049582306241150946) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_install_the_app (6187820778998446168) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_configure_the_app (7953595390775156839) -->
- <skip />
- <!-- no translation found for notes_app_quick_affordance_unavailable_explanation (4796955161600178530) -->
- <skip />
+ <string name="wallet_quick_affordance_unavailable_install_the_app" msgid="7298552910007208368">"Wallet қолданбасын таңбаша ретінде қосу үшін қолданбаның орнатылғанын тексеріңіз."</string>
+ <string name="wallet_quick_affordance_unavailable_configure_the_app" msgid="4387433357429873258">"Wallet қолданбасын таңбаша ретінде қосу үшін кемінде бір картаның қосылғанын тексеріңіз."</string>
+ <string name="qr_scanner_quick_affordance_unavailable_explanation" msgid="3049582306241150946">"QR кодының сканерін таңбаша ретінде қосу үшін камера қолданбасының орнатылғанын тексеріңіз."</string>
+ <string name="home_quick_affordance_unavailable_install_the_app" msgid="6187820778998446168">"Home қолданбасын таңбаша ретінде қосу үшін қолданбаның орнатылғанын тексеріңіз."</string>
+ <string name="home_quick_affordance_unavailable_configure_the_app" msgid="7953595390775156839">"• Кемінде бір құрылғы қолжетімді."</string>
+ <string name="notes_app_quick_affordance_unavailable_explanation" msgid="4796955161600178530">"Жазба жазу таңбашасын пайдалану үшін әдепкі жазба қолданбаны таңдаңыз."</string>
<string name="keyguard_affordance_enablement_dialog_notes_app_action" msgid="6821710209675089470">"Қолданба таңдау"</string>
<string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Таңбашаны басып тұрыңыз."</string>
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Бас тарту"</string>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index 150546c..5132ac0 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -1046,8 +1046,7 @@
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"មានបញ្ហាក្នុងការអានឧបករណ៍រង្វាស់កម្រិតថ្មរបស់អ្នក"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"ចុចដើម្បីទទួលបានព័ត៌មានបន្ថែម"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"មិនបានកំណត់ម៉ោងរោទ៍ទេ"</string>
- <!-- no translation found for accessibility_bouncer (5896923685673320070) -->
- <skip />
+ <string name="accessibility_bouncer" msgid="5896923685673320070">"បញ្ចូលព័ត៌មានផ្ទៀងផ្ទាត់សម្រាប់ការចាក់សោអេក្រង់"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"ឧបករណ៍ចាប់ស្នាមម្រាមដៃ"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"ផ្ទៀងផ្ទាត់"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"បញ្ចូលឧបករណ៍"</string>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index 96e955e..5fa9464 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -1046,8 +1046,7 @@
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"ನಿಮ್ಮ ಬ್ಯಾಟರಿ ಮೀಟರ್ ಓದುವಾಗ ಸಮಸ್ಯೆ ಎದುರಾಗಿದೆ"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"ಇನ್ನಷ್ಟು ಮಾಹಿತಿಗಾಗಿ ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"ಅಲಾರಾಂ ಸೆಟ್ ಆಗಿಲ್ಲ"</string>
- <!-- no translation found for accessibility_bouncer (5896923685673320070) -->
- <skip />
+ <string name="accessibility_bouncer" msgid="5896923685673320070">"ಸ್ಕ್ರೀನ್ ಲಾಕ್ ನಮೂದಿಸಿ"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"ಫಿಂಗರ್ಪ್ರಿಂಟ್ ಸೆನ್ಸರ್"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"ದೃಢೀಕರಿಸಿ"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"ಸಾಧನವನ್ನು ಪ್ರವೇಶಿಸಿ"</string>
@@ -1127,18 +1126,12 @@
<string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"ಇನ್ನಷ್ಟು ತಿಳಿಯಿರಿ"</string>
<string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"<xliff:g id="URL">%s</xliff:g> ನಲ್ಲಿ ಇನ್ನಷ್ಟು ತಿಳಿಯಿರಿ"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> ಅನ್ನು ತೆರೆಯಿರಿ"</string>
- <!-- no translation found for wallet_quick_affordance_unavailable_install_the_app (7298552910007208368) -->
- <skip />
- <!-- no translation found for wallet_quick_affordance_unavailable_configure_the_app (4387433357429873258) -->
- <skip />
- <!-- no translation found for qr_scanner_quick_affordance_unavailable_explanation (3049582306241150946) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_install_the_app (6187820778998446168) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_configure_the_app (7953595390775156839) -->
- <skip />
- <!-- no translation found for notes_app_quick_affordance_unavailable_explanation (4796955161600178530) -->
- <skip />
+ <string name="wallet_quick_affordance_unavailable_install_the_app" msgid="7298552910007208368">"ವಾಲೆಟ್ ಆ್ಯಪ್ ಅನ್ನು ಶಾರ್ಟ್ಕಟ್ ಆಗಿ ಸೇರಿಸಲು, ಆ್ಯಪ್ ಅನ್ನು ಇನ್ಸ್ಟಾಲ್ ಮಾಡಲಾಗಿದೆಯೇ ಎಂಬುದನ್ನು ಖಚಿತಪಡಿಸಿಕೊಳ್ಳಿ"</string>
+ <string name="wallet_quick_affordance_unavailable_configure_the_app" msgid="4387433357429873258">"ವಾಲೆಟ್ ಆ್ಯಪ್ ಅನ್ನು ಶಾರ್ಟ್ಕಟ್ ಆಗಿ ಸೇರಿಸಲು, ಕನಿಷ್ಠ ಒಂದು ಕಾರ್ಡ್ ಅನ್ನು ಸೇರಿಸಲಾಗಿದೆಯೇ ಎಂಬುದನ್ನು ಖಚಿತಪಡಿಸಿಕೊಳ್ಳಿ"</string>
+ <string name="qr_scanner_quick_affordance_unavailable_explanation" msgid="3049582306241150946">"QR ಕೋಡ್ ಸ್ಕ್ಯಾನರ್ ಅನ್ನು ಶಾರ್ಟ್ಕಟ್ ಆಗಿ ಸೇರಿಸಲು, ಕ್ಯಾಮರಾ ಆ್ಯಪ್ ಅನ್ನು ಇನ್ಸ್ಟಾಲ್ ಮಾಡಲಾಗಿದೆಯೇ ಎಂಬುದನ್ನು ಖಚಿತಪಡಿಸಿಕೊಳ್ಳಿ"</string>
+ <string name="home_quick_affordance_unavailable_install_the_app" msgid="6187820778998446168">"Home ಆ್ಯಪ್ ಅನ್ನು ಶಾರ್ಟ್ಕಟ್ ಆಗಿ ಸೇರಿಸಲು, ಆ್ಯಪ್ ಇನ್ಸ್ಟಾಲ್ ಆಗಿದೆಯೇ ಎಂಬುದನ್ನು ಖಚಿತಪಡಿಸಿಕೊಳ್ಳಿ"</string>
+ <string name="home_quick_affordance_unavailable_configure_the_app" msgid="7953595390775156839">"• ಕನಿಷ್ಠ ಒಂದು ಸಾಧನ ಲಭ್ಯವಿದೆ"</string>
+ <string name="notes_app_quick_affordance_unavailable_explanation" msgid="4796955161600178530">"ನೋಟ್ಸ್ ಮಾಡಿಕೊಳ್ಳುವಿಕೆ ಶಾರ್ಟ್ಕಟ್ ಅನ್ನು ಬಳಸಲು ಡೀಫಾಲ್ಟ್ ಟಿಪ್ಪಣಿಗಳ ಆ್ಯಪ್ ಆಯ್ಕೆಮಾಡಿ"</string>
<string name="keyguard_affordance_enablement_dialog_notes_app_action" msgid="6821710209675089470">"ಆ್ಯಪ್ ಆಯ್ಕೆಮಾಡಿ"</string>
<string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"ಸ್ಪರ್ಶಿಸಿ ಹೋಲ್ಡ್ ಮಾಡಿ ಶಾರ್ಟ್ಕಟ್"</string>
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"ರದ್ದುಗೊಳಿಸಿ"</string>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 2a82ddc..eb4afbb 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -1046,8 +1046,7 @@
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"배터리 수준을 읽는 중에 문제가 발생함"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"탭하여 자세한 정보를 확인하세요."</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"설정된 알람 없음"</string>
- <!-- no translation found for accessibility_bouncer (5896923685673320070) -->
- <skip />
+ <string name="accessibility_bouncer" msgid="5896923685673320070">"화면 잠금 입력"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"지문 센서"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"인증"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"기기 입력"</string>
@@ -1127,18 +1126,12 @@
<string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"자세히 알아보기"</string>
<string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"<xliff:g id="URL">%s</xliff:g>에서 자세히 알아보세요."</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> 열기"</string>
- <!-- no translation found for wallet_quick_affordance_unavailable_install_the_app (7298552910007208368) -->
- <skip />
- <!-- no translation found for wallet_quick_affordance_unavailable_configure_the_app (4387433357429873258) -->
- <skip />
- <!-- no translation found for qr_scanner_quick_affordance_unavailable_explanation (3049582306241150946) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_install_the_app (6187820778998446168) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_configure_the_app (7953595390775156839) -->
- <skip />
- <!-- no translation found for notes_app_quick_affordance_unavailable_explanation (4796955161600178530) -->
- <skip />
+ <string name="wallet_quick_affordance_unavailable_install_the_app" msgid="7298552910007208368">"월렛 앱을 바로가기로 추가하려면 앱이 설치되어 있는지 확인하세요."</string>
+ <string name="wallet_quick_affordance_unavailable_configure_the_app" msgid="4387433357429873258">"월렛 앱을 바로가기로 추가하려면 하나 이상의 카드가 추가되어 있는지 확인하세요."</string>
+ <string name="qr_scanner_quick_affordance_unavailable_explanation" msgid="3049582306241150946">"QR 코드 스캐너를 바로가기로 추가하려면 카메라 앱이 설치되어 있는지 확인하세요."</string>
+ <string name="home_quick_affordance_unavailable_install_the_app" msgid="6187820778998446168">"Home 앱을 바로가기로 추가하려면 앱이 설치되어 있는지 확인하세요."</string>
+ <string name="home_quick_affordance_unavailable_configure_the_app" msgid="7953595390775156839">"• 1대 이상의 기기를 사용할 수 있습니다."</string>
+ <string name="notes_app_quick_affordance_unavailable_explanation" msgid="4796955161600178530">"메모 바로가기를 사용하려면 기본 메모 앱을 선택합니다."</string>
<string name="keyguard_affordance_enablement_dialog_notes_app_action" msgid="6821710209675089470">"앱 선택"</string>
<string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"바로가기를 길게 터치하세요."</string>
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"취소"</string>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index 6ceb1e7..c8f6c37 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -1046,8 +1046,7 @@
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Батареяңыздын кубаты аныкталбай жатат"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Кеңири маалымат алуу үчүн таптап коюңуз"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Ойготкуч коюлган жок"</string>
- <!-- no translation found for accessibility_bouncer (5896923685673320070) -->
- <skip />
+ <string name="accessibility_bouncer" msgid="5896923685673320070">"экран кулпусун киргизүү"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Манжа изинин сенсору"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"аныктыгын текшерүү"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"түзмөккө кирүү"</string>
@@ -1127,18 +1126,12 @@
<string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Кеңири маалымат"</string>
<string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Кеңири маалымат: <xliff:g id="URL">%s</xliff:g>"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> ачуу"</string>
- <!-- no translation found for wallet_quick_affordance_unavailable_install_the_app (7298552910007208368) -->
- <skip />
- <!-- no translation found for wallet_quick_affordance_unavailable_configure_the_app (4387433357429873258) -->
- <skip />
- <!-- no translation found for qr_scanner_quick_affordance_unavailable_explanation (3049582306241150946) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_install_the_app (6187820778998446168) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_configure_the_app (7953595390775156839) -->
- <skip />
- <!-- no translation found for notes_app_quick_affordance_unavailable_explanation (4796955161600178530) -->
- <skip />
+ <string name="wallet_quick_affordance_unavailable_install_the_app" msgid="7298552910007208368">"Капчык колдонмосун ыкчам баскыч катары кошуу үчүн колдонмону орнотуу керек"</string>
+ <string name="wallet_quick_affordance_unavailable_configure_the_app" msgid="4387433357429873258">"Капчык колдонмосун ыкчам баскыч катары кошуу үчүн кеминде бир картаны кошуу керек"</string>
+ <string name="qr_scanner_quick_affordance_unavailable_explanation" msgid="3049582306241150946">"QR кодунун сканерин ыкчам баскыч катары кошуу үчүн камера колдонмосун орнотуу керек"</string>
+ <string name="home_quick_affordance_unavailable_install_the_app" msgid="6187820778998446168">"Home колдонмосун ыкчам баскыч катары кошуу үчүн колдонмону орнотуу керек"</string>
+ <string name="home_quick_affordance_unavailable_configure_the_app" msgid="7953595390775156839">"• Кеминде бир түзмөк жеткиликтүү"</string>
+ <string name="notes_app_quick_affordance_unavailable_explanation" msgid="4796955161600178530">"Эскертме жазуу ыкчам баскычын колдонуу үчүн демейки эскертме жазуу колдонмосун тандаңыз"</string>
<string name="keyguard_affordance_enablement_dialog_notes_app_action" msgid="6821710209675089470">"Колдонмо тандоо"</string>
<string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Ыкчам баскычты басып туруңуз"</string>
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Токтотуу"</string>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index deec7d0..756444d 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -1046,8 +1046,7 @@
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"ເກີດບັນຫາໃນການອ່ານຕົວວັດແທກແບັດເຕີຣີຂອງທ່ານ"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"ແຕະເພື່ອເບິ່ງຂໍ້ມູນເພີ່ມເຕີມ"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"ບໍ່ໄດ້ຕັ້ງໂມງປຸກ"</string>
- <!-- no translation found for accessibility_bouncer (5896923685673320070) -->
- <skip />
+ <string name="accessibility_bouncer" msgid="5896923685673320070">"ໃສ່ຂໍ້ມູນການລັອກໜ້າຈໍ"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"ເຊັນເຊີລາຍນິ້ວມື"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"ພິສູດຢືນຢັນ"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"ເຂົ້າອຸປະກອນ"</string>
@@ -1127,18 +1126,12 @@
<string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"ສຶກສາເພີ່ມເຕີມ"</string>
<string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"ສຶກສາເພີ່ມເຕີມຢູ່ <xliff:g id="URL">%s</xliff:g>"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"ເປີດ <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <!-- no translation found for wallet_quick_affordance_unavailable_install_the_app (7298552910007208368) -->
- <skip />
- <!-- no translation found for wallet_quick_affordance_unavailable_configure_the_app (4387433357429873258) -->
- <skip />
- <!-- no translation found for qr_scanner_quick_affordance_unavailable_explanation (3049582306241150946) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_install_the_app (6187820778998446168) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_configure_the_app (7953595390775156839) -->
- <skip />
- <!-- no translation found for notes_app_quick_affordance_unavailable_explanation (4796955161600178530) -->
- <skip />
+ <string name="wallet_quick_affordance_unavailable_install_the_app" msgid="7298552910007208368">"ເພື່ອເພີ່ມແອັບ Wallet ເປັນທາງລັດ, ກະລຸນາກວດສອບໃຫ້ແນ່ໃຈວ່າໄດ້ຕິດຕັ້ງແອັບແລ້ວ"</string>
+ <string name="wallet_quick_affordance_unavailable_configure_the_app" msgid="4387433357429873258">"ເພື່ອເພີ່ມແອັ Wallet ເປັນທາງລັດ, ກະລຸນາກວດສອບໃຫ້ແນ່ໃຈວ່າໄດ້ເພີ່ມຢ່າງໜ້ອຍ 1 ບັດແລ້ວ"</string>
+ <string name="qr_scanner_quick_affordance_unavailable_explanation" msgid="3049582306241150946">"ເພື່ອເພີ່ມຕົວສະແກນລະຫັດ QR ເປັນທາງລັດ, ກະລຸນາກວດສອບໃຫ້ແນ່ໃຈວ່າໄດ້ຕິດຕັ້ງແອັບກ້ອງຖ່າຍຮູບແລ້ວ"</string>
+ <string name="home_quick_affordance_unavailable_install_the_app" msgid="6187820778998446168">"ເພື່ອເພີ່ມແອັບ Home ເປັນທາງລັດ, ກະລຸນາກວດສອບໃຫ້ແນ່ໃຈວ່າໄດ້ຕິດຕັ້ງແອັບແລ້ວ"</string>
+ <string name="home_quick_affordance_unavailable_configure_the_app" msgid="7953595390775156839">"• ມີຢ່າງໜ້ອຍ 1 ອຸປະກອນພ້ອມໃຫ້ນຳໃຊ້"</string>
+ <string name="notes_app_quick_affordance_unavailable_explanation" msgid="4796955161600178530">"ເລືອກແອັບບັນທຶກເລີ່ມຕົ້ນເພື່ອໃຊ້ທາງລັດການຈົດບັນທຶກ"</string>
<string name="keyguard_affordance_enablement_dialog_notes_app_action" msgid="6821710209675089470">"ເລືອກແອັບ"</string>
<string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"ແຕະທາງລັດຄ້າງໄວ້"</string>
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"ຍົກເລີກ"</string>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 44f7b68..ff745b5 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -1046,8 +1046,7 @@
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Nuskaitant akumuliatoriaus skaitiklį iškilo problema"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Palieskite, kad sužinotumėte daugiau informacijos"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Nenustatyta signalų"</string>
- <!-- no translation found for accessibility_bouncer (5896923685673320070) -->
- <skip />
+ <string name="accessibility_bouncer" msgid="5896923685673320070">"įvesti ekrano užraktą"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Kontrolinio kodo jutiklis"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"nustatytumėte tapatybę"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"pasiektumėte įrenginį"</string>
@@ -1127,18 +1126,12 @@
<string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Sužinokite daugiau"</string>
<string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Sužinokite daugiau adresu <xliff:g id="URL">%s</xliff:g>"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Atidaryti „<xliff:g id="APPNAME">%1$s</xliff:g>“"</string>
- <!-- no translation found for wallet_quick_affordance_unavailable_install_the_app (7298552910007208368) -->
- <skip />
- <!-- no translation found for wallet_quick_affordance_unavailable_configure_the_app (4387433357429873258) -->
- <skip />
- <!-- no translation found for qr_scanner_quick_affordance_unavailable_explanation (3049582306241150946) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_install_the_app (6187820778998446168) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_configure_the_app (7953595390775156839) -->
- <skip />
- <!-- no translation found for notes_app_quick_affordance_unavailable_explanation (4796955161600178530) -->
- <skip />
+ <string name="wallet_quick_affordance_unavailable_install_the_app" msgid="7298552910007208368">"Jei norite pridėti programą „Wallet“ kaip šaukinį, įsitikinkite, kad programa įdiegta"</string>
+ <string name="wallet_quick_affordance_unavailable_configure_the_app" msgid="4387433357429873258">"Jei norite pridėti programą „Wallet“ kaip šaukinį, įsitikinkite, kad pridėta bent viena kortelė"</string>
+ <string name="qr_scanner_quick_affordance_unavailable_explanation" msgid="3049582306241150946">"Jei norite pridėti QR kodų skaitytuvą kaip šaukinį, įsitikinkite, kad fotoaparato programa įdiegta"</string>
+ <string name="home_quick_affordance_unavailable_install_the_app" msgid="6187820778998446168">"Jei norite pridėti programą „Home“ kaip šaukinį, įsitikinkite, kad programa įdiegta"</string>
+ <string name="home_quick_affordance_unavailable_configure_the_app" msgid="7953595390775156839">"• Pasiekiamas bent vienas įrenginys"</string>
+ <string name="notes_app_quick_affordance_unavailable_explanation" msgid="4796955161600178530">"Pasirinkite numatytąją užrašų programą, kuriai norite naudoti užrašų kūrimo šaukinį"</string>
<string name="keyguard_affordance_enablement_dialog_notes_app_action" msgid="6821710209675089470">"Pasirinkite programą"</string>
<string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Paliesk. ir palaik. spart. klav."</string>
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Atšaukti"</string>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index fc227f0..c8c18fb 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -1046,8 +1046,7 @@
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Nevar iegūt informāciju par akumulatora uzlādes līmeni."</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Pieskarieties, lai iegūtu plašāku informāciju."</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Nav iestatīts signāls"</string>
- <!-- no translation found for accessibility_bouncer (5896923685673320070) -->
- <skip />
+ <string name="accessibility_bouncer" msgid="5896923685673320070">"ievadīt ekrāna bloķēšanas informāciju"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Pirksta nospieduma sensors"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"veiktu autentificēšanu"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"izmantotu ierīci"</string>
@@ -1127,18 +1126,12 @@
<string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Uzzināt vairāk"</string>
<string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Uzziniet vairāk vietnē <xliff:g id="URL">%s</xliff:g>"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Atvērt lietotni <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <!-- no translation found for wallet_quick_affordance_unavailable_install_the_app (7298552910007208368) -->
- <skip />
- <!-- no translation found for wallet_quick_affordance_unavailable_configure_the_app (4387433357429873258) -->
- <skip />
- <!-- no translation found for qr_scanner_quick_affordance_unavailable_explanation (3049582306241150946) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_install_the_app (6187820778998446168) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_configure_the_app (7953595390775156839) -->
- <skip />
- <!-- no translation found for notes_app_quick_affordance_unavailable_explanation (4796955161600178530) -->
- <skip />
+ <string name="wallet_quick_affordance_unavailable_install_the_app" msgid="7298552910007208368">"Lai varētu pievienot lietotni Maks kā saīsni, lietotnei ir jābūt instalētai."</string>
+ <string name="wallet_quick_affordance_unavailable_configure_the_app" msgid="4387433357429873258">"Lai varētu pievienot lietotni Maks kā saīsni, ir jābūt pievienotai vismaz vienai kartei."</string>
+ <string name="qr_scanner_quick_affordance_unavailable_explanation" msgid="3049582306241150946">"Lai varētu pievienot lietotni Kvadrātkoda skeneris kā saīsni, ir jābūt instalētai kameras lietotnei."</string>
+ <string name="home_quick_affordance_unavailable_install_the_app" msgid="6187820778998446168">"Lai varētu pievienot lietotni Home kā saīsni, lietotnei ir jābūt instalētai."</string>
+ <string name="home_quick_affordance_unavailable_configure_the_app" msgid="7953595390775156839">"• Ir pieejama vismaz viena ierīce."</string>
+ <string name="notes_app_quick_affordance_unavailable_explanation" msgid="4796955161600178530">"Atlasiet noklusējuma piezīmju lietotni, lai izmantotu piezīmju pierakstīšanas saīsni."</string>
<string name="keyguard_affordance_enablement_dialog_notes_app_action" msgid="6821710209675089470">"Atlasīt lietotni"</string>
<string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Pieskarieties saīsnei un turiet."</string>
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Atcelt"</string>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index 5dad015..e429979 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -170,7 +170,7 @@
<string name="biometric_re_enroll_notification_content" msgid="8685925877186288180">"Ова е потребно за да се подобрат сигурноста и изведбата"</string>
<string name="fingerprint_re_enroll_notification_title" msgid="4539432429683916604">"Поставете „Отклучување со отпечаток“ повторно"</string>
<string name="fingerprint_re_enroll_notification_name" msgid="630798657797645704">"Отклучување со отпечаток"</string>
- <string name="fingerprint_re_enroll_dialog_title" msgid="3526033128113925780">"Поставување „Отклучување со отпечаток“"</string>
+ <string name="fingerprint_re_enroll_dialog_title" msgid="3526033128113925780">"Поставете „Отклучување со отпечаток“"</string>
<string name="fingerprint_re_enroll_dialog_content" msgid="4866561176695984879">"За да поставите „Отклучување со отпечаток“ повторно, вашите сегашни слики и модели на отпечаток ќе се избришат.\n\nОткако ќе се избришат, ќе треба повторно да поставите „Отклучување со отпечаток“ за да го користите отпечатокот за отклучување на телефонот или потврда дека сте вие."</string>
<string name="fingerprint_re_enroll_dialog_content_singular" msgid="3083663339787381218">"За да поставите „Отклучување со отпечаток“ повторно, вашите сегашните слики и модели на отпечаток ќе бидат избришат.\n\nОткако ќе се избришат, ќе треба повторно да поставите „Отклучување со отпечаток“ за да го користите отпечатокот за да го отклучите телефонот или да потврдите дека сте вие."</string>
<string name="fingerprint_reenroll_failure_dialog_content" msgid="4733768492747300666">"Не можеше да се постави „Отклучување со отпечаток“. Отворете „Поставки“ за да се обидете повторно."</string>
@@ -399,7 +399,7 @@
<string name="media_projection_sys_service_dialog_warning" msgid="2443872865267330320">"Услугата што ја обезбедува функцијава ќе има пристап до сите податоци што се видливи на екранот или пуштени од вашиот уред додека се снима или емитува. Ова вклучува податоци како лозинките, деталите за плаќање, фотографиите, пораките и аудиото што го пуштате."</string>
<string name="screen_share_permission_dialog_option_entire_screen" msgid="3131200488455089620">"Цел екран"</string>
<string name="screen_share_permission_dialog_option_single_app" msgid="4350961814397220929">"Една апликација"</string>
- <string name="screen_share_permission_app_selector_title" msgid="1404878013670347899">"Споделете или снимете апликација"</string>
+ <string name="screen_share_permission_app_selector_title" msgid="1404878013670347899">"Споделување или снимање апликација"</string>
<string name="media_projection_entry_app_permission_dialog_title" msgid="9155535851866407199">"Да почне снимање или емитување со <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>?"</string>
<string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"Кога споделувате, снимате или емитувате, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> има пристап до сѐ што е видливо на вашиот екран или пуштено на вашиот уред. Затоа, бидете внимателни со работи како лозинки, детали за плаќање, пораки, фотографии и аудио и видео."</string>
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"Кога споделувате, снимате или емитувате апликација, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> има пристап до сѐ што се прикажува или пушта на таа апликација. Затоа, бидете внимателни со работи како лозинки, детали за плаќање, пораки, фотографии и аудио и видео."</string>
@@ -1046,8 +1046,7 @@
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Проблем при читањето на мерачот на батеријата"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Допрете за повеќе информации"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Не е поставен аларм"</string>
- <!-- no translation found for accessibility_bouncer (5896923685673320070) -->
- <skip />
+ <string name="accessibility_bouncer" msgid="5896923685673320070">"внесете PIN/шема/лозинка"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Сензор за отпечатоци"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"автентицирате"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"внесете уред"</string>
@@ -1127,18 +1126,12 @@
<string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Дознајте повеќе"</string>
<string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Дознајте повеќе на <xliff:g id="URL">%s</xliff:g>"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Отворете ја <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <!-- no translation found for wallet_quick_affordance_unavailable_install_the_app (7298552910007208368) -->
- <skip />
- <!-- no translation found for wallet_quick_affordance_unavailable_configure_the_app (4387433357429873258) -->
- <skip />
- <!-- no translation found for qr_scanner_quick_affordance_unavailable_explanation (3049582306241150946) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_install_the_app (6187820778998446168) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_configure_the_app (7953595390775156839) -->
- <skip />
- <!-- no translation found for notes_app_quick_affordance_unavailable_explanation (4796955161600178530) -->
- <skip />
+ <string name="wallet_quick_affordance_unavailable_install_the_app" msgid="7298552910007208368">"За да ја додадете апликацијата Wallet како кратенка, апликацијата мора да е инсталирана"</string>
+ <string name="wallet_quick_affordance_unavailable_configure_the_app" msgid="4387433357429873258">"За да ја додадете апликацијата Wallet како кратенка, мора да имате додадено најмалку една картичка"</string>
+ <string name="qr_scanner_quick_affordance_unavailable_explanation" msgid="3049582306241150946">"За да го додадете скенерот на QR-кодови како кратенка, погрижете се дека имате инсталирано апликација за камера"</string>
+ <string name="home_quick_affordance_unavailable_install_the_app" msgid="6187820778998446168">"За да ја додадете апликацијата Home како кратенка, апликацијата мора да е инсталирана"</string>
+ <string name="home_quick_affordance_unavailable_configure_the_app" msgid="7953595390775156839">"• достапен е најмалку еден уред"</string>
+ <string name="notes_app_quick_affordance_unavailable_explanation" msgid="4796955161600178530">"Изберете стандардна апликација за белешки за да ја користите кратенката за фаќање белешки"</string>
<string name="keyguard_affordance_enablement_dialog_notes_app_action" msgid="6821710209675089470">"Изберете апликација"</string>
<string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Допрете и задржете ја кратенката"</string>
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Откажи"</string>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index 5c6bef3..98d0ddd 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -1046,8 +1046,7 @@
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Таны батарей хэмжигчийг уншихад асуудал гарлаа"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Нэмэлт мэдээлэл авахын тулд товшино уу"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Сэрүүлэг тавиагүй"</string>
- <!-- no translation found for accessibility_bouncer (5896923685673320070) -->
- <skip />
+ <string name="accessibility_bouncer" msgid="5896923685673320070">"дэлгэцийн түгжээ оруулах"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Хурууны хээ мэдрэгч"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"баталгаажуулах"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"төхөөрөмж оруулах"</string>
@@ -1127,18 +1126,12 @@
<string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Нэмэлт мэдээлэл авах"</string>
<string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"<xliff:g id="URL">%s</xliff:g>-с нэмэлт мэдээлэл авна уу"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g>-г нээх"</string>
- <!-- no translation found for wallet_quick_affordance_unavailable_install_the_app (7298552910007208368) -->
- <skip />
- <!-- no translation found for wallet_quick_affordance_unavailable_configure_the_app (4387433357429873258) -->
- <skip />
- <!-- no translation found for qr_scanner_quick_affordance_unavailable_explanation (3049582306241150946) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_install_the_app (6187820778998446168) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_configure_the_app (7953595390775156839) -->
- <skip />
- <!-- no translation found for notes_app_quick_affordance_unavailable_explanation (4796955161600178530) -->
- <skip />
+ <string name="wallet_quick_affordance_unavailable_install_the_app" msgid="7298552910007208368">"Wallet аппыг товчлолоор нэмэхийн тулд уг аппыг суулгасан эсэхийг шалгана уу"</string>
+ <string name="wallet_quick_affordance_unavailable_configure_the_app" msgid="4387433357429873258">"Wallet аппыг товчлолоор нэмэхийн тулд дор хаяж нэг карт нэмсэн эсэхийг шалгана уу"</string>
+ <string name="qr_scanner_quick_affordance_unavailable_explanation" msgid="3049582306241150946">"QR код сканнерыг товчлолоор нэмэхийн тулд камерын аппыг суулгасан эсэхийг шалгана уу"</string>
+ <string name="home_quick_affordance_unavailable_install_the_app" msgid="6187820778998446168">"Home аппыг товчлолоор нэмэхийн тулд уг аппыг суулгасан эсэхийг шалгана уу"</string>
+ <string name="home_quick_affordance_unavailable_configure_the_app" msgid="7953595390775156839">"• Дор хаяж нэг төхөөрөмж боломжтой"</string>
+ <string name="notes_app_quick_affordance_unavailable_explanation" msgid="4796955161600178530">"Тэмдэглэл хөтлөх товчлолыг ашиглахын тулд тэмдэглэлийн өгөгдмөл аппыг сонгоно уу"</string>
<string name="keyguard_affordance_enablement_dialog_notes_app_action" msgid="6821710209675089470">"Апп сонгох"</string>
<string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Товчлолд хүрээд удаан дарна уу"</string>
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Цуцлах"</string>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index 55198be..6547cfe 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -1046,8 +1046,7 @@
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"तुमचे बॅटरी मीटर वाचताना समस्या आली"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"अधिक माहितीसाठी टॅप करा"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"अलार्म सेट केला नाही"</string>
- <!-- no translation found for accessibility_bouncer (5896923685673320070) -->
- <skip />
+ <string name="accessibility_bouncer" msgid="5896923685673320070">"स्क्रीन लॉक एंटर करा"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"फिंगरप्रिंट सेन्सर"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"ऑथेंटिकेट करा"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"डिव्हाइस एंटर करा"</string>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index 100feac..3d1a222 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -1046,8 +1046,7 @@
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Masalah membaca meter bateri anda"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Ketik untuk mendapatkan maklumat lanjut"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Tiada penggera"</string>
- <!-- no translation found for accessibility_bouncer (5896923685673320070) -->
- <skip />
+ <string name="accessibility_bouncer" msgid="5896923685673320070">"masukkan kunci skrin"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Penderia cap jari"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"sahkan"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"akses peranti"</string>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index d516e50..a6111d9 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -1046,8 +1046,7 @@
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Kunne ikke lese batterimåleren"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Trykk for å få mer informasjon"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Ingen alarm angitt"</string>
- <!-- no translation found for accessibility_bouncer (5896923685673320070) -->
- <skip />
+ <string name="accessibility_bouncer" msgid="5896923685673320070">"legg inn skjermlåsen"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Fingeravtrykkssensor"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"autentiser"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"åpne enheten"</string>
@@ -1127,18 +1126,12 @@
<string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Finn ut mer"</string>
<string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Finn ut mer på <xliff:g id="URL">%s</xliff:g>"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Åpne <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <!-- no translation found for wallet_quick_affordance_unavailable_install_the_app (7298552910007208368) -->
- <skip />
- <!-- no translation found for wallet_quick_affordance_unavailable_configure_the_app (4387433357429873258) -->
- <skip />
- <!-- no translation found for qr_scanner_quick_affordance_unavailable_explanation (3049582306241150946) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_install_the_app (6187820778998446168) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_configure_the_app (7953595390775156839) -->
- <skip />
- <!-- no translation found for notes_app_quick_affordance_unavailable_explanation (4796955161600178530) -->
- <skip />
+ <string name="wallet_quick_affordance_unavailable_install_the_app" msgid="7298552910007208368">"For å legge til Wallet-appen som snarvei, sørg for at appen er installert"</string>
+ <string name="wallet_quick_affordance_unavailable_configure_the_app" msgid="4387433357429873258">"For å legge til Wallet-appen som snarvei, sørg for at minst ett kort er lagt til"</string>
+ <string name="qr_scanner_quick_affordance_unavailable_explanation" msgid="3049582306241150946">"For å legge til QR-kodeskanneren som snarvei, sørg for at du har en kameraapp installert"</string>
+ <string name="home_quick_affordance_unavailable_install_the_app" msgid="6187820778998446168">"For å legge til Home-appen som snarvei, sørg for at appen er installert"</string>
+ <string name="home_quick_affordance_unavailable_configure_the_app" msgid="7953595390775156839">"• minst én enhet er tilgjengelig"</string>
+ <string name="notes_app_quick_affordance_unavailable_explanation" msgid="4796955161600178530">"Velg en standard notatapp du vil bruke med notatsnarveien"</string>
<string name="keyguard_affordance_enablement_dialog_notes_app_action" msgid="6821710209675089470">"Velg app"</string>
<string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Trykk på og hold inne snarveien"</string>
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Avbryt"</string>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index 70d3d5b..610e28b 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -79,7 +79,7 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"स्क्रिनसट फेरि लिएर हेर्नुहोस्"</string>
<string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"स्क्रिनसट सुरक्षित गर्न सकिएन"</string>
<string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"उक्त एप वा तपाईंको संगठनले स्क्रिनसटहरू लिन दिँदैन"</string>
- <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"तपाईंको सूचना प्रविधि व्यवस्थापकले स्क्रिनसट लिने सुविधा ब्लक गर्नुभएको छ"</string>
+ <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"तपाईंको IT एड्मिनले स्क्रिनसट लिने सुविधा ब्लक गर्नुभएको छ"</string>
<string name="screenshot_edit_label" msgid="8754981973544133050">"सम्पादन गर्नुहोस्"</string>
<string name="screenshot_edit_description" msgid="3333092254706788906">"स्क्रिनसट सम्पादन गर्नुहोस्"</string>
<string name="screenshot_share_description" msgid="2861628935812656612">"स्क्रिनसट सेयर गर्नुहोस्"</string>
@@ -412,11 +412,11 @@
<string name="media_projection_entry_generic_permission_dialog_warning_entire_screen" msgid="5407906851409410209">"तपाईंले सेयर गर्दा, रेकर्ड गर्दा वा कास्ट गर्दा Android ले तपाईंको स्क्रिनमा देखिने वा डिभाइसमा प्ले गरिने सबै कुरा हेर्न तथा प्रयोग गर्न सक्छ। त्यसैले पासवर्ड, भुक्तानीसम्बन्धी विवरण, म्यासेज, फोटो र अडियो तथा भिडियो जस्ता कुरा हेर्दा वा प्ले गर्दा सावधानी अपनाउनुहोला।"</string>
<string name="media_projection_entry_generic_permission_dialog_warning_single_app" msgid="3454859977888159495">"तपाईंले कुनै एप सेयर गर्दा, रेकर्ड गर्दा वा कास्ट गर्दा Android ले उक्त एपमा देखाइने वा प्ले गरिने सबै कुरा हेर्न तथा प्रयोग गर्न सक्छ। त्यसैले पासवर्ड, भुक्तानीसम्बन्धी विवरण, म्यासेज, फोटो र अडियो तथा भिडियो जस्ता कुरा हेर्दा वा प्ले गर्दा सावधानी अपनाउनुहोला।"</string>
<string name="media_projection_entry_generic_permission_dialog_continue" msgid="8640381403048097116">"सुरु गर्नुहोस्"</string>
- <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"तपाईंका सूचना प्रविधि व्यवस्थापकले ब्लक गर्नुभएको छ"</string>
+ <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"तपाईंका IT एड्मिनले ब्लक गर्नुभएको छ"</string>
<string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"डिभाइसको नीतिका कारण स्क्रिन क्याप्चर गर्ने सुविधा अफ गरिएको छ"</string>
<string name="clear_all_notifications_text" msgid="348312370303046130">"सबै हटाउनुहोस्"</string>
<string name="manage_notifications_text" msgid="6885645344647733116">"व्यवस्थित गर्नुहोस्"</string>
- <string name="manage_notifications_history_text" msgid="57055985396576230">"इतिहास"</string>
+ <string name="manage_notifications_history_text" msgid="57055985396576230">"हिस्ट्री"</string>
<string name="notification_section_header_incoming" msgid="850925217908095197">"नयाँ"</string>
<string name="notification_section_header_gentle" msgid="6804099527336337197">"साइलेन्ट"</string>
<string name="notification_section_header_alerting" msgid="5581175033680477651">"सूचनाहरू"</string>
@@ -1046,8 +1046,7 @@
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"डिभाइसको ब्याट्रीको मिटर रिडिङ क्रममा समस्या भयो"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"थप जानकारी प्राप्त गर्न ट्याप गर्नुहोस्"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"अलार्म राखिएको छैन"</string>
- <!-- no translation found for accessibility_bouncer (5896923685673320070) -->
- <skip />
+ <string name="accessibility_bouncer" msgid="5896923685673320070">"स्क्रिन लक हाल्नुहोस्"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"फिंगरप्रिन्ट सेन्सर"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"प्रमाणित गर्नुहोस्"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"डिभाइस हाल्नुहोस्"</string>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 5dfdb86..3f7f829 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -1046,8 +1046,7 @@
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Probleem bij het lezen van je batterijmeter"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Tik hier voor meer informatie"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Geen wekker gezet"</string>
- <!-- no translation found for accessibility_bouncer (5896923685673320070) -->
- <skip />
+ <string name="accessibility_bouncer" msgid="5896923685673320070">"schermvergrendeling invoeren"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Vingerafdruksensor"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"verifiëren"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"apparaat opgeven"</string>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index 5266083..3728d5a 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -254,7 +254,7 @@
<string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"ଉପଲବ୍ଧ"</string>
<string name="quick_settings_camera_mic_blocked" msgid="4710884905006788281">"ବ୍ଲକ୍ କରାଯାଇଛି"</string>
<string name="quick_settings_media_device_label" msgid="8034019242363789941">"ମିଡିଆ ଡିଭାଇସ୍"</string>
- <string name="quick_settings_user_title" msgid="8673045967216204537">"ଉପଯୋଗକର୍ତ୍ତା"</string>
+ <string name="quick_settings_user_title" msgid="8673045967216204537">"ୟୁଜର"</string>
<string name="quick_settings_wifi_label" msgid="2879507532983487244">"ୱାଇ-ଫାଇ"</string>
<string name="quick_settings_internet_label" msgid="6603068555872455463">"ଇଣ୍ଟରନେଟ"</string>
<string name="quick_settings_networks_available" msgid="1875138606855420438">"ନେଟୱାର୍କଗୁଡ଼ିକ ଉପଲବ୍ଧ"</string>
@@ -1046,8 +1046,7 @@
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"ଆପଣଙ୍କ ବ୍ୟାଟେରୀ ମିଟର୍ ପଢ଼ିବାରେ ସମସ୍ୟା ହେଉଛି"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"ଅଧିକ ସୂଚନା ପାଇଁ ଟାପ୍ କରନ୍ତୁ"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"ଆଲାରାମ ସେଟ ହୋଇନାହିଁ"</string>
- <!-- no translation found for accessibility_bouncer (5896923685673320070) -->
- <skip />
+ <string name="accessibility_bouncer" msgid="5896923685673320070">"ସ୍କ୍ରିନ ଲକ ଲେଖନ୍ତୁ"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"ଟିପଚିହ୍ନ ସେନ୍ସର୍"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"ପ୍ରମାଣୀକରଣ କରନ୍ତୁ"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"ଡିଭାଇସ୍ ବିଷୟରେ ସୂଚନା ଲେଖନ୍ତୁ"</string>
@@ -1127,18 +1126,12 @@
<string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"ଅଧିକ ଜାଣନ୍ତୁ"</string>
<string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"<xliff:g id="URL">%s</xliff:g>ରେ ଅଧିକ ଜାଣନ୍ତୁ"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> ଖୋଲନ୍ତୁ"</string>
- <!-- no translation found for wallet_quick_affordance_unavailable_install_the_app (7298552910007208368) -->
- <skip />
- <!-- no translation found for wallet_quick_affordance_unavailable_configure_the_app (4387433357429873258) -->
- <skip />
- <!-- no translation found for qr_scanner_quick_affordance_unavailable_explanation (3049582306241150946) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_install_the_app (6187820778998446168) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_configure_the_app (7953595390775156839) -->
- <skip />
- <!-- no translation found for notes_app_quick_affordance_unavailable_explanation (4796955161600178530) -->
- <skip />
+ <string name="wallet_quick_affordance_unavailable_install_the_app" msgid="7298552910007208368">"ଏକ ସର୍ଟକଟ ଭାବେ Wallet ଆପ ଯୋଗ କରିବା ପାଇଁ ଏହି ଆପ ଇନଷ୍ଟଲ କରାଯାଇଥିବା ସୁନିଶ୍ଚିତ କରନ୍ତୁ"</string>
+ <string name="wallet_quick_affordance_unavailable_configure_the_app" msgid="4387433357429873258">"ଏକ ସର୍ଟକଟ ଭାବେ Wallet ଆପ ଯୋଗ କରିବାକୁ ଅତିକମରେ ଗୋଟିଏ ଆପ ଯୋଗ କରାଯାଇଥିବା ସୁନିଶ୍ଚିତ କରନ୍ତୁ"</string>
+ <string name="qr_scanner_quick_affordance_unavailable_explanation" msgid="3049582306241150946">"ଏକ ସର୍ଟକଟ ଭାବେ QR କୋଡ ସ୍କାନର ଯୋଗ କରିବାକୁ ଏକ କେମେରା ଆପ ଇନଷ୍ଟଲ କରାଯାଇଥିବା ସୁନିଶ୍ଚିତ କରନ୍ତୁ"</string>
+ <string name="home_quick_affordance_unavailable_install_the_app" msgid="6187820778998446168">"ଏକ ସର୍ଟକଟ ଭାବେ Home ଆପ ଯୋଗ କରିବା ପାଇଁ ଏହି ଆପ ଇନଷ୍ଟଲ କରାଯାଇଥିବା ସୁନିଶ୍ଚିତ କରନ୍ତୁ"</string>
+ <string name="home_quick_affordance_unavailable_configure_the_app" msgid="7953595390775156839">"• ଅତିକମରେ ଗୋଟିଏ ଡିଭାଇସ ଉପଲବ୍ଧ ଅଛି"</string>
+ <string name="notes_app_quick_affordance_unavailable_explanation" msgid="4796955161600178530">"ନୋଟଟେକିଂ ସର୍ଟକଟ ବ୍ୟବହାର କରିବାକୁ ଏକ ଡିଫଲ୍ଟ ନୋଟ୍ସ ଆପ୍ସ ଚୟନ କରନ୍ତୁ"</string>
<string name="keyguard_affordance_enablement_dialog_notes_app_action" msgid="6821710209675089470">"ଆପ ଚୟନ କରନ୍ତୁ"</string>
<string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"ସର୍ଟକଟକୁ ସ୍ପର୍ଶ କରି ଧରି ରଖନ୍ତୁ"</string>
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"ବାତିଲ କରନ୍ତୁ"</string>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index bee58780..bb511e3 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -1046,8 +1046,7 @@
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"ਤੁਹਾਡੇ ਬੈਟਰੀ ਮੀਟਰ ਨੂੰ ਪੜ੍ਹਨ ਵਿੱਚ ਸਮੱਸਿਆ ਹੋ ਰਹੀ ਹੈ"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"ਹੋਰ ਜਾਣਕਾਰੀ ਲਈ ਟੈਪ ਕਰੋ"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"ਕੋਈ ਅਲਾਰਮ ਸੈੱਟ ਨਹੀਂ"</string>
- <!-- no translation found for accessibility_bouncer (5896923685673320070) -->
- <skip />
+ <string name="accessibility_bouncer" msgid="5896923685673320070">"ਸਕ੍ਰੀਨ ਲਾਕ ਦਾਖਲ ਕਰੋ"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਸੈਂਸਰ"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"ਪ੍ਰਮਾਣਿਤ ਕਰੋ"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"ਡੀਵਾਈਸ ਵਿੱਚ ਦਾਖਲ ਹੋਵੋ"</string>
@@ -1127,18 +1126,12 @@
<string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"ਹੋਰ ਜਾਣੋ"</string>
<string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"<xliff:g id="URL">%s</xliff:g> \'ਤੇ ਹੋਰ ਜਾਣੋ"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> ਖੋਲ੍ਹੋ"</string>
- <!-- no translation found for wallet_quick_affordance_unavailable_install_the_app (7298552910007208368) -->
- <skip />
- <!-- no translation found for wallet_quick_affordance_unavailable_configure_the_app (4387433357429873258) -->
- <skip />
- <!-- no translation found for qr_scanner_quick_affordance_unavailable_explanation (3049582306241150946) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_install_the_app (6187820778998446168) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_configure_the_app (7953595390775156839) -->
- <skip />
- <!-- no translation found for notes_app_quick_affordance_unavailable_explanation (4796955161600178530) -->
- <skip />
+ <string name="wallet_quick_affordance_unavailable_install_the_app" msgid="7298552910007208368">"Wallet ਐਪ ਨੂੰ ਸ਼ਾਰਟਕੱਟ ਵਜੋਂ ਸ਼ਾਮਲ ਕਰਨ ਲਈ, ਪੱਕਾ ਕਰੋ ਕਿ ਐਪ ਸਥਾਪਤ ਹੈ"</string>
+ <string name="wallet_quick_affordance_unavailable_configure_the_app" msgid="4387433357429873258">"Wallet ਐਪ ਨੂੰ ਸ਼ਾਰਟਕੱਟ ਵਜੋਂ ਸ਼ਾਮਲ ਕਰਨ ਲਈ, ਪੱਕਾ ਕਰੋ ਕਿ ਘੱਟੋ-ਘੱਟ ਇੱਕ ਕਾਰਡ ਸ਼ਾਮਲ ਕੀਤਾ ਗਿਆ ਹੈ"</string>
+ <string name="qr_scanner_quick_affordance_unavailable_explanation" msgid="3049582306241150946">"QR ਕੋਡ ਸਕੈਨਰ ਨੂੰ ਸ਼ਾਰਟਕੱਟ ਵਜੋਂ ਸ਼ਾਮਲ ਕਰਨ ਲਈ, ਪੱਕਾ ਕਰੋ ਕਿ ਕੈਮਰਾ ਐਪ ਸਥਾਪਤ ਹੈ"</string>
+ <string name="home_quick_affordance_unavailable_install_the_app" msgid="6187820778998446168">"Home ਐਪ ਨੂੰ ਸ਼ਾਰਟਕੱਟ ਵਜੋਂ ਸ਼ਾਮਲ ਕਰਨ ਲਈ, ਪੱਕਾ ਕਰੋ ਕਿ ਐਪ ਸਥਾਪਤ ਹੈ"</string>
+ <string name="home_quick_affordance_unavailable_configure_the_app" msgid="7953595390775156839">"• ਘੱਟੋ-ਘੱਟ ਇੱਕ ਡੀਵਾਈਸ ਉਪਲਬਧ ਹੈ"</string>
+ <string name="notes_app_quick_affordance_unavailable_explanation" msgid="4796955161600178530">"ਨੋਟ ਬਣਾਉਣ ਵਾਲੇ ਸ਼ਾਰਟਕੱਟ ਦੀ ਵਰਤੋਂ ਕਰਨ ਲਈ ਪੂਰਵ-ਨਿਰਧਾਰਿਤ ਨੋਟ ਐਪ ਚੁਣੋ"</string>
<string name="keyguard_affordance_enablement_dialog_notes_app_action" msgid="6821710209675089470">"ਐਪ ਚੁਣੋ"</string>
<string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"ਸ਼ਾਰਟਕੱਟ ਨੂੰ ਸਪਰਸ਼ ਕਰ ਕੇ ਰੱਖੋ"</string>
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"ਰੱਦ ਕਰੋ"</string>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 899460e..5dcdd7e 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -399,7 +399,7 @@
<string name="media_projection_sys_service_dialog_warning" msgid="2443872865267330320">"Podczas nagrywania i przesyłania usługa udostępniająca tę funkcję będzie miała dostęp do wszystkich informacji widocznych na ekranie lub odtwarzanych na urządzeniu. Dotyczy to m.in. haseł, szczegółów płatności, zdjęć, wiadomości i odtwarzanych dźwięków."</string>
<string name="screen_share_permission_dialog_option_entire_screen" msgid="3131200488455089620">"Cały ekran"</string>
<string name="screen_share_permission_dialog_option_single_app" msgid="4350961814397220929">"Pojedyncza aplikacja"</string>
- <string name="screen_share_permission_app_selector_title" msgid="1404878013670347899">"Udostępnianie i nagrywanie za pomocą aplikacji"</string>
+ <string name="screen_share_permission_app_selector_title" msgid="1404878013670347899">"Udostępnianie i nagrywanie aplikacji"</string>
<string name="media_projection_entry_app_permission_dialog_title" msgid="9155535851866407199">"Rozpocząć nagrywanie lub przesyłanie za pomocą aplikacji <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>?"</string>
<string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"Podczas udostępniania, nagrywania lub przesyłania treści aplikacja <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ma dostęp do wszystkiego, co jest widoczne na ekranie lub odtwarzane na urządzeniu. Dlatego zachowaj ostrożność w zakresie haseł, danych do płatności, wiadomości, zdjęć, audio i filmów."</string>
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"Podczas udostępniania, nagrywania lub przesyłania treści aplikacja <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ma dostęp do wszystkiego, co jest w niej wyświetlane lub odtwarzane. Dlatego zachowaj ostrożność w zakresie haseł, danych do płatności, wiadomości, zdjęć, audio i filmów."</string>
@@ -1046,8 +1046,7 @@
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problem z odczytaniem pomiaru wykorzystania baterii"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Kliknij, aby uzyskać więcej informacji"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Nie ustawiono alarmu"</string>
- <!-- no translation found for accessibility_bouncer (5896923685673320070) -->
- <skip />
+ <string name="accessibility_bouncer" msgid="5896923685673320070">"Wprowadź blokadę ekranu"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Czytnik linii papilarnych"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"uwierzytelnij"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"otwórz urządzenie"</string>
@@ -1127,18 +1126,12 @@
<string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Więcej informacji"</string>
<string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Więcej informacji: <xliff:g id="URL">%s</xliff:g>"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Otwórz: <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <!-- no translation found for wallet_quick_affordance_unavailable_install_the_app (7298552910007208368) -->
- <skip />
- <!-- no translation found for wallet_quick_affordance_unavailable_configure_the_app (4387433357429873258) -->
- <skip />
- <!-- no translation found for qr_scanner_quick_affordance_unavailable_explanation (3049582306241150946) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_install_the_app (6187820778998446168) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_configure_the_app (7953595390775156839) -->
- <skip />
- <!-- no translation found for notes_app_quick_affordance_unavailable_explanation (4796955161600178530) -->
- <skip />
+ <string name="wallet_quick_affordance_unavailable_install_the_app" msgid="7298552910007208368">"Aby dodać aplikację Portfel jako skrót, upewnij się, że jest zainstalowana"</string>
+ <string name="wallet_quick_affordance_unavailable_configure_the_app" msgid="4387433357429873258">"Aby dodać aplikację Portfel jako skrót, upewnij się, że została dodana co najmniej 1 karta"</string>
+ <string name="qr_scanner_quick_affordance_unavailable_explanation" msgid="3049582306241150946">"Aby dodać Skaner kodów QR jako skrót, upewnij się, że jest zainstalowana aplikacja aparatu"</string>
+ <string name="home_quick_affordance_unavailable_install_the_app" msgid="6187820778998446168">"Aby dodać aplikację Home jako skrót, upewnij się, że jest zainstalowana"</string>
+ <string name="home_quick_affordance_unavailable_configure_the_app" msgid="7953595390775156839">"• Dostępne jest co najmniej 1 urządzenie."</string>
+ <string name="notes_app_quick_affordance_unavailable_explanation" msgid="4796955161600178530">"Wybierz domyślną aplikację do obsługi notatek, której skrótu będziesz używać do funkcji notowania"</string>
<string name="keyguard_affordance_enablement_dialog_notes_app_action" msgid="6821710209675089470">"Wybierz aplikację"</string>
<string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Skrót – naciśnij i przytrzymaj"</string>
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Anuluj"</string>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index 785856e..3ac3692 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -1046,8 +1046,7 @@
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problema para ler seu medidor de bateria"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Toque para mais informações"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Nenhum alarme definido"</string>
- <!-- no translation found for accessibility_bouncer (5896923685673320070) -->
- <skip />
+ <string name="accessibility_bouncer" msgid="5896923685673320070">"inserir bloqueio de tela"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Sensor de impressão digital"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"autenticar"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"acessar o dispositivo"</string>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index c6612a7..6d54a64 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -1046,8 +1046,7 @@
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Ocorreu um problema ao ler o medidor da bateria"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Toque para obter mais informações"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Nenhum alarme defin."</string>
- <!-- no translation found for accessibility_bouncer (5896923685673320070) -->
- <skip />
+ <string name="accessibility_bouncer" msgid="5896923685673320070">"introduzir bloqueio de ecrã"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Sensor de impressões digitais"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"autenticar"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"entrar no dispositivo"</string>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index 785856e..3ac3692 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -1046,8 +1046,7 @@
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problema para ler seu medidor de bateria"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Toque para mais informações"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Nenhum alarme definido"</string>
- <!-- no translation found for accessibility_bouncer (5896923685673320070) -->
- <skip />
+ <string name="accessibility_bouncer" msgid="5896923685673320070">"inserir bloqueio de tela"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Sensor de impressão digital"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"autenticar"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"acessar o dispositivo"</string>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index a7a2731..d0764dd 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -399,7 +399,7 @@
<string name="media_projection_sys_service_dialog_warning" msgid="2443872865267330320">"Serviciul care oferă această funcție va avea acces la toate informațiile vizibile pe ecran sau redate pe dispozitiv în timp ce înregistrezi sau proiectezi. Între aceste informații se numără parole, detalii de plată, fotografii, mesaje și conținutul audio pe care îl redai."</string>
<string name="screen_share_permission_dialog_option_entire_screen" msgid="3131200488455089620">"Tot ecranul"</string>
<string name="screen_share_permission_dialog_option_single_app" msgid="4350961814397220929">"O singură aplicație"</string>
- <string name="screen_share_permission_app_selector_title" msgid="1404878013670347899">"Permite accesul la o aplicație sau înregistreaz-o"</string>
+ <string name="screen_share_permission_app_selector_title" msgid="1404878013670347899">"Distribuie o aplicație sau înregistreaz-o"</string>
<string name="media_projection_entry_app_permission_dialog_title" msgid="9155535851866407199">"Începi să înregistrezi sau să proiectezi cu <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>?"</string>
<string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"Când permiți accesul, înregistrezi sau proiectezi, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> are acces la orice este vizibil pe ecran sau se redă pe dispozitiv. Prin urmare, ai grijă cu parolele, detaliile de plată, mesajele, fotografiile și conținutul audio și video."</string>
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"Când permiți accesul, înregistrezi sau proiectezi o aplicație, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> are acces la orice se afișează pe ecran sau se redă în aplicație. Prin urmare, ai grijă cu informații cum ar fi parolele, detaliile de plată, mesajele, fotografiile și conținutul audio și video."</string>
@@ -1046,8 +1046,7 @@
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problemă la citirea măsurării bateriei"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Atinge pentru mai multe informații"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Nicio alarmă setată"</string>
- <!-- no translation found for accessibility_bouncer (5896923685673320070) -->
- <skip />
+ <string name="accessibility_bouncer" msgid="5896923685673320070">"intră în blocarea ecranului"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Senzor de amprentă"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"autentifică-te"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"Accesează dispozitivul"</string>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 279d9a6..91a8534 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -981,7 +981,7 @@
<string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"Выбрано устройств: <xliff:g id="COUNT">%1$d</xliff:g>"</string>
<string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(нет подключения)"</string>
<string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Не удается переключиться. Нажмите, чтобы повторить попытку."</string>
- <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Подключите устройство"</string>
+ <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Подключить устройство"</string>
<string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Чтобы начать трансляцию сеанса, откройте приложение"</string>
<string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Неизвестное приложение"</string>
<string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Остановить трансляцию"</string>
@@ -1046,8 +1046,7 @@
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Не удалось узнать уровень заряда батареи"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Нажмите, чтобы узнать больше."</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Нет будильников"</string>
- <!-- no translation found for accessibility_bouncer (5896923685673320070) -->
- <skip />
+ <string name="accessibility_bouncer" msgid="5896923685673320070">"разблокировать экран"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Сканер отпечатков пальцев"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"выполнить аутентификацию"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"указать устройство"</string>
@@ -1127,18 +1126,12 @@
<string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Подробнее"</string>
<string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Подробнее: <xliff:g id="URL">%s</xliff:g>."</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Открыть \"<xliff:g id="APPNAME">%1$s</xliff:g>\""</string>
- <!-- no translation found for wallet_quick_affordance_unavailable_install_the_app (7298552910007208368) -->
- <skip />
- <!-- no translation found for wallet_quick_affordance_unavailable_configure_the_app (4387433357429873258) -->
- <skip />
- <!-- no translation found for qr_scanner_quick_affordance_unavailable_explanation (3049582306241150946) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_install_the_app (6187820778998446168) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_configure_the_app (7953595390775156839) -->
- <skip />
- <!-- no translation found for notes_app_quick_affordance_unavailable_explanation (4796955161600178530) -->
- <skip />
+ <string name="wallet_quick_affordance_unavailable_install_the_app" msgid="7298552910007208368">"Вы можете добавить ярлык приложения \"Кошелек\", только если оно установлено."</string>
+ <string name="wallet_quick_affordance_unavailable_configure_the_app" msgid="4387433357429873258">"Вы можете добавить ярлык приложения \"Кошелек\", только если добавлена хотя бы одна карта."</string>
+ <string name="qr_scanner_quick_affordance_unavailable_explanation" msgid="3049582306241150946">"Вы можете добавить ярлык сканера QR-кодов, только если установлено приложение камеры."</string>
+ <string name="home_quick_affordance_unavailable_install_the_app" msgid="6187820778998446168">"Вы можете добавить ярлык приложения Home, только если оно установлено."</string>
+ <string name="home_quick_affordance_unavailable_configure_the_app" msgid="7953595390775156839">"• Доступно хотя бы одно устройство."</string>
+ <string name="notes_app_quick_affordance_unavailable_explanation" msgid="4796955161600178530">"Выберите стандартное приложение для заметок, которое будет открываться при нажатии на ярлык."</string>
<string name="keyguard_affordance_enablement_dialog_notes_app_action" msgid="6821710209675089470">"Выбрать приложение"</string>
<string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Нажмите и удерживайте ярлык"</string>
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Отмена"</string>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index ddca7f5..1efb408 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -1046,8 +1046,7 @@
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"ඔබගේ බැටරි මනුව කියවීමේ දෝෂයකි"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"තවත් තොරතුරු සඳහා තට්ටු කරන්න"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"එලාම සකසා නැත"</string>
- <!-- no translation found for accessibility_bouncer (5896923685673320070) -->
- <skip />
+ <string name="accessibility_bouncer" msgid="5896923685673320070">"තිර අගුල ඇතුළු කරන්න"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"ඇඟිලි සලකුණු සංවේදකය"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"සත්යාපනය කරන්න"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"උපාංගය ඇතුළු කරන්න"</string>
@@ -1127,18 +1126,12 @@
<string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"තව දැන ගන්න"</string>
<string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"<xliff:g id="URL">%s</xliff:g> තුළින් තව දැන ගන්න"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> විවෘත කරන්න"</string>
- <!-- no translation found for wallet_quick_affordance_unavailable_install_the_app (7298552910007208368) -->
- <skip />
- <!-- no translation found for wallet_quick_affordance_unavailable_configure_the_app (4387433357429873258) -->
- <skip />
- <!-- no translation found for qr_scanner_quick_affordance_unavailable_explanation (3049582306241150946) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_install_the_app (6187820778998446168) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_configure_the_app (7953595390775156839) -->
- <skip />
- <!-- no translation found for notes_app_quick_affordance_unavailable_explanation (4796955161600178530) -->
- <skip />
+ <string name="wallet_quick_affordance_unavailable_install_the_app" msgid="7298552910007208368">"කෙටිමඟක් ලෙස Wallet යෙදුම එක් කිරීම සඳහා, යෙදුම ස්ථාපනය කර ඇති බවට වග බලා ගන්න"</string>
+ <string name="wallet_quick_affordance_unavailable_configure_the_app" msgid="4387433357429873258">"කෙටිමඟක් ලෙස Wallet යෙදුම එක් කිරීම සඳහා, අවම වශයෙන් එක් කාඩ්පතක් එක් කර ඇති බවට වග බලා ගන්න"</string>
+ <string name="qr_scanner_quick_affordance_unavailable_explanation" msgid="3049582306241150946">"කෙටිමඟක් ලෙස QR කේත ස්කෑනරය එක් කිරීම සඳහා, කැමරා යෙදුමක් ස්ථාපනය කර ඇති බවට වග බලා ගන්න"</string>
+ <string name="home_quick_affordance_unavailable_install_the_app" msgid="6187820778998446168">"Home යෙදුම කෙටිමඟක් ලෙස එක් කිරීම සඳහා, යෙදුම ස්ථාපනය කර ඇති බව සහතික කර ගන්න"</string>
+ <string name="home_quick_affordance_unavailable_configure_the_app" msgid="7953595390775156839">"• අවම වශයෙන් එක උපාංගයක් ලැබේ"</string>
+ <string name="notes_app_quick_affordance_unavailable_explanation" msgid="4796955161600178530">"සටහන් ගැනීමේ කෙටිමඟ භාවිතා කිරීමට පෙරනිමි සටහන් යෙදුමක් තෝරන්න"</string>
<string name="keyguard_affordance_enablement_dialog_notes_app_action" msgid="6821710209675089470">"යෙදුම තෝරන්න"</string>
<string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"ස්පර්ශ කර අල්ලා සිටීමේ කෙටිමඟ"</string>
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"අවලංගු කරන්න"</string>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 996f454..b353293 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -399,7 +399,7 @@
<string name="media_projection_sys_service_dialog_warning" msgid="2443872865267330320">"Služba poskytujúca túto funkciu bude mať prístup k všetkým informáciám zobrazovaným na obrazovke alebo prehrávaným v zariadení počas nahrávania či prenosu. Patria medzi ne informácie, ako sú heslá, platobné údaje, fotky, správy a prehrávaný zvuk."</string>
<string name="screen_share_permission_dialog_option_entire_screen" msgid="3131200488455089620">"Celá obrazovka"</string>
<string name="screen_share_permission_dialog_option_single_app" msgid="4350961814397220929">"Jedna aplikácia"</string>
- <string name="screen_share_permission_app_selector_title" msgid="1404878013670347899">"Aplikácia na zdieľanie alebo nahrávanie"</string>
+ <string name="screen_share_permission_app_selector_title" msgid="1404878013670347899">"Vyberte aplikáciu, ktorú chcete zdieľať alebo nahrávať"</string>
<string name="media_projection_entry_app_permission_dialog_title" msgid="9155535851866407199">"Chcete spustiť nahrávanie alebo prenos s aktivovaným povolením <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>?"</string>
<string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"Počas zdieľania, nahrávania alebo prenosu bude mať <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> prístup k všetkému, čo sa zobrazuje na obrazovke alebo prehráva v zariadení. Preto zvýšte pozornosť v prípade položiek, ako sú heslá, platobné údaje, správy, fotky a zvuk či video."</string>
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"Počas zdieľania, nahrávania alebo prenosu v aplikácii bude mať <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> prístup k všetkému, čo sa v danej aplikácii zobrazuje alebo prehráva. Preto zvýšte pozornosť v prípade položiek, ako sú heslá, platobné údaje, správy, fotky a zvuk či video."</string>
@@ -1046,8 +1046,7 @@
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Pri čítaní meradla batérie sa vyskytol problém"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Klepnutím si zobrazíte ďalšie informácie"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Žiadny budík"</string>
- <!-- no translation found for accessibility_bouncer (5896923685673320070) -->
- <skip />
+ <string name="accessibility_bouncer" msgid="5896923685673320070">"zadať zámku obrazovky"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Senzor odtlačkov prstov"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"overte"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"vstúpte do zariadenia"</string>
@@ -1127,18 +1126,12 @@
<string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Ďalšie informácie"</string>
<string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Viac sa dozviete na <xliff:g id="URL">%s</xliff:g>"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Otvoriť <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <!-- no translation found for wallet_quick_affordance_unavailable_install_the_app (7298552910007208368) -->
- <skip />
- <!-- no translation found for wallet_quick_affordance_unavailable_configure_the_app (4387433357429873258) -->
- <skip />
- <!-- no translation found for qr_scanner_quick_affordance_unavailable_explanation (3049582306241150946) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_install_the_app (6187820778998446168) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_configure_the_app (7953595390775156839) -->
- <skip />
- <!-- no translation found for notes_app_quick_affordance_unavailable_explanation (4796955161600178530) -->
- <skip />
+ <string name="wallet_quick_affordance_unavailable_install_the_app" msgid="7298552910007208368">"Ak chcete pridať aplikáciu Peňaženka ako odkaz, uistite sa, že je nainštalovaná"</string>
+ <string name="wallet_quick_affordance_unavailable_configure_the_app" msgid="4387433357429873258">"Ak chcete pridať aplikáciu Peňaženka ako odkaz, uistite sa, že bola pridaná aspoň jedna karta"</string>
+ <string name="qr_scanner_quick_affordance_unavailable_explanation" msgid="3049582306241150946">"Ak chcete pridať skener QR kódov ako odkaz, uistite, že je nainštalovaná aplikácia fotoaparátu"</string>
+ <string name="home_quick_affordance_unavailable_install_the_app" msgid="6187820778998446168">"Ak chcete pridať aplikáciu Home ako odkaz, uistite sa, že je nainštalovaná"</string>
+ <string name="home_quick_affordance_unavailable_configure_the_app" msgid="7953595390775156839">"• K dispozícii je minimálne jedno zariadenie"</string>
+ <string name="notes_app_quick_affordance_unavailable_explanation" msgid="4796955161600178530">"Ak chcete používať odkaz na písanie poznámok, vyberte predvolenú aplikáciu na písanie poznámok"</string>
<string name="keyguard_affordance_enablement_dialog_notes_app_action" msgid="6821710209675089470">"Výber aplikácie"</string>
<string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Pridržte skratku"</string>
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Zrušiť"</string>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 6bebdcc..4dd753b 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -1046,8 +1046,7 @@
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Težava z branjem indikatorja stanja napolnjenosti baterije"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Dotaknite se za več informacij"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Ni nastavljenih alarmov"</string>
- <!-- no translation found for accessibility_bouncer (5896923685673320070) -->
- <skip />
+ <string name="accessibility_bouncer" msgid="5896923685673320070">"odklenite zaslon"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Tipalo prstnih odtisov"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"preverjanje pristnosti"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"vstop v napravo"</string>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index 24d5fca..475e799 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -1046,8 +1046,7 @@
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problem me leximin e matësit të baterisë"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Trokit për më shumë informacione"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Nuk është caktuar asnjë alarm"</string>
- <!-- no translation found for accessibility_bouncer (5896923685673320070) -->
- <skip />
+ <string name="accessibility_bouncer" msgid="5896923685673320070">"hyr te kyçja e ekranit"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Sensori i gjurmës së gishtit"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"për ta vërtetuar"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"për të hyrë në pajisje"</string>
@@ -1127,18 +1126,12 @@
<string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Mëso më shumë"</string>
<string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Mëso më shumë në <xliff:g id="URL">%s</xliff:g>"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Hap \"<xliff:g id="APPNAME">%1$s</xliff:g>\""</string>
- <!-- no translation found for wallet_quick_affordance_unavailable_install_the_app (7298552910007208368) -->
- <skip />
- <!-- no translation found for wallet_quick_affordance_unavailable_configure_the_app (4387433357429873258) -->
- <skip />
- <!-- no translation found for qr_scanner_quick_affordance_unavailable_explanation (3049582306241150946) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_install_the_app (6187820778998446168) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_configure_the_app (7953595390775156839) -->
- <skip />
- <!-- no translation found for notes_app_quick_affordance_unavailable_explanation (4796955161600178530) -->
- <skip />
+ <string name="wallet_quick_affordance_unavailable_install_the_app" msgid="7298552910007208368">"Për të shtuar aplikacionin \"Portofoli\" si një shkurtore, sigurohu që aplikacioni të jetë i instaluar"</string>
+ <string name="wallet_quick_affordance_unavailable_configure_the_app" msgid="4387433357429873258">"Për të shtuar aplikacionin \"Portofoli\" si një shkurtore, sigurohu që të jetë shtuar të paktën një kartë"</string>
+ <string name="qr_scanner_quick_affordance_unavailable_explanation" msgid="3049582306241150946">"Për të shtuar skanerin e kodeve QR si një shkurtore, sigurohu që aplikacioni i kamerës të jetë i instaluar"</string>
+ <string name="home_quick_affordance_unavailable_install_the_app" msgid="6187820778998446168">"Për të shtuar aplikacionin Home si një shkurtore, sigurohu që aplikacioni të jetë i instaluar"</string>
+ <string name="home_quick_affordance_unavailable_configure_the_app" msgid="7953595390775156839">"• Ofrohet të paktën një pajisje"</string>
+ <string name="notes_app_quick_affordance_unavailable_explanation" msgid="4796955161600178530">"Zgjidh një aplikacion të parazgjedhur shënimesh për të përdorur shkurtoren e mbajtjes së shënimeve"</string>
<string name="keyguard_affordance_enablement_dialog_notes_app_action" msgid="6821710209675089470">"Zgjidh aplikacionin"</string>
<string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Prek dhe mbaj shtypur shkurtoren"</string>
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Anulo"</string>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 9ca97b9..eb69224 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -1046,8 +1046,7 @@
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Проблем са очитавањем мерача батерије"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Додирните за више информација"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Није подешен"</string>
- <!-- no translation found for accessibility_bouncer (5896923685673320070) -->
- <skip />
+ <string name="accessibility_bouncer" msgid="5896923685673320070">"унесите закључавање екрана"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Сензор за отисак прста"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"потврдите идентитет"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"унесите уређај"</string>
@@ -1127,18 +1126,12 @@
<string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Сазнајте више"</string>
<string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Сазнајте више на <xliff:g id="URL">%s</xliff:g>"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Отворите: <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <!-- no translation found for wallet_quick_affordance_unavailable_install_the_app (7298552910007208368) -->
- <skip />
- <!-- no translation found for wallet_quick_affordance_unavailable_configure_the_app (4387433357429873258) -->
- <skip />
- <!-- no translation found for qr_scanner_quick_affordance_unavailable_explanation (3049582306241150946) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_install_the_app (6187820778998446168) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_configure_the_app (7953595390775156839) -->
- <skip />
- <!-- no translation found for notes_app_quick_affordance_unavailable_explanation (4796955161600178530) -->
- <skip />
+ <string name="wallet_quick_affordance_unavailable_install_the_app" msgid="7298552910007208368">"Да бисте додали апликацију Новчаник као пречицу, уверите се да је апликација инсталирана"</string>
+ <string name="wallet_quick_affordance_unavailable_configure_the_app" msgid="4387433357429873258">"Да бисте додали апликацију Новчаник као пречицу, уверите се да је додата бар једна картица"</string>
+ <string name="qr_scanner_quick_affordance_unavailable_explanation" msgid="3049582306241150946">"Да бисте додали Скенер QR кода као пречицу, уверите се да је апликација за камеру инсталирана"</string>
+ <string name="home_quick_affordance_unavailable_install_the_app" msgid="6187820778998446168">"Да бисте додали апликацију Home као пречицу, уверите се да је апликација инсталирана"</string>
+ <string name="home_quick_affordance_unavailable_configure_the_app" msgid="7953595390775156839">"• Доступан је бар један уређај"</string>
+ <string name="notes_app_quick_affordance_unavailable_explanation" msgid="4796955161600178530">"Изаберите подразумевану апликацију за белешке да бисте користили пречицу за прављење белешки"</string>
<string name="keyguard_affordance_enablement_dialog_notes_app_action" msgid="6821710209675089470">"Изабери апликацију"</string>
<string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Додирните и задржите пречицу"</string>
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Откажи"</string>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 82468cb..7e2e006 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -1046,8 +1046,7 @@
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Batteriindikatorn visas inte"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Tryck för mer information"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Inget inställt alarm"</string>
- <!-- no translation found for accessibility_bouncer (5896923685673320070) -->
- <skip />
+ <string name="accessibility_bouncer" msgid="5896923685673320070">"ange skärmlåset"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Fingeravtryckssensor"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"autentisera"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"ange enhet"</string>
@@ -1127,18 +1126,12 @@
<string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Läs mer"</string>
<string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Läs mer på <xliff:g id="URL">%s</xliff:g>"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Öppna <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <!-- no translation found for wallet_quick_affordance_unavailable_install_the_app (7298552910007208368) -->
- <skip />
- <!-- no translation found for wallet_quick_affordance_unavailable_configure_the_app (4387433357429873258) -->
- <skip />
- <!-- no translation found for qr_scanner_quick_affordance_unavailable_explanation (3049582306241150946) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_install_the_app (6187820778998446168) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_configure_the_app (7953595390775156839) -->
- <skip />
- <!-- no translation found for notes_app_quick_affordance_unavailable_explanation (4796955161600178530) -->
- <skip />
+ <string name="wallet_quick_affordance_unavailable_install_the_app" msgid="7298552910007208368">"Se till att Wallet-appen är installerad om du vill lägga till den som genväg"</string>
+ <string name="wallet_quick_affordance_unavailable_configure_the_app" msgid="4387433357429873258">"Se till att minst ett kort har lagts till om du vill lägga till Wallet-appen som genväg"</string>
+ <string name="qr_scanner_quick_affordance_unavailable_explanation" msgid="3049582306241150946">"Se till att en kameraapp är installerad om du vill lägga till QR-skannern som genväg"</string>
+ <string name="home_quick_affordance_unavailable_install_the_app" msgid="6187820778998446168">"Se till att Home-appen är installerad om du vill lägga till den som genväg"</string>
+ <string name="home_quick_affordance_unavailable_configure_the_app" msgid="7953595390775156839">"• minst en enhet är tillgänglig"</string>
+ <string name="notes_app_quick_affordance_unavailable_explanation" msgid="4796955161600178530">"Välj en standardapp för anteckningar om du vill använda genvägen för anteckningar"</string>
<string name="keyguard_affordance_enablement_dialog_notes_app_action" msgid="6821710209675089470">"Välj app"</string>
<string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Tryck länge på genvägen"</string>
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Avbryt"</string>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index ef92eb6..676edb7 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -1046,8 +1046,7 @@
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Tatizo la kusoma mita ya betri yako"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Gusa ili upate maelezo zaidi"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Hujaweka kengele"</string>
- <!-- no translation found for accessibility_bouncer (5896923685673320070) -->
- <skip />
+ <string name="accessibility_bouncer" msgid="5896923685673320070">"weka kifunga skrini"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Kitambua alama ya kidole"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"thibitisha"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"weka kifaa"</string>
diff --git a/packages/SystemUI/res/values-sw720dp/dimens.xml b/packages/SystemUI/res/values-sw720dp/dimens.xml
index 2086459..d277dae 100644
--- a/packages/SystemUI/res/values-sw720dp/dimens.xml
+++ b/packages/SystemUI/res/values-sw720dp/dimens.xml
@@ -16,8 +16,15 @@
*/
-->
<resources>
+ <!-- padding for container with status icons and battery -->
+ <dimen name="status_bar_icons_padding_end">12dp</dimen>
+ <!-- it's a bit smaller on large screen to account for status_bar_icon_horizontal_margin -->
+ <dimen name="status_bar_icons_padding_start">10dp</dimen>
+
+ <dimen name="status_bar_padding_end">0dp</dimen>
+
<!-- gap on either side of status bar notification icons -->
- <dimen name="status_bar_icon_padding">1dp</dimen>
+ <dimen name="status_bar_icon_horizontal_margin">1dp</dimen>
<dimen name="controls_header_horizontal_padding">28dp</dimen>
<dimen name="controls_content_margin_horizontal">40dp</dimen>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index b277f55..390bd47 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -1046,8 +1046,7 @@
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"பேட்டரி அளவை அறிவதில் சிக்கல்"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"மேலும் தகவல்களுக்கு தட்டவும்"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"அலாரம் எதுவுமில்லை"</string>
- <!-- no translation found for accessibility_bouncer (5896923685673320070) -->
- <skip />
+ <string name="accessibility_bouncer" msgid="5896923685673320070">"திரைப் பூட்டை உள்ளிடலாம்"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"கைரேகை சென்சார்"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"அங்கீகரி"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"சாதனத்தைத் திற"</string>
@@ -1127,18 +1126,12 @@
<string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"மேலும் அறிக"</string>
<string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"மேலும் அறிக: <xliff:g id="URL">%s</xliff:g>"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> ஆப்ஸைத் திற"</string>
- <!-- no translation found for wallet_quick_affordance_unavailable_install_the_app (7298552910007208368) -->
- <skip />
- <!-- no translation found for wallet_quick_affordance_unavailable_configure_the_app (4387433357429873258) -->
- <skip />
- <!-- no translation found for qr_scanner_quick_affordance_unavailable_explanation (3049582306241150946) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_install_the_app (6187820778998446168) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_configure_the_app (7953595390775156839) -->
- <skip />
- <!-- no translation found for notes_app_quick_affordance_unavailable_explanation (4796955161600178530) -->
- <skip />
+ <string name="wallet_quick_affordance_unavailable_install_the_app" msgid="7298552910007208368">"Wallet ஆப்ஸை ஷார்ட்கட்டாகச் சேர்க்க, அந்த ஆப்ஸ் நிறுவப்பட்டுள்ளதை உறுதிசெய்துகொள்ளவும்"</string>
+ <string name="wallet_quick_affordance_unavailable_configure_the_app" msgid="4387433357429873258">"Wallet ஆப்ஸை ஷார்ட்கட்டாகச் சேர்க்க, அதில் குறைந்தது ஒரு கார்டாவது சேர்க்கப்பட்டுள்ளதை உறுதிசெய்துகொள்ளவும்"</string>
+ <string name="qr_scanner_quick_affordance_unavailable_explanation" msgid="3049582306241150946">"QR குறியீடு ஸ்கேனரை ஷார்ட்கட்டாகச் சேர்க்க, கேமரா ஆப்ஸ் நிறுவப்பட்டுள்ளதை உறுதிசெய்துகொள்ளவும்"</string>
+ <string name="home_quick_affordance_unavailable_install_the_app" msgid="6187820778998446168">"Home ஆப்ஸை ஷார்ட்கட்டாகச் சேர்க்க, அந்த ஆப்ஸ் நிறுவப்பட்டுள்ளதை உறுதிசெய்துகொள்ளவும்"</string>
+ <string name="home_quick_affordance_unavailable_configure_the_app" msgid="7953595390775156839">"• குறைந்தபட்சம் ஒரு சாதனமாவது இருக்கிறது"</string>
+ <string name="notes_app_quick_affordance_unavailable_explanation" msgid="4796955161600178530">"குறிப்பெடுத்தல் ஷார்ட்கட்டைப் பயன்படுத்த, குறிப்பெடுப்பதற்கான இயல்புநிலை ஆப்ஸைத் தேர்ந்தெடுக்கவும்"</string>
<string name="keyguard_affordance_enablement_dialog_notes_app_action" msgid="6821710209675089470">"ஆப்ஸைத் தேர்ந்தெடு"</string>
<string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"ஷார்ட்கட்டை தொட்டுப் பிடிக்கவும்"</string>
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"ரத்துசெய்"</string>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 4b15309..307d113 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -1046,8 +1046,7 @@
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"พบปัญหาในการอ่านเครื่องวัดแบตเตอรี่"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"แตะดูข้อมูลเพิ่มเติม"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"ไม่มีการตั้งปลุก"</string>
- <!-- no translation found for accessibility_bouncer (5896923685673320070) -->
- <skip />
+ <string name="accessibility_bouncer" msgid="5896923685673320070">"ป้อนข้อมูลการล็อกหน้าจอ"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"เซ็นเซอร์ลายนิ้วมือ"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"ตรวจสอบสิทธิ์"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"เข้าถึงอุปกรณ์"</string>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 395c07c..6962aa4 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -1046,8 +1046,7 @@
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Pil ölçeriniz okunurken sorun oluştu"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Daha fazla bilgi için dokunun"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Alarm yok"</string>
- <!-- no translation found for accessibility_bouncer (5896923685673320070) -->
- <skip />
+ <string name="accessibility_bouncer" msgid="5896923685673320070">"ekran kilidini gir"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Parmak izi sensörü"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"kimlik doğrulaması yapın"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"cihaz girin"</string>
@@ -1127,18 +1126,12 @@
<string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Daha fazla bilgi"</string>
<string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Daha fazla bilgiyi <xliff:g id="URL">%s</xliff:g> sayfasında bulabilirsiniz"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> uygulamasını aç"</string>
- <!-- no translation found for wallet_quick_affordance_unavailable_install_the_app (7298552910007208368) -->
- <skip />
- <!-- no translation found for wallet_quick_affordance_unavailable_configure_the_app (4387433357429873258) -->
- <skip />
- <!-- no translation found for qr_scanner_quick_affordance_unavailable_explanation (3049582306241150946) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_install_the_app (6187820778998446168) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_configure_the_app (7953595390775156839) -->
- <skip />
- <!-- no translation found for notes_app_quick_affordance_unavailable_explanation (4796955161600178530) -->
- <skip />
+ <string name="wallet_quick_affordance_unavailable_install_the_app" msgid="7298552910007208368">"Cüzdan uygulamasını kısayol olarak eklemek için uygulamanın yüklü olduğundan emin olun"</string>
+ <string name="wallet_quick_affordance_unavailable_configure_the_app" msgid="4387433357429873258">"Cüzdan uygulamasını kısayol olarak eklemek için en az bir kart eklendiğinden emin olun"</string>
+ <string name="qr_scanner_quick_affordance_unavailable_explanation" msgid="3049582306241150946">"QR kodu tarayıcıyı kısayol olarak eklemek için bir kamera uygulamasının yüklü olduğundan emin olun"</string>
+ <string name="home_quick_affordance_unavailable_install_the_app" msgid="6187820778998446168">"Home uygulamasını kısayol olarak eklemek için uygulamanın yüklü olduğundan emin olun"</string>
+ <string name="home_quick_affordance_unavailable_configure_the_app" msgid="7953595390775156839">"• En az bir cihaz mevcut olmalıdır"</string>
+ <string name="notes_app_quick_affordance_unavailable_explanation" msgid="4796955161600178530">"Not alma kısayolunu kullanmak için varsayılan bir notlar uygulaması seçin"</string>
<string name="keyguard_affordance_enablement_dialog_notes_app_action" msgid="6821710209675089470">"Uygulama seçin"</string>
<string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Kısayola dokunup basılı tutun"</string>
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"İptal"</string>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 86b609b..93807d0 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -1046,8 +1046,7 @@
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Не вдалось отримати дані про рівень заряду акумулятора"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Натисніть, щоб дізнатися більше"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Немає будильників"</string>
- <!-- no translation found for accessibility_bouncer (5896923685673320070) -->
- <skip />
+ <string name="accessibility_bouncer" msgid="5896923685673320070">"показати способи розблокування екрана"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Сканер відбитків пальців"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"пройти автентифікацію"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"відкрити пристрій"</string>
@@ -1127,18 +1126,12 @@
<string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Докладніше"</string>
<string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Докладніше: <xliff:g id="URL">%s</xliff:g>"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Відкрити <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <!-- no translation found for wallet_quick_affordance_unavailable_install_the_app (7298552910007208368) -->
- <skip />
- <!-- no translation found for wallet_quick_affordance_unavailable_configure_the_app (4387433357429873258) -->
- <skip />
- <!-- no translation found for qr_scanner_quick_affordance_unavailable_explanation (3049582306241150946) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_install_the_app (6187820778998446168) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_configure_the_app (7953595390775156839) -->
- <skip />
- <!-- no translation found for notes_app_quick_affordance_unavailable_explanation (4796955161600178530) -->
- <skip />
+ <string name="wallet_quick_affordance_unavailable_install_the_app" msgid="7298552910007208368">"Щоб додати ярлик для запуску додатка Google Гаманець, переконайтеся, що додаток установлено"</string>
+ <string name="wallet_quick_affordance_unavailable_configure_the_app" msgid="4387433357429873258">"Щоб додати ярлик для запуску додатка Google Гаманець, переконайтеся, що він містить дані принаймні однієї картки"</string>
+ <string name="qr_scanner_quick_affordance_unavailable_explanation" msgid="3049582306241150946">"Щоб додати ярлик для запуску сканера QR-коду, переконайтеся, що встановлено додаток для камери"</string>
+ <string name="home_quick_affordance_unavailable_install_the_app" msgid="6187820778998446168">"Щоб додати ярлик для запуску додатка Google Home, переконайтеся, що додаток установлено"</string>
+ <string name="home_quick_affordance_unavailable_configure_the_app" msgid="7953595390775156839">"• Принаймні один пристрій доступний"</string>
+ <string name="notes_app_quick_affordance_unavailable_explanation" msgid="4796955161600178530">"Виберіть стандартний додаток для нотаток, щоб створювати їх за допомогою ярлика"</string>
<string name="keyguard_affordance_enablement_dialog_notes_app_action" msgid="6821710209675089470">"Вибрати додаток"</string>
<string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Натисніть і утримуйте ярлик"</string>
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Скасувати"</string>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index 2069d26..ff4965f 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -1046,8 +1046,7 @@
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"آپ کے بیٹری میٹر کو پڑھنے میں دشواری"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"مزید معلومات کے لیے تھپتھپائیں"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"کوئی الارم سیٹ نہیں ہے"</string>
- <!-- no translation found for accessibility_bouncer (5896923685673320070) -->
- <skip />
+ <string name="accessibility_bouncer" msgid="5896923685673320070">"اسکرین لاک درج کریں"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"فنگر پرنٹ سینسر"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"تصدیق کریں"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"آلہ درج کریں"</string>
@@ -1127,18 +1126,12 @@
<string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"مزید جانیں"</string>
<string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"مزید جاننے کیلئے <xliff:g id="URL">%s</xliff:g> ملاحظہ کریں"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"<xliff:g id="APPNAME">%1$s</xliff:g> کھولیں"</string>
- <!-- no translation found for wallet_quick_affordance_unavailable_install_the_app (7298552910007208368) -->
- <skip />
- <!-- no translation found for wallet_quick_affordance_unavailable_configure_the_app (4387433357429873258) -->
- <skip />
- <!-- no translation found for qr_scanner_quick_affordance_unavailable_explanation (3049582306241150946) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_install_the_app (6187820778998446168) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_configure_the_app (7953595390775156839) -->
- <skip />
- <!-- no translation found for notes_app_quick_affordance_unavailable_explanation (4796955161600178530) -->
- <skip />
+ <string name="wallet_quick_affordance_unavailable_install_the_app" msgid="7298552910007208368">"والٹ ایپ کو شارٹ کٹ کے طور پر شامل کرنے کے لیے، یقینی بنائیں کہ ایپ انسٹال ہے"</string>
+ <string name="wallet_quick_affordance_unavailable_configure_the_app" msgid="4387433357429873258">"والٹ ایپ کو شارٹ کٹ کے طور پر شامل کرنے کے لیے، یقینی بنائیں کہ کم از کم ایک کارڈ شامل کیا گیا ہے"</string>
+ <string name="qr_scanner_quick_affordance_unavailable_explanation" msgid="3049582306241150946">"QR کوڈ اسکینر کو شارٹ کٹ کے طور پر شامل کرنے کے لیے، یقینی بنائیں کہ کیمرا ایپ انسٹال ہے"</string>
+ <string name="home_quick_affordance_unavailable_install_the_app" msgid="6187820778998446168">"ہوم ایپ کو شارٹ کٹ کے طور پر شامل کرنے کے لیے، یقینی بنائیں کہ ایپ انسٹال ہے"</string>
+ <string name="home_quick_affordance_unavailable_configure_the_app" msgid="7953595390775156839">"• کم از کم ایک آلہ دستیاب ہے"</string>
+ <string name="notes_app_quick_affordance_unavailable_explanation" msgid="4796955161600178530">"نوٹ لینے والے شارٹ کٹ کا استعمال کرنے کے لیے ڈیفالٹ نوٹس ایپ منتخب کریں"</string>
<string name="keyguard_affordance_enablement_dialog_notes_app_action" msgid="6821710209675089470">"ایپ منتخب کریں"</string>
<string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"شارٹ کٹ ٹچ کریں اور دبائے رکھیں"</string>
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"منسوخ کریں"</string>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index e6a9414..538fe16d 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -176,7 +176,7 @@
<string name="fingerprint_reenroll_failure_dialog_content" msgid="4733768492747300666">"Barmoq izi bilan ochish sozlanmadi. Sozlamalarni ochib, qaytadan urining."</string>
<string name="face_re_enroll_notification_title" msgid="1850838867718410520">"Yuz bilan ochishni qayta sozlash"</string>
<string name="face_re_enroll_notification_name" msgid="7384545252206120659">"Yuz bilan ochish"</string>
- <string name="face_re_enroll_dialog_title" msgid="6392173708176069994">"Yuz bilan ochish funksiyasini sozlash"</string>
+ <string name="face_re_enroll_dialog_title" msgid="6392173708176069994">"Yuz bilan ochishni sozlash"</string>
<string name="face_re_enroll_dialog_content" msgid="7353502359464038511">"Yuz bilan ochish funksiyasini qayta sozlash uchun joriy yuz modelingiz oʻchirib tashlanadi.\n\nTelefonni qulfdan chiqarish maqsadida yuzingizdan foydalanish uchun bu funksiyani qayta sozlashingiz kerak."</string>
<string name="face_reenroll_failure_dialog_content" msgid="7073947334397236935">"Yuz bilan ochish sozlanmadimi. Sozlamalarni ochib, qaytadan urining."</string>
<string name="fingerprint_dialog_touch_sensor" msgid="2817887108047658975">"Barmoq izi skaneriga tegining"</string>
@@ -1046,8 +1046,7 @@
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Batareya quvvati aniqlanmadi"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Batafsil axborot olish uchun bosing"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Signal sozlanmagan"</string>
- <!-- no translation found for accessibility_bouncer (5896923685673320070) -->
- <skip />
+ <string name="accessibility_bouncer" msgid="5896923685673320070">"ekran qulfini kiriting"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Barmoq izi skaneri"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"autentifikatsiya"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"qurilmani ochish"</string>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 33ae91e..4120e57e 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -399,7 +399,7 @@
<string name="media_projection_sys_service_dialog_warning" msgid="2443872865267330320">"Dịch vụ cung cấp chức năng này có quyền truy cập vào tất cả thông tin xuất hiện trên màn hình của bạn hoặc phát trên thiết bị của bạn trong khi ghi hoặc truyền, bao gồm cả thông tin như mật khẩu, thông tin thanh toán, ảnh, tin nhắn và âm thanh mà bạn phát."</string>
<string name="screen_share_permission_dialog_option_entire_screen" msgid="3131200488455089620">"Toàn màn hình"</string>
<string name="screen_share_permission_dialog_option_single_app" msgid="4350961814397220929">"Một ứng dụng"</string>
- <string name="screen_share_permission_app_selector_title" msgid="1404878013670347899">"Chia sẻ hoặc ghi ứng dụng"</string>
+ <string name="screen_share_permission_app_selector_title" msgid="1404878013670347899">"Chia sẻ hoặc ghi màn hình ứng dụng"</string>
<string name="media_projection_entry_app_permission_dialog_title" msgid="9155535851866407199">"Bắt đầu ghi hoặc truyền bằng <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>?"</string>
<string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"Khi bạn chia sẻ, ghi hoặc truyền, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> sẽ có quyền truy cập vào mọi nội dung xuất hiện trên màn hình hoặc phát trên thiết bị của bạn. Vì vậy, hãy thận trọng để không làm lộ thông tin như mật khẩu, thông tin thanh toán, tin nhắn, ảnh, âm thanh và video."</string>
<string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"Khi bạn chia sẻ, ghi hoặc truyền ứng dụng, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> sẽ có quyền truy cập vào mọi nội dung xuất hiện hoặc phát trên ứng dụng đó. Vì vậy, hãy thận trọng để không làm lộ các thông tin như mật khẩu, thông tin thanh toán, tin nhắn, ảnh, âm thanh và video."</string>
@@ -1046,8 +1046,7 @@
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Đã xảy ra vấn đề khi đọc dung lượng pin của bạn"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Nhấn để biết thêm thông tin"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Chưa đặt chuông báo"</string>
- <!-- no translation found for accessibility_bouncer (5896923685673320070) -->
- <skip />
+ <string name="accessibility_bouncer" msgid="5896923685673320070">"nhập phương thức mở khoá màn hình"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Cảm biến vân tay"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"xác thực"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"truy cập thiết bị"</string>
@@ -1127,18 +1126,12 @@
<string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Tìm hiểu thêm"</string>
<string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Tìm hiểu thêm tại <xliff:g id="URL">%s</xliff:g>"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Mở <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <!-- no translation found for wallet_quick_affordance_unavailable_install_the_app (7298552910007208368) -->
- <skip />
- <!-- no translation found for wallet_quick_affordance_unavailable_configure_the_app (4387433357429873258) -->
- <skip />
- <!-- no translation found for qr_scanner_quick_affordance_unavailable_explanation (3049582306241150946) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_install_the_app (6187820778998446168) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_configure_the_app (7953595390775156839) -->
- <skip />
- <!-- no translation found for notes_app_quick_affordance_unavailable_explanation (4796955161600178530) -->
- <skip />
+ <string name="wallet_quick_affordance_unavailable_install_the_app" msgid="7298552910007208368">"Để tạo lối tắt cho ứng dụng Wallet, hãy đảm bảo bạn đã cài đặt ứng dụng đó"</string>
+ <string name="wallet_quick_affordance_unavailable_configure_the_app" msgid="4387433357429873258">"Để tạo lối tắt cho ứng dụng Wallet, hãy đảm bảo bạn đã thêm ít nhất một thẻ"</string>
+ <string name="qr_scanner_quick_affordance_unavailable_explanation" msgid="3049582306241150946">"Để tạo lối tắt cho Trình quét mã QR, hãy đảm bảo rằng bạn đã cài đặt một ứng dụng máy ảnh"</string>
+ <string name="home_quick_affordance_unavailable_install_the_app" msgid="6187820778998446168">"Để tạo lối tắt cho ứng dụng Home, hãy đảm bảo bạn đã cài đặt ứng dụng đó"</string>
+ <string name="home_quick_affordance_unavailable_configure_the_app" msgid="7953595390775156839">"• Có ít nhất một thiết bị đang hoạt động"</string>
+ <string name="notes_app_quick_affordance_unavailable_explanation" msgid="4796955161600178530">"Chọn một ứng dụng ghi chú mặc định để dùng lối tắt ghi chú"</string>
<string name="keyguard_affordance_enablement_dialog_notes_app_action" msgid="6821710209675089470">"Chọn ứng dụng"</string>
<string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Chạm và giữ phím tắt"</string>
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Huỷ"</string>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index 6c6f504..4066a89 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -1126,18 +1126,12 @@
<string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"瞭解詳情"</string>
<string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"詳情請瀏覽 <xliff:g id="URL">%s</xliff:g>"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"開啟「<xliff:g id="APPNAME">%1$s</xliff:g>」"</string>
- <!-- no translation found for wallet_quick_affordance_unavailable_install_the_app (7298552910007208368) -->
- <skip />
- <!-- no translation found for wallet_quick_affordance_unavailable_configure_the_app (4387433357429873258) -->
- <skip />
- <!-- no translation found for qr_scanner_quick_affordance_unavailable_explanation (3049582306241150946) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_install_the_app (6187820778998446168) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_configure_the_app (7953595390775156839) -->
- <skip />
- <!-- no translation found for notes_app_quick_affordance_unavailable_explanation (4796955161600178530) -->
- <skip />
+ <string name="wallet_quick_affordance_unavailable_install_the_app" msgid="7298552910007208368">"如要將「錢包」應用程式新增為捷徑,請確認已安裝該應用程式"</string>
+ <string name="wallet_quick_affordance_unavailable_configure_the_app" msgid="4387433357429873258">"如要將「錢包」應用程式新增為捷徑,請確認已新增至少一張付款卡"</string>
+ <string name="qr_scanner_quick_affordance_unavailable_explanation" msgid="3049582306241150946">"如要將 QR 碼掃瞄器新增為捷徑,請確認已安裝相機應用程式"</string>
+ <string name="home_quick_affordance_unavailable_install_the_app" msgid="6187820778998446168">"如要將 Home 應用程式新增為捷徑,請確認已安裝該應用程式"</string>
+ <string name="home_quick_affordance_unavailable_configure_the_app" msgid="7953595390775156839">"• 至少一部裝置可用"</string>
+ <string name="notes_app_quick_affordance_unavailable_explanation" msgid="4796955161600178530">"選取預設的筆記應用程式,即可使用筆記捷徑"</string>
<string name="keyguard_affordance_enablement_dialog_notes_app_action" msgid="6821710209675089470">"選取應用程式"</string>
<string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"輕觸並按住快速鍵"</string>
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"取消"</string>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 888908a..7abe1de 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -770,8 +770,8 @@
<string name="high_temp_alarm_title" msgid="8654754369605452169">"拔除裝置"</string>
<string name="high_temp_alarm_notify_message" msgid="3917622943609118956">"裝置的充電埠附近越來越熱。如果裝置已連接充電器或 USB 配件,請立即拔除。此外,電線也可能會變熱,請特別留意。"</string>
<string name="high_temp_alarm_help_care_steps" msgid="5017002218341329566">"查看處理步驟"</string>
- <string name="lockscreen_shortcut_left" msgid="1238765178956067599">"向左快速鍵"</string>
- <string name="lockscreen_shortcut_right" msgid="4138414674531853719">"向右快速鍵"</string>
+ <string name="lockscreen_shortcut_left" msgid="1238765178956067599">"左側捷徑"</string>
+ <string name="lockscreen_shortcut_right" msgid="4138414674531853719">"右側捷徑"</string>
<string name="lockscreen_unlock_left" msgid="1417801334370269374">"向左快速鍵可一併解鎖裝置"</string>
<string name="lockscreen_unlock_right" msgid="4658008735541075346">"向右快速鍵可一併解鎖裝置"</string>
<string name="lockscreen_none" msgid="4710862479308909198">"無"</string>
@@ -1126,18 +1126,12 @@
<string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"瞭解詳情"</string>
<string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"如要瞭解詳情,請前往 <xliff:g id="URL">%s</xliff:g>"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"開啟「<xliff:g id="APPNAME">%1$s</xliff:g>」"</string>
- <!-- no translation found for wallet_quick_affordance_unavailable_install_the_app (7298552910007208368) -->
- <skip />
- <!-- no translation found for wallet_quick_affordance_unavailable_configure_the_app (4387433357429873258) -->
- <skip />
- <!-- no translation found for qr_scanner_quick_affordance_unavailable_explanation (3049582306241150946) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_install_the_app (6187820778998446168) -->
- <skip />
- <!-- no translation found for home_quick_affordance_unavailable_configure_the_app (7953595390775156839) -->
- <skip />
- <!-- no translation found for notes_app_quick_affordance_unavailable_explanation (4796955161600178530) -->
- <skip />
+ <string name="wallet_quick_affordance_unavailable_install_the_app" msgid="7298552910007208368">"如要將錢包應用程式新增為捷徑,請確認已安裝該應用程式"</string>
+ <string name="wallet_quick_affordance_unavailable_configure_the_app" msgid="4387433357429873258">"如要將錢包應用程式新增為捷徑,請確認已新增至少一張卡片"</string>
+ <string name="qr_scanner_quick_affordance_unavailable_explanation" msgid="3049582306241150946">"如要將 QR code 掃描器新增為捷徑,請確認已安裝相機應用程式"</string>
+ <string name="home_quick_affordance_unavailable_install_the_app" msgid="6187820778998446168">"如要將 Google Home 應用程式新增為捷徑,請確認已安裝該應用程式"</string>
+ <string name="home_quick_affordance_unavailable_configure_the_app" msgid="7953595390775156839">"• 至少要有一部可用裝置"</string>
+ <string name="notes_app_quick_affordance_unavailable_explanation" msgid="4796955161600178530">"選取預設的記事應用程式,即可使用筆記捷徑"</string>
<string name="keyguard_affordance_enablement_dialog_notes_app_action" msgid="6821710209675089470">"選取應用程式"</string>
<string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"按住快速鍵"</string>
<string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"取消"</string>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index e57e60b..e5b4c14 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -1046,8 +1046,7 @@
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Kube khona inkinga ngokufunda imitha yakho yebhethri"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Thepha ukuze uthole olunye ulwazi"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Akukho alamu esethiwe"</string>
- <!-- no translation found for accessibility_bouncer (5896923685673320070) -->
- <skip />
+ <string name="accessibility_bouncer" msgid="5896923685673320070">"faka ukukhiya isikrini"</string>
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Inzwa yesigxivizo somunwe"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"gunyaza"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"faka idivayisi"</string>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 421f41f..9c864ab 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -698,6 +698,10 @@
-->
<integer name="config_face_auth_supported_posture">0</integer>
+ <!-- Components to allow running fingerprint listening if their activity is occluding the lock screen. -->
+ <string-array name="config_fingerprint_listen_on_occluding_activity_packages" translatable="false">
+ </string-array>
+
<!-- Whether the communal service should be enabled -->
<bool name="config_communalServiceEnabled">false</bool>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index da6417d..3bd7a06 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -326,8 +326,16 @@
<!-- opacity at which Notification icons will be drawn in the status bar -->
<item type="dimen" name="status_bar_icon_drawing_alpha">90%</item>
+ <!-- paddings for container with status icons and battery -->
+ <!-- padding start is a bit smaller than end to account for status icon margin-->
+ <dimen name="status_bar_icons_padding_start">11dp</dimen>
+
+ <dimen name="status_bar_icons_padding_end">0dp</dimen>
+ <dimen name="status_bar_icons_padding_bottom">8dp</dimen>
+ <dimen name="status_bar_icons_padding_top">8dp</dimen>
+
<!-- gap on either side of status bar notification icons -->
- <dimen name="status_bar_icon_padding">0dp</dimen>
+ <dimen name="status_bar_icon_horizontal_margin">0dp</dimen>
<!-- the padding on the start of the statusbar -->
<dimen name="status_bar_padding_start">8dp</dimen>
@@ -1560,7 +1568,8 @@
<!-- Status bar user chip -->
<dimen name="status_bar_user_chip_avatar_size">16dp</dimen>
- <dimen name="status_bar_user_chip_end_margin">12dp</dimen>
+ <!-- below also works as break between user chip and hover state of status icons -->
+ <dimen name="status_bar_user_chip_end_margin">4dp</dimen>
<dimen name="status_bar_user_chip_text_size">12sp</dimen>
<!-- System UI Dialog -->
diff --git a/packages/SystemUI/res/values/ids.xml b/packages/SystemUI/res/values/ids.xml
index d651a21..134a7a9 100644
--- a/packages/SystemUI/res/values/ids.xml
+++ b/packages/SystemUI/res/values/ids.xml
@@ -211,4 +211,6 @@
<item type="id" name="keyguard_indication_area" />
<item type="id" name="keyguard_indication_text" />
<item type="id" name="keyguard_indication_text_bottom" />
+ <item type="id" name="lock_icon" />
+ <item type="id" name="lock_icon_bg" />
</resources>
diff --git a/packages/SystemUI/res/xml/combined_qs_header_scene.xml b/packages/SystemUI/res/xml/combined_qs_header_scene.xml
index 8512f6f..c167256 100644
--- a/packages/SystemUI/res/xml/combined_qs_header_scene.xml
+++ b/packages/SystemUI/res/xml/combined_qs_header_scene.xml
@@ -53,56 +53,28 @@
android:alpha="0"
/>
<KeyPosition
+ app:motionTarget="@id/shade_header_system_icons"
app:keyPositionType="deltaRelative"
app:percentX="0"
app:percentY="@dimen/percent_displacement_at_fade_out"
app:framePosition="@integer/fade_out_complete_frame"
app:sizePercent="0"
- app:curveFit="linear"
- app:motionTarget="@id/statusIcons" />
+ app:curveFit="linear" />
<KeyPosition
+ app:motionTarget="@id/shade_header_system_icons"
app:keyPositionType="deltaRelative"
app:percentX="1"
app:percentY="0.5"
app:framePosition="50"
app:sizePercent="1"
- app:curveFit="linear"
- app:motionTarget="@id/statusIcons" />
+ app:curveFit="linear" />
<KeyAttribute
- app:motionTarget="@id/statusIcons"
+ app:motionTarget="@id/shade_header_system_icons"
app:framePosition="@integer/fade_out_complete_frame"
android:alpha="0"
/>
<KeyAttribute
- app:motionTarget="@id/statusIcons"
- app:framePosition="@integer/fade_in_start_frame"
- android:alpha="0"
- />
- <KeyPosition
- app:keyPositionType="deltaRelative"
- app:percentX="0"
- app:percentY="@dimen/percent_displacement_at_fade_out"
- app:framePosition="@integer/fade_out_complete_frame"
- app:percentWidth="1"
- app:percentHeight="1"
- app:curveFit="linear"
- app:motionTarget="@id/batteryRemainingIcon" />
- <KeyPosition
- app:keyPositionType="deltaRelative"
- app:percentX="1"
- app:percentY="0.5"
- app:framePosition="50"
- app:percentWidth="1"
- app:percentHeight="1"
- app:curveFit="linear"
- app:motionTarget="@id/batteryRemainingIcon" />
- <KeyAttribute
- app:motionTarget="@id/batteryRemainingIcon"
- app:framePosition="@integer/fade_out_complete_frame"
- android:alpha="0"
- />
- <KeyAttribute
- app:motionTarget="@id/batteryRemainingIcon"
+ app:motionTarget="@id/shade_header_system_icons"
app:framePosition="@integer/fade_in_start_frame"
android:alpha="0"
/>
diff --git a/packages/SystemUI/res/xml/large_screen_shade_header.xml b/packages/SystemUI/res/xml/large_screen_shade_header.xml
index bf576dc..39f4c81 100644
--- a/packages/SystemUI/res/xml/large_screen_shade_header.xml
+++ b/packages/SystemUI/res/xml/large_screen_shade_header.xml
@@ -45,7 +45,7 @@
android:layout_height="0dp"
android:layout_gravity="end|center_vertical"
app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintEnd_toStartOf="@id/statusIcons"
+ app:layout_constraintEnd_toStartOf="@id/shade_header_system_icons"
app:layout_constraintStart_toEndOf="@id/date"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_default="wrap"
@@ -53,28 +53,17 @@
<PropertySet android:alpha="1" />
</Constraint>
- <Constraint android:id="@+id/statusIcons">
+ <Constraint android:id="@+id/shade_header_system_icons">
<Layout
android:layout_width="wrap_content"
android:layout_height="@dimen/large_screen_shade_header_min_height"
app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintEnd_toStartOf="@id/batteryRemainingIcon"
+ app:layout_constraintEnd_toStartOf="@id/privacy_container"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="@id/carrier_group"/>
<PropertySet android:alpha="1" />
</Constraint>
- <Constraint android:id="@+id/batteryRemainingIcon">
- <Layout
- android:layout_width="wrap_content"
- android:layout_height="0dp"
- app:layout_constraintHeight_min="@dimen/large_screen_shade_header_min_height"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintEnd_toStartOf="@id/privacy_container"
- app:layout_constraintTop_toTopOf="parent" />
- <PropertySet android:alpha="1" />
- </Constraint>
-
<Constraint android:id="@+id/privacy_container">
<Layout
android:layout_width="wrap_content"
diff --git a/packages/SystemUI/res/xml/qqs_header.xml b/packages/SystemUI/res/xml/qqs_header.xml
index 1950965..50a388d 100644
--- a/packages/SystemUI/res/xml/qqs_header.xml
+++ b/packages/SystemUI/res/xml/qqs_header.xml
@@ -54,27 +54,12 @@
</Constraint>
<Constraint
- android:id="@+id/statusIcons">
+ android:id="@+id/shade_header_system_icons">
<Layout
android:layout_width="wrap_content"
android:layout_height="@dimen/new_qs_header_non_clickable_element_height"
app:layout_constraintHeight_min="@dimen/new_qs_header_non_clickable_element_height"
app:layout_constraintStart_toEndOf="@id/date"
- app:layout_constraintEnd_toStartOf="@id/batteryRemainingIcon"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintBottom_toBottomOf="@id/qqs_header_bottom_guideline"
- app:layout_constraintHorizontal_bias="1"
- app:layout_constraintHorizontal_chainStyle="packed"
- />
- </Constraint>
-
- <Constraint
- android:id="@+id/batteryRemainingIcon">
- <Layout
- android:layout_width="wrap_content"
- android:layout_height="@dimen/new_qs_header_non_clickable_element_height"
- app:layout_constraintHeight_min="@dimen/new_qs_header_non_clickable_element_height"
- app:layout_constraintStart_toEndOf="@id/statusIcons"
app:layout_constraintEnd_toEndOf="@id/end_guide"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="@id/qqs_header_bottom_guideline"
diff --git a/packages/SystemUI/res/xml/qs_header.xml b/packages/SystemUI/res/xml/qs_header.xml
index 8039c68..7b4282f 100644
--- a/packages/SystemUI/res/xml/qs_header.xml
+++ b/packages/SystemUI/res/xml/qs_header.xml
@@ -59,7 +59,7 @@
/>
</Constraint>
- <!-- LargeScreenShadeHeaderController helps with managing clock width to layout this view -->
+ <!-- ShadeHeaderController helps with managing clock width to layout this view -->
<Constraint
android:id="@+id/carrier_group">
<Layout
@@ -78,25 +78,11 @@
</Constraint>
<Constraint
- android:id="@+id/statusIcons">
+ android:id="@+id/shade_header_system_icons">
<Layout
android:layout_width="0dp"
android:layout_height="@dimen/new_qs_header_non_clickable_element_height"
app:layout_constraintWidth_default="wrap"
- app:layout_constraintStart_toEndOf="@id/date"
- app:layout_constraintEnd_toStartOf="@id/batteryRemainingIcon"
- app:layout_constraintTop_toTopOf="@id/date"
- app:layout_constraintBottom_toBottomOf="@id/date"
- />
- </Constraint>
-
- <Constraint
- android:id="@+id/batteryRemainingIcon">
- <Layout
- android:layout_width="0dp"
- android:layout_height="@dimen/new_qs_header_non_clickable_element_height"
- app:layout_constraintWidth_default="wrap"
- app:layout_constraintHeight_min="@dimen/new_qs_header_non_clickable_element_height"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/date"
app:layout_constraintBottom_toBottomOf="@id/date"
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/InteractionJankMonitorWrapper.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/InteractionJankMonitorWrapper.java
index 4269530..c844db7 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/InteractionJankMonitorWrapper.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/InteractionJankMonitorWrapper.java
@@ -61,6 +61,8 @@
InteractionJankMonitor.CUJ_LAUNCHER_APP_SWIPE_TO_RECENTS;
public static final int CUJ_OPEN_SEARCH_RESULT =
InteractionJankMonitor.CUJ_LAUNCHER_OPEN_SEARCH_RESULT;
+ public static final int CUJ_SHADE_EXPAND_FROM_STATUS_BAR =
+ InteractionJankMonitor.CUJ_SHADE_EXPAND_FROM_STATUS_BAR;
@IntDef({
CUJ_APP_LAUNCH_FROM_RECENTS,
@@ -76,6 +78,7 @@
CUJ_CLOSE_ALL_APPS_SWIPE,
CUJ_CLOSE_ALL_APPS_TO_HOME,
CUJ_OPEN_SEARCH_RESULT,
+ CUJ_SHADE_EXPAND_FROM_STATUS_BAR,
})
@Retention(RetentionPolicy.SOURCE)
public @interface CujType {
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardFingerprintListenModel.kt b/packages/SystemUI/src/com/android/keyguard/KeyguardFingerprintListenModel.kt
index f2685c5..f23ae67 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardFingerprintListenModel.kt
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardFingerprintListenModel.kt
@@ -27,6 +27,7 @@
override var userId: Int = 0,
override var listening: Boolean = false,
// keepSorted
+ var allowOnCurrentOccludingActivity: Boolean = false,
var alternateBouncerShowing: Boolean = false,
var biometricEnabledForUser: Boolean = false,
var bouncerIsOrWillShow: Boolean = false,
@@ -58,6 +59,7 @@
userId.toString(),
listening.toString(),
// keep sorted
+ allowOnCurrentOccludingActivity.toString(),
alternateBouncerShowing.toString(),
biometricEnabledForUser.toString(),
bouncerIsOrWillShow.toString(),
@@ -98,6 +100,7 @@
userId = model.userId
listening = model.listening
// keep sorted
+ allowOnCurrentOccludingActivity = model.allowOnCurrentOccludingActivity
alternateBouncerShowing = model.alternateBouncerShowing
biometricEnabledForUser = model.biometricEnabledForUser
bouncerIsOrWillShow = model.bouncerIsOrWillShow
@@ -144,6 +147,7 @@
"userId",
"listening",
// keep sorted
+ "allowOnCurrentOccludingActivity",
"alternateBouncerShowing",
"biometricAllowedForUser",
"bouncerIsOrWillShow",
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java
index ad9fea6..49f788c 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java
@@ -236,6 +236,7 @@
getKeyguardSecurityCallback().onCancelClicked();
});
}
+ mView.onDevicePostureChanged(mPostureController.getDevicePosture());
mPostureController.addCallback(mPostureCallback);
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 90401cb..56e90bf 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -18,6 +18,8 @@
import static android.app.StatusBarManager.SESSION_KEYGUARD;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.content.Intent.ACTION_USER_REMOVED;
import static android.content.Intent.ACTION_USER_STOPPED;
@@ -76,9 +78,9 @@
import android.annotation.AnyThread;
import android.annotation.MainThread;
import android.annotation.SuppressLint;
-import android.app.ActivityTaskManager;
import android.app.ActivityTaskManager.RootTaskInfo;
import android.app.AlarmManager;
+import android.app.IActivityTaskManager;
import android.app.admin.DevicePolicyManager;
import android.app.trust.TrustManager;
import android.content.BroadcastReceiver;
@@ -305,6 +307,7 @@
private final AuthController mAuthController;
private final UiEventLogger mUiEventLogger;
private final Set<Integer> mFaceAcquiredInfoIgnoreList;
+ private final Set<String> mAllowFingerprintOnOccludingActivitiesFromPackage;
private final PackageManager mPackageManager;
private int mStatusBarState;
private final StatusBarStateController.StateListener mStatusBarStateControllerListener =
@@ -346,6 +349,7 @@
private boolean mSecureCameraLaunched;
@VisibleForTesting
protected boolean mTelephonyCapable;
+ private boolean mAllowFingerprintOnCurrentOccludingActivity;
// Device provisioning state
private boolean mDeviceProvisioned;
@@ -389,6 +393,8 @@
private final FaceManager mFaceManager;
@Nullable
private KeyguardFaceAuthInteractor mFaceAuthInteractor;
+ private final TaskStackChangeListeners mTaskStackChangeListeners;
+ private final IActivityTaskManager mActivityTaskManager;
private final LockPatternUtils mLockPatternUtils;
@VisibleForTesting
@DevicePostureInt
@@ -2322,7 +2328,9 @@
FaceWakeUpTriggersConfig faceWakeUpTriggersConfig,
DevicePostureController devicePostureController,
Optional<FingerprintInteractiveToAuthProvider> interactiveToAuthProvider,
- FeatureFlags featureFlags) {
+ FeatureFlags featureFlags,
+ TaskStackChangeListeners taskStackChangeListeners,
+ IActivityTaskManager activityTaskManagerService) {
mContext = context;
mSubscriptionManager = subscriptionManager;
mUserTracker = userTracker;
@@ -2364,6 +2372,12 @@
mConfigFaceAuthSupportedPosture = mContext.getResources().getInteger(
R.integer.config_face_auth_supported_posture);
mFaceWakeUpTriggersConfig = faceWakeUpTriggersConfig;
+ mAllowFingerprintOnOccludingActivitiesFromPackage = Arrays.stream(
+ mContext.getResources().getStringArray(
+ R.array.config_fingerprint_listen_on_occluding_activity_packages))
+ .collect(Collectors.toSet());
+ mTaskStackChangeListeners = taskStackChangeListeners;
+ mActivityTaskManager = activityTaskManagerService;
mHandler = new Handler(mainLooper) {
@Override
@@ -2579,7 +2593,7 @@
}
updateBiometricListeningState(BIOMETRIC_ACTION_UPDATE, FACE_AUTH_UPDATED_ON_KEYGUARD_INIT);
- TaskStackChangeListeners.getInstance().registerTaskStackListener(mTaskStackListener);
+ mTaskStackChangeListeners.registerTaskStackListener(mTaskStackListener);
mIsSystemUser = mUserManager.isSystemUser();
int user = mUserTracker.getUserId();
mUserIsUnlocked.put(user, mUserManager.isUserUnlocked(user));
@@ -3049,7 +3063,7 @@
&& (mOccludingAppRequestingFp
|| isUdfps
|| mAlternateBouncerShowing
- || mFeatureFlags.isEnabled(Flags.FP_LISTEN_OCCLUDING_APPS)
+ || mAllowFingerprintOnCurrentOccludingActivity
)
);
@@ -3092,6 +3106,7 @@
System.currentTimeMillis(),
user,
shouldListen,
+ mAllowFingerprintOnCurrentOccludingActivity,
mAlternateBouncerShowing,
biometricEnabledForUser,
mPrimaryBouncerIsOrWillBeShowing,
@@ -4120,19 +4135,35 @@
return mSimDatas.get(subId).slotId;
}
- private final TaskStackChangeListener
- mTaskStackListener = new TaskStackChangeListener() {
+ private final TaskStackChangeListener mTaskStackListener = new TaskStackChangeListener() {
@Override
public void onTaskStackChangedBackground() {
try {
- RootTaskInfo info = ActivityTaskManager.getService().getRootTaskInfo(
+ if (mFeatureFlags.isEnabled(Flags.FP_LISTEN_OCCLUDING_APPS)) {
+ RootTaskInfo standardTask = mActivityTaskManager.getRootTaskInfo(
+ WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
+ final boolean previousState = mAllowFingerprintOnCurrentOccludingActivity;
+ mAllowFingerprintOnCurrentOccludingActivity =
+ standardTask.topActivity != null
+ && !TextUtils.isEmpty(standardTask.topActivity.getPackageName())
+ && mAllowFingerprintOnOccludingActivitiesFromPackage.contains(
+ standardTask.topActivity.getPackageName())
+ && standardTask.visible;
+ if (mAllowFingerprintOnCurrentOccludingActivity != previousState) {
+ mLogger.allowFingerprintOnCurrentOccludingActivityChanged(
+ mAllowFingerprintOnCurrentOccludingActivity);
+ updateFingerprintListeningState(BIOMETRIC_ACTION_UPDATE);
+ }
+ }
+
+ RootTaskInfo assistantTask = mActivityTaskManager.getRootTaskInfo(
WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_ASSISTANT);
- if (info == null) {
+ if (assistantTask == null) {
return;
}
- mLogger.logTaskStackChangedForAssistant(info.visible);
+ mLogger.logTaskStackChangedForAssistant(assistantTask.visible);
mHandler.sendMessage(mHandler.obtainMessage(MSG_ASSISTANT_STACK_CHANGED,
- info.visible));
+ assistantTask.visible));
} catch (RemoteException e) {
mLogger.logException(e, "unable to check task stack ");
}
@@ -4324,7 +4355,7 @@
mUserTracker.removeCallback(mUserChangedCallback);
- TaskStackChangeListeners.getInstance().unregisterTaskStackListener(mTaskStackListener);
+ mTaskStackChangeListeners.unregisterTaskStackListener(mTaskStackListener);
mBroadcastDispatcher.unregisterReceiver(mBroadcastReceiver);
mBroadcastDispatcher.unregisterReceiver(mBroadcastAllReceiver);
@@ -4383,6 +4414,8 @@
pw.println(" enabledByUser=" + mBiometricEnabledForUser.get(userId));
pw.println(" mKeyguardOccluded=" + mKeyguardOccluded);
pw.println(" mIsDreaming=" + mIsDreaming);
+ pw.println(" mFingerprintListenOnOccludingActivitiesFromPackage="
+ + mAllowFingerprintOnOccludingActivitiesFromPackage);
if (isUdfpsSupported()) {
pw.println(" udfpsEnrolled=" + isUdfpsEnrolled());
pw.println(" shouldListenForUdfps=" + shouldListenForFingerprint(true));
diff --git a/packages/SystemUI/src/com/android/keyguard/LockIconView.java b/packages/SystemUI/src/com/android/keyguard/LockIconView.java
index abad0be..d1fffaa 100644
--- a/packages/SystemUI/src/com/android/keyguard/LockIconView.java
+++ b/packages/SystemUI/src/com/android/keyguard/LockIconView.java
@@ -16,6 +16,8 @@
package com.android.keyguard;
+import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
+
import android.content.Context;
import android.content.res.ColorStateList;
import android.graphics.Color;
@@ -23,6 +25,7 @@
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
+import android.view.Gravity;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
@@ -68,13 +71,9 @@
public LockIconView(Context context, AttributeSet attrs) {
super(context, attrs);
mSensorRect = new RectF();
- }
- @Override
- public void onFinishInflate() {
- super.onFinishInflate();
- mLockIcon = findViewById(R.id.lock_icon);
- mBgView = findViewById(R.id.lock_icon_bg);
+ addBgImageView(context, attrs);
+ addLockIconImageView(context, attrs);
}
void setDozeAmount(float dozeAmount) {
@@ -184,6 +183,30 @@
mLockIcon.setImageState(getLockIconState(mIconType, mAod), true);
}
+ private void addLockIconImageView(Context context, AttributeSet attrs) {
+ mLockIcon = new ImageView(context, attrs);
+ mLockIcon.setId(R.id.lock_icon);
+ mLockIcon.setScaleType(ImageView.ScaleType.CENTER_CROP);
+ addView(mLockIcon);
+ LayoutParams lp = (LayoutParams) mLockIcon.getLayoutParams();
+ lp.height = MATCH_PARENT;
+ lp.width = MATCH_PARENT;
+ lp.gravity = Gravity.CENTER;
+ mLockIcon.setLayoutParams(lp);
+ }
+
+ private void addBgImageView(Context context, AttributeSet attrs) {
+ mBgView = new ImageView(context, attrs);
+ mBgView.setId(R.id.lock_icon_bg);
+ mBgView.setImageDrawable(context.getDrawable(R.drawable.fingerprint_bg));
+ mBgView.setVisibility(View.INVISIBLE);
+ addView(mBgView);
+ LayoutParams lp = (LayoutParams) mBgView.getLayoutParams();
+ lp.height = MATCH_PARENT;
+ lp.width = MATCH_PARENT;
+ mBgView.setLayoutParams(lp);
+ }
+
private static int[] getLockIconState(@IconType int icon, boolean aod) {
if (icon == ICON_NONE) {
return new int[0];
diff --git a/packages/SystemUI/src/com/android/keyguard/dagger/ClockRegistryModule.java b/packages/SystemUI/src/com/android/keyguard/dagger/ClockRegistryModule.java
index d2b10d6..83fc278 100644
--- a/packages/SystemUI/src/com/android/keyguard/dagger/ClockRegistryModule.java
+++ b/packages/SystemUI/src/com/android/keyguard/dagger/ClockRegistryModule.java
@@ -71,7 +71,8 @@
context.getString(R.string.lockscreen_clock_id_fallback),
logBuffer,
/* keepAllLoaded = */ false,
- /* subTag = */ "System");
+ /* subTag = */ "System",
+ /* isTransitClockEnabled = */ featureFlags.isEnabled(Flags.TRANSIT_CLOCK));
registry.registerListeners();
return registry;
}
diff --git a/packages/SystemUI/src/com/android/keyguard/logging/KeyguardUpdateMonitorLogger.kt b/packages/SystemUI/src/com/android/keyguard/logging/KeyguardUpdateMonitorLogger.kt
index 1b1a3e9..18ba09a 100644
--- a/packages/SystemUI/src/com/android/keyguard/logging/KeyguardUpdateMonitorLogger.kt
+++ b/packages/SystemUI/src/com/android/keyguard/logging/KeyguardUpdateMonitorLogger.kt
@@ -601,6 +601,15 @@
)
}
+ fun allowFingerprintOnCurrentOccludingActivityChanged(allow: Boolean) {
+ logBuffer.log(
+ TAG,
+ VERBOSE,
+ { bool1 = allow },
+ { "allowFingerprintOnCurrentOccludingActivityChanged: $bool1" }
+ )
+ }
+
fun logAssistantVisible(assistantVisible: Boolean) {
logBuffer.log(
TAG,
diff --git a/packages/SystemUI/src/com/android/systemui/authentication/data/repository/AuthenticationRepository.kt b/packages/SystemUI/src/com/android/systemui/authentication/data/repository/AuthenticationRepository.kt
index c4ebee2..0530aed 100644
--- a/packages/SystemUI/src/com/android/systemui/authentication/data/repository/AuthenticationRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/authentication/data/repository/AuthenticationRepository.kt
@@ -77,7 +77,9 @@
override val isUnlocked: StateFlow<Boolean> = _isUnlocked.asStateFlow()
private val _authenticationMethod =
- MutableStateFlow<AuthenticationMethodModel>(AuthenticationMethodModel.Pin(1234))
+ MutableStateFlow<AuthenticationMethodModel>(
+ AuthenticationMethodModel.Pin(listOf(1, 2, 3, 4), autoConfirm = false)
+ )
override val authenticationMethod: StateFlow<AuthenticationMethodModel> =
_authenticationMethod.asStateFlow()
diff --git a/packages/SystemUI/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractor.kt b/packages/SystemUI/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractor.kt
index dd9dcbe..20e82f7 100644
--- a/packages/SystemUI/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractor.kt
@@ -122,14 +122,36 @@
/**
* Attempts to authenticate the user and unlock the device.
*
+ * If [tryAutoConfirm] is `true`, authentication is attempted if and only if the auth method
+ * supports auto-confirming, and the input's length is at least the code's length. Otherwise,
+ * `null` is returned.
+ *
* @param input The input from the user to try to authenticate with. This can be a list of
* different things, based on the current authentication method.
- * @return `true` if the authentication succeeded and the device is now unlocked; `false`
- * otherwise.
+ * @param tryAutoConfirm `true` if called while the user inputs the code, without an explicit
+ * request to validate.
+ * @return `true` if the authentication succeeded and the device is now unlocked; `false` when
+ * authentication failed, `null` if the check was not performed.
*/
- fun authenticate(input: List<Any>): Boolean {
+ fun authenticate(input: List<Any>, tryAutoConfirm: Boolean = false): Boolean? {
+ val authMethod = this.authenticationMethod.value
+ if (tryAutoConfirm) {
+ if ((authMethod as? AuthenticationMethodModel.Pin)?.autoConfirm != true) {
+ // Do not attempt to authenticate unless the PIN lock is set to auto-confirm.
+ return null
+ }
+
+ if (input.size < authMethod.code.size) {
+ // Do not attempt to authenticate if the PIN has not yet the required amount of
+ // digits. This intentionally only skip for shorter PINs; if the PIN is longer, the
+ // layer above might have throttled this check, and the PIN should be rejected via
+ // the auth code below.
+ return null
+ }
+ }
+
val isSuccessful =
- when (val authMethod = this.authenticationMethod.value) {
+ when (authMethod) {
is AuthenticationMethodModel.Pin -> input.asCode() == authMethod.code
is AuthenticationMethodModel.Password -> input.asPassword() == authMethod.password
is AuthenticationMethodModel.Pattern -> input.asPattern() == authMethod.coordinates
@@ -180,21 +202,17 @@
* Returns a PIN code from the given list. It's assumed the given list elements are all
* [Int] in the range [0-9].
*/
- private fun List<Any>.asCode(): Long? {
+ private fun List<Any>.asCode(): List<Int>? {
if (isEmpty() || size > DevicePolicyManager.MAX_PASSWORD_LENGTH) {
return null
}
- var code = 0L
- map {
- require(it is Int && it in 0..9) {
- "Pin is required to be Int in range [0..9], but got $it"
- }
- it
+ return map {
+ require(it is Int && it in 0..9) {
+ "Pin is required to be Int in range [0..9], but got $it"
}
- .forEach { integer -> code = code * 10 + integer }
-
- return code
+ it
+ }
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/authentication/shared/model/AuthenticationMethodModel.kt b/packages/SystemUI/src/com/android/systemui/authentication/shared/model/AuthenticationMethodModel.kt
index e4fbf9a..1016b6b 100644
--- a/packages/SystemUI/src/com/android/systemui/authentication/shared/model/AuthenticationMethodModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/authentication/shared/model/AuthenticationMethodModel.kt
@@ -16,6 +16,8 @@
package com.android.systemui.authentication.shared.model
+import androidx.annotation.VisibleForTesting
+
/** Enumerates all known authentication methods. */
sealed class AuthenticationMethodModel(
/**
@@ -38,7 +40,16 @@
* In practice, a pin is restricted to 16 decimal digits , see
* [android.app.admin.DevicePolicyManager.MAX_PASSWORD_LENGTH]
*/
- data class Pin(val code: Long) : AuthenticationMethodModel(isSecure = true)
+ data class Pin(val code: List<Int>, val autoConfirm: Boolean) :
+ AuthenticationMethodModel(isSecure = true) {
+
+ /** Convenience constructor for tests only. */
+ @VisibleForTesting
+ constructor(
+ code: Long,
+ autoConfirm: Boolean = false
+ ) : this(code.toString(10).map { it - '0' }, autoConfirm) {}
+ }
data class Password(val password: String) : AuthenticationMethodModel(isSecure = true)
diff --git a/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterView.java b/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterView.java
index 98dd838..f5f47d0 100644
--- a/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterView.java
+++ b/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterView.java
@@ -350,7 +350,7 @@
updatePercentText();
addView(mBatteryPercentView, new LayoutParams(
LayoutParams.WRAP_CONTENT,
- LayoutParams.MATCH_PARENT));
+ LayoutParams.WRAP_CONTENT));
}
} else {
if (showing) {
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
index d3b739d..76e48e9 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
@@ -1057,8 +1057,16 @@
}
private String getNotRecognizedString(@Modality int modality) {
- return mContext.getString(modality == TYPE_FACE
- ? R.string.biometric_face_not_recognized : R.string.fingerprint_error_not_match);
+ final int messageRes;
+ final int userId = mCurrentDialogArgs.argi1;
+ if (isFaceAuthEnrolled(userId) && isFingerprintEnrolled(userId)) {
+ messageRes = modality == TYPE_FACE
+ ? R.string.biometric_face_not_recognized
+ : R.string.fingerprint_error_not_match;
+ } else {
+ messageRes = R.string.biometric_not_recognized;
+ }
+ return mContext.getString(messageRes);
}
private String getErrorString(@Modality int modality, int error, int vendorCode) {
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialogPanelInteractionDetector.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialogPanelInteractionDetector.kt
index b72801d..5218537 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialogPanelInteractionDetector.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialogPanelInteractionDetector.kt
@@ -16,11 +16,13 @@
@Main private val mainExecutor: Executor,
) {
private var action: Action? = null
+ private var panelState: Int = -1
@MainThread
fun enable(onPanelInteraction: Runnable) {
if (action == null) {
action = Action(onPanelInteraction)
+ shadeExpansionStateManager.addStateListener(this::onPanelStateChanged)
shadeExpansionStateManager.addExpansionListener(this::onPanelExpansionChanged)
} else {
Log.e(TAG, "Already enabled")
@@ -32,6 +34,8 @@
if (action != null) {
Log.i(TAG, "Disable dectector")
action = null
+ panelState = -1
+ shadeExpansionStateManager.removeStateListener(this::onPanelStateChanged)
shadeExpansionStateManager.removeExpansionListener(this::onPanelExpansionChanged)
}
}
@@ -40,13 +44,34 @@
private fun onPanelExpansionChanged(event: ShadeExpansionChangeEvent) =
mainExecutor.execute {
action?.let {
- if (event.tracking || (event.expanded && event.fraction > 0)) {
- Log.i(TAG, "Detected panel interaction, event: $event")
+ if (event.tracking || (event.expanded && event.fraction > 0 && panelState == 1)) {
+ Log.i(TAG, "onPanelExpansionChanged, event: $event")
it.onPanelInteraction.run()
disable()
}
}
}
+
+ @AnyThread
+ private fun onPanelStateChanged(state: Int) =
+ mainExecutor.execute {
+ // When device owner set screen lock type as Swipe, and install work profile with
+ // pin/pattern/password & fingerprint or face, if work profile allow user to verify
+ // by BP, it is possible that BP will be displayed when keyguard is closing, in this
+ // case event.expanded = true and event.fraction > 0, so BP will be closed, adding
+ // panel state into consideration is workaround^2, this workaround works because
+ // onPanelStateChanged is earlier than onPanelExpansionChanged
+
+ // we don't want to close BP in below case
+ //
+ // | Action | tracking | expanded | fraction | panelState |
+ // | HeadsUp | NA | NA | NA | 1 |
+ // | b/285111529 | false | true | > 0 | 2 |
+
+ // Note: HeadsUp behavior was changed, so we can't got onPanelExpansionChanged now
+ panelState = state
+ Log.i(TAG, "onPanelStateChanged, state: $state")
+ }
}
private data class Action(val onPanelInteraction: Runnable)
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractor.kt b/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractor.kt
index c833def..256c635 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractor.kt
@@ -149,19 +149,28 @@
* If the input is correct, the device will be unlocked and the lock screen and bouncer will be
* dismissed and hidden.
*
+ * If [tryAutoConfirm] is `true`, authentication is attempted if and only if the auth method
+ * supports auto-confirming, and the input's length is at least the code's length. Otherwise,
+ * `null` is returned.
+ *
* @param input The input from the user to try to authenticate with. This can be a list of
* different things, based on the current authentication method.
- * @return `true` if the authentication succeeded and the device is now unlocked; `false`
- * otherwise.
+ * @param tryAutoConfirm `true` if called while the user inputs the code, without an explicit
+ * request to validate.
+ * @return `true` if the authentication succeeded and the device is now unlocked; `false` when
+ * authentication failed, `null` if the check was not performed.
*/
fun authenticate(
input: List<Any>,
- ): Boolean {
+ tryAutoConfirm: Boolean = false,
+ ): Boolean? {
if (repository.throttling.value != null) {
return false
}
- val isAuthenticated = authenticationInteractor.authenticate(input)
+ val isAuthenticated =
+ authenticationInteractor.authenticate(input, tryAutoConfirm) ?: return null
+
val failedAttempts = authenticationInteractor.failedAuthenticationAttempts.value
when {
isAuthenticated -> {
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModel.kt b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModel.kt
index 55929b5..0146e40 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModel.kt
@@ -50,7 +50,7 @@
/** Notifies that the user has pressed the key for attempting to authenticate the password. */
fun onAuthenticateKeyPressed() {
- if (!interactor.authenticate(password.value.toCharArray().toList())) {
+ if (interactor.authenticate(password.value.toCharArray().toList()) != true) {
showFailureAnimation()
}
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModel.kt b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModel.kt
index d9ef75d..700703e 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModel.kt
@@ -153,9 +153,8 @@
/** Notifies that the user has ended the drag gesture across the dot grid. */
fun onDragEnd() {
- val isSuccessfullyAuthenticated =
- interactor.authenticate(_selectedDots.value.map { it.toCoordinate() })
- if (!isSuccessfullyAuthenticated) {
+ val pattern = _selectedDots.value.map { it.toCoordinate() }
+ if (interactor.authenticate(pattern) != true) {
showFailureAnimation()
}
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModel.kt b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModel.kt
index 94d3d19..1944c74 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModel.kt
@@ -16,14 +16,19 @@
package com.android.systemui.bouncer.ui.viewmodel
+import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
import com.android.systemui.bouncer.domain.interactor.BouncerInteractor
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.stateIn
/** Holds UI state and handles user input for the PIN code bouncer UI. */
class PinBouncerViewModel(
- private val applicationScope: CoroutineScope,
+ applicationScope: CoroutineScope,
private val interactor: BouncerInteractor,
isInputEnabled: StateFlow<Boolean>,
) :
@@ -34,6 +39,42 @@
private val mutablePinEntries = MutableStateFlow<List<EnteredKey>>(emptyList())
val pinEntries: StateFlow<List<EnteredKey>> = mutablePinEntries
+ /** The length of the hinted PIN, or null if pin length hint should not be shown. */
+ val hintedPinLength: StateFlow<Int?> =
+ interactor.authenticationMethod
+ .map { authMethod -> computeHintedPinLength(authMethod) }
+ .stateIn(
+ scope = applicationScope,
+ started = SharingStarted.Eagerly,
+ initialValue = computeHintedPinLength(interactor.authenticationMethod.value),
+ )
+
+ /** Appearance of the backspace button. */
+ val backspaceButtonAppearance: StateFlow<ActionButtonAppearance> =
+ combine(interactor.authenticationMethod, mutablePinEntries) { authMethod, enteredPin ->
+ computeBackspaceButtonAppearance(authMethod, enteredPin)
+ }
+ .stateIn(
+ scope = applicationScope,
+ started = SharingStarted.Eagerly,
+ initialValue =
+ computeBackspaceButtonAppearance(
+ interactor.authenticationMethod.value,
+ mutablePinEntries.value
+ ),
+ )
+
+ /** Appearance of the confirm button. */
+ val confirmButtonAppearance: StateFlow<ActionButtonAppearance> =
+ interactor.authenticationMethod
+ .map { authMethod -> computeConfirmButtonAppearance(authMethod) }
+ .stateIn(
+ scope = applicationScope,
+ started = SharingStarted.Eagerly,
+ initialValue =
+ computeConfirmButtonAppearance(interactor.authenticationMethod.value),
+ )
+
/** Notifies that the UI has been shown to the user. */
fun onShown() {
interactor.resetMessage()
@@ -46,6 +87,8 @@
}
mutablePinEntries.value += EnteredKey(input)
+
+ tryAuthenticate(useAutoConfirm = true)
}
/** Notifies that the user clicked the backspace button. */
@@ -63,14 +106,72 @@
/** Notifies that the user clicked the "enter" button. */
fun onAuthenticateButtonClicked() {
- if (!interactor.authenticate(mutablePinEntries.value.map { it.input })) {
+ tryAuthenticate(useAutoConfirm = false)
+ }
+
+ private fun tryAuthenticate(useAutoConfirm: Boolean) {
+ val pinCode = mutablePinEntries.value.map { it.input }
+ val isSuccess = interactor.authenticate(pinCode, useAutoConfirm) ?: return
+
+ if (!isSuccess) {
showFailureAnimation()
}
mutablePinEntries.value = emptyList()
}
+
+ private fun isAutoConfirmEnabled(authMethodModel: AuthenticationMethodModel): Boolean {
+ return (authMethodModel as? AuthenticationMethodModel.Pin)?.autoConfirm == true
+ }
+
+ private fun autoConfirmPinLength(authMethodModel: AuthenticationMethodModel): Int? {
+ if (!isAutoConfirmEnabled(authMethodModel)) return null
+
+ return (authMethodModel as? AuthenticationMethodModel.Pin)?.code?.size
+ }
+
+ private fun computeHintedPinLength(authMethodModel: AuthenticationMethodModel): Int? {
+ // Hinting is enabled for 6-digit codes only
+ return autoConfirmPinLength(authMethodModel).takeIf { it == HINTING_PASSCODE_LENGTH }
+ }
+
+ private fun computeBackspaceButtonAppearance(
+ authMethodModel: AuthenticationMethodModel,
+ enteredPin: List<EnteredKey>
+ ): ActionButtonAppearance {
+ val isAutoConfirmEnabled = isAutoConfirmEnabled(authMethodModel)
+ val isEmpty = enteredPin.isEmpty()
+
+ return when {
+ isAutoConfirmEnabled && isEmpty -> ActionButtonAppearance.Hidden
+ isAutoConfirmEnabled -> ActionButtonAppearance.Subtle
+ else -> ActionButtonAppearance.Shown
+ }
+ }
+ private fun computeConfirmButtonAppearance(
+ authMethodModel: AuthenticationMethodModel
+ ): ActionButtonAppearance {
+ return if (isAutoConfirmEnabled(authMethodModel)) {
+ ActionButtonAppearance.Hidden
+ } else {
+ ActionButtonAppearance.Shown
+ }
+ }
}
+/** Appearance of pin-pad action buttons. */
+enum class ActionButtonAppearance {
+ /** Button must not be shown. */
+ Hidden,
+ /** Button is shown, but with no background to make it less prominent. */
+ Subtle,
+ /** Button is shown. */
+ Shown,
+}
+
+/** Auto-confirm passcodes of exactly 6 digits show a length hint, see http://shortn/_IXlmSNbDh6 */
+private const val HINTING_PASSCODE_LENGTH = 6
+
private var nextSequenceNumber = 1
/**
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
index f87d009..3954959 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
@@ -87,6 +87,7 @@
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.NotificationShadeWindowController;
import com.android.systemui.statusbar.connectivity.ConnectivityModule;
+import com.android.systemui.statusbar.disableflags.dagger.DisableFlagsModule;
import com.android.systemui.statusbar.events.SystemStatusAnimationScheduler;
import com.android.systemui.statusbar.notification.NotifPipelineFlags;
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
@@ -166,6 +167,7 @@
DreamModule.class,
ControlsModule.class,
DemoModeModule.class,
+ DisableFlagsModule.class,
FalsingModule.class,
FlagsModule.class,
SystemPropertiesFlagsModule.class,
diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
index 43e2d4a..0f3345f 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
@@ -249,10 +249,18 @@
@JvmField
val DELAY_BOUNCER = unreleasedFlag(235, "delay_bouncer", teamfood = true)
+
+ /** Keyguard Migration */
+
/** Migrate the indication area to the new keyguard root view. */
// TODO(b/280067944): Tracking bug.
@JvmField
- val MIGRATE_INDICATION_AREA = unreleasedFlag(236, "migrate_indication_area")
+ val MIGRATE_INDICATION_AREA = unreleasedFlag(236, "migrate_indication_area", teamfood = true)
+
+ /** Migrate the lock icon view to the new keyguard root view. */
+ // TODO(b/286552209): Tracking bug.
+ @JvmField
+ val MIGRATE_LOCK_ICON = unreleasedFlag(238, "migrate_lock_icon")
/** Whether to listen for fingerprint authentication over keyguard occluding activities. */
// TODO(b/283260512): Tracking bug.
@@ -264,6 +272,10 @@
@JvmField
val KEYGUARD_TALKBACK_FIX = releasedFlag(238, "keyguard_talkback_fix")
+ // TODO(b/287268101): Tracking bug.
+ @JvmField
+ val TRANSIT_CLOCK = unreleasedFlag(239, "lockscreen_custom_transit_clock")
+
// 300 - power menu
// TODO(b/254512600): Tracking Bug
@JvmField val POWER_MENU_LITE = releasedFlag(300, "power_menu_lite")
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt
index 05c23ae..e8881a4 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt
@@ -47,9 +47,10 @@
private var indicationAreaHandle: DisposableHandle? = null
override fun start() {
- bindIndicationArea(
+ val notificationPanel =
notificationShadeWindowView.requireViewById(R.id.notification_panel) as ViewGroup
- )
+ bindIndicationArea(notificationPanel)
+ bindLockIconView(notificationPanel)
}
fun bindIndicationArea(legacyParent: ViewGroup) {
@@ -74,4 +75,16 @@
indicationController
)
}
+
+ private fun bindLockIconView(legacyParent: ViewGroup) {
+ if (featureFlags.isEnabled(Flags.MIGRATE_LOCK_ICON)) {
+ legacyParent.requireViewById<View>(R.id.lock_icon_view).let {
+ legacyParent.removeView(it)
+ }
+ } else {
+ keyguardRootView.findViewById<View?>(R.id.lock_icon_view)?.let {
+ keyguardRootView.removeView(it)
+ }
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index ce8ab23..8cb2aea 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -2770,7 +2770,7 @@
// It's possible that the device was unlocked (via BOUNCER or Fingerprint) while
// dreaming. It's time to wake up.
- if (mDreamOverlayShowing) {
+ if (mDreamOverlayShowing || mUpdateMonitor.isDreaming()) {
mPM.wakeUp(mSystemClock.uptimeMillis(), PowerManager.WAKE_REASON_GESTURE,
"com.android.systemui:UNLOCK_DREAMING");
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardFaceAuthNotSupportedModule.kt b/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardFaceAuthNotSupportedModule.kt
index a44df7e..d8eb81c 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardFaceAuthNotSupportedModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardFaceAuthNotSupportedModule.kt
@@ -16,6 +16,8 @@
package com.android.systemui.keyguard.dagger
+import com.android.systemui.keyguard.data.repository.DeviceEntryFaceAuthRepository
+import com.android.systemui.keyguard.data.repository.NoopDeviceEntryFaceAuthRepository
import com.android.systemui.keyguard.domain.interactor.KeyguardFaceAuthInteractor
import com.android.systemui.keyguard.domain.interactor.NoopKeyguardFaceAuthInteractor
import dagger.Binds
@@ -32,4 +34,9 @@
interface KeyguardFaceAuthNotSupportedModule {
@Binds
fun keyguardFaceAuthInteractor(impl: NoopKeyguardFaceAuthInteractor): KeyguardFaceAuthInteractor
+
+ @Binds
+ fun deviceEntryFaceAuthRepository(
+ impl: NoopDeviceEntryFaceAuthRepository
+ ): DeviceEntryFaceAuthRepository
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepository.kt
index f9e9a93..128057a 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepository.kt
@@ -335,6 +335,11 @@
biometricSettingsRepository.isCurrentUserInLockdown.isFalse(),
"userHasNotLockedDownDevice",
tableLogBuffer
+ ),
+ logAndObserve(
+ keyguardRepository.isKeyguardShowing,
+ "isKeyguardShowing",
+ tableLogBuffer
)
)
.reduce(::and)
@@ -598,7 +603,7 @@
const val DEFAULT_CANCEL_SIGNAL_TIMEOUT = 3000L
/** Number of allowed retries whenever there is a face hardware error */
- const val HAL_ERROR_RETRY_MAX = 20
+ const val HAL_ERROR_RETRY_MAX = 5
/** Timeout before retries whenever there is a HAL error. */
const val HAL_ERROR_RETRY_TIMEOUT = 500L // ms
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/NoopDeviceEntryFaceAuthRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/NoopDeviceEntryFaceAuthRepository.kt
new file mode 100644
index 0000000..abe59b7
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/NoopDeviceEntryFaceAuthRepository.kt
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyguard.data.repository
+
+import com.android.keyguard.FaceAuthUiEvent
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.keyguard.shared.model.AuthenticationStatus
+import com.android.systemui.keyguard.shared.model.DetectionStatus
+import javax.inject.Inject
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.emptyFlow
+
+/**
+ * Implementation of the repository that noops all face auth operations.
+ *
+ * This is required for SystemUI variants that do not support face authentication but still inject
+ * other SysUI components that depend on [DeviceEntryFaceAuthRepository].
+ */
+@SysUISingleton
+class NoopDeviceEntryFaceAuthRepository @Inject constructor() : DeviceEntryFaceAuthRepository {
+ override val isAuthenticated: Flow<Boolean>
+ get() = emptyFlow()
+
+ private val _canRunFaceAuth = MutableStateFlow(false)
+ override val canRunFaceAuth: StateFlow<Boolean> = _canRunFaceAuth
+
+ override val authenticationStatus: Flow<AuthenticationStatus>
+ get() = emptyFlow()
+
+ override val detectionStatus: Flow<DetectionStatus>
+ get() = emptyFlow()
+
+ private val _isLockedOut = MutableStateFlow(false)
+ override val isLockedOut: StateFlow<Boolean> = _isLockedOut
+
+ private val _isAuthRunning = MutableStateFlow(false)
+ override val isAuthRunning: StateFlow<Boolean> = _isAuthRunning
+
+ override val isBypassEnabled: Flow<Boolean>
+ get() = emptyFlow()
+
+ /**
+ * Trigger face authentication.
+ *
+ * [uiEvent] provided should be logged whenever face authentication runs. Invocation should be
+ * ignored if face authentication is already running. Results should be propagated through
+ * [authenticationStatus]
+ *
+ * Run only face detection when [fallbackToDetection] is true and [canRunFaceAuth] is false.
+ */
+ override suspend fun authenticate(uiEvent: FaceAuthUiEvent, fallbackToDetection: Boolean) {}
+
+ /** Stop currently running face authentication or detection. */
+ override fun cancel() {}
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/TransitionStep.kt b/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/TransitionStep.kt
index 767fd58..0fa6f4f 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/TransitionStep.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/TransitionStep.kt
@@ -16,7 +16,9 @@
package com.android.systemui.keyguard.shared.model
/** This information will flow from the [KeyguardTransitionRepository] to control the UI layer */
-data class TransitionStep(
+data class TransitionStep
+@JvmOverloads
+constructor(
val from: KeyguardState = KeyguardState.OFF,
val to: KeyguardState = KeyguardState.OFF,
val value: Float = 0f, // constrained [0.0, 1.0]
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt
index 1c2e85b..b92d104 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt
@@ -346,6 +346,10 @@
?.largeClock
?.events
?.onTargetRegionChanged(KeyguardClockSwitch.getLargeClockRegion(parentView))
+ clockController.clock
+ ?.smallClock
+ ?.events
+ ?.onTargetRegionChanged(KeyguardClockSwitch.getSmallClockRegion(parentView))
}
}
parentView.addOnLayoutChangeListener(layoutChangeListener)
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/KeyguardRootView.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/KeyguardRootView.kt
index abf0e80..a62f383 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/KeyguardRootView.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/KeyguardRootView.kt
@@ -23,6 +23,7 @@
import android.view.ViewGroup.LayoutParams.MATCH_PARENT
import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
import android.widget.FrameLayout
+import com.android.keyguard.LockIconView
import com.android.systemui.R
/** Provides a container for all keyguard ui content. */
@@ -37,6 +38,7 @@
init {
addIndicationTextArea()
+ addLockIconView()
}
private fun addIndicationTextArea() {
@@ -54,6 +56,17 @@
)
}
+ private fun addLockIconView() {
+ val view = LockIconView(context, attrs).apply { id = R.id.lock_icon_view }
+ addView(
+ view,
+ LayoutParams(
+ WRAP_CONTENT,
+ WRAP_CONTENT,
+ )
+ )
+ }
+
private fun Int.dp(): Int {
return context.resources.getDimensionPixelSize(this)
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/util/IndicationHelper.kt b/packages/SystemUI/src/com/android/systemui/keyguard/util/IndicationHelper.kt
new file mode 100644
index 0000000..7129001
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/util/IndicationHelper.kt
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.keyguard.util
+
+import android.hardware.biometrics.BiometricFaceConstants
+import android.hardware.biometrics.BiometricFingerprintConstants
+import android.hardware.biometrics.BiometricSourceType
+import com.android.keyguard.KeyguardUpdateMonitor
+import com.android.systemui.dagger.SysUISingleton
+import javax.inject.Inject
+
+@SysUISingleton
+class IndicationHelper
+@Inject
+constructor(
+ val keyguardUpdateMonitor: KeyguardUpdateMonitor,
+) {
+ fun shouldSuppressErrorMsg(biometricSource: BiometricSourceType, msgId: Int): Boolean {
+ return when (biometricSource) {
+ BiometricSourceType.FINGERPRINT ->
+ (isPrimaryAuthRequired() && !isFingerprintLockoutErrorMsg(msgId)) ||
+ msgId == BiometricFingerprintConstants.FINGERPRINT_ERROR_CANCELED ||
+ msgId == BiometricFingerprintConstants.FINGERPRINT_ERROR_USER_CANCELED ||
+ msgId == BiometricFingerprintConstants.BIOMETRIC_ERROR_POWER_PRESSED
+ BiometricSourceType.FACE ->
+ (isPrimaryAuthRequired() && !isFaceLockoutErrorMsg(msgId)) ||
+ msgId == BiometricFaceConstants.FACE_ERROR_CANCELED ||
+ msgId == BiometricFaceConstants.FACE_ERROR_UNABLE_TO_PROCESS
+ else -> false
+ }
+ }
+
+ private fun isFingerprintLockoutErrorMsg(msgId: Int): Boolean {
+ return msgId == BiometricFingerprintConstants.FINGERPRINT_ERROR_LOCKOUT ||
+ msgId == BiometricFingerprintConstants.FINGERPRINT_ERROR_LOCKOUT_PERMANENT
+ }
+
+ fun isFaceLockoutErrorMsg(msgId: Int): Boolean {
+ return msgId == BiometricFaceConstants.FACE_ERROR_LOCKOUT ||
+ msgId == BiometricFaceConstants.FACE_ERROR_LOCKOUT_PERMANENT
+ }
+
+ private fun isPrimaryAuthRequired(): Boolean {
+ // Only checking if unlocking with Biometric is allowed (no matter strong or non-strong
+ // as long as primary auth, i.e. PIN/pattern/password, is required), so it's ok to
+ // pass true for isStrongBiometric to isUnlockingWithBiometricAllowed() to bypass the
+ // check of whether non-strong biometric is allowed since strong biometrics can still be
+ // used.
+ return !keyguardUpdateMonitor.isUnlockingWithBiometricAllowed(true /* isStrongBiometric */)
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/DisableFlagsRepositoryLog.kt b/packages/SystemUI/src/com/android/systemui/log/dagger/DisableFlagsRepositoryLog.kt
new file mode 100644
index 0000000..e141291
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/log/dagger/DisableFlagsRepositoryLog.kt
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.log.dagger
+
+import com.android.systemui.log.LogBuffer
+import javax.inject.Qualifier
+
+/** A [LogBuffer] for changes to [DisableFlagsRepository]. */
+@Qualifier
+@MustBeDocumented
+@Retention(AnnotationRetention.RUNTIME)
+annotation class DisableFlagsRepositoryLog
diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
index 0261ee5..3497285 100644
--- a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
+++ b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
@@ -224,6 +224,15 @@
false /* systrace */);
}
+ /** Provides a logging buffer for the disable flags repository. */
+ @Provides
+ @SysUISingleton
+ @DisableFlagsRepositoryLog
+ public static LogBuffer provideDisableFlagsRepositoryLogBuffer(LogBufferFactory factory) {
+ return factory.create("DisableFlagsRepository", 40 /* maxSize */,
+ false /* systrace */);
+ }
+
/** Provides a logging buffer for logs related to swipe up gestures. */
@Provides
@SysUISingleton
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/resume/MediaResumeListener.kt b/packages/SystemUI/src/com/android/systemui/media/controls/resume/MediaResumeListener.kt
index b0389b5..23ee00d 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/resume/MediaResumeListener.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/resume/MediaResumeListener.kt
@@ -122,9 +122,9 @@
Log.e(TAG, "Error getting package information", e)
}
- Log.d(TAG, "Adding resume controls $desc")
+ Log.d(TAG, "Adding resume controls for ${browser.userId}: $desc")
mediaDataManager.addResumptionControls(
- currentUserId,
+ browser.userId,
desc,
resumeAction,
token,
@@ -196,7 +196,11 @@
}
resumeComponents.add(component to lastPlayed)
}
- Log.d(TAG, "loaded resume components ${resumeComponents.toArray().contentToString()}")
+ Log.d(
+ TAG,
+ "loaded resume components for $currentUserId: " +
+ "${resumeComponents.toArray().contentToString()}"
+ )
if (needsUpdate) {
// Save any missing times that we had to fill in
@@ -210,11 +214,21 @@
return
}
+ val pm = context.packageManager
val now = systemClock.currentTimeMillis()
resumeComponents.forEach {
if (now.minus(it.second) <= RESUME_MEDIA_TIMEOUT) {
- val browser = mediaBrowserFactory.create(mediaBrowserCallback, it.first)
- browser.findRecentMedia()
+ // Verify that the service exists for this user
+ val intent = Intent(MediaBrowserService.SERVICE_INTERFACE)
+ intent.component = it.first
+ val inf = pm.resolveServiceAsUser(intent, 0, currentUserId)
+ if (inf != null) {
+ val browser =
+ mediaBrowserFactory.create(mediaBrowserCallback, it.first, currentUserId)
+ browser.findRecentMedia()
+ } else {
+ Log.d(TAG, "User $currentUserId does not have component ${it.first}")
+ }
}
}
}
@@ -244,7 +258,7 @@
Log.d(TAG, "Checking for service component for " + data.packageName)
val pm = context.packageManager
val serviceIntent = Intent(MediaBrowserService.SERVICE_INTERFACE)
- val resumeInfo = pm.queryIntentServices(serviceIntent, 0)
+ val resumeInfo = pm.queryIntentServicesAsUser(serviceIntent, 0, currentUserId)
val inf = resumeInfo?.filter { it.serviceInfo.packageName == data.packageName }
if (inf != null && inf.size > 0) {
@@ -280,13 +294,17 @@
browser: ResumeMediaBrowser
) {
// Since this is a test, just save the component for later
- Log.d(TAG, "Can get resumable media from $componentName")
+ Log.d(
+ TAG,
+ "Can get resumable media for ${browser.userId} from $componentName"
+ )
mediaDataManager.setResumeAction(key, getResumeAction(componentName))
updateResumptionList(componentName)
mediaBrowser = null
}
},
- componentName
+ componentName,
+ currentUserId
)
mediaBrowser?.testConnection()
}
@@ -326,7 +344,7 @@
/** Get a runnable which will resume media playback */
private fun getResumeAction(componentName: ComponentName): Runnable {
return Runnable {
- mediaBrowser = mediaBrowserFactory.create(null, componentName)
+ mediaBrowser = mediaBrowserFactory.create(null, componentName, currentUserId)
mediaBrowser?.restart()
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/resume/ResumeMediaBrowser.java b/packages/SystemUI/src/com/android/systemui/media/controls/resume/ResumeMediaBrowser.java
index d460b5b..ceaccaf 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/resume/ResumeMediaBrowser.java
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/resume/ResumeMediaBrowser.java
@@ -17,6 +17,7 @@
package com.android.systemui.media.controls.resume;
import android.annotation.Nullable;
+import android.annotation.UserIdInt;
import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
@@ -53,6 +54,7 @@
private final ResumeMediaBrowserLogger mLogger;
private final ComponentName mComponentName;
private final MediaController.Callback mMediaControllerCallback = new SessionDestroyCallback();
+ @UserIdInt private final int mUserId;
private MediaBrowser mMediaBrowser;
@Nullable private MediaController mMediaController;
@@ -62,18 +64,21 @@
* @param context the context
* @param callback used to report media items found
* @param componentName Component name of the MediaBrowserService this browser will connect to
+ * @param userId ID of the current user
*/
public ResumeMediaBrowser(
Context context,
@Nullable Callback callback,
ComponentName componentName,
MediaBrowserFactory browserFactory,
- ResumeMediaBrowserLogger logger) {
+ ResumeMediaBrowserLogger logger,
+ @UserIdInt int userId) {
mContext = context;
mCallback = callback;
mComponentName = componentName;
mBrowserFactory = browserFactory;
mLogger = logger;
+ mUserId = userId;
}
/**
@@ -285,6 +290,14 @@
}
/**
+ * Get the ID of the user associated with this broswer
+ * @return the user ID
+ */
+ public @UserIdInt int getUserId() {
+ return mUserId;
+ }
+
+ /**
* Get the media session token
* @return the token, or null if the MediaBrowser is null or disconnected
*/
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/resume/ResumeMediaBrowserFactory.java b/packages/SystemUI/src/com/android/systemui/media/controls/resume/ResumeMediaBrowserFactory.java
index c558227..e374191 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/resume/ResumeMediaBrowserFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/resume/ResumeMediaBrowserFactory.java
@@ -16,6 +16,7 @@
package com.android.systemui.media.controls.resume;
+import android.annotation.UserIdInt;
import android.content.ComponentName;
import android.content.Context;
@@ -42,10 +43,12 @@
*
* @param callback will be called on connection or error, and addTrack when media item found
* @param componentName component to browse
+ * @param userId ID of the current user
* @return
*/
public ResumeMediaBrowser create(ResumeMediaBrowser.Callback callback,
- ComponentName componentName) {
- return new ResumeMediaBrowser(mContext, callback, componentName, mBrowserFactory, mLogger);
+ ComponentName componentName, @UserIdInt int userId) {
+ return new ResumeMediaBrowser(mContext, callback, componentName, mBrowserFactory, mLogger,
+ userId);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselController.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselController.kt
index 1e9a466..70b5e75 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselController.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselController.kt
@@ -21,6 +21,8 @@
import android.content.Intent
import android.content.res.ColorStateList
import android.content.res.Configuration
+import android.database.ContentObserver
+import android.provider.Settings
import android.provider.Settings.ACTION_MEDIA_CONTROLS_SETTINGS
import android.util.Log
import android.util.MathUtils
@@ -64,6 +66,7 @@
import com.android.systemui.util.animation.UniqueObjectHostView
import com.android.systemui.util.animation.requiresRemeasuring
import com.android.systemui.util.concurrency.DelayableExecutor
+import com.android.systemui.util.settings.GlobalSettings
import com.android.systemui.util.time.SystemClock
import com.android.systemui.util.traceSection
import java.io.PrintWriter
@@ -105,6 +108,7 @@
private val mediaFlags: MediaFlags,
private val keyguardUpdateMonitor: KeyguardUpdateMonitor,
private val keyguardTransitionInteractor: KeyguardTransitionInteractor,
+ private val globalSettings: GlobalSettings,
) : Dumpable {
/** The current width of the carousel */
var currentCarouselWidth: Int = 0
@@ -169,6 +173,13 @@
private var carouselLocale: Locale? = null
+ private val animationScaleObserver: ContentObserver =
+ object : ContentObserver(null) {
+ override fun onChange(selfChange: Boolean) {
+ MediaPlayerData.players().forEach { it.updateAnimatorDurationScale() }
+ }
+ }
+
/** Whether the media card currently has the "expanded" layout */
@VisibleForTesting
var currentlyExpanded = true
@@ -529,6 +540,12 @@
listenForAnyStateToGoneKeyguardTransition(this)
}
}
+
+ // Notifies all active players about animation scale changes.
+ globalSettings.registerContentObserver(
+ Settings.Global.getUriFor(Settings.Global.ANIMATOR_DURATION_SCALE),
+ animationScaleObserver
+ )
}
private fun inflateSettingsButton() {
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaControlPanel.java b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaControlPanel.java
index 0819d0d..35082fd 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaControlPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaControlPanel.java
@@ -34,7 +34,6 @@
import android.content.res.ColorStateList;
import android.content.res.Configuration;
import android.content.res.Resources;
-import android.database.ContentObserver;
import android.graphics.Bitmap;
import android.graphics.BlendMode;
import android.graphics.Color;
@@ -252,13 +251,6 @@
private boolean mWasPlaying = false;
private boolean mButtonClicked = false;
- private ContentObserver mAnimationScaleObserver = new ContentObserver(null) {
- @Override
- public void onChange(boolean selfChange) {
- updateAnimatorDurationScale();
- }
- };
-
/**
* Initialize a new control panel
*
@@ -318,10 +310,6 @@
mFeatureFlags = featureFlags;
mGlobalSettings = globalSettings;
- mGlobalSettings.registerContentObserver(
- Settings.Global.getUriFor(Settings.Global.ANIMATOR_DURATION_SCALE),
- mAnimationScaleObserver
- );
updateAnimatorDurationScale();
}
@@ -405,7 +393,10 @@
updateSeekBarVisibility();
}
- private void updateAnimatorDurationScale() {
+ /**
+ * Reloads animator duration scale.
+ */
+ void updateAnimatorDurationScale() {
if (mSeekBarObserver != null) {
mSeekBarObserver.setAnimationEnabled(
mGlobalSettings.getFloat(Settings.Global.ANIMATOR_DURATION_SCALE, 1f) > 0f);
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java
index 0a5b4b3..7712690 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java
@@ -105,6 +105,7 @@
private WallpaperColors mWallpaperColors;
private boolean mShouldLaunchLeBroadcastDialog;
private boolean mIsLeBroadcastCallbackRegistered;
+ private boolean mDismissing;
MediaOutputBaseAdapter mAdapter;
@@ -265,13 +266,22 @@
mDevicesRecyclerView.setHasFixedSize(false);
// Init bottom buttons
mDoneButton.setOnClickListener(v -> dismiss());
- mStopButton.setOnClickListener(v -> {
- mMediaOutputController.releaseSession();
- dismiss();
- });
+ mStopButton.setOnClickListener(v -> onStopButtonClick());
mAppButton.setOnClickListener(mMediaOutputController::tryToLaunchMediaApplication);
mMediaMetadataSectionLayout.setOnClickListener(
mMediaOutputController::tryToLaunchMediaApplication);
+
+ mDismissing = false;
+ }
+
+ @Override
+ public void dismiss() {
+ // TODO(287191450): remove this once expensive binder calls are removed from refresh().
+ // Due to these binder calls on the UI thread, calling refresh() during dismissal causes
+ // significant frame drops for the dismissal animation. Since the dialog is going away
+ // anyway, we use this state to turn refresh() into a no-op.
+ mDismissing = true;
+ super.dismiss();
}
@Override
@@ -299,7 +309,9 @@
}
void refresh(boolean deviceSetChanged) {
- if (mMediaOutputController.isRefreshing()) {
+ // TODO(287191450): remove binder calls in this method from the UI thread.
+ // If the dialog is going away or is already refreshing, do nothing.
+ if (mDismissing || mMediaOutputController.isRefreshing()) {
return;
}
mMediaOutputController.setRefreshing(true);
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialog.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialog.java
index 19b32e9..f3865f5 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialog.java
@@ -28,6 +28,7 @@
import com.android.internal.logging.UiEvent;
import com.android.internal.logging.UiEventLogger;
import com.android.systemui.R;
+import com.android.systemui.animation.DialogLaunchAnimator;
import com.android.systemui.broadcast.BroadcastSender;
import com.android.systemui.dagger.SysUISingleton;
@@ -36,11 +37,14 @@
*/
@SysUISingleton
public class MediaOutputDialog extends MediaOutputBaseDialog {
- final UiEventLogger mUiEventLogger;
+ private final DialogLaunchAnimator mDialogLaunchAnimator;
+ private final UiEventLogger mUiEventLogger;
MediaOutputDialog(Context context, boolean aboveStatusbar, BroadcastSender broadcastSender,
- MediaOutputController mediaOutputController, UiEventLogger uiEventLogger) {
+ MediaOutputController mediaOutputController, DialogLaunchAnimator dialogLaunchAnimator,
+ UiEventLogger uiEventLogger) {
super(context, broadcastSender, mediaOutputController);
+ mDialogLaunchAnimator = dialogLaunchAnimator;
mUiEventLogger = uiEventLogger;
mAdapter = new MediaOutputAdapter(mMediaOutputController);
if (!aboveStatusbar) {
@@ -138,6 +142,7 @@
}
} else {
mMediaOutputController.releaseSession();
+ mDialogLaunchAnimator.disableAllCurrentDialogsExitAnimations();
dismiss();
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialogFactory.kt b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialogFactory.kt
index 8024886..4c168ec 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialogFactory.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialogFactory.kt
@@ -28,11 +28,11 @@
import com.android.systemui.animation.DialogCuj
import com.android.systemui.animation.DialogLaunchAnimator
import com.android.systemui.broadcast.BroadcastSender
+import com.android.systemui.flags.FeatureFlags
import com.android.systemui.media.nearby.NearbyMediaDevicesManager
import com.android.systemui.plugins.ActivityStarter
-import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection
-import com.android.systemui.flags.FeatureFlags
import com.android.systemui.settings.UserTracker
+import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection
import java.util.Optional
import javax.inject.Inject
@@ -71,7 +71,8 @@
dialogLaunchAnimator, nearbyMediaDevicesManagerOptional, audioManager,
powerExemptionManager, keyGuardManager, featureFlags, userTracker)
val dialog =
- MediaOutputDialog(context, aboveStatusBar, broadcastSender, controller, uiEventLogger)
+ MediaOutputDialog(context, aboveStatusBar, broadcastSender, controller,
+ dialogLaunchAnimator, uiEventLogger)
mediaOutputDialog = dialog
// Show the dialog.
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 cf192f9..7b86d0a 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
@@ -264,6 +264,7 @@
private boolean mGestureBlockingActivityRunning;
private boolean mIsNewBackAffordanceEnabled;
private boolean mIsTrackpadGestureFeaturesEnabled;
+ private boolean mIsTrackpadThreeFingerSwipe;
private boolean mIsButtonForcedVisible;
private InputMonitor mInputMonitor;
@@ -986,18 +987,21 @@
(int) mEndPoint.x, (int) mEndPoint.y,
mEdgeWidthLeft + mLeftInset,
mDisplaySize.x - (mEdgeWidthRight + mRightInset),
- mUseMLModel ? mMLResults : -2, logPackageName);
+ mUseMLModel ? mMLResults : -2, logPackageName,
+ mIsTrackpadThreeFingerSwipe ? SysUiStatsLog.BACK_GESTURE__INPUT_TYPE__TRACKPAD
+ : SysUiStatsLog.BACK_GESTURE__INPUT_TYPE__TOUCH);
}
private void onMotionEvent(MotionEvent ev) {
int action = ev.getActionMasked();
- boolean isTrackpadThreeFingerSwipe = isTrackpadThreeFingerSwipe(
- mIsTrackpadGestureFeaturesEnabled, ev);
if (action == MotionEvent.ACTION_DOWN) {
if (DEBUG_MISSING_GESTURE) {
Log.d(DEBUG_MISSING_GESTURE_TAG, "Start gesture: " + ev);
}
+ mIsTrackpadThreeFingerSwipe = isTrackpadThreeFingerSwipe(
+ mIsTrackpadGestureFeaturesEnabled, ev);
+
// ACTION_UP or ACTION_CANCEL is not guaranteed to be called before a new
// ACTION_DOWN, in that case we should just reuse the old instance.
mVelocityTracker.clear();
@@ -1005,7 +1009,7 @@
// Verify if this is in within the touch region and we aren't in immersive mode, and
// either the bouncer is showing or the notification panel is hidden
mInputEventReceiver.setBatchingEnabled(false);
- if (isTrackpadThreeFingerSwipe) {
+ if (mIsTrackpadThreeFingerSwipe) {
// Since trackpad gestures don't have zones, this will be determined later by the
// direction of the gesture. {@code mIsOnLeftEdge} is set to false to begin with.
mDeferSetIsOnLeftEdge = true;
@@ -1021,11 +1025,11 @@
&& !mGestureBlockingActivityRunning
&& !QuickStepContract.isBackGestureDisabled(mSysUiFlags)
&& !isTrackpadScroll(mIsTrackpadGestureFeaturesEnabled, ev);
- if (isTrackpadThreeFingerSwipe) {
+ if (mIsTrackpadThreeFingerSwipe) {
// Trackpad back gestures don't have zones, so we don't need to check if the down
// event is within insets.
mAllowGesture = isBackAllowedCommon && isValidTrackpadBackGesture(
- isTrackpadThreeFingerSwipe);
+ true /* isTrackpadEvent */);
} else {
mAllowGesture = isBackAllowedCommon && !mUsingThreeButtonNav && isWithinInsets
&& isWithinTouchRegion((int) ev.getX(), (int) ev.getY())
@@ -1036,7 +1040,7 @@
mEdgeBackPlugin.onMotionEvent(ev);
dispatchToBackAnimation(ev);
}
- if (mLogGesture || isTrackpadThreeFingerSwipe) {
+ if (mLogGesture || mIsTrackpadThreeFingerSwipe) {
mDownPoint.set(ev.getX(), ev.getY());
mEndPoint.set(-1, -1);
mThresholdCrossed = false;
@@ -1050,7 +1054,7 @@
"Gesture [%d [%s],alw=%B, t3fs=%B, left=%B, defLeft=%B, backAlw=%B, disbld=%B,"
+ " qsDisbld=%b, blkdAct=%B, pip=%B,"
+ " disp=%s, wl=%d, il=%d, wr=%d, ir=%d, excl=%s]",
- curTime, curTimeStr, mAllowGesture, isTrackpadThreeFingerSwipe,
+ curTime, curTimeStr, mAllowGesture, mIsTrackpadThreeFingerSwipe,
mIsOnLeftEdge, mDeferSetIsOnLeftEdge, mIsBackGestureAllowed,
QuickStepContract.isBackGestureDisabled(mSysUiFlags), mDisabledForQuickstep,
mGestureBlockingActivityRunning, mIsInPip, mDisplaySize,
@@ -1059,7 +1063,7 @@
if (!mThresholdCrossed) {
mEndPoint.x = (int) ev.getX();
mEndPoint.y = (int) ev.getY();
- if (action == MotionEvent.ACTION_POINTER_DOWN && !isTrackpadThreeFingerSwipe) {
+ if (action == MotionEvent.ACTION_POINTER_DOWN && !mIsTrackpadThreeFingerSwipe) {
if (mAllowGesture) {
logGesture(SysUiStatsLog.BACK_GESTURE__TYPE__INCOMPLETE_MULTI_TOUCH);
if (DEBUG_MISSING_GESTURE) {
@@ -1071,7 +1075,7 @@
mLogGesture = false;
return;
} else if (action == MotionEvent.ACTION_MOVE) {
- if (isTrackpadThreeFingerSwipe && mDeferSetIsOnLeftEdge) {
+ if (mIsTrackpadThreeFingerSwipe && mDeferSetIsOnLeftEdge) {
// mIsOnLeftEdge is determined by the relative position between the down
// and the current motion event for trackpad gestures instead of zoning.
mIsOnLeftEdge = mEndPoint.x > mDownPoint.x;
diff --git a/packages/SystemUI/src/com/android/systemui/scene/ui/view/WindowRootView.kt b/packages/SystemUI/src/com/android/systemui/scene/ui/view/WindowRootView.kt
index e118f1f..860ebcb 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/ui/view/WindowRootView.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/ui/view/WindowRootView.kt
@@ -33,6 +33,7 @@
}
private fun isRoot(): Boolean {
+ // TODO(b/283300105): remove this check once there's only one subclass of WindowRootView.
return parent.let { it !is View || it.id == android.R.id.content }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/CombinedShadeHeadersConstraintManagerImpl.kt b/packages/SystemUI/src/com/android/systemui/shade/CombinedShadeHeadersConstraintManagerImpl.kt
index 7e0f504..a9b3d0a 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/CombinedShadeHeadersConstraintManagerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/CombinedShadeHeadersConstraintManagerImpl.kt
@@ -31,8 +31,7 @@
val constraintAlpha = if (visible) 0f else 1f
return ConstraintsChanges(
qqsConstraintsChanges = {
- setAlpha(R.id.statusIcons, constraintAlpha)
- setAlpha(R.id.batteryRemainingIcon, constraintAlpha)
+ setAlpha(R.id.shade_header_system_icons, constraintAlpha)
}
)
}
@@ -45,14 +44,15 @@
R.id.barrier,
ConstraintSet.START,
0,
- R.id.statusIcons,
+ R.id.shade_header_system_icons,
R.id.privacy_container
)
- connect(R.id.statusIcons, ConstraintSet.START, R.id.date, ConstraintSet.END)
+ connect(R.id.shade_header_system_icons, ConstraintSet.START, R.id.date,
+ ConstraintSet.END)
connect(R.id.privacy_container, ConstraintSet.START, R.id.date, ConstraintSet.END)
- constrainWidth(R.id.statusIcons, ViewGroup.LayoutParams.WRAP_CONTENT)
+ constrainWidth(R.id.shade_header_system_icons, ViewGroup.LayoutParams.WRAP_CONTENT)
constrainedWidth(R.id.date, true)
- constrainedWidth(R.id.statusIcons, true)
+ constrainedWidth(R.id.shade_header_system_icons, true)
}
)
}
@@ -84,7 +84,7 @@
setGuidelineEnd(centerEnd, offsetFromEdge)
connect(R.id.date, ConstraintSet.END, centerStart, ConstraintSet.START)
connect(
- R.id.statusIcons,
+ R.id.shade_header_system_icons,
ConstraintSet.START,
centerEnd,
ConstraintSet.END
@@ -96,7 +96,7 @@
ConstraintSet.END
)
constrainedWidth(R.id.date, true)
- constrainedWidth(R.id.statusIcons, true)
+ constrainedWidth(R.id.shade_header_system_icons, true)
},
qsConstraintsChanges = {
setGuidelineBegin(centerStart, offsetFromEdge)
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
index f7cacb9..2ef9e07 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
@@ -90,7 +90,6 @@
import com.android.app.animation.Interpolators;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.jank.InteractionJankMonitor;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.policy.SystemBarUtils;
@@ -158,6 +157,7 @@
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener;
import com.android.systemui.shade.transition.ShadeTransitionController;
+import com.android.systemui.shared.system.InteractionJankMonitorWrapper;
import com.android.systemui.shared.system.QuickStepContract;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.GestureRecorder;
@@ -349,7 +349,6 @@
private final NotificationGutsManager mGutsManager;
private final AlternateBouncerInteractor mAlternateBouncerInteractor;
private final QuickSettingsController mQsController;
- private final InteractionJankMonitor mInteractionJankMonitor;
private final TouchHandler mTouchHandler = new TouchHandler();
private long mDownTime;
@@ -362,6 +361,7 @@
/** The current squish amount for the predictive back animation */
private float mCurrentBackProgress = 0.0f;
private boolean mTracking;
+ private boolean mIsTrackingExpansionFromStatusBar;
private boolean mHintAnimationRunning;
private KeyguardBottomAreaView mKeyguardBottomArea;
private boolean mExpanding;
@@ -727,7 +727,6 @@
NotificationStackSizeCalculator notificationStackSizeCalculator,
UnlockedScreenOffAnimationController unlockedScreenOffAnimationController,
ShadeTransitionController shadeTransitionController,
- InteractionJankMonitor interactionJankMonitor,
SystemClock systemClock,
KeyguardBottomAreaViewModel keyguardBottomAreaViewModel,
KeyguardBottomAreaInteractor keyguardBottomAreaInteractor,
@@ -746,7 +745,6 @@
ActivityStarter activityStarter,
KeyguardViewConfigurator keyguardViewConfigurator,
KeyguardFaceAuthInteractor keyguardFaceAuthInteractor) {
- mInteractionJankMonitor = interactionJankMonitor;
keyguardStateController.addCallback(new KeyguardStateController.Callback() {
@Override
public void onKeyguardFadingAwayChanged() {
@@ -1034,7 +1032,7 @@
new NsslHeightChangedListener());
mNotificationStackScrollLayoutController.setOnEmptySpaceClickListener(
mOnEmptySpaceClickListener);
- mQsController.initNotificationStackScrollLayoutController();
+ mQsController.init();
mShadeExpansionStateManager.addQsExpansionListener(this::onQsExpansionChanged);
mShadeHeadsUpTracker.addTrackingHeadsUpListener(
mNotificationStackScrollLayoutController::setTrackingHeadsUp);
@@ -1822,6 +1820,7 @@
// Set after notifyExpandingStarted, as notifyExpandingStarted resets the closing state.
setClosing(true);
+ mUpdateFlingOnLayout = false;
if (delayed) {
mNextCollapseSpeedUpFactor = speedUpFactor;
this.mView.postDelayed(mFlingCollapseRunnable, 120);
@@ -2665,6 +2664,8 @@
private void onTrackingStopped(boolean expand) {
mFalsingCollector.onTrackingStopped();
mTracking = false;
+ maybeStopTrackingExpansionFromStatusBar(expand);
+
updateExpansionAndVisibility();
if (expand) {
mNotificationStackScrollLayoutController.setOverScrollAmount(0.0f, true /* onTop */,
@@ -4036,6 +4037,42 @@
}
@Override
+ public void startTrackingExpansionFromStatusBar() {
+ mIsTrackingExpansionFromStatusBar = true;
+ InteractionJankMonitorWrapper.begin(
+ mView, InteractionJankMonitorWrapper.CUJ_SHADE_EXPAND_FROM_STATUS_BAR);
+ }
+
+ /**
+ * Stops tracking an expansion that originated from the status bar (if we had started tracking
+ * it).
+ *
+ * @param expand the expand boolean passed to {@link #onTrackingStopped(boolean)}.
+ */
+ private void maybeStopTrackingExpansionFromStatusBar(boolean expand) {
+ if (!mIsTrackingExpansionFromStatusBar) {
+ return;
+ }
+ mIsTrackingExpansionFromStatusBar = false;
+
+ // Determine whether the shade actually expanded due to the status bar touch:
+ // - If the user just taps on the status bar, then #isExpanded is false but
+ // #onTrackingStopped is called with `true`.
+ // - If the user drags down on the status bar but doesn't drag down far enough, then
+ // #onTrackingStopped is called with `false` but #isExpanded is true.
+ // So, we need *both* #onTrackingStopped called with `true` *and* #isExpanded to be true in
+ // order to confirm that the shade successfully opened.
+ boolean shadeExpansionFromStatusBarSucceeded = expand && isExpanded();
+ if (shadeExpansionFromStatusBarSucceeded) {
+ InteractionJankMonitorWrapper.end(
+ InteractionJankMonitorWrapper.CUJ_SHADE_EXPAND_FROM_STATUS_BAR);
+ } else {
+ InteractionJankMonitorWrapper.cancel(
+ InteractionJankMonitorWrapper.CUJ_SHADE_EXPAND_FROM_STATUS_BAR);
+ }
+ }
+
+ @Override
public void updateTouchableRegion() {
//A layout will ensure that onComputeInternalInsets will be called and after that we can
// resize the layout. Make sure that the window stays small for one frame until the
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java
index ade59d7..5c41d57 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java
@@ -58,6 +58,7 @@
import com.android.systemui.multishade.domain.interactor.MultiShadeInteractor;
import com.android.systemui.multishade.domain.interactor.MultiShadeMotionEventInteractor;
import com.android.systemui.multishade.ui.view.MultiShadeView;
+import com.android.systemui.power.domain.interactor.PowerInteractor;
import com.android.systemui.shared.animation.DisableSubpixelTextTransitionListener;
import com.android.systemui.statusbar.DragDownHelper;
import com.android.systemui.statusbar.LockscreenShadeTransitionController;
@@ -113,6 +114,7 @@
private PhoneStatusBarViewController mStatusBarViewController;
private final CentralSurfaces mService;
private final BackActionInteractor mBackActionInteractor;
+ private final PowerInteractor mPowerInteractor;
private final NotificationShadeWindowController mNotificationShadeWindowController;
private DragDownHelper mDragDownHelper;
private boolean mExpandingBelowNotch;
@@ -147,6 +149,7 @@
LockIconViewController lockIconViewController,
CentralSurfaces centralSurfaces,
BackActionInteractor backActionInteractor,
+ PowerInteractor powerInteractor,
NotificationShadeWindowController controller,
Optional<UnfoldTransitionProgressProvider> unfoldTransitionProgressProvider,
KeyguardUnlockAnimationController keyguardUnlockAnimationController,
@@ -179,6 +182,7 @@
mBackActionInteractor = backActionInteractor;
mLockIconViewController.init();
mService = centralSurfaces;
+ mPowerInteractor = powerInteractor;
mNotificationShadeWindowController = controller;
mKeyguardUnlockAnimationController = keyguardUnlockAnimationController;
mAmbientState = ambientState;
@@ -311,8 +315,7 @@
/* onGestureDetectedRunnable */
() -> {
mService.userActivity();
- mService.wakeUpIfDozing(
- mClock.uptimeMillis(),
+ mPowerInteractor.wakeUpIfDozing(
"LOCK_ICON_TOUCH",
PowerManager.WAKE_REASON_GESTURE);
}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsController.java b/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsController.java
index 91e2aa0..1361c9f 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsController.java
@@ -78,6 +78,7 @@
import com.android.systemui.plugins.qs.QS;
import com.android.systemui.screenrecord.RecordingController;
import com.android.systemui.shade.data.repository.ShadeRepository;
+import com.android.systemui.shade.domain.interactor.ShadeInteractor;
import com.android.systemui.shade.transition.ShadeTransitionController;
import com.android.systemui.shared.system.QuickStepContract;
import com.android.systemui.statusbar.LockscreenShadeTransitionController;
@@ -101,6 +102,7 @@
import com.android.systemui.statusbar.policy.CastController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.util.LargeScreenUtils;
+import com.android.systemui.util.kotlin.JavaAdapter;
import dagger.Lazy;
@@ -153,6 +155,8 @@
private final FeatureFlags mFeatureFlags;
private final InteractionJankMonitor mInteractionJankMonitor;
private final ShadeRepository mShadeRepository;
+ private final ShadeInteractor mShadeInteractor;
+ private final JavaAdapter mJavaAdapter;
private final FalsingManager mFalsingManager;
private final AccessibilityManager mAccessibilityManager;
private final MetricsLogger mMetricsLogger;
@@ -342,6 +346,8 @@
DumpManager dumpManager,
KeyguardFaceAuthInteractor keyguardFaceAuthInteractor,
ShadeRepository shadeRepository,
+ ShadeInteractor shadeInteractor,
+ JavaAdapter javaAdapter,
CastController castController
) {
mPanelViewControllerLazy = panelViewControllerLazy;
@@ -387,6 +393,8 @@
mFeatureFlags = featureFlags;
mInteractionJankMonitor = interactionJankMonitor;
mShadeRepository = shadeRepository;
+ mShadeInteractor = shadeInteractor;
+ mJavaAdapter = javaAdapter;
mLockscreenShadeTransitionController.addCallback(new LockscreenShadeTransitionCallback());
dumpManager.registerDumpable(this);
@@ -459,7 +467,13 @@
}
// TODO (b/265054088): move this and others to a CoreStartable
- void initNotificationStackScrollLayoutController() {
+ void init() {
+ initNotificationStackScrollLayoutController();
+ mJavaAdapter.alwaysCollectFlow(
+ mShadeInteractor.isExpandToQsEnabled(), this::setExpansionEnabledPolicy);
+ }
+
+ private void initNotificationStackScrollLayoutController() {
mNotificationStackScrollLayoutController.setOverscrollTopChangedListener(
new NsslOverscrollTopChangedListener());
mNotificationStackScrollLayoutController.setOnStackYChanged(this::onStackYChanged);
@@ -883,7 +897,7 @@
}
/** */
- public void setExpansionEnabledPolicy(boolean expansionEnabledPolicy) {
+ private void setExpansionEnabledPolicy(boolean expansionEnabledPolicy) {
mExpansionEnabledPolicy = expansionEnabledPolicy;
if (mQs != null) {
mQs.setHeaderClickable(isExpansionEnabled());
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeViewController.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeViewController.kt
index 05d2bc6..3d9fcf9 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeViewController.kt
@@ -231,6 +231,9 @@
/** Sends an external (e.g. Status Bar) touch event to the Shade touch handler. */
fun handleExternalTouch(event: MotionEvent): Boolean
+ /** Starts tracking a shade expansion gesture that originated from the status bar. */
+ fun startTrackingExpansionFromStatusBar()
+
// ******* End Keyguard Section *********
/** Returns the ShadeHeadsUpTracker. */
diff --git a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractor.kt b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractor.kt
new file mode 100644
index 0000000..eceda84
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractor.kt
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.shade.domain.interactor
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.keyguard.data.repository.KeyguardRepository
+import com.android.systemui.statusbar.disableflags.data.repository.DisableFlagsRepository
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.UserSetupRepository
+import com.android.systemui.statusbar.policy.DeviceProvisionedController
+import com.android.systemui.user.domain.interactor.UserInteractor
+import javax.inject.Inject
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.combine
+
+/** Business logic for shade interactions. */
+@SysUISingleton
+class ShadeInteractor
+@Inject
+constructor(
+ disableFlagsRepository: DisableFlagsRepository,
+ keyguardRepository: KeyguardRepository,
+ userSetupRepository: UserSetupRepository,
+ deviceProvisionedController: DeviceProvisionedController,
+ userInteractor: UserInteractor,
+) {
+ /** Emits true if the shade can be expanded from QQS to QS and false otherwise. */
+ val isExpandToQsEnabled: Flow<Boolean> =
+ combine(
+ disableFlagsRepository.disableFlags,
+ keyguardRepository.isDozing,
+ userSetupRepository.isUserSetupFlow,
+ ) { disableFlags, isDozing, isUserSetup ->
+ deviceProvisionedController.isDeviceProvisioned &&
+ // Disallow QS during setup if it's a simple user switcher. (The user intends to
+ // use the lock screen user switcher, QS is not needed.)
+ (isUserSetup || !userInteractor.isSimpleUserSwitcher) &&
+ disableFlags.isShadeEnabled() &&
+ disableFlags.isQuickSettingsEnabled() &&
+ !isDozing
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
index 795bcad..9692482 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
@@ -56,7 +56,6 @@
import android.graphics.Color;
import android.hardware.biometrics.BiometricSourceType;
import android.hardware.face.FaceManager;
-import android.hardware.fingerprint.FingerprintManager;
import android.os.BatteryManager;
import android.os.Handler;
import android.os.Looper;
@@ -86,6 +85,8 @@
import com.android.systemui.R;
import com.android.systemui.biometrics.AuthController;
import com.android.systemui.biometrics.FaceHelpMessageDeferral;
+import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor;
+import com.android.systemui.bouncer.domain.interactor.BouncerMessageInteractor;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Background;
@@ -95,8 +96,7 @@
import com.android.systemui.keyguard.KeyguardIndication;
import com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController;
import com.android.systemui.keyguard.ScreenLifecycle;
-import com.android.systemui.bouncer.domain.interactor.BouncerMessageInteractor;
-import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor;
+import com.android.systemui.keyguard.util.IndicationHelper;
import com.android.systemui.log.LogLevel;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
@@ -227,7 +227,8 @@
// triggered while the device is asleep
private final AlarmTimeout mHideTransientMessageHandler;
private final AlarmTimeout mHideBiometricMessageHandler;
- private FeatureFlags mFeatureFlags;
+ private final FeatureFlags mFeatureFlags;
+ private final IndicationHelper mIndicationHelper;
/**
* Creates a new KeyguardIndicationController and registers callbacks.
@@ -259,7 +260,8 @@
AlarmManager alarmManager,
UserTracker userTracker,
BouncerMessageInteractor bouncerMessageInteractor,
- FeatureFlags flags
+ FeatureFlags flags,
+ IndicationHelper indicationHelper
) {
mContext = context;
mBroadcastDispatcher = broadcastDispatcher;
@@ -286,6 +288,7 @@
mUserTracker = userTracker;
mBouncerMessageInteractor = bouncerMessageInteractor;
mFeatureFlags = flags;
+ mIndicationHelper = indicationHelper;
mFaceAcquiredMessageDeferral = faceHelpMessageDeferral;
mCoExFaceAcquisitionMsgIdsToShow = new HashSet<>();
@@ -1249,13 +1252,13 @@
private void onFaceAuthError(int msgId, String errString) {
CharSequence deferredFaceMessage = mFaceAcquiredMessageDeferral.getDeferredMessage();
mFaceAcquiredMessageDeferral.reset();
- if (shouldSuppressFaceError(msgId)) {
- mKeyguardLogger.logBiometricMessage("suppressingFaceError", msgId, errString);
+ if (mIndicationHelper.shouldSuppressErrorMsg(FACE, msgId)) {
+ mKeyguardLogger.logBiometricMessage("KIC suppressingFaceError", msgId, errString);
return;
}
if (msgId == FaceManager.FACE_ERROR_TIMEOUT) {
handleFaceAuthTimeoutError(deferredFaceMessage);
- } else if (isLockoutError(msgId)) {
+ } else if (mIndicationHelper.isFaceLockoutErrorMsg(msgId)) {
handleFaceLockoutError(errString);
} else {
showErrorMessageNowOrLater(errString, null);
@@ -1263,8 +1266,8 @@
}
private void onFingerprintAuthError(int msgId, String errString) {
- if (shouldSuppressFingerprintError(msgId)) {
- mKeyguardLogger.logBiometricMessage("suppressingFingerprintError",
+ if (mIndicationHelper.shouldSuppressErrorMsg(FINGERPRINT, msgId)) {
+ mKeyguardLogger.logBiometricMessage("KIC suppressingFingerprintError",
msgId,
errString);
} else {
@@ -1272,19 +1275,6 @@
}
}
- private boolean shouldSuppressFingerprintError(int msgId) {
- return ((isPrimaryAuthRequired() && !isLockoutError(msgId))
- || msgId == FingerprintManager.FINGERPRINT_ERROR_CANCELED
- || msgId == FingerprintManager.FINGERPRINT_ERROR_USER_CANCELED
- || msgId == FingerprintManager.BIOMETRIC_ERROR_POWER_PRESSED);
- }
-
- private boolean shouldSuppressFaceError(int msgId) {
- return ((isPrimaryAuthRequired() && msgId != FaceManager.FACE_ERROR_LOCKOUT_PERMANENT)
- || msgId == FaceManager.FACE_ERROR_CANCELED
- || msgId == FaceManager.FACE_ERROR_UNABLE_TO_PROCESS);
- }
-
@Override
public void onTrustChanged(int userId) {
if (!isCurrentUser(userId)) return;
@@ -1408,11 +1398,6 @@
return mContext.getString(followupMsgId);
}
- private static boolean isLockoutError(int msgId) {
- return msgId == FaceManager.FACE_ERROR_LOCKOUT_PERMANENT
- || msgId == FaceManager.FACE_ERROR_LOCKOUT;
- }
-
private void handleFaceAuthTimeoutError(@Nullable CharSequence deferredFaceMessage) {
mKeyguardLogger.logBiometricMessage("deferred message after face auth timeout",
null, String.valueOf(deferredFaceMessage));
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
index c519115..da84afe 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
@@ -27,7 +27,6 @@
import android.os.PowerManager;
import android.os.RemoteException;
import android.os.ServiceManager;
-import android.os.SystemClock;
import android.os.SystemProperties;
import android.os.UserManager;
import android.service.notification.StatusBarNotification;
@@ -52,6 +51,7 @@
import com.android.systemui.R;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.power.domain.interactor.PowerInteractor;
import com.android.systemui.statusbar.dagger.CentralSurfacesDependenciesModule;
import com.android.systemui.statusbar.notification.NotifPipelineFlags;
import com.android.systemui.statusbar.notification.RemoteInputControllerLogger;
@@ -60,19 +60,15 @@
import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
import com.android.systemui.statusbar.notification.logging.NotificationLogger;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
-import com.android.systemui.statusbar.phone.CentralSurfaces;
import com.android.systemui.statusbar.policy.RemoteInputUriController;
import com.android.systemui.statusbar.policy.RemoteInputView;
import com.android.systemui.util.DumpUtilsKt;
import com.android.systemui.util.ListenerSet;
-import dagger.Lazy;
-
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
-import java.util.Optional;
import java.util.function.Consumer;
/**
@@ -95,10 +91,8 @@
private final NotificationLockscreenUserManager mLockscreenUserManager;
private final SmartReplyController mSmartReplyController;
private final NotificationVisibilityProvider mVisibilityProvider;
+ private final PowerInteractor mPowerInteractor;
private final ActionClickLogger mLogger;
-
- private final Lazy<Optional<CentralSurfaces>> mCentralSurfacesOptionalLazy;
-
protected final Context mContext;
protected final NotifPipelineFlags mNotifPipelineFlags;
private final UserManager mUserManager;
@@ -122,10 +116,8 @@
@Override
public boolean onInteraction(
View view, PendingIntent pendingIntent, RemoteViews.RemoteResponse response) {
- mCentralSurfacesOptionalLazy.get().ifPresent(
- centralSurfaces -> centralSurfaces.wakeUpIfDozing(
- SystemClock.uptimeMillis(), "NOTIFICATION_CLICK",
- PowerManager.WAKE_REASON_GESTURE));
+ mPowerInteractor.wakeUpIfDozing(
+ "NOTIFICATION_CLICK", PowerManager.WAKE_REASON_GESTURE);
final NotificationEntry entry = getNotificationForParent(view.getParent());
mLogger.logInitialClick(entry, pendingIntent);
@@ -259,7 +251,7 @@
NotificationLockscreenUserManager lockscreenUserManager,
SmartReplyController smartReplyController,
NotificationVisibilityProvider visibilityProvider,
- Lazy<Optional<CentralSurfaces>> centralSurfacesOptionalLazy,
+ PowerInteractor powerInteractor,
StatusBarStateController statusBarStateController,
RemoteInputUriController remoteInputUriController,
RemoteInputControllerLogger remoteInputControllerLogger,
@@ -271,7 +263,7 @@
mLockscreenUserManager = lockscreenUserManager;
mSmartReplyController = smartReplyController;
mVisibilityProvider = visibilityProvider;
- mCentralSurfacesOptionalLazy = centralSurfacesOptionalLazy;
+ mPowerInteractor = powerInteractor;
mLogger = logger;
mBarService = IStatusBarService.Stub.asInterface(
ServiceManager.getService(Context.STATUS_BAR_SERVICE));
@@ -402,7 +394,7 @@
while (p != null) {
if (p instanceof View) {
View pv = (View) p;
- if (pv.isRootNamespace()) {
+ if (pv.getId() == com.android.internal.R.id.status_bar_latest_event_content) {
riv = findRemoteInputView(pv);
row = (ExpandableNotificationRow) pv.getTag(R.id.row_tag_for_content_view);
break;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/dagger/CentralSurfacesDependenciesModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/dagger/CentralSurfacesDependenciesModule.java
index 73eba0e..075b41b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/dagger/CentralSurfacesDependenciesModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/dagger/CentralSurfacesDependenciesModule.java
@@ -28,6 +28,7 @@
import com.android.systemui.animation.ActivityLaunchAnimator;
import com.android.systemui.animation.AnimationFeatureFlags;
import com.android.systemui.animation.DialogLaunchAnimator;
+import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor;
import com.android.systemui.colorextraction.SysuiColorExtractor;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Main;
@@ -35,10 +36,10 @@
import com.android.systemui.dump.DumpManager;
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.flags.Flags;
-import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor;
import com.android.systemui.media.controls.pipeline.MediaDataManager;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.power.domain.interactor.PowerInteractor;
import com.android.systemui.settings.DisplayTracker;
import com.android.systemui.shade.carrier.ShadeCarrierGroupController;
import com.android.systemui.statusbar.ActionClickLogger;
@@ -79,14 +80,14 @@
import com.android.systemui.util.concurrency.DelayableExecutor;
import com.android.systemui.util.time.SystemClock;
-import java.util.Optional;
-import java.util.concurrent.Executor;
-
import dagger.Binds;
import dagger.Lazy;
import dagger.Module;
import dagger.Provides;
+import java.util.Optional;
+import java.util.concurrent.Executor;
+
/**
* This module provides instances needed to construct {@link CentralSurfacesImpl}. These are moved to
* this separate from {@link CentralSurfacesModule} module so that components that wish to build
@@ -104,7 +105,7 @@
NotificationLockscreenUserManager lockscreenUserManager,
SmartReplyController smartReplyController,
NotificationVisibilityProvider visibilityProvider,
- Lazy<Optional<CentralSurfaces>> centralSurfacesOptionalLazy,
+ PowerInteractor powerInteractor,
StatusBarStateController statusBarStateController,
RemoteInputUriController remoteInputUriController,
RemoteInputControllerLogger remoteInputControllerLogger,
@@ -117,7 +118,7 @@
lockscreenUserManager,
smartReplyController,
visibilityProvider,
- centralSurfacesOptionalLazy,
+ powerInteractor,
statusBarStateController,
remoteInputUriController,
remoteInputControllerLogger,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/disableflags/dagger/DisableFlagsModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/disableflags/dagger/DisableFlagsModule.kt
new file mode 100644
index 0000000..3d5f8df
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/disableflags/dagger/DisableFlagsModule.kt
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.disableflags.dagger
+
+import com.android.systemui.statusbar.disableflags.data.repository.DisableFlagsRepository
+import com.android.systemui.statusbar.disableflags.data.repository.DisableFlagsRepositoryImpl
+import dagger.Binds
+import dagger.Module
+
+/** Provides information related to disable flags. */
+@Module
+abstract class DisableFlagsModule {
+ @Binds
+ abstract fun bindDisableFlagsRepo(impl: DisableFlagsRepositoryImpl): DisableFlagsRepository
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/disableflags/data/model/DisableFlagsModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/disableflags/data/model/DisableFlagsModel.kt
new file mode 100644
index 0000000..ac05248
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/disableflags/data/model/DisableFlagsModel.kt
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.systemui.statusbar.disableflags.data.model
+
+import android.app.StatusBarManager.DISABLE2_NONE
+import android.app.StatusBarManager.DISABLE2_NOTIFICATION_SHADE
+import android.app.StatusBarManager.DISABLE2_QUICK_SETTINGS
+import android.app.StatusBarManager.DISABLE_NONE
+import android.app.StatusBarManager.DISABLE_NOTIFICATION_ALERTS
+import com.android.systemui.log.LogBuffer
+import com.android.systemui.log.LogLevel
+import com.android.systemui.statusbar.disableflags.DisableFlagsLogger
+
+/**
+ * Model for the disable flags that come from [IStatusBar].
+ *
+ * For clients of the disable flags: do *not* refer to the disable integers directly. Instead,
+ * re-use or define a helper method that internally processes the flags. (We want to hide the
+ * bitwise logic here so no one else has to worry about it.)
+ */
+data class DisableFlagsModel(
+ private val disable1: Int = DISABLE_NONE,
+ private val disable2: Int = DISABLE2_NONE,
+) {
+ /** Returns true if notification alerts are allowed based on the flags. */
+ fun areNotificationAlertsEnabled(): Boolean {
+ return (disable1 and DISABLE_NOTIFICATION_ALERTS) == 0
+ }
+
+ /** Returns true if the shade is allowed based on the flags. */
+ fun isShadeEnabled(): Boolean {
+ return (disable2 and DISABLE2_NOTIFICATION_SHADE) == 0
+ }
+
+ /** Returns true if full quick settings are allowed based on the flags. */
+ fun isQuickSettingsEnabled(): Boolean {
+ return (disable2 and DISABLE2_QUICK_SETTINGS) == 0
+ }
+
+ /** Logs the change to the provided buffer. */
+ fun logChange(buffer: LogBuffer, disableFlagsLogger: DisableFlagsLogger) {
+ buffer.log(
+ TAG,
+ LogLevel.INFO,
+ {
+ int1 = disable1
+ int2 = disable2
+ },
+ {
+ disableFlagsLogger.getDisableFlagsString(
+ new = DisableFlagsLogger.DisableState(int1, int2),
+ )
+ }
+ )
+ }
+
+ private companion object {
+ const val TAG = "DisableFlagsModel"
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/disableflags/data/repository/DisableFlagsRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/disableflags/data/repository/DisableFlagsRepository.kt
new file mode 100644
index 0000000..13b74b4
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/disableflags/data/repository/DisableFlagsRepository.kt
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.systemui.statusbar.disableflags.data.repository
+
+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.DisplayId
+import com.android.systemui.log.LogBuffer
+import com.android.systemui.log.dagger.DisableFlagsRepositoryLog
+import com.android.systemui.statusbar.CommandQueue
+import com.android.systemui.statusbar.disableflags.DisableFlagsLogger
+import com.android.systemui.statusbar.disableflags.data.model.DisableFlagsModel
+import com.android.systemui.statusbar.policy.RemoteInputQuickSettingsDisabler
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.channels.awaitClose
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.onEach
+import kotlinx.coroutines.flow.stateIn
+
+/** Repository for the disable flags received from external systems. See [IStatusBar.disable]. */
+interface DisableFlagsRepository {
+ /** A model of the disable flags last received from [IStatusBar]. */
+ val disableFlags: StateFlow<DisableFlagsModel>
+}
+
+@SysUISingleton
+class DisableFlagsRepositoryImpl
+@Inject
+constructor(
+ commandQueue: CommandQueue,
+ @DisplayId private val thisDisplayId: Int,
+ @Application scope: CoroutineScope,
+ remoteInputQuickSettingsDisabler: RemoteInputQuickSettingsDisabler,
+ @DisableFlagsRepositoryLog private val logBuffer: LogBuffer,
+ private val disableFlagsLogger: DisableFlagsLogger,
+) : DisableFlagsRepository {
+ override val disableFlags: StateFlow<DisableFlagsModel> =
+ conflatedCallbackFlow {
+ val callback =
+ object : CommandQueue.Callbacks {
+ override fun disable(
+ displayId: Int,
+ state1: Int,
+ state2: Int,
+ animate: Boolean,
+ ) {
+ if (displayId != thisDisplayId) {
+ return
+ }
+ trySend(
+ DisableFlagsModel(
+ state1,
+ // Ideally, [RemoteInputQuickSettingsDisabler] should instead
+ // expose a flow that gets `combine`d with this [disableFlags]
+ // flow in a [DisableFlagsInteractor] or
+ // [QuickSettingsInteractor]-type class. However, that's out of
+ // scope for the CentralSurfaces removal project.
+ remoteInputQuickSettingsDisabler.adjustDisableFlags(state2),
+ )
+ )
+ }
+ }
+ commandQueue.addCallback(callback)
+ awaitClose { commandQueue.removeCallback(callback) }
+ }
+ .distinctUntilChanged()
+ .onEach { it.logChange(logBuffer, disableFlagsLogger) }
+ // Use Eagerly because we always need to know about disable flags
+ .stateIn(scope, SharingStarted.Eagerly, DisableFlagsModel())
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt
index cf39038..8778463 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt
@@ -176,7 +176,16 @@
now.isBefore(Instant.ofEpochMilli(t.expiryTimeMillis))
}
if (weatherTarget != null) {
- val weatherData = WeatherData.fromBundle(weatherTarget.baseAction.extras)
+ val clickIntent = weatherTarget.headerAction?.intent
+ val weatherData = WeatherData.fromBundle(weatherTarget.baseAction.extras, { v ->
+ if (!falsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) {
+ activityStarter.startActivity(
+ clickIntent,
+ true, /* dismissShade */
+ null,
+ false)
+ }
+ })
if (weatherData != null) {
keyguardUpdateMonitor.sendWeatherData(weatherData)
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationClicker.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationClicker.java
index bab553e..d10fac6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationClicker.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationClicker.java
@@ -17,15 +17,14 @@
import android.app.Notification;
import android.os.PowerManager;
-import android.os.SystemClock;
import android.service.notification.StatusBarNotification;
import android.util.Log;
import android.view.View;
import com.android.systemui.DejankUtils;
+import com.android.systemui.power.domain.interactor.PowerInteractor;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
-import com.android.systemui.statusbar.phone.CentralSurfaces;
import com.android.wm.shell.bubbles.Bubbles;
import java.util.Optional;
@@ -40,7 +39,7 @@
private static final String TAG = "NotificationClicker";
private final NotificationClickerLogger mLogger;
- private final Optional<CentralSurfaces> mCentralSurfacesOptional;
+ private final PowerInteractor mPowerInteractor;
private final Optional<Bubbles> mBubblesOptional;
private final NotificationActivityStarter mNotificationActivityStarter;
@@ -54,11 +53,11 @@
private NotificationClicker(
NotificationClickerLogger logger,
- Optional<CentralSurfaces> centralSurfacesOptional,
+ PowerInteractor powerInteractor,
Optional<Bubbles> bubblesOptional,
NotificationActivityStarter notificationActivityStarter) {
mLogger = logger;
- mCentralSurfacesOptional = centralSurfacesOptional;
+ mPowerInteractor = powerInteractor;
mBubblesOptional = bubblesOptional;
mNotificationActivityStarter = notificationActivityStarter;
}
@@ -70,9 +69,7 @@
return;
}
- mCentralSurfacesOptional.ifPresent(centralSurfaces -> centralSurfaces.wakeUpIfDozing(
- SystemClock.uptimeMillis(), "NOTIFICATION_CLICK",
- PowerManager.WAKE_REASON_GESTURE));
+ mPowerInteractor.wakeUpIfDozing("NOTIFICATION_CLICK", PowerManager.WAKE_REASON_GESTURE);
final ExpandableNotificationRow row = (ExpandableNotificationRow) v;
final NotificationEntry entry = row.getEntry();
@@ -131,21 +128,22 @@
/** Daggerized builder for NotificationClicker. */
public static class Builder {
private final NotificationClickerLogger mLogger;
+ private final PowerInteractor mPowerInteractor;
@Inject
- public Builder(NotificationClickerLogger logger) {
+ public Builder(NotificationClickerLogger logger, PowerInteractor powerInteractor) {
mLogger = logger;
+ mPowerInteractor = powerInteractor;
}
/** Builds an instance. */
public NotificationClicker build(
- Optional<CentralSurfaces> centralSurfacesOptional,
Optional<Bubbles> bubblesOptional,
NotificationActivityStarter notificationActivityStarter
) {
return new NotificationClicker(
mLogger,
- centralSurfacesOptional,
+ mPowerInteractor,
bubblesOptional,
notificationActivityStarter);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifCollection.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifCollection.java
index 2796340..5c72731 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifCollection.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifCollection.java
@@ -875,6 +875,7 @@
&& !hasFlag(entry, Notification.FLAG_ONGOING_EVENT)
&& !hasFlag(entry, Notification.FLAG_BUBBLE)
&& !hasFlag(entry, Notification.FLAG_NO_CLEAR)
+ && (entry.getChannel() == null || !entry.getChannel().isImportantConversation())
&& entry.getDismissState() != DISMISSED;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java
index 38c3723..1896080 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java
@@ -140,7 +140,6 @@
.expandableNotificationRow(row)
.notificationEntry(entry)
.onExpandClickListener(mPresenter)
- .listContainer(mListContainer)
.build();
ExpandableNotificationRowController rowController =
component.getExpandableNotificationRowController();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
index b100d44..31d4ab9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
@@ -63,8 +63,12 @@
import com.android.systemui.statusbar.notification.logging.NotificationPanelLoggerImpl;
import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
import com.android.systemui.statusbar.notification.row.OnUserInteractionCallback;
+import com.android.systemui.statusbar.notification.row.ui.viewmodel.ActivatableNotificationViewModelModule;
+import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
import com.android.systemui.statusbar.notification.stack.NotificationSectionsManager;
+import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
import com.android.systemui.statusbar.notification.stack.StackScrollAlgorithm;
+import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationListViewModelModule;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
import dagger.Binds;
@@ -85,6 +89,8 @@
ShadeEventsModule.class,
NotifPipelineChoreographerModule.class,
NotificationSectionHeadersModule.class,
+ NotificationListViewModelModule.class,
+ ActivatableNotificationViewModelModule.class,
})
public interface NotificationsModule {
@Binds
@@ -159,6 +165,14 @@
}
}
+ /** Provides the container for the notification list. */
+ @Provides
+ @SysUISingleton
+ static NotificationListContainer provideListContainer(
+ NotificationStackScrollLayoutController nsslController) {
+ return nsslController.getNotificationListContainer();
+ }
+
/**
* Provide the active notification collection managing the notifications to render.
*/
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationsInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationsInteractor.kt
new file mode 100644
index 0000000..8f7e269
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationsInteractor.kt
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.domain.interactor
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.statusbar.disableflags.data.repository.DisableFlagsRepository
+import javax.inject.Inject
+
+/** Interactor for notifications in general. */
+@SysUISingleton
+class NotificationsInteractor
+@Inject
+constructor(
+ private val disableFlagsRepository: DisableFlagsRepository,
+) {
+ /** Returns true if notification alerts are allowed. */
+ fun areNotificationAlertsEnabled(): Boolean {
+ return disableFlagsRepository.disableFlags.value.areNotificationAlertsEnabled()
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsController.kt
index c9ebed1..76e228b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsController.kt
@@ -22,7 +22,6 @@
import com.android.systemui.statusbar.notification.NotificationActivityStarter
import com.android.systemui.statusbar.notification.collection.render.NotifStackController
import com.android.systemui.statusbar.notification.stack.NotificationListContainer
-import com.android.systemui.statusbar.phone.CentralSurfaces
/**
* The master controller for all notifications-related work
@@ -32,7 +31,6 @@
*/
interface NotificationsController {
fun initialize(
- centralSurfaces: CentralSurfaces,
presenter: NotificationPresenter,
listContainer: NotificationListContainer,
stackController: NotifStackController,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerImpl.kt
index 6409635..f7bd177 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerImpl.kt
@@ -42,7 +42,6 @@
import com.android.systemui.statusbar.notification.logging.NotificationMemoryMonitor
import com.android.systemui.statusbar.notification.row.NotifBindPipelineInitializer
import com.android.systemui.statusbar.notification.stack.NotificationListContainer
-import com.android.systemui.statusbar.phone.CentralSurfaces
import com.android.wm.shell.bubbles.Bubbles
import dagger.Lazy
import java.util.Optional
@@ -78,7 +77,6 @@
) : NotificationsController {
override fun initialize(
- centralSurfaces: CentralSurfaces,
presenter: NotificationPresenter,
listContainer: NotificationListContainer,
stackController: NotifStackController,
@@ -93,9 +91,7 @@
})
notificationRowBinder.setNotificationClicker(
- clickerBuilder.build(
- Optional.ofNullable(centralSurfaces), bubblesOptional,
- notificationActivityStarter))
+ clickerBuilder.build(bubblesOptional, notificationActivityStarter))
notificationRowBinder.setUpWithPresenter(presenter, listContainer)
headsUpViewBinder.setPresenter(presenter)
notifBindPipelineInitializer.initialize()
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerStub.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerStub.kt
index 302a1f4..65ba6de 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerStub.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerStub.kt
@@ -23,7 +23,6 @@
import com.android.systemui.statusbar.notification.NotificationActivityStarter
import com.android.systemui.statusbar.notification.collection.render.NotifStackController
import com.android.systemui.statusbar.notification.stack.NotificationListContainer
-import com.android.systemui.statusbar.phone.CentralSurfaces
import javax.inject.Inject
/**
@@ -34,7 +33,6 @@
) : NotificationsController {
override fun initialize(
- centralSurfaces: CentralSurfaces,
presenter: NotificationPresenter,
listContainer: NotificationListContainer,
stackController: NotifStackController,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
index 0bfd3c3..30747db 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
@@ -53,6 +53,7 @@
import android.view.NotificationHeaderView;
import android.view.View;
import android.view.ViewGroup;
+import android.view.ViewParent;
import android.view.ViewStub;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
@@ -103,6 +104,8 @@
import com.android.systemui.statusbar.notification.stack.AnimationProperties;
import com.android.systemui.statusbar.notification.stack.ExpandableViewState;
import com.android.systemui.statusbar.notification.stack.NotificationChildrenContainer;
+import com.android.systemui.statusbar.notification.stack.NotificationChildrenContainerLogger;
+import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
import com.android.systemui.statusbar.notification.stack.SwipeableView;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.policy.HeadsUpManager;
@@ -170,6 +173,7 @@
private PeopleNotificationIdentifier mPeopleNotificationIdentifier;
private Optional<BubblesManager> mBubblesManagerOptional;
private MetricsLogger mMetricsLogger;
+ private NotificationChildrenContainerLogger mChildrenContainerLogger;
private NotificationDismissibilityProvider mDismissibilityProvider;
private FeatureFlags mFeatureFlags;
private int mIconTransformContentShift;
@@ -1627,6 +1631,51 @@
NotificationEntry child,
NotificationEntry newParent
);
+
+ /**
+ * Called when an ExpandableNotificationRow transient view is removed from the
+ * NotificationChildrenContainer
+ */
+ void logRemoveTransientFromContainer(
+ NotificationEntry childEntry,
+ NotificationEntry containerEntry
+ );
+
+ /**
+ * Called when an ExpandableNotificationRow transient view is removed from the
+ * NotificationStackScrollLayout
+ */
+ void logRemoveTransientFromNssl(
+ NotificationEntry childEntry
+ );
+
+ /**
+ * Called when an ExpandableNotificationRow transient view is removed from a ViewGroup that
+ * is not NotificationChildrenContainer or NotificationStackScrollLayout
+ */
+ void logRemoveTransientFromViewGroup(
+ NotificationEntry childEntry,
+ ViewGroup containerView
+ );
+
+ /**
+ * Called when an ExpandableNotificationRow transient view is added to this
+ * ExpandableNotificationRow
+ */
+ void logAddTransientRow(
+ NotificationEntry childEntry,
+ NotificationEntry containerEntry,
+ int index
+ );
+
+ /**
+ * Called when an ExpandableNotificationRow transient view is removed from this
+ * ExpandableNotificationRow
+ */
+ void logRemoveTransientRow(
+ NotificationEntry childEntry,
+ NotificationEntry containerEntry
+ );
}
/**
@@ -1668,6 +1717,7 @@
NotificationGutsManager gutsManager,
NotificationDismissibilityProvider dismissibilityProvider,
MetricsLogger metricsLogger,
+ NotificationChildrenContainerLogger childrenContainerLogger,
SmartReplyConstants smartReplyConstants,
SmartReplyController smartReplyController,
FeatureFlags featureFlags,
@@ -1706,6 +1756,7 @@
mBubblesManagerOptional = bubblesManagerOptional;
mNotificationGutsManager = gutsManager;
mMetricsLogger = metricsLogger;
+ mChildrenContainerLogger = childrenContainerLogger;
mDismissibilityProvider = dismissibilityProvider;
mFeatureFlags = featureFlags;
}
@@ -1874,6 +1925,7 @@
mChildrenContainer.setIsLowPriority(mIsLowPriority);
mChildrenContainer.setContainingNotification(ExpandableNotificationRow.this);
mChildrenContainer.onNotificationUpdated();
+ mChildrenContainer.setLogger(mChildrenContainerLogger);
mTranslateableViews.add(mChildrenContainer);
});
@@ -3714,4 +3766,73 @@
public boolean getShowSnooze() {
return mShowSnooze;
}
+
+ @Override
+ public void removeFromTransientContainer() {
+ final ViewGroup transientContainer = getTransientContainer();
+ final ViewParent parent = getParent();
+ // Only log when there is real removal of transient views
+ if (transientContainer == null || transientContainer != parent) {
+ super.removeFromTransientContainer();
+ return;
+ }
+ logRemoveFromTransientContainer(transientContainer);
+ super.removeFromTransientContainer();
+ }
+
+ /**
+ * Log calls to removeFromTransientContainer when the container is NotificationChildrenContainer
+ * or NotificationStackScrollLayout.
+ */
+ public void logRemoveFromTransientContainer(ViewGroup transientContainer) {
+ if (mLogger == null) {
+ return;
+ }
+ if (transientContainer instanceof NotificationChildrenContainer) {
+ mLogger.logRemoveTransientFromContainer(
+ /* childEntry = */ getEntry(),
+ /* containerEntry = */ ((NotificationChildrenContainer) transientContainer)
+ .getContainingNotification().getEntry()
+ );
+ } else if (transientContainer instanceof NotificationStackScrollLayout) {
+ mLogger.logRemoveTransientFromNssl(
+ /* childEntry = */ getEntry()
+ );
+ } else {
+ mLogger.logRemoveTransientFromViewGroup(
+ /* childEntry = */ getEntry(),
+ /* containerView = */ transientContainer
+ );
+ }
+ }
+
+ @Override
+ public void addTransientView(View view, int index) {
+ if (view instanceof ExpandableNotificationRow) {
+ logAddTransientRow((ExpandableNotificationRow) view, index);
+ }
+ super.addTransientView(view, index);
+ }
+
+ private void logAddTransientRow(ExpandableNotificationRow row, int index) {
+ if (mLogger == null) {
+ return;
+ }
+ mLogger.logAddTransientRow(row.getEntry(), getEntry(), index);
+ }
+
+ @Override
+ public void removeTransientView(View view) {
+ if (view instanceof ExpandableNotificationRow) {
+ logRemoveTransientRow((ExpandableNotificationRow) view);
+ }
+ super.removeTransientView(view);
+ }
+
+ private void logRemoveTransientRow(ExpandableNotificationRow row) {
+ if (mLogger == null) {
+ return;
+ }
+ mLogger.logRemoveTransientRow(row.getEntry(), getEntry());
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java
index 1acc9f9..a4e8c2e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java
@@ -50,6 +50,7 @@
import com.android.systemui.statusbar.notification.row.dagger.AppName;
import com.android.systemui.statusbar.notification.row.dagger.NotificationKey;
import com.android.systemui.statusbar.notification.row.dagger.NotificationRowScope;
+import com.android.systemui.statusbar.notification.stack.NotificationChildrenContainerLogger;
import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.policy.HeadsUpManager;
@@ -88,6 +89,7 @@
private final ExpandableNotificationRow.OnExpandClickListener mOnExpandClickListener;
private final StatusBarStateController mStatusBarStateController;
private final MetricsLogger mMetricsLogger;
+ private final NotificationChildrenContainerLogger mChildrenContainerLogger;
private final ExpandableNotificationRow.CoordinateOnClickListener mOnFeedbackClickListener;
private final NotificationGutsManager mNotificationGutsManager;
private final OnUserInteractionCallback mOnUserInteractionCallback;
@@ -125,6 +127,46 @@
) {
mLogBufferLogger.logSkipAttachingKeepInParentChild(child, newParent);
}
+
+ @Override
+ public void logRemoveTransientFromContainer(
+ NotificationEntry childEntry,
+ NotificationEntry containerEntry
+ ) {
+ mLogBufferLogger.logRemoveTransientFromContainer(childEntry, containerEntry);
+ }
+
+ @Override
+ public void logRemoveTransientFromNssl(
+ NotificationEntry childEntry
+ ) {
+ mLogBufferLogger.logRemoveTransientFromNssl(childEntry);
+ }
+
+ @Override
+ public void logRemoveTransientFromViewGroup(
+ NotificationEntry childEntry,
+ ViewGroup containerView
+ ) {
+ mLogBufferLogger.logRemoveTransientFromViewGroup(childEntry, containerView);
+ }
+
+ @Override
+ public void logAddTransientRow(
+ NotificationEntry childEntry,
+ NotificationEntry containerEntry,
+ int index
+ ) {
+ mLogBufferLogger.logAddTransientRow(childEntry, containerEntry, index);
+ }
+
+ @Override
+ public void logRemoveTransientRow(
+ NotificationEntry childEntry,
+ NotificationEntry containerEntry
+ ) {
+ mLogBufferLogger.logRemoveTransientRow(childEntry, containerEntry);
+ }
};
@@ -135,6 +177,7 @@
RemoteInputViewSubcomponent.Factory rivSubcomponentFactory,
MetricsLogger metricsLogger,
NotificationRowLogger logBufferLogger,
+ NotificationChildrenContainerLogger childrenContainerLogger,
NotificationListContainer listContainer,
SmartReplyConstants smartReplyConstants,
SmartReplyController smartReplyController,
@@ -188,6 +231,7 @@
mBubblesManagerOptional = bubblesManagerOptional;
mDragController = dragController;
mMetricsLogger = metricsLogger;
+ mChildrenContainerLogger = childrenContainerLogger;
mLogBufferLogger = logBufferLogger;
mSmartReplyConstants = smartReplyConstants;
mSmartReplyController = smartReplyController;
@@ -222,6 +266,7 @@
mNotificationGutsManager,
mDismissibilityProvider,
mMetricsLogger,
+ mChildrenContainerLogger,
mSmartReplyConstants,
mSmartReplyController,
mFeatureFlags,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java
index b4bfded..13d1978 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java
@@ -474,7 +474,6 @@
parentLayout,
remoteViewClickHandler);
validateView(v, entry, row.getResources());
- v.setIsRootNamespace(true);
applyCallback.setResultView(v);
} else {
newContentView.reapply(
@@ -511,7 +510,6 @@
return;
}
if (isNewView) {
- v.setIsRootNamespace(true);
applyCallback.setResultView(v);
} else if (existingWrapper != null) {
existingWrapper.onReinflated();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
index 124df8c..20f4429 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
@@ -208,6 +208,23 @@
mSmartReplyConstants = smartReplyConstants;
mSmartReplyController = smartReplyController;
mStatusBarService = statusBarService;
+ // We set root namespace so that we avoid searching children for id. Notification might
+ // contain custom view and their ids may clash with ids already existing in shade or
+ // notification panel
+ setIsRootNamespace(true);
+ }
+
+ @Override
+ public View focusSearch(View focused, int direction) {
+ // This implementation is copied from ViewGroup but with removed special handling of
+ // setIsRootNamespace. This view is set as tree root using setIsRootNamespace and it
+ // causes focus to be stuck inside of it. We need to be root to avoid id conflicts
+ // but we don't want to behave like root when it comes to focusing.
+ if (mParent != null) {
+ return mParent.focusSearch(focused, direction);
+ }
+ Log.wtf(TAG, "NotificationContentView doesn't have parent");
+ return null;
}
public void reinflate() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowLogger.kt
index c3dd92a..89338f9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowLogger.kt
@@ -17,14 +17,21 @@
package com.android.systemui.statusbar.notification.row
+import android.view.ViewGroup
import com.android.systemui.log.LogBuffer
import com.android.systemui.log.LogLevel
import com.android.systemui.log.dagger.NotificationLog
+import com.android.systemui.log.dagger.NotificationRenderLog
import com.android.systemui.statusbar.notification.collection.NotificationEntry
import com.android.systemui.statusbar.notification.logKey
import javax.inject.Inject
-class NotificationRowLogger @Inject constructor(@NotificationLog private val buffer: LogBuffer) {
+class NotificationRowLogger
+@Inject
+constructor(
+ @NotificationLog private val buffer: LogBuffer,
+ @NotificationRenderLog private val notificationRenderBuffer: LogBuffer
+) {
fun logKeepInParentChildDetached(child: NotificationEntry, oldParent: NotificationEntry?) {
buffer.log(
TAG,
@@ -48,6 +55,79 @@
{ "Skipping to attach $str1 to $str2, because it still flagged to keep in parent" }
)
}
+
+ fun logRemoveTransientFromContainer(
+ childEntry: NotificationEntry,
+ containerEntry: NotificationEntry
+ ) {
+ notificationRenderBuffer.log(
+ TAG,
+ LogLevel.INFO,
+ {
+ str1 = childEntry.logKey
+ str2 = containerEntry.logKey
+ },
+ { "RemoveTransientRow from ChildrenContainer: childKey: $str1 -- containerKey: $str2" }
+ )
+ }
+
+ fun logRemoveTransientFromNssl(
+ childEntry: NotificationEntry,
+ ) {
+ notificationRenderBuffer.log(
+ TAG,
+ LogLevel.INFO,
+ { str1 = childEntry.logKey },
+ { "RemoveTransientRow from Nssl: childKey: $str1" }
+ )
+ }
+
+ fun logRemoveTransientFromViewGroup(
+ childEntry: NotificationEntry,
+ containerView: ViewGroup,
+ ) {
+ notificationRenderBuffer.log(
+ TAG,
+ LogLevel.WARNING,
+ {
+ str1 = childEntry.logKey
+ str2 = containerView.toString()
+ },
+ { "RemoveTransientRow from other ViewGroup: childKey: $str1 -- ViewGroup: $str2" }
+ )
+ }
+
+ fun logAddTransientRow(
+ childEntry: NotificationEntry,
+ containerEntry: NotificationEntry,
+ index: Int
+ ) {
+ notificationRenderBuffer.log(
+ TAG,
+ LogLevel.ERROR,
+ {
+ str1 = childEntry.logKey
+ str2 = containerEntry.logKey
+ int1 = index
+ },
+ { "addTransientRow to row: childKey: $str1 -- containerKey: $str2 -- index: $int1" }
+ )
+ }
+
+ fun logRemoveTransientRow(
+ childEntry: NotificationEntry,
+ containerEntry: NotificationEntry,
+ ) {
+ notificationRenderBuffer.log(
+ TAG,
+ LogLevel.ERROR,
+ {
+ str1 = childEntry.logKey
+ str2 = containerEntry.logKey
+ },
+ { "removeTransientRow from row: childKey: $str1 -- containerKey: $str2" }
+ )
+ }
}
private const val TAG = "NotifRow"
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/ExpandableNotificationRowComponent.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/ExpandableNotificationRowComponent.java
index 1a7417a..3588621 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/ExpandableNotificationRowComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/ExpandableNotificationRowComponent.java
@@ -25,7 +25,6 @@
import com.android.systemui.statusbar.notification.row.ActivatableNotificationView;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRowController;
-import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
import com.android.systemui.statusbar.phone.CentralSurfaces;
import dagger.Binds;
@@ -59,8 +58,6 @@
Builder notificationEntry(NotificationEntry entry);
@BindsInstance
Builder onExpandClickListener(ExpandableNotificationRow.OnExpandClickListener presenter);
- @BindsInstance
- Builder listContainer(NotificationListContainer listContainer);
ExpandableNotificationRowComponent build();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/shelf/ui/viewmodel/NotificationShelfViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/shelf/ui/viewmodel/NotificationShelfViewModel.kt
index fb19443..5ca8b53 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/shelf/ui/viewmodel/NotificationShelfViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/shelf/ui/viewmodel/NotificationShelfViewModel.kt
@@ -16,16 +16,16 @@
package com.android.systemui.statusbar.notification.shelf.ui.viewmodel
+import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.statusbar.NotificationShelf
import com.android.systemui.statusbar.notification.row.ui.viewmodel.ActivatableNotificationViewModel
import com.android.systemui.statusbar.notification.shelf.domain.interactor.NotificationShelfInteractor
-import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent.CentralSurfacesScope
import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
/** ViewModel for [NotificationShelf]. */
-@CentralSurfacesScope
+@SysUISingleton
class NotificationShelfViewModel
@Inject
constructor(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
index f8e374d..dad8064 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
@@ -132,6 +132,8 @@
private boolean mContainingNotificationIsFaded = false;
private RoundableState mRoundableState;
+ private NotificationChildrenContainerLogger mLogger;
+
public NotificationChildrenContainer(Context context) {
this(context, null);
}
@@ -1507,6 +1509,33 @@
return mNotificationHeaderWrapper;
}
+ public void setLogger(NotificationChildrenContainerLogger logger) {
+ mLogger = logger;
+ }
+
+ @Override
+ public void addTransientView(View view, int index) {
+ if (mLogger != null && view instanceof ExpandableNotificationRow) {
+ mLogger.addTransientRow(
+ ((ExpandableNotificationRow) view).getEntry(),
+ getContainingNotification().getEntry(),
+ index
+ );
+ }
+ super.addTransientView(view, index);
+ }
+
+ @Override
+ public void removeTransientView(View view) {
+ if (mLogger != null && view instanceof ExpandableNotificationRow) {
+ mLogger.removeTransientRow(
+ ((ExpandableNotificationRow) view).getEntry(),
+ getContainingNotification().getEntry()
+ );
+ }
+ super.removeTransientView(view);
+ }
+
public String debugString() {
return TAG + " { "
+ "visibility: " + getVisibility()
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainerLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainerLogger.kt
new file mode 100644
index 0000000..6be1ef8
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainerLogger.kt
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.stack
+
+import com.android.systemui.log.LogBuffer
+import com.android.systemui.log.LogLevel
+import com.android.systemui.log.dagger.NotificationRenderLog
+import com.android.systemui.statusbar.notification.collection.NotificationEntry
+import com.android.systemui.statusbar.notification.logKey
+import javax.inject.Inject
+
+class NotificationChildrenContainerLogger
+@Inject
+constructor(@NotificationRenderLog private val notificationRenderBuffer: LogBuffer) {
+ fun addTransientRow(
+ childEntry: NotificationEntry,
+ containerEntry: NotificationEntry,
+ index: Int
+ ) {
+ notificationRenderBuffer.log(
+ TAG,
+ LogLevel.INFO,
+ {
+ str1 = childEntry.logKey
+ str2 = containerEntry.logKey
+ int1 = index
+ },
+ { "addTransientRow: childKey: $str1 -- containerKey: $str2 -- index: $int1" }
+ )
+ }
+
+ fun removeTransientRow(
+ childEntry: NotificationEntry,
+ containerEntry: NotificationEntry,
+ ) {
+ notificationRenderBuffer.log(
+ TAG,
+ LogLevel.INFO,
+ {
+ str1 = childEntry.logKey
+ str2 = containerEntry.logKey
+ },
+ { "removeTransientRow: childKey: $str1 -- containerKey: $str2" }
+ )
+ }
+
+ companion object {
+ private const val TAG = "NotifChildrenContainer"
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index d1413a2..479fbdb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
@@ -2759,6 +2759,7 @@
boolean animationGenerated = container != null && generateRemoveAnimation(child);
if (animationGenerated) {
if (!mSwipedOutViews.contains(child) || !isFullySwipedOut(child)) {
+ logAddTransientChild(child, container);
container.addTransientView(child, 0);
child.setTransientContainer(container);
}
@@ -2774,6 +2775,46 @@
focusNextViewIfFocused(child);
}
+ private void logAddTransientChild(ExpandableView child, ViewGroup container) {
+ if (mLogger == null) {
+ return;
+ }
+ if (child instanceof ExpandableNotificationRow) {
+ if (container instanceof NotificationChildrenContainer) {
+ mLogger.addTransientChildNotificationToChildContainer(
+ ((ExpandableNotificationRow) child).getEntry(),
+ ((NotificationChildrenContainer) container)
+ .getContainingNotification().getEntry()
+ );
+ } else if (container instanceof NotificationStackScrollLayout) {
+ mLogger.addTransientChildNotificationToNssl(
+ ((ExpandableNotificationRow) child).getEntry()
+ );
+ } else {
+ mLogger.addTransientChildNotificationToViewGroup(
+ ((ExpandableNotificationRow) child).getEntry(),
+ container
+ );
+ }
+ }
+ }
+
+ @Override
+ public void addTransientView(View view, int index) {
+ if (mLogger != null && view instanceof ExpandableNotificationRow) {
+ mLogger.addTransientRow(((ExpandableNotificationRow) view).getEntry(), index);
+ }
+ super.addTransientView(view, index);
+ }
+
+ @Override
+ public void removeTransientView(View view) {
+ if (mLogger != null && view instanceof ExpandableNotificationRow) {
+ mLogger.removeTransientRow(((ExpandableNotificationRow) view).getEntry());
+ }
+ super.removeTransientView(view);
+ }
+
/**
* Has this view been fully swiped out such that it's not visible anymore.
*/
@@ -3033,7 +3074,9 @@
if (!animationsEnabled) {
mSwipedOutViews.clear();
mChildrenToRemoveAnimated.clear();
- clearTemporaryViewsInGroup(this);
+ clearTemporaryViewsInGroup(
+ /* viewGroup = */ this,
+ /* reason = */ "setAnimationsEnabled");
}
}
@@ -4008,26 +4051,48 @@
private void clearTemporaryViews() {
// lets make sure nothing is transient anymore
- clearTemporaryViewsInGroup(this);
+ clearTemporaryViewsInGroup(
+ /* viewGroup = */ this,
+ /* reason = */ "clearTemporaryViews"
+ );
for (int i = 0; i < getChildCount(); i++) {
ExpandableView child = getChildAtIndex(i);
if (child instanceof ExpandableNotificationRow) {
ExpandableNotificationRow row = (ExpandableNotificationRow) child;
- clearTemporaryViewsInGroup(row.getChildrenContainer());
+ clearTemporaryViewsInGroup(
+ /* viewGroup = */ row.getChildrenContainer(),
+ /* reason = */ "clearTemporaryViewsInGroup(row.getChildrenContainer())"
+ );
}
}
}
- private void clearTemporaryViewsInGroup(ViewGroup viewGroup) {
+ private void clearTemporaryViewsInGroup(ViewGroup viewGroup, String reason) {
while (viewGroup != null && viewGroup.getTransientViewCount() != 0) {
final View transientView = viewGroup.getTransientView(0);
viewGroup.removeTransientView(transientView);
if (transientView instanceof ExpandableView) {
((ExpandableView) transientView).setTransientContainer(null);
+ if (transientView instanceof ExpandableNotificationRow) {
+ logTransientNotificationRowTraversalCleaned(
+ (ExpandableNotificationRow) transientView,
+ reason
+ );
+ }
}
}
}
+ private void logTransientNotificationRowTraversalCleaned(
+ ExpandableNotificationRow transientView,
+ String reason
+ ) {
+ if (mLogger == null) {
+ return;
+ }
+ mLogger.transientNotificationRowTraversalCleaned(transientView.getEntry(), reason);
+ }
+
void onPanelTrackingStarted() {
mPanelTracking = true;
mAmbientState.setPanelTracking(true);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
index ad7cdc4..7c66bbe5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
@@ -29,6 +29,7 @@
import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.ROWS_HIGH_PRIORITY;
import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.SelectedRows;
import static com.android.systemui.statusbar.phone.NotificationIconAreaController.HIGH_PRIORITY;
+import static com.android.systemui.util.kotlin.JavaAdapterKt.collectFlow;
import android.content.res.Configuration;
import android.content.res.Resources;
@@ -59,11 +60,15 @@
import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor;
import com.android.systemui.classifier.Classifier;
import com.android.systemui.classifier.FalsingCollector;
+import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.flags.Flags;
+import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository;
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor;
+import com.android.systemui.keyguard.shared.model.KeyguardState;
+import com.android.systemui.keyguard.shared.model.TransitionStep;
import com.android.systemui.media.controls.ui.KeyguardMediaController;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.FalsingManager;
@@ -118,7 +123,6 @@
import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.phone.NotificationIconAreaController;
import com.android.systemui.statusbar.phone.ScrimController;
-import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
@@ -141,7 +145,7 @@
/**
* Controller for {@link NotificationStackScrollLayout}.
*/
-@CentralSurfacesComponent.CentralSurfacesScope
+@SysUISingleton
public class NotificationStackScrollLayoutController {
private static final String TAG = "StackScrollerController";
private static final boolean DEBUG = Compile.IS_DEBUG && Log.isLoggable(TAG, Log.DEBUG);
@@ -189,6 +193,7 @@
private final GroupExpansionManager mGroupExpansionManager;
private final NotifPipelineFlags mNotifPipelineFlags;
private final SeenNotificationsProvider mSeenNotificationsProvider;
+ private final KeyguardTransitionRepository mKeyguardTransitionRepo;
private NotificationStackScrollLayout mView;
private NotificationSwipeHelper mSwipeHelper;
@@ -197,6 +202,8 @@
private int mBarState;
private boolean mIsBouncerShowingFromCentralSurfaces;
private HeadsUpAppearanceController mHeadsUpAppearanceController;
+ private boolean mIsInTransitionToAod = false;
+
private final FeatureFlags mFeatureFlags;
private final NotificationTargetsHelper mNotificationTargetsHelper;
private final SecureSettings mSecureSettings;
@@ -633,6 +640,7 @@
KeyguardBypassController keyguardBypassController,
KeyguardInteractor keyguardInteractor,
PrimaryBouncerInteractor primaryBouncerInteractor,
+ KeyguardTransitionRepository keyguardTransitionRepo,
ZenModeController zenModeController,
NotificationLockscreenUserManager lockscreenUserManager,
Optional<NotificationListViewModel> nsslViewModel,
@@ -665,6 +673,7 @@
NotificationDismissibilityProvider dismissibilityProvider,
ActivityStarter activityStarter) {
mView = view;
+ mKeyguardTransitionRepo = keyguardTransitionRepo;
mStackStateLogger = stackLogger;
mLogger = logger;
mAllowLongPress = allowLongPress;
@@ -819,6 +828,9 @@
mViewModel.ifPresent(
vm -> NotificationListViewBinder
.bind(mView, vm, mFalsingManager, mFeatureFlags, mNotifIconAreaController));
+
+ collectFlow(mView, mKeyguardTransitionRepo.getTransitions(),
+ this::onKeyguardTransitionChanged);
}
private boolean isInVisibleLocation(NotificationEntry entry) {
@@ -1241,10 +1253,10 @@
final boolean shouldShow = getVisibleNotificationCount() == 0
&& !mView.isQsFullScreen()
- // Hide empty shade view when in transition to Keyguard.
+ // Hide empty shade view when in transition to AOD.
// That avoids "No Notifications" to blink when transitioning to AOD.
// For more details, see: b/228790482
- && !isInTransitionToKeyguard()
+ && !mIsInTransitionToAod
// Don't show any notification content if the bouncer is showing. See b/267060171.
&& !isBouncerShowing();
@@ -1462,7 +1474,7 @@
return mNotificationRoundnessManager;
}
- NotificationListContainer getNotificationListContainer() {
+ public NotificationListContainer getNotificationListContainer() {
return mNotificationListContainer;
}
@@ -1643,6 +1655,16 @@
return shelf == null ? 0 : shelf.getIntrinsicHeight();
}
+ @VisibleForTesting
+ void onKeyguardTransitionChanged(TransitionStep transitionStep) {
+ boolean isTransitionToAod = transitionStep.getFrom().equals(KeyguardState.GONE)
+ && transitionStep.getTo().equals(KeyguardState.AOD);
+ if (mIsInTransitionToAod != isTransitionToAod) {
+ mIsInTransitionToAod = isTransitionToAod;
+ updateShowEmptyShadeView();
+ }
+ }
+
/**
* Enum for UiEvent logged from this class
*/
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutListContainerModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutListContainerModule.java
deleted file mode 100644
index 3dcaae2..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutListContainerModule.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.statusbar.notification.stack;
-
-import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent;
-
-import dagger.Module;
-import dagger.Provides;
-
-@Module
-public abstract class NotificationStackScrollLayoutListContainerModule {
- @Provides
- @CentralSurfacesComponent.CentralSurfacesScope
- static NotificationListContainer provideListContainer(
- NotificationStackScrollLayoutController nsslController) {
- return nsslController.getNotificationListContainer();
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLogger.kt
index 5b0ec1d..9c1bd17 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLogger.kt
@@ -1,9 +1,12 @@
package com.android.systemui.statusbar.notification.stack
+import android.view.ViewGroup
import com.android.systemui.log.dagger.NotificationHeadsUpLog
import com.android.systemui.log.LogBuffer
import com.android.systemui.log.LogLevel.DEBUG
import com.android.systemui.log.LogLevel.INFO
+import com.android.systemui.log.LogLevel.ERROR
+import com.android.systemui.log.dagger.NotificationRenderLog
import com.android.systemui.statusbar.notification.collection.NotificationEntry
import com.android.systemui.statusbar.notification.logKey
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.AnimationEvent.ANIMATION_TYPE_ADD
@@ -15,7 +18,8 @@
import javax.inject.Inject
class NotificationStackScrollLogger @Inject constructor(
- @NotificationHeadsUpLog private val buffer: LogBuffer
+ @NotificationHeadsUpLog private val buffer: LogBuffer,
+ @NotificationRenderLog private val notificationRenderBuffer: LogBuffer
) {
fun hunAnimationSkipped(entry: NotificationEntry, reason: String) {
buffer.log(TAG, INFO, {
@@ -77,6 +81,79 @@
"isTouchBelowNotification: $bool2 motionEvent: $str1"
})
}
+
+ fun transientNotificationRowTraversalCleaned(entry: NotificationEntry, reason: String) {
+ notificationRenderBuffer.log(TAG, INFO, {
+ str1 = entry.logKey
+ str2 = reason
+ }, {
+ "transientNotificationRowTraversalCleaned: key: $str1 reason: $str2"
+ })
+ }
+
+ fun addTransientChildNotificationToChildContainer(
+ childEntry: NotificationEntry,
+ containerEntry: NotificationEntry,
+ ) {
+ notificationRenderBuffer.log(TAG, INFO, {
+ str1 = childEntry.logKey
+ str2 = containerEntry.logKey
+ }, {
+ "addTransientChildToContainer from onViewRemovedInternal: childKey: $str1 " +
+ "-- containerKey: $str2"
+ })
+ }
+
+ fun addTransientChildNotificationToNssl(
+ childEntry: NotificationEntry,
+ ) {
+ notificationRenderBuffer.log(TAG, INFO, {
+ str1 = childEntry.logKey
+ }, {
+ "addTransientRowToNssl from onViewRemovedInternal: childKey: $str1"
+ })
+ }
+
+ fun addTransientChildNotificationToViewGroup(
+ childEntry: NotificationEntry,
+ container: ViewGroup
+ ) {
+ notificationRenderBuffer.log(TAG, ERROR, {
+ str1 = childEntry.logKey
+ str2 = container.toString()
+ }, {
+ "addTransientRowTo unhandled ViewGroup from onViewRemovedInternal: childKey: $str1 " +
+ "-- ViewGroup: $str2"
+ })
+ }
+
+ fun addTransientRow(
+ childEntry: NotificationEntry,
+ index: Int
+ ) {
+ notificationRenderBuffer.log(
+ TAG,
+ INFO,
+ {
+ str1 = childEntry.logKey
+ int1 = index
+ },
+ { "addTransientRow to NSSL: childKey: $str1 -- index: $int1" }
+ )
+ }
+
+ fun removeTransientRow(
+ childEntry: NotificationEntry,
+ ) {
+ notificationRenderBuffer.log(
+ TAG,
+ INFO,
+ {
+ str1 = childEntry.logKey
+ },
+ { "removeTransientRow from NSSL: childKey: $str1" }
+ )
+ }
}
private const val TAG = "NotificationStackScroll"
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java
index f07dd00..d73919b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java
@@ -347,10 +347,12 @@
final ExpandableView changingView = (ExpandableView) event.mChangingView;
boolean loggable = false;
boolean isHeadsUp = false;
+ boolean isGroupChild = false;
String key = null;
if (changingView instanceof ExpandableNotificationRow && mLogger != null) {
loggable = true;
isHeadsUp = ((ExpandableNotificationRow) changingView).isHeadsUp();
+ isGroupChild = changingView.isChildInGroup();
key = ((ExpandableNotificationRow) changingView).getEntry().getKey();
}
if (event.animationType ==
@@ -407,13 +409,21 @@
}
Runnable postAnimation = changingView::removeFromTransientContainer;
- if (loggable && isHeadsUp) {
- mLogger.logHUNViewDisappearingWithRemoveEvent(key);
+ if (loggable) {
String finalKey = key;
- postAnimation = () -> {
- mLogger.disappearAnimationEnded(finalKey);
- changingView.removeFromTransientContainer();
- };
+ if (isHeadsUp) {
+ mLogger.logHUNViewDisappearingWithRemoveEvent(key);
+ postAnimation = () -> {
+ mLogger.disappearAnimationEnded(finalKey);
+ changingView.removeFromTransientContainer();
+ };
+ } else if (isGroupChild) {
+ mLogger.groupChildRemovalEventProcessed(key);
+ postAnimation = () -> {
+ mLogger.groupChildRemovalAnimationEnded(finalKey);
+ changingView.removeFromTransientContainer();
+ };
+ }
}
changingView.performRemoveAnimation(ANIMATION_DURATION_APPEAR_DISAPPEAR,
0 /* delay */, translationDirection, false /* isHeadsUpAppear */,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateLogger.kt
index cca84b3..c7f80f3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateLogger.kt
@@ -3,11 +3,13 @@
import com.android.systemui.log.dagger.NotificationHeadsUpLog
import com.android.systemui.log.LogBuffer
import com.android.systemui.log.LogLevel
+import com.android.systemui.log.dagger.NotificationRenderLog
import com.android.systemui.statusbar.notification.logKey
import javax.inject.Inject
class StackStateLogger @Inject constructor(
- @NotificationHeadsUpLog private val buffer: LogBuffer
+ @NotificationHeadsUpLog private val buffer: LogBuffer,
+ @NotificationRenderLog private val notificationRenderBuffer: LogBuffer
) {
fun logHUNViewDisappearing(key: String) {
buffer.log(TAG, LogLevel.INFO, {
@@ -56,6 +58,21 @@
"Heads up notification appear animation ended $str1 "
})
}
+
+ fun groupChildRemovalEventProcessed(key: String) {
+ notificationRenderBuffer.log(TAG, LogLevel.DEBUG, {
+ str1 = logKey(key)
+ }, {
+ "Group Child Notification removal event processed $str1 for ANIMATION_TYPE_REMOVE"
+ })
+ }
+ fun groupChildRemovalAnimationEnded(key: String) {
+ notificationRenderBuffer.log(TAG, LogLevel.INFO, {
+ str1 = logKey(key)
+ }, {
+ "Group child notification removal animation ended $str1 "
+ })
+ }
}
private const val TAG = "StackScroll"
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationListViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationListViewModel.kt
index aab1c2b..11f68e0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationListViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationListViewModel.kt
@@ -16,6 +16,7 @@
package com.android.systemui.statusbar.notification.stack.ui.viewmodel
+import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags
import com.android.systemui.statusbar.notification.shelf.ui.viewmodel.NotificationShelfViewModel
@@ -33,6 +34,7 @@
object NotificationListViewModelModule {
@JvmStatic
@Provides
+ @SysUISingleton
fun maybeProvideViewModel(
featureFlags: FeatureFlags,
shelfViewModel: Provider<NotificationShelfViewModel>,
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 01c00b6..0242e91 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
@@ -24,7 +24,6 @@
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
-import android.os.PowerManager;
import android.os.UserHandle;
import android.view.KeyEvent;
import android.view.MotionEvent;
@@ -43,7 +42,6 @@
import com.android.systemui.animation.ActivityLaunchAnimator;
import com.android.systemui.navigationbar.NavigationBarView;
import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
-import com.android.systemui.power.domain.interactor.PowerInteractor;
import com.android.systemui.qs.QSPanelController;
import com.android.systemui.shade.ShadeViewController;
import com.android.systemui.shared.system.RemoteAnimationRunnerCompat;
@@ -196,14 +194,6 @@
@Override
Lifecycle getLifecycle();
- /**
- * Wakes up the device if the device was dozing.
- *
- * @deprecated Use {@link PowerInteractor#wakeUpIfDozing(String, int)} instead.
- */
- @Deprecated
- void wakeUpIfDozing(long time, String why, @PowerManager.WakeReason int wakeReason);
-
/** */
ShadeViewController getShadeViewController();
@@ -212,8 +202,6 @@
int getStatusBarHeight();
- void updateQsExpansionEnabled();
-
boolean isShadeDisabled();
boolean isLaunchingActivityOverLockscreen();
@@ -406,9 +394,6 @@
void setLaunchEmergencyActionOnFinishedWaking(boolean launch);
QSPanelController getQSPanelController();
-
- boolean areNotificationAlertsDisabled();
-
float getDisplayDensity();
void extendDozePulse();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java
index 555a3c2..332be2a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java
@@ -244,8 +244,13 @@
}
/**
* State is one or more of the DISABLE constants from StatusBarManager.
+ *
+ * @deprecated If you need to react to changes in disable flags, listen to
+ * {@link com.android.systemui.statusbar.disableflags.data.repository.DisableFlagsRepository}
+ * instead.
*/
@Override
+ @Deprecated
public void disable(int displayId, int state1, int state2, boolean animate) {
if (displayId != mDisplayId) {
return;
@@ -275,17 +280,12 @@
}
if ((diff1 & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0) {
- if (mCentralSurfaces.areNotificationAlertsDisabled()) {
+ if ((state1 & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0) {
mHeadsUpManager.releaseAllImmediately();
}
}
- if ((diff2 & StatusBarManager.DISABLE2_QUICK_SETTINGS) != 0) {
- mCentralSurfaces.updateQsExpansionEnabled();
- }
-
if ((diff2 & StatusBarManager.DISABLE2_NOTIFICATION_SHADE) != 0) {
- mCentralSurfaces.updateQsExpansionEnabled();
if ((state2 & StatusBarManager.DISABLE2_NOTIFICATION_SHADE) != 0) {
mShadeController.animateCollapseShade();
}
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 bba581b..4ae4c52 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
@@ -312,7 +312,7 @@
private final DeviceStateManager mDeviceStateManager;
private CentralSurfacesCommandQueueCallbacks mCommandQueueCallbacks;
private float mTransitionToFullShadeProgress = 0f;
- private NotificationListContainer mNotifListContainer;
+ private final NotificationListContainer mNotifListContainer;
private boolean mIsShortcutListSearchEnabled;
private final KeyguardStateController.Callback mKeyguardStateControllerCallback =
@@ -660,8 +660,7 @@
private final ActivityIntentHelper mActivityIntentHelper;
- @VisibleForTesting
- protected NotificationStackScrollLayoutController mStackScrollerController;
+ private final NotificationStackScrollLayoutController mStackScrollerController;
private final ColorExtractor.OnColorsChangedListener mOnColorsChangedListener =
(extractor, which) -> updateTheme();
@@ -749,6 +748,7 @@
ConfigurationController configurationController,
NotificationShadeWindowController notificationShadeWindowController,
NotificationShelfController notificationShelfController,
+ NotificationStackScrollLayoutController notificationStackScrollLayoutController,
DozeParameters dozeParameters,
ScrimController scrimController,
Lazy<LockscreenWallpaper> lockscreenWallpaperLazy,
@@ -849,6 +849,9 @@
mConfigurationController = configurationController;
mNotificationShadeWindowController = notificationShadeWindowController;
mNotificationShelfController = notificationShelfController;
+ mStackScrollerController = notificationStackScrollLayoutController;
+ mStackScroller = mStackScrollerController.getView();
+ mNotifListContainer = mStackScrollerController.getNotificationListContainer();
mDozeServiceHost = dozeServiceHost;
mPowerManager = powerManager;
mDozeParameters = dozeParameters;
@@ -1582,7 +1585,6 @@
mGutsManager.setNotificationActivityStarter(mNotificationActivityStarter);
mShadeController.setNotificationPresenter(mPresenter);
mNotificationsController.initialize(
- this,
mPresenter,
mNotifListContainer,
mStackScrollerController.getNotifStackController(),
@@ -1598,24 +1600,6 @@
mCommandQueue.disable(mDisplayId, state1, state2, false /* animate */);
}
- /**
- * Ask the display to wake up if currently dozing, else do nothing
- *
- * @deprecated Use {@link PowerInteractor#wakeUpIfDozing(String, int)} instead.
- *
- * @param time when to wake up
- * @param why the reason for the wake up
- */
- @Override
- @Deprecated
- public void wakeUpIfDozing(long time, String why, @PowerManager.WakeReason int wakeReason) {
- if (mDozing && mScreenOffAnimationController.allowWakeUpIfDozing()) {
- mPowerManager.wakeUp(
- time, wakeReason, "com.android.systemui:" + why);
- mFalsingCollector.onScreenOnFromTouch();
- }
- }
-
// TODO(b/117478341): This was left such that CarStatusBar can override this method.
// Try to remove this.
protected void createNavigationBar(@Nullable RegisterStatusBarResult result) {
@@ -1658,12 +1642,8 @@
mShadeController.setNotificationPanelViewController(npvc);
mShadeController.setNotificationShadeWindowViewController(
mNotificationShadeWindowViewController);
- mStackScrollerController =
- mCentralSurfacesComponent.getNotificationStackScrollLayoutController();
mQsController = mCentralSurfacesComponent.getQuickSettingsController();
mBackActionInteractor.setup(mQsController, mShadeSurface);
- mStackScroller = mStackScrollerController.getView();
- mNotifListContainer = mCentralSurfacesComponent.getNotificationListContainer();
mPresenter = mCentralSurfacesComponent.getNotificationPresenter();
mNotificationActivityStarter = mCentralSurfacesComponent.getNotificationActivityStarter();
@@ -1744,23 +1724,6 @@
return mStatusBarWindowController.getStatusBarHeight();
}
- /**
- * Disable QS if device not provisioned.
- * If the user switcher is simple then disable QS during setup because
- * the user intends to use the lock screen user switcher, QS in not needed.
- */
- @Override
- public void updateQsExpansionEnabled() {
- final boolean expandEnabled = mDeviceProvisionedController.isDeviceProvisioned()
- && (mUserSetup || mUserSwitcherController == null
- || !mUserSwitcherController.isSimpleUserSwitcher())
- && !isShadeDisabled()
- && ((mDisabled2 & StatusBarManager.DISABLE2_QUICK_SETTINGS) == 0)
- && !mDozing;
- mQsController.setExpansionEnabledPolicy(expandEnabled);
- Log.d(TAG, "updateQsExpansionEnabled - QS Expand enabled: " + expandEnabled);
- }
-
@Override
public boolean isShadeDisabled() {
return (mDisabled2 & StatusBarManager.DISABLE2_NOTIFICATION_SHADE) != 0;
@@ -1774,11 +1737,6 @@
&& mFalsingCollector.isReportingEnabled() ? View.VISIBLE : View.INVISIBLE);
}
- @Override
- public boolean areNotificationAlertsDisabled() {
- return (mDisabled1 & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0;
- }
-
/**
* Whether we are currently animating an activity launch above the lockscreen (occluding
* activity).
@@ -2728,7 +2686,6 @@
|| (mDozing && mDozeParameters.shouldControlScreenOff() && keyguardVisibleOrWillBe);
mShadeSurface.setDozing(mDozing, animate);
- updateQsExpansionEnabled();
Trace.endSection();
}
@@ -2913,8 +2870,7 @@
mStatusBarHideIconsForBouncerManager.setBouncerShowingAndTriggerUpdate(bouncerShowing);
mCommandQueue.recomputeDisableFlags(mDisplayId, true /* animate */);
if (mBouncerShowing) {
- wakeUpIfDozing(SystemClock.uptimeMillis(), "BOUNCER_VISIBLE",
- PowerManager.WAKE_REASON_GESTURE);
+ mPowerInteractor.wakeUpIfDozing("BOUNCER_VISIBLE", PowerManager.WAKE_REASON_GESTURE);
}
updateScrimController();
if (!mBouncerShowing) {
@@ -3369,7 +3325,7 @@
protected IStatusBarService mBarService;
// all notifications
- protected NotificationStackScrollLayout mStackScroller;
+ private final NotificationStackScrollLayout mStackScroller;
protected AccessibilityManager mAccessibilityManager;
@@ -3636,7 +3592,6 @@
mShadeSurface.collapse(true /* animate */, false /* delayed */,
1.0f /* speedUpFactor */);
}
- updateQsExpansionEnabled();
}
}
};
@@ -3771,7 +3726,6 @@
// reset them again when we're waking up
mShadeSurface.resetViews(dozingAnimated && isDozing);
- updateQsExpansionEnabled();
mKeyguardViewMediator.setDozing(mDozing);
updateDozingState();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LetterboxAppearanceCalculator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LetterboxAppearanceCalculator.kt
index f742645..a61914a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LetterboxAppearanceCalculator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LetterboxAppearanceCalculator.kt
@@ -209,7 +209,7 @@
if (this.contains(other) || other.contains(this)) {
return false
}
- return this.intersect(other)
+ return this.intersects(other.left, other.top, other.right, other.bottom)
}
override fun dump(pw: PrintWriter, args: Array<out String>) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
index 313410a..2fd244e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
@@ -240,7 +240,7 @@
private void reloadDimens(Context context) {
Resources res = context.getResources();
mIconSize = res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_icon_size);
- mIconHPadding = res.getDimensionPixelSize(R.dimen.status_bar_icon_padding);
+ mIconHPadding = res.getDimensionPixelSize(R.dimen.status_bar_icon_horizontal_margin);
mAodIconAppearTranslation = res.getDimensionPixelSize(
R.dimen.shelf_appear_translation);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt
index e6cb68f..f0fc143 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt
@@ -176,6 +176,7 @@
shadeLogger.logMotionEvent(event, "top edge touch ignored")
return true
}
+ centralSurfaces.shadeViewController.startTrackingExpansionFromStatusBar()
}
return centralSurfaces.shadeViewController.handleExternalTouch(event)
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
index a8a834f..b14fe90 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
@@ -173,7 +173,7 @@
*/
class DarkIconManager extends IconManager {
private final DarkIconDispatcher mDarkIconDispatcher;
- private int mIconHPadding;
+ private final int mIconHorizontalMargin;
public DarkIconManager(
LinearLayout linearLayout,
@@ -189,8 +189,8 @@
wifiUiAdapter,
mobileUiAdapter,
mobileContextProvider);
- mIconHPadding = mContext.getResources().getDimensionPixelSize(
- R.dimen.status_bar_icon_padding);
+ mIconHorizontalMargin = mContext.getResources().getDimensionPixelSize(
+ R.dimen.status_bar_icon_horizontal_margin);
mDarkIconDispatcher = darkIconDispatcher;
}
@@ -205,7 +205,7 @@
protected LayoutParams onCreateLayoutParams() {
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT, mIconSize);
- lp.setMargins(mIconHPadding, 0, mIconHPadding, 0);
+ lp.setMargins(mIconHorizontalMargin, 0, mIconHorizontalMargin, 0);
return lp;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java
index 3b56d27..35285b2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java
@@ -22,7 +22,6 @@
import android.os.PowerManager;
import android.os.RemoteException;
import android.os.ServiceManager;
-import android.os.SystemClock;
import android.service.notification.StatusBarNotification;
import android.service.vr.IVrManager;
import android.service.vr.IVrStateCallbacks;
@@ -36,6 +35,7 @@
import com.android.systemui.R;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
+import com.android.systemui.power.domain.interactor.PowerInteractor;
import com.android.systemui.shade.NotificationShadeWindowView;
import com.android.systemui.shade.QuickSettingsController;
import com.android.systemui.shade.ShadeViewController;
@@ -53,6 +53,7 @@
import com.android.systemui.statusbar.notification.NotifPipelineFlags;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.render.NotifShadeEventSource;
+import com.android.systemui.statusbar.notification.domain.interactor.NotificationsInteractor;
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider;
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptSuppressor;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
@@ -83,7 +84,9 @@
private final AboveShelfObserver mAboveShelfObserver;
private final DozeScrimController mDozeScrimController;
private final CentralSurfaces mCentralSurfaces;
+ private final NotificationsInteractor mNotificationsInteractor;
private final LockscreenShadeTransitionController mShadeTransitionController;
+ private final PowerInteractor mPowerInteractor;
private final CommandQueue mCommandQueue;
private final AccessibilityManager mAccessibilityManager;
@@ -111,7 +114,9 @@
DynamicPrivacyController dynamicPrivacyController,
KeyguardStateController keyguardStateController,
CentralSurfaces centralSurfaces,
+ NotificationsInteractor notificationsInteractor,
LockscreenShadeTransitionController shadeTransitionController,
+ PowerInteractor powerInteractor,
CommandQueue commandQueue,
NotificationLockscreenUserManager lockscreenUserManager,
SysuiStatusBarStateController sysuiStatusBarStateController,
@@ -133,7 +138,9 @@
mDynamicPrivacyController = dynamicPrivacyController;
// TODO: use KeyguardStateController#isOccluded to remove this dependency
mCentralSurfaces = centralSurfaces;
+ mNotificationsInteractor = notificationsInteractor;
mShadeTransitionController = shadeTransitionController;
+ mPowerInteractor = powerInteractor;
mCommandQueue = commandQueue;
mLockscreenUserManager = lockscreenUserManager;
mStatusBarStateController = sysuiStatusBarStateController;
@@ -234,9 +241,7 @@
public void onExpandClicked(NotificationEntry clickedEntry, View clickedView,
boolean nowExpanded) {
mHeadsUpManager.setExpanded(clickedEntry, nowExpanded);
- mCentralSurfaces.wakeUpIfDozing(
- SystemClock.uptimeMillis(), "NOTIFICATION_CLICK",
- PowerManager.WAKE_REASON_GESTURE);
+ mPowerInteractor.wakeUpIfDozing("NOTIFICATION_CLICK", PowerManager.WAKE_REASON_GESTURE);
if (nowExpanded) {
if (mStatusBarStateController.getState() == StatusBarState.KEYGUARD) {
mShadeTransitionController.goToLockedShade(clickedEntry.getRow());
@@ -333,7 +338,7 @@
@Override
public boolean suppressInterruptions(NotificationEntry entry) {
- return mCentralSurfaces.areNotificationAlertsDisabled();
+ return !mNotificationsInteractor.areNotificationAlertsEnabled();
}
};
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusIconContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusIconContainer.java
index 26c1767..c332280 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusIconContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusIconContainer.java
@@ -145,8 +145,8 @@
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
mMeasureViews.clear();
- int mode = MeasureSpec.getMode(widthMeasureSpec);
- final int width = MeasureSpec.getSize(widthMeasureSpec);
+ int widthMode = MeasureSpec.getMode(widthMeasureSpec);
+ final int specWidth = MeasureSpec.getSize(widthMeasureSpec);
final int count = getChildCount();
// Collect all of the views which want to be laid out
for (int i = 0; i < count; i++) {
@@ -163,7 +163,7 @@
boolean trackWidth = true;
// Measure all children so that they report the correct width
- int childWidthSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.UNSPECIFIED);
+ int childWidthSpec = MeasureSpec.makeMeasureSpec(specWidth, MeasureSpec.UNSPECIFIED);
mNeedsUnderflow = mShouldRestrictIcons && visibleCount > MAX_ICONS;
for (int i = 0; i < visibleCount; i++) {
// Walking backwards
@@ -182,18 +182,35 @@
totalWidth += getViewTotalMeasuredWidth(child) + spacing;
}
}
+ setMeasuredDimension(
+ getMeasuredWidth(widthMode, specWidth, totalWidth),
+ getMeasuredHeight(heightMeasureSpec, mMeasureViews));
+ }
- if (mode == MeasureSpec.EXACTLY) {
- if (!mNeedsUnderflow && totalWidth > width) {
- mNeedsUnderflow = true;
- }
- setMeasuredDimension(width, MeasureSpec.getSize(heightMeasureSpec));
+ private int getMeasuredHeight(int heightMeasureSpec, List<View> measuredChildren) {
+ if (MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.EXACTLY) {
+ return MeasureSpec.getSize(heightMeasureSpec);
} else {
- if (mode == MeasureSpec.AT_MOST && totalWidth > width) {
- mNeedsUnderflow = true;
- totalWidth = width;
+ int highest = 0;
+ for (View child : measuredChildren) {
+ highest = Math.max(child.getMeasuredHeight(), highest);
}
- setMeasuredDimension(totalWidth, MeasureSpec.getSize(heightMeasureSpec));
+ return highest + getPaddingTop() + getPaddingBottom();
+ }
+ }
+
+ private int getMeasuredWidth(int widthMode, int specWidth, int totalWidth) {
+ if (widthMode == MeasureSpec.EXACTLY) {
+ if (!mNeedsUnderflow && totalWidth > specWidth) {
+ mNeedsUnderflow = true;
+ }
+ return specWidth;
+ } else {
+ if (widthMode == MeasureSpec.AT_MOST && totalWidth > specWidth) {
+ mNeedsUnderflow = true;
+ totalWidth = specWidth;
+ }
+ return totalWidth;
}
}
@@ -280,34 +297,6 @@
}
/**
- * Sets the list of ignored icon slots clearing the current list.
- * @param slots names of the icons to ignore
- */
- public void setIgnoredSlots(List<String> slots) {
- mIgnoredSlots.clear();
- addIgnoredSlots(slots);
- }
-
- /**
- * Returns the view corresponding to a particular slot.
- *
- * Use it solely to manipulate how it is presented.
- * @param slot name of the slot to find. Names are defined in
- * {@link com.android.internal.R.config_statusBarIcons}
- * @return a view for the slot if this container has it, else {@code null}
- */
- public View getViewForSlot(String slot) {
- for (int i = 0; i < getChildCount(); i++) {
- View child = getChildAt(i);
- if (child instanceof StatusIconDisplayable
- && ((StatusIconDisplayable) child).getSlot().equals(slot)) {
- return child;
- }
- }
- return null;
- }
-
- /**
* Layout is happening from end -> start
*/
private void calculateIconTranslations() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesComponent.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesComponent.java
index 64c798b..c618be8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesComponent.java
@@ -28,9 +28,6 @@
import com.android.systemui.shade.ShadeHeaderController;
import com.android.systemui.statusbar.NotificationPresenter;
import com.android.systemui.statusbar.notification.NotificationActivityStarter;
-import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
-import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
-import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutListContainerModule;
import com.android.systemui.statusbar.phone.CentralSurfacesCommandQueueCallbacks;
import com.android.systemui.statusbar.phone.CentralSurfacesImpl;
import com.android.systemui.statusbar.phone.StatusBarHeadsUpChangeListener;
@@ -56,7 +53,6 @@
* outside the component. Should more items be moved *into* this component to avoid so many getters?
*/
@Subcomponent(modules = {
- NotificationStackScrollLayoutListContainerModule.class,
StatusBarViewModule.class,
StatusBarNotificationActivityStarterModule.class,
StatusBarNotificationPresenterModule.class,
@@ -87,9 +83,6 @@
*/
NotificationShadeWindowView getNotificationShadeWindowView();
- /** */
- NotificationStackScrollLayoutController getNotificationStackScrollLayoutController();
-
/**
* Creates a NotificationShadeWindowViewController.
*/
@@ -128,6 +121,4 @@
NotificationActivityStarter getNotificationActivityStarter();
NotificationPresenter getNotificationPresenter();
-
- NotificationListContainer getNotificationListContainer();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java
index 260d986..6b0746f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java
@@ -31,8 +31,6 @@
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.OperatorNameViewController;
import com.android.systemui.statusbar.events.SystemStatusAnimationScheduler;
-import com.android.systemui.statusbar.notification.row.ui.viewmodel.ActivatableNotificationViewModelModule;
-import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationListViewModelModule;
import com.android.systemui.statusbar.phone.KeyguardBottomAreaView;
import com.android.systemui.statusbar.phone.NotificationIconAreaController;
import com.android.systemui.statusbar.phone.StatusBarBoundsProvider;
@@ -60,11 +58,14 @@
import javax.inject.Named;
-@Module(subcomponents = StatusBarFragmentComponent.class,
- includes = {
- ActivatableNotificationViewModelModule.class,
- NotificationListViewModelModule.class,
- })
+/**
+ * A module for {@link CentralSurfacesComponent.CentralSurfacesScope} components.
+ *
+ * @deprecated CentralSurfacesScope will be removed shortly (b/277762009). Classes should be
+ * annotated with @SysUISingleton instead.
+ */
+@Module(subcomponents = StatusBarFragmentComponent.class)
+@Deprecated
public abstract class StatusBarViewModule {
public static final String STATUS_BAR_FRAGMENT = "status_bar_fragment";
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryImpl.kt
index a47f95d..74352d29 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryImpl.kt
@@ -57,7 +57,6 @@
import kotlinx.coroutines.asExecutor
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.combine
@@ -205,9 +204,6 @@
}
.stateIn(scope, SharingStarted.WhileSubscribed(), null)
- private val defaultDataSubIdChangeEvent: MutableSharedFlow<Unit> =
- MutableSharedFlow(extraBufferCapacity = 1)
-
override val defaultDataSubId: StateFlow<Int> =
broadcastDispatcher
.broadcastFlow(
@@ -223,7 +219,6 @@
initialValue = INVALID_SUBSCRIPTION_ID,
)
.onStart { emit(subscriptionManagerProxy.getDefaultDataSubscriptionId()) }
- .onEach { defaultDataSubIdChangeEvent.tryEmit(Unit) }
.stateIn(scope, SharingStarted.WhileSubscribed(), INVALID_SUBSCRIPTION_ID)
private val carrierConfigChangedEvent =
@@ -232,7 +227,7 @@
.onEach { logger.logActionCarrierConfigChanged() }
override val defaultDataSubRatConfig: StateFlow<Config> =
- merge(defaultDataSubIdChangeEvent, carrierConfigChangedEvent)
+ merge(defaultDataSubId, carrierConfigChangedEvent)
.onStart { emit(Unit) }
.mapLatest { Config.readConfig(context) }
.distinctUntilChanged()
diff --git a/packages/SystemUI/src/com/android/systemui/util/kotlin/JavaAdapter.kt b/packages/SystemUI/src/com/android/systemui/util/kotlin/JavaAdapter.kt
index d6b3b22..12d7b4d 100644
--- a/packages/SystemUI/src/com/android/systemui/util/kotlin/JavaAdapter.kt
+++ b/packages/SystemUI/src/com/android/systemui/util/kotlin/JavaAdapter.kt
@@ -19,12 +19,44 @@
import android.view.View
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.repeatOnLifecycle
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.lifecycle.repeatWhenAttached
import java.util.function.Consumer
+import javax.inject.Inject
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.collect
+import kotlinx.coroutines.launch
+
+/** A class allowing Java classes to collect on Kotlin flows. */
+@SysUISingleton
+class JavaAdapter
+@Inject
+constructor(
+ @Application private val scope: CoroutineScope,
+) {
+ /**
+ * Collect information for the given [flow], calling [consumer] for each emitted event.
+ *
+ * Important: This will immediately start collection and *never* stop it. This should only be
+ * used by classes that *need* to always be collecting a value and processing it. Whenever
+ * possible, please use [collectFlow] instead; that method will stop the collection when a view
+ * has disappeared, which will ensure that we don't perform unnecessary work.
+ *
+ * Do *not* call this method in a class's constructor. Instead, call it in
+ * [com.android.systemui.CoreStartable.start] or similar method.
+ */
+ fun <T> alwaysCollectFlow(
+ flow: Flow<T>,
+ consumer: Consumer<T>,
+ ): Job {
+ return scope.launch { flow.collect { consumer.accept(it) } }
+ }
+}
/**
* Collect information for the given [flow], calling [consumer] for each emitted event. Defaults to
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt
index 71a57c7..2eea9eb 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt
@@ -18,10 +18,12 @@
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
+import android.view.View
+import androidx.constraintlayout.widget.ConstraintLayout
+import androidx.constraintlayout.widget.ConstraintSet
import androidx.test.filters.SmallTest
import com.android.internal.util.LatencyTracker
import com.android.internal.widget.LockPatternUtils
-import com.android.internal.widget.LockPatternView
import com.android.systemui.R
import com.android.systemui.SysuiTestCase
import com.android.systemui.classifier.FalsingCollector
@@ -29,6 +31,10 @@
import com.android.systemui.flags.FakeFeatureFlags
import com.android.systemui.flags.Flags
import com.android.systemui.statusbar.policy.DevicePostureController
+import com.android.systemui.statusbar.policy.DevicePostureController.DEVICE_POSTURE_HALF_OPENED
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.whenever
+import com.google.common.truth.Truth.assertThat
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@@ -45,7 +51,7 @@
@RunWith(AndroidTestingRunner::class)
@TestableLooper.RunWithLooper
class KeyguardPatternViewControllerTest : SysuiTestCase() {
- @Mock private lateinit var mKeyguardPatternView: KeyguardPatternView
+ private lateinit var mKeyguardPatternView: KeyguardPatternView
@Mock private lateinit var mKeyguardUpdateMonitor: KeyguardUpdateMonitor
@@ -63,54 +69,70 @@
@Mock
private lateinit var mKeyguardMessageAreaControllerFactory: KeyguardMessageAreaController.Factory
- @Mock private lateinit var mKeyguardMessageArea: BouncerKeyguardMessageArea
-
@Mock
private lateinit var mKeyguardMessageAreaController:
KeyguardMessageAreaController<BouncerKeyguardMessageArea>
- @Mock private lateinit var mLockPatternView: LockPatternView
-
- @Mock private lateinit var mPostureController: DevicePostureController
+ @Mock private lateinit var mPostureController: DevicePostureController
private lateinit var mKeyguardPatternViewController: KeyguardPatternViewController
private lateinit var fakeFeatureFlags: FakeFeatureFlags
- @Before
- fun setup() {
- MockitoAnnotations.initMocks(this)
- `when`(mKeyguardPatternView.isAttachedToWindow).thenReturn(true)
- `when`(
- mKeyguardPatternView.requireViewById<BouncerKeyguardMessageArea>(
- R.id.bouncer_message_area))
- .thenReturn(mKeyguardMessageArea)
- `when`(mKeyguardPatternView.findViewById<LockPatternView>(R.id.lockPatternView))
- .thenReturn(mLockPatternView)
- `when`(mKeyguardMessageAreaControllerFactory.create(mKeyguardMessageArea))
- .thenReturn(mKeyguardMessageAreaController)
- `when`(mKeyguardPatternView.resources).thenReturn(context.resources)
- fakeFeatureFlags = FakeFeatureFlags()
- fakeFeatureFlags.set(Flags.REVAMPED_BOUNCER_MESSAGES, false)
- mKeyguardPatternViewController =
- KeyguardPatternViewController(
- mKeyguardPatternView,
- mKeyguardUpdateMonitor,
- mSecurityMode,
- mLockPatternUtils,
- mKeyguardSecurityCallback,
- mLatencyTracker,
- mFalsingCollector,
- mEmergencyButtonController,
- mKeyguardMessageAreaControllerFactory,
- mPostureController,
- fakeFeatureFlags)
- }
+ @Before
+ fun setup() {
+ MockitoAnnotations.initMocks(this)
+ whenever(mKeyguardMessageAreaControllerFactory.create(any()))
+ .thenReturn(mKeyguardMessageAreaController)
+ fakeFeatureFlags = FakeFeatureFlags()
+ fakeFeatureFlags.set(Flags.REVAMPED_BOUNCER_MESSAGES, false)
+ mKeyguardPatternView = View.inflate(mContext, R.layout.keyguard_pattern_view, null)
+ as KeyguardPatternView
+
+
+ mKeyguardPatternViewController =
+ KeyguardPatternViewController(
+ mKeyguardPatternView,
+ mKeyguardUpdateMonitor,
+ mSecurityMode,
+ mLockPatternUtils,
+ mKeyguardSecurityCallback,
+ mLatencyTracker,
+ mFalsingCollector,
+ mEmergencyButtonController,
+ mKeyguardMessageAreaControllerFactory,
+ mPostureController,
+ fakeFeatureFlags
+ )
+ mKeyguardPatternView.onAttachedToWindow()
+ }
+
+ @Test
+ fun tabletopPostureIsDetectedFromStart() {
+ overrideResource(R.dimen.half_opened_bouncer_height_ratio, 0.5f)
+ whenever(mPostureController.devicePosture).thenReturn(DEVICE_POSTURE_HALF_OPENED)
+
+ mKeyguardPatternViewController.onViewAttached()
+
+ assertThat(getPatternTopGuideline()).isEqualTo(getExpectedTopGuideline())
+ }
+
+ private fun getPatternTopGuideline(): Float {
+ val cs = ConstraintSet()
+ val container =
+ mKeyguardPatternView.findViewById(R.id.pattern_container) as ConstraintLayout
+ cs.clone(container)
+ return cs.getConstraint(R.id.pattern_top_guideline).layout.guidePercent
+ }
+
+ private fun getExpectedTopGuideline(): Float {
+ return mContext.resources.getFloat(R.dimen.half_opened_bouncer_height_ratio)
+ }
@Test
fun withFeatureFlagOn_oldMessage_isHidden() {
fakeFeatureFlags.set(Flags.REVAMPED_BOUNCER_MESSAGES, true)
- mKeyguardPatternViewController.init()
+ mKeyguardPatternViewController.onViewAttached()
verify<KeyguardMessageAreaController<*>>(mKeyguardMessageAreaController).disable()
}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
index b0576e0..901c3fb 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -17,6 +17,7 @@
package com.android.keyguard;
import static android.app.StatusBarManager.SESSION_KEYGUARD;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT;
import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ERROR_LOCKOUT;
import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ERROR_LOCKOUT_PERMANENT;
@@ -65,6 +66,8 @@
import static org.mockito.Mockito.when;
import android.app.Activity;
+import android.app.ActivityTaskManager;
+import android.app.IActivityTaskManager;
import android.app.admin.DevicePolicyManager;
import android.app.trust.IStrongAuthTracker;
import android.app.trust.TrustManager;
@@ -116,6 +119,7 @@
import android.test.suitebuilder.annotation.SmallTest;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
+import android.text.TextUtils;
import androidx.annotation.NonNull;
@@ -139,6 +143,8 @@
import com.android.systemui.log.SessionTracker;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.settings.UserTracker;
+import com.android.systemui.shared.system.TaskStackChangeListener;
+import com.android.systemui.shared.system.TaskStackChangeListeners;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.policy.DevicePostureController;
@@ -175,6 +181,8 @@
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper
public class KeyguardUpdateMonitorTest extends SysuiTestCase {
+ private static final String PKG_ALLOWING_FP_LISTEN_ON_OCCLUDING_ACTIVITY =
+ "test_app_fp_listen_on_occluding_activity";
private static final String TEST_CARRIER = "TEST_CARRIER";
private static final String TEST_CARRIER_2 = "TEST_CARRIER_2";
private static final int TEST_CARRIER_ID = 1;
@@ -264,6 +272,10 @@
private UsbPortStatus mUsbPortStatus;
@Mock
private Uri mURI;
+ @Mock
+ private TaskStackChangeListeners mTaskStackChangeListeners;
+ @Mock
+ private IActivityTaskManager mActivityTaskManager;
private List<FaceSensorPropertiesInternal> mFaceSensorProperties;
private List<FingerprintSensorPropertiesInternal> mFingerprintSensorProperties;
@@ -327,6 +339,10 @@
mDumpManager
);
+ mContext.getOrCreateTestableResources().addOverride(com.android.systemui
+ .R.array.config_fingerprint_listen_on_occluding_activity_packages,
+ new String[]{ PKG_ALLOWING_FP_LISTEN_ON_OCCLUDING_ACTIVITY });
+
mTestableLooper = TestableLooper.get(this);
allowTestableLooperAsMainThread();
mFeatureFlags = new FakeFeatureFlags();
@@ -1560,7 +1576,8 @@
}
@Test
- public void testOccludingAppFingerprintListeningState_featureFlagEnabled() {
+ public void listenForFingerprint_whenOccludingAppPkgOnAllowlist()
+ throws RemoteException {
mFeatureFlags.set(FP_LISTEN_OCCLUDING_APPS, true);
// GIVEN keyguard isn't visible (app occluding)
@@ -1568,10 +1585,36 @@
mKeyguardUpdateMonitor.setKeyguardShowing(true, true);
when(mStrongAuthTracker.hasUserAuthenticatedSinceBoot()).thenReturn(true);
+ // GIVEN the top activity is from a package that allows fingerprint listening over its
+ // occluding activities
+ setTopStandardActivity(PKG_ALLOWING_FP_LISTEN_ON_OCCLUDING_ACTIVITY);
+ onTaskStackChanged();
+
// THEN we SHOULD listen for non-UDFPS fingerprint
assertThat(mKeyguardUpdateMonitor.shouldListenForFingerprint(false)).isEqualTo(true);
- // THEN we should listen for udfps (hiding of mechanism to actually auth is
+ // THEN we should listen for udfps (hiding mechanism to actually auth is
+ // controlled by UdfpsKeyguardViewController)
+ assertThat(mKeyguardUpdateMonitor.shouldListenForFingerprint(true)).isEqualTo(true);
+ }
+
+ @Test
+ public void doNotListenForFingerprint_whenOccludingAppPkgNotOnAllowlist()
+ throws RemoteException {
+ mFeatureFlags.set(FP_LISTEN_OCCLUDING_APPS, true);
+
+ // GIVEN keyguard isn't visible (app occluding)
+ mKeyguardUpdateMonitor.dispatchStartedWakingUp(PowerManager.WAKE_REASON_POWER_BUTTON);
+ mKeyguardUpdateMonitor.setKeyguardShowing(true, true);
+ when(mStrongAuthTracker.hasUserAuthenticatedSinceBoot()).thenReturn(true);
+
+ // GIVEN top activity is not in the allowlist for listening to fp over occluding activities
+ setTopStandardActivity("notInAllowList");
+
+ // THEN we should not listen for non-UDFPS fingerprint
+ assertThat(mKeyguardUpdateMonitor.shouldListenForFingerprint(false)).isEqualTo(false);
+
+ // THEN we should listen for udfps (hiding mechanism to actually auth is
// controlled by UdfpsKeyguardViewController)
assertThat(mKeyguardUpdateMonitor.shouldListenForFingerprint(true)).isEqualTo(true);
}
@@ -3267,6 +3310,23 @@
BatteryManager.CHARGING_POLICY_ADAPTIVE_LONGLIFE);
}
+ private void setTopStandardActivity(String pkgName) throws RemoteException {
+ final ActivityTaskManager.RootTaskInfo taskInfo = new ActivityTaskManager.RootTaskInfo();
+ taskInfo.visible = true;
+ taskInfo.topActivity = TextUtils.isEmpty(pkgName)
+ ? null : new ComponentName(pkgName, "testClass");
+ when(mActivityTaskManager.getRootTaskInfo(anyInt(), eq(ACTIVITY_TYPE_STANDARD)))
+ .thenReturn(taskInfo);
+ }
+
+ private void onTaskStackChanged() {
+ ArgumentCaptor<TaskStackChangeListener> taskStackChangeListenerCaptor =
+ ArgumentCaptor.forClass(TaskStackChangeListener.class);
+ verify(mTaskStackChangeListeners).registerTaskStackListener(
+ taskStackChangeListenerCaptor.capture());
+ taskStackChangeListenerCaptor.getValue().onTaskStackChangedBackground();
+ }
+
private class TestableKeyguardUpdateMonitor extends KeyguardUpdateMonitor {
AtomicBoolean mSimStateChanged = new AtomicBoolean(false);
AtomicInteger mCachedSimState = new AtomicInteger(-1);
@@ -3284,7 +3344,8 @@
mDreamManager, mDevicePolicyManager, mSensorPrivacyManager, mTelephonyManager,
mPackageManager, mFaceManager, mFingerprintManager, mBiometricManager,
mFaceWakeUpTriggersConfig, mDevicePostureController,
- Optional.of(mInteractiveToAuthProvider), mFeatureFlags);
+ Optional.of(mInteractiveToAuthProvider), mFeatureFlags,
+ mTaskStackChangeListeners, mActivityTaskManager);
setStrongAuthTracker(KeyguardUpdateMonitorTest.this.mStrongAuthTracker);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractorTest.kt
index 3a93e77..ac2d492 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractorTest.kt
@@ -337,6 +337,110 @@
}
@Test
+ fun tryAutoConfirm_withAutoConfirmPinAndEmptyInput_returnsNullAndHasNoEffect() =
+ testScope.runTest {
+ val failedAttemptCount by collectLastValue(underTest.failedAuthenticationAttempts)
+ val isUnlocked by collectLastValue(underTest.isUnlocked)
+ underTest.setAuthenticationMethod(
+ AuthenticationMethodModel.Pin(1234, autoConfirm = true)
+ )
+ assertThat(isUnlocked).isFalse()
+
+ assertThat(underTest.authenticate(listOf(), tryAutoConfirm = true)).isNull()
+ assertThat(isUnlocked).isFalse()
+ assertThat(failedAttemptCount).isEqualTo(0)
+ }
+
+ @Test
+ fun tryAutoConfirm_withAutoConfirmPinAndShorterPin_returnsNullAndHasNoEffect() =
+ testScope.runTest {
+ val failedAttemptCount by collectLastValue(underTest.failedAuthenticationAttempts)
+ val isUnlocked by collectLastValue(underTest.isUnlocked)
+ underTest.setAuthenticationMethod(
+ AuthenticationMethodModel.Pin(1234, autoConfirm = true)
+ )
+ assertThat(isUnlocked).isFalse()
+
+ assertThat(underTest.authenticate(listOf(1, 2, 3), tryAutoConfirm = true)).isNull()
+ assertThat(isUnlocked).isFalse()
+ assertThat(failedAttemptCount).isEqualTo(0)
+ }
+
+ @Test
+ fun tryAutoConfirm_withAutoConfirmWrongPinCorrectLength_returnsFalseAndDoesNotUnlockDevice() =
+ testScope.runTest {
+ val failedAttemptCount by collectLastValue(underTest.failedAuthenticationAttempts)
+ val isUnlocked by collectLastValue(underTest.isUnlocked)
+ underTest.setAuthenticationMethod(
+ AuthenticationMethodModel.Pin(1234, autoConfirm = true)
+ )
+ assertThat(isUnlocked).isFalse()
+
+ assertThat(underTest.authenticate(listOf(1, 2, 4, 4), tryAutoConfirm = true)).isFalse()
+ assertThat(isUnlocked).isFalse()
+ assertThat(failedAttemptCount).isEqualTo(1)
+ }
+
+ @Test
+ fun tryAutoConfirm_withAutoConfirmLongerPin_returnsFalseAndDoesNotUnlockDevice() =
+ testScope.runTest {
+ val failedAttemptCount by collectLastValue(underTest.failedAuthenticationAttempts)
+ val isUnlocked by collectLastValue(underTest.isUnlocked)
+ underTest.setAuthenticationMethod(
+ AuthenticationMethodModel.Pin(1234, autoConfirm = true)
+ )
+ assertThat(isUnlocked).isFalse()
+
+ assertThat(underTest.authenticate(listOf(1, 2, 3, 4, 5), tryAutoConfirm = true))
+ .isFalse()
+ assertThat(isUnlocked).isFalse()
+ assertThat(failedAttemptCount).isEqualTo(1)
+ }
+
+ @Test
+ fun tryAutoConfirm_withAutoConfirmCorrectPin_returnsTrueAndUnlocksDevice() =
+ testScope.runTest {
+ val failedAttemptCount by collectLastValue(underTest.failedAuthenticationAttempts)
+ val isUnlocked by collectLastValue(underTest.isUnlocked)
+ underTest.setAuthenticationMethod(
+ AuthenticationMethodModel.Pin(1234, autoConfirm = true)
+ )
+ assertThat(isUnlocked).isFalse()
+
+ assertThat(underTest.authenticate(listOf(1, 2, 4, 4), tryAutoConfirm = true)).isFalse()
+ assertThat(isUnlocked).isFalse()
+ assertThat(failedAttemptCount).isEqualTo(1)
+ }
+
+ @Test
+ fun tryAutoConfirm_withoutAutoConfirmButCorrectPin_returnsNullAndHasNoEffects() =
+ testScope.runTest {
+ val failedAttemptCount by collectLastValue(underTest.failedAuthenticationAttempts)
+ val isUnlocked by collectLastValue(underTest.isUnlocked)
+ underTest.setAuthenticationMethod(
+ AuthenticationMethodModel.Pin(1234, autoConfirm = false)
+ )
+ assertThat(isUnlocked).isFalse()
+
+ assertThat(underTest.authenticate(listOf(1, 2, 3, 4), tryAutoConfirm = true)).isNull()
+ assertThat(isUnlocked).isFalse()
+ assertThat(failedAttemptCount).isEqualTo(0)
+ }
+
+ @Test
+ fun tryAutoConfirm_withoutCorrectPassword_returnsNullAndHasNoEffects() =
+ testScope.runTest {
+ val failedAttemptCount by collectLastValue(underTest.failedAuthenticationAttempts)
+ val isUnlocked by collectLastValue(underTest.isUnlocked)
+ underTest.setAuthenticationMethod(AuthenticationMethodModel.Password("password"))
+ assertThat(isUnlocked).isFalse()
+
+ assertThat(underTest.authenticate("password".toList(), tryAutoConfirm = true)).isNull()
+ assertThat(isUnlocked).isFalse()
+ assertThat(failedAttemptCount).isEqualTo(0)
+ }
+
+ @Test
fun unlocksDevice_whenAuthMethodBecomesNone() =
testScope.runTest {
val isUnlocked by collectLastValue(underTest.isUnlocked)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
index 9d47839..5cae23c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
@@ -488,6 +488,50 @@
assertEquals(modalityCaptor.getValue().intValue(), modality);
assertEquals(messageCaptor.getValue(),
+ mContext.getString(R.string.biometric_not_recognized));
+ }
+
+ @Test
+ public void testOnAuthenticationFailedInvoked_whenFaceAuthRejected() throws RemoteException {
+ final int modality = BiometricAuthenticator.TYPE_FACE;
+ final int userId = 0;
+
+ enrollFingerprintAndFace(userId);
+
+ showDialog(new int[] {1} /* sensorIds */, false /* credentialAllowed */);
+
+ mAuthController.onBiometricError(modality,
+ BiometricConstants.BIOMETRIC_PAUSED_REJECTED,
+ 0 /* vendorCode */);
+
+ ArgumentCaptor<Integer> modalityCaptor = ArgumentCaptor.forClass(Integer.class);
+ ArgumentCaptor<String> messageCaptor = ArgumentCaptor.forClass(String.class);
+ verify(mDialog1).onAuthenticationFailed(modalityCaptor.capture(), messageCaptor.capture());
+
+ assertEquals(modalityCaptor.getValue().intValue(), modality);
+ assertEquals(messageCaptor.getValue(),
+ mContext.getString(R.string.biometric_face_not_recognized));
+ }
+
+ @Test
+ public void testOnAuthenticationFailedInvoked_whenFingerprintAuthRejected() {
+ final int modality = BiometricAuthenticator.TYPE_FINGERPRINT;
+ final int userId = 0;
+
+ enrollFingerprintAndFace(userId);
+
+ showDialog(new int[] {1} /* sensorIds */, false /* credentialAllowed */);
+
+ mAuthController.onBiometricError(modality,
+ BiometricConstants.BIOMETRIC_PAUSED_REJECTED,
+ 0 /* vendorCode */);
+
+ ArgumentCaptor<Integer> modalityCaptor = ArgumentCaptor.forClass(Integer.class);
+ ArgumentCaptor<String> messageCaptor = ArgumentCaptor.forClass(String.class);
+ verify(mDialog1).onAuthenticationFailed(modalityCaptor.capture(), messageCaptor.capture());
+
+ assertEquals(modalityCaptor.getValue().intValue(), modality);
+ assertEquals(messageCaptor.getValue(),
mContext.getString(R.string.fingerprint_error_not_match));
}
@@ -1017,6 +1061,31 @@
return HAT;
}
+ private void enrollFingerprintAndFace(final int userId) {
+
+ // Enroll fingerprint
+ verify(mFingerprintManager).registerBiometricStateListener(
+ mBiometricStateCaptor.capture());
+ assertFalse(mAuthController.isFingerprintEnrolled(userId));
+
+ mBiometricStateCaptor.getValue().onEnrollmentsChanged(userId,
+ 1 /* sensorId */, true /* hasEnrollments */);
+ waitForIdleSync();
+
+ assertTrue(mAuthController.isFingerprintEnrolled(userId));
+
+ // Enroll face
+ verify(mFaceManager).registerBiometricStateListener(
+ mBiometricStateCaptor.capture());
+ assertFalse(mAuthController.isFaceAuthEnrolled(userId));
+
+ mBiometricStateCaptor.getValue().onEnrollmentsChanged(userId,
+ 2 /* sensorId */, true /* hasEnrollments */);
+ waitForIdleSync();
+
+ assertTrue(mAuthController.isFaceAuthEnrolled(userId));
+ }
+
private final class TestableAuthController extends AuthController {
private int mBuildCount = 0;
private PromptInfo mLastBiometricPromptInfo;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthDialogPanelInteractionDetectorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthDialogPanelInteractionDetectorTest.kt
index ef750be..9cabd35 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthDialogPanelInteractionDetectorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthDialogPanelInteractionDetectorTest.kt
@@ -20,12 +20,12 @@
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.shade.ShadeExpansionStateManager
+import org.junit.Assert
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
-import org.mockito.Mockito.times
import org.mockito.Mockito.verify
import org.mockito.Mockito.verifyZeroInteractions
import org.mockito.junit.MockitoJUnit
@@ -63,10 +63,10 @@
}
@Test
- fun testEnableDetector_expandOnly_shouldPostRunnable() {
+ fun testEnableDetector_expandOnly_shouldNotPostRunnable() {
detector.enable(action)
shadeExpansionStateManager.onPanelExpansionChanged(1.0f, true, false, 0f)
- verify(action).run()
+ verifyZeroInteractions(action)
}
@Test
@@ -84,4 +84,14 @@
shadeExpansionStateManager.onPanelExpansionChanged(1.0f, true, true, 0f)
verifyZeroInteractions(action)
}
+
+ @Test
+ fun testFromOpenState_becomeStateClose_enableDetector_shouldNotPostRunnable() {
+ // STATE_OPEN is 2
+ shadeExpansionStateManager.updateState(2)
+ detector.enable(action)
+ shadeExpansionStateManager.onPanelExpansionChanged(0.5f, false, false, 0f)
+ verifyZeroInteractions(action)
+ Assert.assertEquals(true, shadeExpansionStateManager.isClosed())
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorTest.kt
index 6a63c32..9483667 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorTest.kt
@@ -95,6 +95,61 @@
}
@Test
+ fun pinAuthMethod_tryAutoConfirm_withAutoConfirmPin() =
+ testScope.runTest {
+ val currentScene by collectLastValue(sceneInteractor.currentScene("container1"))
+ val message by collectLastValue(underTest.message)
+
+ authenticationInteractor.setAuthenticationMethod(
+ AuthenticationMethodModel.Pin(1234, autoConfirm = true)
+ )
+ authenticationInteractor.lockDevice()
+ underTest.showOrUnlockDevice("container1")
+ assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
+ assertThat(message).isEqualTo(MESSAGE_ENTER_YOUR_PIN)
+ underTest.clearMessage()
+
+ // Incomplete input.
+ assertThat(underTest.authenticate(listOf(1, 2), tryAutoConfirm = true)).isNull()
+ assertThat(message).isEmpty()
+ assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
+
+ // Wrong 4-digit pin
+ assertThat(underTest.authenticate(listOf(1, 2, 3, 5), tryAutoConfirm = true)).isFalse()
+ assertThat(message).isEqualTo(MESSAGE_WRONG_PIN)
+ assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
+
+ // Correct input.
+ assertThat(underTest.authenticate(listOf(1, 2, 3, 4), tryAutoConfirm = true)).isTrue()
+ assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Gone))
+ }
+
+ @Test
+ fun pinAuthMethod_tryAutoConfirm_withoutAutoConfirmPin() =
+ testScope.runTest {
+ val currentScene by collectLastValue(sceneInteractor.currentScene("container1"))
+ val message by collectLastValue(underTest.message)
+
+ authenticationInteractor.setAuthenticationMethod(
+ AuthenticationMethodModel.Pin(1234, autoConfirm = false)
+ )
+ authenticationInteractor.lockDevice()
+ underTest.showOrUnlockDevice("container1")
+ assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
+ underTest.clearMessage()
+
+ // Incomplete input.
+ assertThat(underTest.authenticate(listOf(1, 2), tryAutoConfirm = true)).isNull()
+ assertThat(message).isEmpty()
+ assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
+
+ // Correct input.
+ assertThat(underTest.authenticate(listOf(1, 2, 3, 4), tryAutoConfirm = true)).isNull()
+ assertThat(message).isEmpty()
+ assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
+ }
+
+ @Test
fun passwordAuthMethod() =
testScope.runTest {
val currentScene by collectLastValue(sceneInteractor.currentScene("container1"))
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModelTest.kt
index 7b6bb37..7e358d2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModelTest.kt
@@ -25,7 +25,6 @@
import com.android.systemui.scene.SceneTestUtils
import com.android.systemui.scene.shared.model.SceneKey
import com.android.systemui.scene.shared.model.SceneModel
-import com.google.common.truth.Correspondence
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.MutableStateFlow
@@ -286,15 +285,160 @@
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Gone))
}
+ @Test
+ fun onAutoConfirm_whenCorrect() =
+ testScope.runTest {
+ val isUnlocked by collectLastValue(authenticationInteractor.isUnlocked)
+ val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
+ authenticationInteractor.setAuthenticationMethod(
+ AuthenticationMethodModel.Pin(1234, autoConfirm = true)
+ )
+ authenticationInteractor.lockDevice()
+ sceneInteractor.setCurrentScene(CONTAINER_NAME, SceneModel(SceneKey.Bouncer))
+ assertThat(isUnlocked).isFalse()
+ assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
+ underTest.onShown()
+ underTest.onPinButtonClicked(1)
+ underTest.onPinButtonClicked(2)
+ underTest.onPinButtonClicked(3)
+ underTest.onPinButtonClicked(4)
+
+ assertThat(isUnlocked).isTrue()
+ assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Gone))
+ }
+
+ @Test
+ fun onAutoConfirm_whenWrong() =
+ testScope.runTest {
+ val isUnlocked by collectLastValue(authenticationInteractor.isUnlocked)
+ val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_NAME))
+ val message by collectLastValue(bouncerViewModel.message)
+ val entries by collectLastValue(underTest.pinEntries)
+ authenticationInteractor.setAuthenticationMethod(
+ AuthenticationMethodModel.Pin(1234, autoConfirm = true)
+ )
+ authenticationInteractor.lockDevice()
+ sceneInteractor.setCurrentScene(CONTAINER_NAME, SceneModel(SceneKey.Bouncer))
+ assertThat(isUnlocked).isFalse()
+ assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
+ underTest.onShown()
+ underTest.onPinButtonClicked(1)
+ underTest.onPinButtonClicked(2)
+ underTest.onPinButtonClicked(3)
+ underTest.onPinButtonClicked(5) // PIN is now wrong!
+
+ assertThat(entries).hasSize(0)
+ assertThat(message?.text).isEqualTo(WRONG_PIN)
+ assertThat(isUnlocked).isFalse()
+ assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
+ }
+
+ @Test
+ fun backspaceButtonAppearance_withoutAutoConfirm_alwaysShown() =
+ testScope.runTest {
+ val backspaceButtonAppearance by collectLastValue(underTest.backspaceButtonAppearance)
+
+ authenticationInteractor.setAuthenticationMethod(
+ AuthenticationMethodModel.Pin(1234, autoConfirm = false)
+ )
+
+ assertThat(backspaceButtonAppearance).isEqualTo(ActionButtonAppearance.Shown)
+ }
+
+ @Test
+ fun backspaceButtonAppearance_withAutoConfirmButNoInput_isHidden() =
+ testScope.runTest {
+ val backspaceButtonAppearance by collectLastValue(underTest.backspaceButtonAppearance)
+ authenticationInteractor.setAuthenticationMethod(
+ AuthenticationMethodModel.Pin(1234, autoConfirm = true)
+ )
+
+ assertThat(backspaceButtonAppearance).isEqualTo(ActionButtonAppearance.Hidden)
+ }
+
+ @Test
+ fun backspaceButtonAppearance_withAutoConfirmAndInput_isShownQuiet() =
+ testScope.runTest {
+ val backspaceButtonAppearance by collectLastValue(underTest.backspaceButtonAppearance)
+ authenticationInteractor.setAuthenticationMethod(
+ AuthenticationMethodModel.Pin(1234, autoConfirm = true)
+ )
+
+ underTest.onPinButtonClicked(1)
+
+ assertThat(backspaceButtonAppearance).isEqualTo(ActionButtonAppearance.Subtle)
+ }
+
+ @Test
+ fun confirmButtonAppearance_withoutAutoConfirm_alwaysShown() =
+ testScope.runTest {
+ val confirmButtonAppearance by collectLastValue(underTest.confirmButtonAppearance)
+
+ authenticationInteractor.setAuthenticationMethod(
+ AuthenticationMethodModel.Pin(1234, autoConfirm = false)
+ )
+
+ assertThat(confirmButtonAppearance).isEqualTo(ActionButtonAppearance.Shown)
+ }
+
+ @Test
+ fun confirmButtonAppearance_withAutoConfirm_isHidden() =
+ testScope.runTest {
+ val confirmButtonAppearance by collectLastValue(underTest.confirmButtonAppearance)
+ authenticationInteractor.setAuthenticationMethod(
+ AuthenticationMethodModel.Pin(1234, autoConfirm = true)
+ )
+
+ assertThat(confirmButtonAppearance).isEqualTo(ActionButtonAppearance.Hidden)
+ }
+
+ @Test
+ fun hintedPinLength_withoutAutoConfirm_isNull() =
+ testScope.runTest {
+ val hintedPinLength by collectLastValue(underTest.hintedPinLength)
+ authenticationInteractor.setAuthenticationMethod(
+ AuthenticationMethodModel.Pin(1234, autoConfirm = false)
+ )
+
+ assertThat(hintedPinLength).isNull()
+ }
+
+ @Test
+ fun hintedPinLength_withAutoConfirmPinLessThanSixDigits_isNull() =
+ testScope.runTest {
+ val hintedPinLength by collectLastValue(underTest.hintedPinLength)
+ authenticationInteractor.setAuthenticationMethod(
+ AuthenticationMethodModel.Pin(12345, autoConfirm = true)
+ )
+
+ assertThat(hintedPinLength).isNull()
+ }
+
+ @Test
+ fun hintedPinLength_withAutoConfirmPinExactlySixDigits_isSix() =
+ testScope.runTest {
+ val hintedPinLength by collectLastValue(underTest.hintedPinLength)
+ authenticationInteractor.setAuthenticationMethod(
+ AuthenticationMethodModel.Pin(123456, autoConfirm = true)
+ )
+
+ assertThat(hintedPinLength).isEqualTo(6)
+ }
+
+ @Test
+ fun hintedPinLength_withAutoConfirmPinMoreThanSixDigits_isNull() =
+ testScope.runTest {
+ val hintedPinLength by collectLastValue(underTest.hintedPinLength)
+ authenticationInteractor.setAuthenticationMethod(
+ AuthenticationMethodModel.Pin(1234567, autoConfirm = true)
+ )
+
+ assertThat(hintedPinLength).isNull()
+ }
+
companion object {
private const val CONTAINER_NAME = "container1"
private const val ENTER_YOUR_PIN = "Enter your pin"
private const val WRONG_PIN = "Wrong pin"
-
- val KEY_CODE =
- Correspondence.transforming<EnteredKey, Int>(
- { it?.input },
- "has a eventId of",
- )
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/demomode/DemoModeControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/demomode/DemoModeControllerTest.kt
index 75eec72..68ea7eb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/demomode/DemoModeControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/demomode/DemoModeControllerTest.kt
@@ -94,7 +94,7 @@
intent.putExtra("command", command)
args.forEach { arg -> intent.putExtra(arg.key, arg.value) }
- fakeBroadcastDispatcher.registeredReceivers.forEach { it.onReceive(context, intent) }
+ fakeBroadcastDispatcher.sendIntentToMatchingReceiversOnly(context, intent)
}
companion object {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
index b324b4713..fe876d5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
@@ -37,6 +37,7 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.doAnswer;
@@ -361,6 +362,27 @@
@Test
@TestableLooper.RunWithLooper(setAsMainLooper = true)
+ public void wakeupFromDreamingWhenKeyguardHides() {
+ mViewMediator.onSystemReady();
+ TestableLooper.get(this).processAllMessages();
+
+ // Given device is dreaming
+ when(mUpdateMonitor.isDreaming()).thenReturn(true);
+
+ // When keyguard is going away
+ mKeyguardStateController.notifyKeyguardGoingAway(true);
+
+ // And keyguard is disabled which will call #handleHide
+ mViewMediator.setKeyguardEnabled(false);
+ TestableLooper.get(this).processAllMessages();
+
+ // Then dream should wake up
+ verify(mPowerManager).wakeUp(anyLong(), anyInt(),
+ eq("com.android.systemui:UNLOCK_DREAMING"));
+ }
+
+ @Test
+ @TestableLooper.RunWithLooper(setAsMainLooper = true)
public void restoreBouncerWhenSimLockedAndKeyguardIsGoingAway() {
// When showing and provisioned
mViewMediator.onSystemReady();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManagerTest.kt
index b2528c5..edaff44 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManagerTest.kt
@@ -25,6 +25,7 @@
import com.android.systemui.R
import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
+import com.android.systemui.backup.BackupHelper
import com.android.systemui.settings.FakeUserTracker
import com.android.systemui.settings.UserFileManager
import com.android.systemui.util.FakeSharedPreferences
@@ -360,7 +361,10 @@
}
clearInvocations(userFileManager)
- fakeBroadcastDispatcher.registeredReceivers.firstOrNull()?.onReceive(context, Intent())
+ fakeBroadcastDispatcher.sendIntentToMatchingReceiversOnly(
+ context,
+ Intent(BackupHelper.ACTION_RESTORE_FINISHED),
+ )
verify(userFileManager, atLeastOnce()).getSharedPreferences(anyString(), anyInt(), anyInt())
job.cancel()
@@ -374,12 +378,13 @@
arrayOf("leftTest:testShortcut1", "rightTest:testShortcut2")
)
- assertThat(underTest.getSelections()).isEqualTo(
- mapOf(
- "leftTest" to listOf("testShortcut1"),
- "rightTest" to listOf("testShortcut2"),
+ assertThat(underTest.getSelections())
+ .isEqualTo(
+ mapOf(
+ "leftTest" to listOf("testShortcut1"),
+ "rightTest" to listOf("testShortcut2"),
+ )
)
- )
}
private fun assertSelections(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/BiometricSettingsRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/BiometricSettingsRepositoryTest.kt
index b925aeb..f9070b3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/BiometricSettingsRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/BiometricSettingsRepositoryTest.kt
@@ -461,12 +461,10 @@
}
private fun broadcastDPMStateChange() {
- fakeBroadcastDispatcher.registeredReceivers.forEach { receiver ->
- receiver.onReceive(
- context,
- Intent(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED)
- )
- }
+ fakeBroadcastDispatcher.sendIntentToMatchingReceiversOnly(
+ context,
+ Intent(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED),
+ )
}
companion object {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt
index 92ec9a1..5922cbf 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt
@@ -507,6 +507,18 @@
}
@Test
+ fun authenticateDoesNotRunIfKeyguardIsNotShowing() =
+ testScope.runTest {
+ testGatingCheckForFaceAuth { keyguardRepository.setKeyguardShowing(false) }
+ }
+
+ @Test
+ fun detectDoesNotRunIfKeyguardIsNotShowing() =
+ testScope.runTest {
+ testGatingCheckForDetect { keyguardRepository.setKeyguardShowing(false) }
+ }
+
+ @Test
fun authenticateDoesNotRunWhenFpIsLockedOut() =
testScope.runTest {
testGatingCheckForFaceAuth { deviceEntryFingerprintAuthRepository.setLockedOut(true) }
@@ -565,6 +577,8 @@
testScope.runTest {
testGatingCheckForFaceAuth {
bouncerRepository.setAlternateVisible(false)
+ // Keyguard is occluded when secure camera is active.
+ keyguardRepository.setKeyguardOccluded(true)
fakeCommandQueue.doForEachCallback {
it.onCameraLaunchGestureDetected(CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP)
}
@@ -774,6 +788,8 @@
testScope.runTest {
testGatingCheckForDetect {
bouncerRepository.setAlternateVisible(false)
+ // Keyguard is occluded when secure camera is active.
+ keyguardRepository.setKeyguardOccluded(true)
fakeCommandQueue.doForEachCallback {
it.onCameraLaunchGestureDetected(CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP)
}
@@ -1011,6 +1027,7 @@
fakeUserRepository.setSelectedUserInfo(primaryUser)
biometricSettingsRepository.setIsFaceAuthSupportedInCurrentPosture(true)
bouncerRepository.setAlternateVisible(true)
+ keyguardRepository.setKeyguardShowing(true)
runCurrent()
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorTest.kt
index f63be61..e9c22f9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorTest.kt
@@ -194,9 +194,10 @@
underTest.onLongPress()
assertThat(isMenuVisible).isTrue()
- fakeBroadcastDispatcher.registeredReceivers.forEach { broadcastReceiver ->
- broadcastReceiver.onReceive(context, Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS))
- }
+ fakeBroadcastDispatcher.sendIntentToMatchingReceiversOnly(
+ context,
+ Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS),
+ )
assertThat(isMenuVisible).isFalse()
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/util/IndicationHelperTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/util/IndicationHelperTest.kt
new file mode 100644
index 0000000..fd0ff9b
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/util/IndicationHelperTest.kt
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyguard.util
+
+import android.hardware.biometrics.BiometricFaceConstants.BIOMETRIC_ERROR_POWER_PRESSED
+import android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_CANCELED
+import android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_LOCKOUT
+import android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_LOCKOUT_PERMANENT
+import android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_TIMEOUT
+import android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_UNABLE_TO_PROCESS
+import android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_VENDOR
+import android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ERROR_CANCELED
+import android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ERROR_LOCKOUT
+import android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ERROR_LOCKOUT_PERMANENT
+import android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ERROR_TIMEOUT
+import android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ERROR_USER_CANCELED
+import android.hardware.biometrics.BiometricSourceType
+import android.testing.TestableLooper
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.keyguard.KeyguardUpdateMonitor
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.util.mockito.whenever
+import junit.framework.Assert.assertFalse
+import junit.framework.Assert.assertTrue
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.anyBoolean
+import org.mockito.Mock
+import org.mockito.junit.MockitoJUnit
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+@TestableLooper.RunWithLooper
+class IndicationHelperTest : SysuiTestCase() {
+
+ @JvmField @Rule var mockitoRule = MockitoJUnit.rule()
+
+ @Mock lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor
+ private lateinit var underTest: IndicationHelper
+
+ @Before
+ fun setup() {
+ underTest =
+ IndicationHelper(
+ keyguardUpdateMonitor,
+ )
+ }
+
+ @Test
+ fun suppressErrorMsg_faceErrorCancelled() {
+ givenPrimaryAuthNotRequired()
+ assertTrue(underTest.shouldSuppressErrorMsg(BiometricSourceType.FACE, FACE_ERROR_CANCELED))
+ }
+
+ @Test
+ fun suppressErrorMsg_faceErrorUnableToProcess() {
+ givenPrimaryAuthNotRequired()
+ assertTrue(
+ underTest.shouldSuppressErrorMsg(BiometricSourceType.FACE, FACE_ERROR_UNABLE_TO_PROCESS)
+ )
+ }
+
+ @Test
+ fun suppressErrorMsg_facePrimaryAuthRequired() {
+ givenPrimaryAuthRequired()
+ assertTrue(underTest.shouldSuppressErrorMsg(BiometricSourceType.FACE, FACE_ERROR_TIMEOUT))
+ }
+
+ @Test
+ fun doNotSuppressErrorMsg_facePrimaryAuthRequired_faceLockout() {
+ givenPrimaryAuthRequired()
+ assertFalse(underTest.shouldSuppressErrorMsg(BiometricSourceType.FACE, FACE_ERROR_LOCKOUT))
+ assertFalse(
+ underTest.shouldSuppressErrorMsg(BiometricSourceType.FACE, FACE_ERROR_LOCKOUT_PERMANENT)
+ )
+ }
+
+ @Test
+ fun suppressErrorMsg_fingerprintErrorCancelled() {
+ givenPrimaryAuthNotRequired()
+ assertTrue(
+ underTest.shouldSuppressErrorMsg(
+ BiometricSourceType.FINGERPRINT,
+ FINGERPRINT_ERROR_CANCELED
+ )
+ )
+ }
+
+ @Test
+ fun suppressErrorMsg_fingerprintErrorUserCancelled() {
+ givenPrimaryAuthNotRequired()
+ assertTrue(
+ underTest.shouldSuppressErrorMsg(
+ BiometricSourceType.FINGERPRINT,
+ FINGERPRINT_ERROR_USER_CANCELED
+ )
+ )
+ }
+
+ @Test
+ fun suppressErrorMsg_fingerprintErrorPowerPressed() {
+ givenPrimaryAuthNotRequired()
+ assertTrue(
+ underTest.shouldSuppressErrorMsg(
+ BiometricSourceType.FINGERPRINT,
+ BIOMETRIC_ERROR_POWER_PRESSED
+ )
+ )
+ }
+
+ @Test
+ fun suppressErrorMsg_fingerprintPrimaryAuthRequired() {
+ givenPrimaryAuthRequired()
+ assertTrue(
+ underTest.shouldSuppressErrorMsg(BiometricSourceType.FACE, FINGERPRINT_ERROR_TIMEOUT)
+ )
+ }
+
+ @Test
+ fun doNotSuppressErrorMsg_fingerprintPrimaryAuthRequired_fingerprintLockout() {
+ givenPrimaryAuthRequired()
+ assertFalse(
+ underTest.shouldSuppressErrorMsg(
+ BiometricSourceType.FINGERPRINT,
+ FINGERPRINT_ERROR_LOCKOUT
+ )
+ )
+ assertFalse(
+ underTest.shouldSuppressErrorMsg(
+ BiometricSourceType.FACE,
+ FINGERPRINT_ERROR_LOCKOUT_PERMANENT
+ )
+ )
+ }
+
+ @Test
+ fun isFaceLockoutErrorMsgId() {
+ givenPrimaryAuthRequired()
+ assertTrue(underTest.isFaceLockoutErrorMsg(FACE_ERROR_LOCKOUT))
+ assertTrue(underTest.isFaceLockoutErrorMsg(FACE_ERROR_LOCKOUT_PERMANENT))
+ assertFalse(underTest.isFaceLockoutErrorMsg(FACE_ERROR_TIMEOUT))
+ assertFalse(underTest.isFaceLockoutErrorMsg(FACE_ERROR_CANCELED))
+ assertFalse(underTest.isFaceLockoutErrorMsg(FACE_ERROR_UNABLE_TO_PROCESS))
+ assertFalse(underTest.isFaceLockoutErrorMsg(FACE_ERROR_VENDOR))
+ }
+
+ private fun givenPrimaryAuthNotRequired() {
+ whenever(keyguardUpdateMonitor.isUnlockingWithBiometricAllowed(anyBoolean()))
+ .thenReturn(true)
+ }
+
+ private fun givenPrimaryAuthRequired() {
+ whenever(keyguardUpdateMonitor.isUnlockingWithBiometricAllowed(anyBoolean()))
+ .thenReturn(false)
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/resume/MediaResumeListenerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/resume/MediaResumeListenerTest.kt
index 9ab7289..530b86e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/resume/MediaResumeListenerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/resume/MediaResumeListenerTest.kt
@@ -98,6 +98,8 @@
@Captor lateinit var callbackCaptor: ArgumentCaptor<ResumeMediaBrowser.Callback>
@Captor lateinit var actionCaptor: ArgumentCaptor<Runnable>
@Captor lateinit var componentCaptor: ArgumentCaptor<String>
+ @Captor lateinit var userIdCaptor: ArgumentCaptor<Int>
+ @Captor lateinit var userCallbackCaptor: ArgumentCaptor<UserTracker.Callback>
private lateinit var executor: FakeExecutor
private lateinit var data: MediaData
@@ -124,7 +126,7 @@
)
Settings.Secure.putInt(context.contentResolver, Settings.Secure.MEDIA_CONTROLS_RESUME, 1)
- whenever(resumeBrowserFactory.create(capture(callbackCaptor), any()))
+ whenever(resumeBrowserFactory.create(capture(callbackCaptor), any(), capture(userIdCaptor)))
.thenReturn(resumeBrowser)
// resume components are stored in sharedpreferences
@@ -334,6 +336,7 @@
@Test
fun testOnUserUnlock_loadsTracks() {
// Set up mock service to successfully find valid media
+ setUpMbsWithValidResolveInfo()
val description = MediaDescription.Builder().setTitle(TITLE).build()
val component = ComponentName(PACKAGE_NAME, CLASS_NAME)
whenever(resumeBrowser.token).thenReturn(token)
@@ -417,6 +420,7 @@
@Test
fun testLoadComponents_recentlyPlayed_adds() {
// Set up browser to return successfully
+ setUpMbsWithValidResolveInfo()
val description = MediaDescription.Builder().setTitle(TITLE).build()
val component = ComponentName(PACKAGE_NAME, CLASS_NAME)
whenever(resumeBrowser.token).thenReturn(token)
@@ -600,7 +604,7 @@
// Set up our factory to return a new browser so we can verify we disconnected the old one
val newResumeBrowser = mock(ResumeMediaBrowser::class.java)
- whenever(resumeBrowserFactory.create(capture(callbackCaptor), any()))
+ whenever(resumeBrowserFactory.create(capture(callbackCaptor), any(), anyInt()))
.thenReturn(newResumeBrowser)
// When the resume action is run
@@ -610,6 +614,66 @@
verify(resumeBrowser).disconnect()
}
+ @Test
+ fun testUserUnlocked_userChangeWhileQuerying() {
+ val firstUserId = 1
+ val secondUserId = 2
+ val description = MediaDescription.Builder().setTitle(TITLE).build()
+ val component = ComponentName(PACKAGE_NAME, CLASS_NAME)
+
+ setUpMbsWithValidResolveInfo()
+ whenever(resumeBrowser.token).thenReturn(token)
+ whenever(resumeBrowser.appIntent).thenReturn(pendingIntent)
+
+ val unlockIntent =
+ Intent(Intent.ACTION_USER_UNLOCKED).apply {
+ putExtra(Intent.EXTRA_USER_HANDLE, firstUserId)
+ }
+ verify(userTracker).addCallback(capture(userCallbackCaptor), any())
+
+ // When the first user unlocks and we query their recent media
+ userCallbackCaptor.value.onUserChanged(firstUserId, context)
+ resumeListener.userUnlockReceiver.onReceive(context, unlockIntent)
+ whenever(resumeBrowser.userId).thenReturn(userIdCaptor.value)
+ verify(resumeBrowser, times(3)).findRecentMedia()
+
+ // And the user changes before the MBS response is received
+ userCallbackCaptor.value.onUserChanged(secondUserId, context)
+ callbackCaptor.value.addTrack(description, component, resumeBrowser)
+
+ // Then the loaded media is correctly associated with the first user
+ verify(mediaDataManager)
+ .addResumptionControls(
+ eq(firstUserId),
+ eq(description),
+ any(),
+ eq(token),
+ eq(PACKAGE_NAME),
+ eq(pendingIntent),
+ eq(PACKAGE_NAME)
+ )
+ }
+
+ @Test
+ fun testUserUnlocked_noComponent_doesNotQuery() {
+ // Set up a valid MBS, but user does not have the service available
+ setUpMbsWithValidResolveInfo()
+ val pm = mock(PackageManager::class.java)
+ whenever(mockContext.packageManager).thenReturn(pm)
+ whenever(pm.resolveServiceAsUser(any(), anyInt(), anyInt())).thenReturn(null)
+
+ val unlockIntent =
+ Intent(Intent.ACTION_USER_UNLOCKED).apply {
+ putExtra(Intent.EXTRA_USER_HANDLE, context.userId)
+ }
+
+ // When the user is unlocked, but does not have the component installed
+ resumeListener.userUnlockReceiver.onReceive(context, unlockIntent)
+
+ // Then we never attempt to connect to it
+ verify(resumeBrowser, never()).findRecentMedia()
+ }
+
/** Sets up mocks to successfully find a MBS that returns valid media. */
private fun setUpMbsWithValidResolveInfo() {
val pm = mock(PackageManager::class.java)
@@ -620,6 +684,8 @@
resolveInfo.serviceInfo = serviceInfo
resolveInfo.serviceInfo.name = CLASS_NAME
val resumeInfo = listOf(resolveInfo)
- whenever(pm.queryIntentServices(any(), anyInt())).thenReturn(resumeInfo)
+ whenever(pm.queryIntentServicesAsUser(any(), anyInt(), anyInt())).thenReturn(resumeInfo)
+ whenever(pm.resolveServiceAsUser(any(), anyInt(), anyInt())).thenReturn(resolveInfo)
+ whenever(pm.getApplicationLabel(any())).thenReturn(PACKAGE_NAME)
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/resume/ResumeMediaBrowserTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/resume/ResumeMediaBrowserTest.kt
index a04cfd4..b45e66b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/resume/ResumeMediaBrowserTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/resume/ResumeMediaBrowserTest.kt
@@ -93,7 +93,8 @@
component,
browserFactory,
logger,
- mediaController
+ mediaController,
+ context.userId,
)
}
@@ -381,8 +382,9 @@
componentName: ComponentName,
browserFactory: MediaBrowserFactory,
logger: ResumeMediaBrowserLogger,
- private val fakeController: MediaController
- ) : ResumeMediaBrowser(context, callback, componentName, browserFactory, logger) {
+ private val fakeController: MediaController,
+ userId: Int,
+ ) : ResumeMediaBrowser(context, callback, componentName, browserFactory, logger, userId) {
override fun createMediaController(token: MediaSession.Token): MediaController {
return fakeController
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaCarouselControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaCarouselControllerTest.kt
index 2aff90c..5b8272b0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaCarouselControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaCarouselControllerTest.kt
@@ -19,7 +19,9 @@
import android.app.PendingIntent
import android.content.res.ColorStateList
import android.content.res.Configuration
+import android.database.ContentObserver
import android.os.LocaleList
+import android.provider.Settings
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
import android.util.MathUtils.abs
@@ -56,6 +58,7 @@
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.capture
import com.android.systemui.util.mockito.eq
+import com.android.systemui.util.settings.GlobalSettings
import com.android.systemui.util.time.FakeSystemClock
import java.util.Locale
import javax.inject.Provider
@@ -113,6 +116,7 @@
@Mock lateinit var mediaFlags: MediaFlags
@Mock lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor
@Mock lateinit var keyguardTransitionInteractor: KeyguardTransitionInteractor
+ @Mock lateinit var globalSettings: GlobalSettings
private lateinit var transitionRepository: FakeKeyguardTransitionRepository
@Captor lateinit var listener: ArgumentCaptor<MediaDataManager.Listener>
@Captor
@@ -120,6 +124,7 @@
@Captor lateinit var visualStabilityCallback: ArgumentCaptor<OnReorderingAllowedListener>
@Captor lateinit var keyguardCallback: ArgumentCaptor<KeyguardUpdateMonitorCallback>
@Captor lateinit var hostStateCallback: ArgumentCaptor<MediaHostStatesManager.Callback>
+ @Captor lateinit var settingsObserverCaptor: ArgumentCaptor<ContentObserver>
private val clock = FakeSystemClock()
private lateinit var mediaCarouselController: MediaCarouselController
@@ -148,6 +153,7 @@
mediaFlags,
keyguardUpdateMonitor,
KeyguardTransitionInteractor(transitionRepository, TestScope().backgroundScope),
+ globalSettings
)
verify(configurationController).addCallback(capture(configListener))
verify(mediaDataManager).addListener(capture(listener))
@@ -160,6 +166,11 @@
whenever(mediaDataManager.smartspaceMediaData).thenReturn(smartspaceMediaData)
whenever(mediaFlags.isPersistentSsCardEnabled()).thenReturn(false)
MediaPlayerData.clear()
+ verify(globalSettings)
+ .registerContentObserver(
+ eq(Settings.Global.getUriFor(Settings.Global.ANIMATOR_DURATION_SCALE)),
+ settingsObserverCaptor.capture()
+ )
}
@Test
@@ -873,6 +884,15 @@
assertTrue(stateUpdated)
}
+ @Test
+ fun testAnimationScaleChanged_mediaControlPanelsNotified() {
+ MediaPlayerData.addMediaPlayer("key", DATA, panel, clock, isSsReactivated = false)
+
+ globalSettings.putFloat(Settings.Global.ANIMATOR_DURATION_SCALE, 0f)
+ settingsObserverCaptor.value!!.onChange(false)
+ verify(panel).updateAnimatorDurationScale()
+ }
+
/**
* Helper method when a configuration change occurs.
*
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaControlPanelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaControlPanelTest.kt
index f6075ad..f902be3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaControlPanelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaControlPanelTest.kt
@@ -25,7 +25,6 @@
import android.content.pm.ApplicationInfo
import android.content.pm.PackageManager
import android.content.res.Configuration
-import android.database.ContentObserver
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Color
@@ -113,7 +112,6 @@
import org.mockito.ArgumentCaptor
import org.mockito.ArgumentMatchers.anyInt
import org.mockito.ArgumentMatchers.anyLong
-import org.mockito.Captor
import org.mockito.Mock
import org.mockito.Mockito.anyString
import org.mockito.Mockito.mock
@@ -239,7 +237,6 @@
this.set(Flags.MEDIA_RECOMMENDATION_CARD_UPDATE, false)
}
@Mock private lateinit var globalSettings: GlobalSettings
- @Captor private lateinit var settingsObserverCaptor: ArgumentCaptor<ContentObserver>
@JvmField @Rule val mockito = MockitoJUnit.rule()
@@ -281,7 +278,7 @@
lockscreenUserManager,
broadcastDialogController,
fakeFeatureFlag,
- globalSettings,
+ globalSettings
) {
override fun loadAnimator(
animId: Int,
@@ -292,12 +289,6 @@
}
}
- verify(globalSettings)
- .registerContentObserver(
- eq(Settings.Global.getUriFor(Settings.Global.ANIMATOR_DURATION_SCALE)),
- settingsObserverCaptor.capture()
- )
-
initGutsViewHolderMocks()
initMediaViewHolderMocks()
@@ -986,7 +977,7 @@
// When the setting changes,
globalSettings.putFloat(Settings.Global.ANIMATOR_DURATION_SCALE, 0f)
- settingsObserverCaptor.value!!.onChange(false)
+ player.updateAnimatorDurationScale()
// Then the seekbar is set to not animate
assertThat(seekBarObserver.animationEnabled).isFalse()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java
index f3aee48..a14ff2f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java
@@ -356,6 +356,7 @@
});
verify(mockMediaOutputController).releaseSession();
+ verify(mDialogLaunchAnimator).disableAllCurrentDialogsExitAnimations();
}
@Test
@@ -371,7 +372,7 @@
@NonNull
private MediaOutputDialog makeTestDialog(MediaOutputController controller) {
return new MediaOutputDialog(mContext, false, mBroadcastSender,
- controller, mUiEventLogger);
+ controller, mDialogLaunchAnimator, mUiEventLogger);
}
private void withTestDialog(MediaOutputController controller, Consumer<MediaOutputDialog> c) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/CombinedShadeHeaderConstraintsTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/CombinedShadeHeaderConstraintsTest.kt
index 3706859..0a1eca6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/CombinedShadeHeaderConstraintsTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/CombinedShadeHeaderConstraintsTest.kt
@@ -62,9 +62,9 @@
assertThat(getConstraint(R.id.clock).layout.startToStart).isEqualTo(R.id.begin_guide)
assertThat(getConstraint(R.id.clock).layout.horizontalBias).isEqualTo(0f)
- assertThat(getConstraint(R.id.batteryRemainingIcon).layout.endToEnd)
+ assertThat(getConstraint(R.id.shade_header_system_icons).layout.endToEnd)
.isEqualTo(R.id.end_guide)
- assertThat(getConstraint(R.id.batteryRemainingIcon).layout.horizontalBias)
+ assertThat(getConstraint(R.id.shade_header_system_icons).layout.horizontalBias)
.isEqualTo(1f)
assertThat(getConstraint(R.id.privacy_container).layout.endToEnd)
@@ -95,9 +95,9 @@
assertThat(getConstraint(R.id.date).layout.startToStart).isEqualTo(PARENT_ID)
assertThat(getConstraint(R.id.date).layout.horizontalBias).isEqualTo(0.5f)
- assertThat(getConstraint(R.id.batteryRemainingIcon).layout.endToEnd)
+ assertThat(getConstraint(R.id.shade_header_system_icons).layout.endToEnd)
.isEqualTo(PARENT_ID)
- assertThat(getConstraint(R.id.batteryRemainingIcon).layout.horizontalBias)
+ assertThat(getConstraint(R.id.shade_header_system_icons).layout.horizontalBias)
.isEqualTo(0.5f)
assertThat(getConstraint(R.id.privacy_container).layout.endToEnd)
@@ -133,18 +133,15 @@
changes()
with(qqsConstraint) {
- assertThat(getConstraint(R.id.statusIcons).propertySet.alpha).isEqualTo(1f)
- assertThat(getConstraint(R.id.batteryRemainingIcon).propertySet.alpha).isEqualTo(1f)
+ assertThat(systemIconsAlphaConstraint).isEqualTo(1f)
}
with(qsConstraint) {
- assertThat(getConstraint(R.id.statusIcons).propertySet.alpha).isEqualTo(1f)
- assertThat(getConstraint(R.id.batteryRemainingIcon).propertySet.alpha).isEqualTo(1f)
+ assertThat(systemIconsAlphaConstraint).isEqualTo(1f)
}
with(largeScreenConstraint) {
- assertThat(getConstraint(R.id.statusIcons).propertySet.alpha).isEqualTo(1f)
- assertThat(getConstraint(R.id.batteryRemainingIcon).propertySet.alpha).isEqualTo(1f)
+ assertThat(systemIconsAlphaConstraint).isEqualTo(1f)
}
}
@@ -155,18 +152,15 @@
changes()
with(qqsConstraint) {
- assertThat(getConstraint(R.id.statusIcons).propertySet.alpha).isEqualTo(0f)
- assertThat(getConstraint(R.id.batteryRemainingIcon).propertySet.alpha).isEqualTo(0f)
+ assertThat(systemIconsAlphaConstraint).isEqualTo(0f)
}
with(qsConstraint) {
- assertThat(getConstraint(R.id.statusIcons).propertySet.alpha).isEqualTo(1f)
- assertThat(getConstraint(R.id.batteryRemainingIcon).propertySet.alpha).isEqualTo(1f)
+ assertThat(systemIconsAlphaConstraint).isEqualTo(1f)
}
with(largeScreenConstraint) {
- assertThat(getConstraint(R.id.statusIcons).propertySet.alpha).isEqualTo(1f)
- assertThat(getConstraint(R.id.batteryRemainingIcon).propertySet.alpha).isEqualTo(1f)
+ assertThat(systemIconsAlphaConstraint).isEqualTo(1f)
}
}
@@ -181,12 +175,13 @@
with(qqsConstraint) {
// In this case, the date is constrained on the end by a Barrier determined by either
- // privacy or statusIcons
+ // privacy or clickableIcons
assertThat(getConstraint(R.id.date).layout.endToStart).isEqualTo(R.id.barrier)
- assertThat(getConstraint(R.id.statusIcons).layout.startToEnd).isEqualTo(R.id.date)
+ assertThat(getConstraint(R.id.shade_header_system_icons).layout.startToEnd)
+ .isEqualTo(R.id.date)
assertThat(getConstraint(R.id.privacy_container).layout.startToEnd).isEqualTo(R.id.date)
assertThat(getConstraint(R.id.barrier).layout.mReferenceIds).asList().containsExactly(
- R.id.statusIcons,
+ R.id.shade_header_system_icons,
R.id.privacy_container
)
assertThat(getConstraint(R.id.barrier).layout.mBarrierDirection).isEqualTo(START)
@@ -272,7 +267,7 @@
assertThat(getConstraint(R.id.center_left).layout.guideBegin).isEqualTo(offsetFromEdge)
assertThat(getConstraint(R.id.center_right).layout.guideEnd).isEqualTo(offsetFromEdge)
assertThat(getConstraint(R.id.date).layout.endToStart).isEqualTo(R.id.center_left)
- assertThat(getConstraint(R.id.statusIcons).layout.startToEnd)
+ assertThat(getConstraint(R.id.shade_header_system_icons).layout.startToEnd)
.isEqualTo(R.id.center_right)
assertThat(getConstraint(R.id.privacy_container).layout.startToEnd)
.isEqualTo(R.id.center_right)
@@ -285,9 +280,9 @@
assertThat(getConstraint(R.id.date).layout.endToStart).isNotEqualTo(R.id.center_left)
assertThat(getConstraint(R.id.date).layout.endToStart).isNotEqualTo(R.id.center_right)
- assertThat(getConstraint(R.id.statusIcons).layout.startToEnd)
+ assertThat(getConstraint(R.id.shade_header_system_icons).layout.startToEnd)
.isNotEqualTo(R.id.center_left)
- assertThat(getConstraint(R.id.statusIcons).layout.startToEnd)
+ assertThat(getConstraint(R.id.shade_header_system_icons).layout.startToEnd)
.isNotEqualTo(R.id.center_right)
assertThat(getConstraint(R.id.privacy_container).layout.startToEnd)
@@ -311,7 +306,7 @@
assertThat(getConstraint(R.id.center_left).layout.guideEnd).isEqualTo(offsetFromEdge)
assertThat(getConstraint(R.id.center_right).layout.guideBegin).isEqualTo(offsetFromEdge)
assertThat(getConstraint(R.id.date).layout.endToStart).isEqualTo(R.id.center_right)
- assertThat(getConstraint(R.id.statusIcons).layout.startToEnd)
+ assertThat(getConstraint(R.id.shade_header_system_icons).layout.startToEnd)
.isEqualTo(R.id.center_left)
assertThat(getConstraint(R.id.privacy_container).layout.startToEnd)
.isEqualTo(R.id.center_left)
@@ -324,9 +319,9 @@
assertThat(getConstraint(R.id.date).layout.endToStart).isNotEqualTo(R.id.center_left)
assertThat(getConstraint(R.id.date).layout.endToStart).isNotEqualTo(R.id.center_right)
- assertThat(getConstraint(R.id.statusIcons).layout.startToEnd)
+ assertThat(getConstraint(R.id.shade_header_system_icons).layout.startToEnd)
.isNotEqualTo(R.id.center_left)
- assertThat(getConstraint(R.id.statusIcons).layout.startToEnd)
+ assertThat(getConstraint(R.id.shade_header_system_icons).layout.startToEnd)
.isNotEqualTo(R.id.center_right)
assertThat(getConstraint(R.id.privacy_container).layout.startToEnd)
@@ -382,7 +377,8 @@
CombinedShadeHeadersConstraintManagerImpl.emptyCutoutConstraints()()
assertThat(qqsConstraint.getConstraint(R.id.date).layout.constrainedWidth).isTrue()
- assertThat(qqsConstraint.getConstraint(R.id.statusIcons).layout.constrainedWidth).isTrue()
+ val shadeHeaderConstraint = qqsConstraint.getConstraint(R.id.shade_header_system_icons)
+ assertThat(shadeHeaderConstraint.layout.constrainedWidth).isTrue()
}
@Test
@@ -390,9 +386,13 @@
CombinedShadeHeadersConstraintManagerImpl.centerCutoutConstraints(false, 10)()
assertThat(qqsConstraint.getConstraint(R.id.date).layout.constrainedWidth).isTrue()
- assertThat(qqsConstraint.getConstraint(R.id.statusIcons).layout.constrainedWidth).isTrue()
+ val shadeHeaderConstraint = qqsConstraint.getConstraint(R.id.shade_header_system_icons)
+ assertThat(shadeHeaderConstraint.layout.constrainedWidth).isTrue()
}
+ private val ConstraintSet.systemIconsAlphaConstraint
+ get() = getConstraint(R.id.shade_header_system_icons).propertySet.alpha
+
private operator fun ConstraintsChanges.invoke() {
qqsConstraintsChanges?.invoke(qqsConstraint)
qsConstraintsChanges?.invoke(qsConstraint)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
index 46ced82..ef7c7bc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
@@ -117,6 +117,7 @@
import com.android.systemui.qs.QSFragment;
import com.android.systemui.screenrecord.RecordingController;
import com.android.systemui.shade.data.repository.ShadeRepository;
+import com.android.systemui.shade.domain.interactor.ShadeInteractor;
import com.android.systemui.shade.transition.ShadeTransitionController;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.KeyguardIndicationController;
@@ -168,6 +169,7 @@
import com.android.systemui.statusbar.policy.KeyguardUserSwitcherView;
import com.android.systemui.statusbar.window.StatusBarWindowStateController;
import com.android.systemui.unfold.SysUIUnfoldComponent;
+import com.android.systemui.util.kotlin.JavaAdapter;
import com.android.systemui.util.time.FakeSystemClock;
import com.android.systemui.util.time.SystemClock;
import com.android.wm.shell.animation.FlingAnimationUtils;
@@ -311,6 +313,8 @@
@Mock protected ActivityStarter mActivityStarter;
@Mock protected KeyguardFaceAuthInteractor mKeyguardFaceAuthInteractor;
@Mock protected ShadeRepository mShadeRepository;
+ @Mock private ShadeInteractor mShadeInteractor;
+ @Mock private JavaAdapter mJavaAdapter;
@Mock private CastController mCastController;
protected final int mMaxUdfpsBurnInOffsetY = 5;
@@ -599,7 +603,6 @@
mNotificationStackSizeCalculator,
mUnlockedScreenOffAnimationController,
mShadeTransitionController,
- mInteractionJankMonitor,
systemClock,
mKeyguardBottomAreaViewModel,
mKeyguardBottomAreaInteractor,
@@ -688,6 +691,8 @@
mDumpManager,
mKeyguardFaceAuthInteractor,
mShadeRepository,
+ mShadeInteractor,
+ mJavaAdapter,
mCastController
);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt
index c737a18..2a9b403 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt
@@ -49,6 +49,7 @@
import com.android.systemui.multishade.data.repository.MultiShadeRepository
import com.android.systemui.multishade.domain.interactor.MultiShadeInteractor
import com.android.systemui.multishade.domain.interactor.MultiShadeMotionEventInteractor
+import com.android.systemui.power.domain.interactor.PowerInteractor
import com.android.systemui.shade.NotificationShadeWindowView.InteractionEventHandler
import com.android.systemui.statusbar.LockscreenShadeTransitionController
import com.android.systemui.statusbar.NotificationInsetsController
@@ -93,6 +94,7 @@
@Mock private lateinit var sysuiStatusBarStateController: SysuiStatusBarStateController
@Mock private lateinit var centralSurfaces: CentralSurfaces
@Mock private lateinit var backActionInteractor: BackActionInteractor
+ @Mock private lateinit var powerInteractor: PowerInteractor
@Mock private lateinit var dockManager: DockManager
@Mock private lateinit var notificationPanelViewController: NotificationPanelViewController
@Mock private lateinit var notificationShadeDepthController: NotificationShadeDepthController
@@ -174,6 +176,7 @@
lockIconViewController,
centralSurfaces,
backActionInteractor,
+ powerInteractor,
notificationShadeWindowController,
unfoldTransitionProgressProvider,
keyguardUnlockAnimationController,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.kt
index 1740284..252a03b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.kt
@@ -48,6 +48,7 @@
import com.android.systemui.multishade.data.repository.MultiShadeRepository
import com.android.systemui.multishade.domain.interactor.MultiShadeInteractor
import com.android.systemui.multishade.domain.interactor.MultiShadeMotionEventInteractor
+import com.android.systemui.power.domain.interactor.PowerInteractor
import com.android.systemui.shade.NotificationShadeWindowView.InteractionEventHandler
import com.android.systemui.statusbar.DragDownHelper
import com.android.systemui.statusbar.LockscreenShadeTransitionController
@@ -95,6 +96,7 @@
@Mock private lateinit var shadeController: ShadeController
@Mock private lateinit var centralSurfaces: CentralSurfaces
@Mock private lateinit var backActionInteractor: BackActionInteractor
+ @Mock private lateinit var powerInteractor: PowerInteractor
@Mock private lateinit var dockManager: DockManager
@Mock private lateinit var notificationPanelViewController: NotificationPanelViewController
@Mock private lateinit var notificationStackScrollLayout: NotificationStackScrollLayout
@@ -187,6 +189,7 @@
lockIconViewController,
centralSurfaces,
backActionInteractor,
+ powerInteractor,
notificationShadeWindowController,
unfoldTransitionProgressProvider,
keyguardUnlockAnimationController,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerBaseTest.java
new file mode 100644
index 0000000..c72f4e7
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerBaseTest.java
@@ -0,0 +1,265 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.shade;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import android.content.res.Resources;
+import android.os.Handler;
+import android.os.Looper;
+import android.view.ViewGroup;
+import android.view.ViewParent;
+import android.view.accessibility.AccessibilityManager;
+
+import com.android.internal.jank.InteractionJankMonitor;
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.UiEventLogger;
+import com.android.keyguard.KeyguardStatusView;
+import com.android.keyguard.KeyguardUpdateMonitor;
+import com.android.keyguard.TestScopeProvider;
+import com.android.systemui.R;
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.classifier.FalsingCollector;
+import com.android.systemui.dump.DumpManager;
+import com.android.systemui.flags.FeatureFlags;
+import com.android.systemui.fragments.FragmentHostManager;
+import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository;
+import com.android.systemui.keyguard.domain.interactor.KeyguardFaceAuthInteractor;
+import com.android.systemui.media.controls.pipeline.MediaDataManager;
+import com.android.systemui.media.controls.ui.MediaHierarchyManager;
+import com.android.systemui.plugins.FalsingManager;
+import com.android.systemui.plugins.qs.QS;
+import com.android.systemui.qs.QSFragment;
+import com.android.systemui.screenrecord.RecordingController;
+import com.android.systemui.shade.data.repository.ShadeRepository;
+import com.android.systemui.shade.domain.interactor.ShadeInteractor;
+import com.android.systemui.shade.transition.ShadeTransitionController;
+import com.android.systemui.statusbar.LockscreenShadeTransitionController;
+import com.android.systemui.statusbar.NotificationRemoteInputManager;
+import com.android.systemui.statusbar.NotificationShadeDepthController;
+import com.android.systemui.statusbar.PulseExpansionHandler;
+import com.android.systemui.statusbar.QsFrameTranslateController;
+import com.android.systemui.statusbar.StatusBarStateControllerImpl;
+import com.android.systemui.statusbar.SysuiStatusBarStateController;
+import com.android.systemui.statusbar.disableflags.data.repository.FakeDisableFlagsRepository;
+import com.android.systemui.statusbar.notification.stack.AmbientState;
+import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
+import com.android.systemui.statusbar.phone.KeyguardBottomAreaView;
+import com.android.systemui.statusbar.phone.KeyguardBypassController;
+import com.android.systemui.statusbar.phone.KeyguardStatusBarView;
+import com.android.systemui.statusbar.phone.LightBarController;
+import com.android.systemui.statusbar.phone.LockscreenGestureLogger;
+import com.android.systemui.statusbar.phone.ScrimController;
+import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
+import com.android.systemui.statusbar.phone.StatusBarTouchableRegionManager;
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeUserSetupRepository;
+import com.android.systemui.statusbar.policy.CastController;
+import com.android.systemui.statusbar.policy.DeviceProvisionedController;
+import com.android.systemui.statusbar.policy.KeyguardStateController;
+import com.android.systemui.user.domain.interactor.UserInteractor;
+import com.android.systemui.util.kotlin.JavaAdapter;
+
+import dagger.Lazy;
+
+import org.junit.After;
+import org.junit.Before;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import kotlinx.coroutines.test.TestScope;
+
+public class QuickSettingsControllerBaseTest extends SysuiTestCase {
+ protected static final float QS_FRAME_START_X = 0f;
+ protected static final int QS_FRAME_WIDTH = 1000;
+ protected static final int QS_FRAME_TOP = 0;
+ protected static final int QS_FRAME_BOTTOM = 1000;
+ protected static final int DEFAULT_HEIGHT = 1000;
+ // In split shade min = max
+ protected static final int DEFAULT_MIN_HEIGHT_SPLIT_SHADE = DEFAULT_HEIGHT;
+ protected static final int DEFAULT_MIN_HEIGHT = 300;
+
+ protected QuickSettingsController mQsController;
+
+ protected TestScope mTestScope = TestScopeProvider.getTestScope();
+
+ @Mock
+ protected Resources mResources;
+ @Mock protected KeyguardBottomAreaView mQsFrame;
+ @Mock protected KeyguardStatusBarView mKeyguardStatusBar;
+ @Mock protected QS mQs;
+ @Mock protected QSFragment mQSFragment;
+ @Mock protected Lazy<NotificationPanelViewController> mPanelViewControllerLazy;
+ @Mock protected NotificationPanelViewController mNotificationPanelViewController;
+ @Mock protected NotificationPanelView mPanelView;
+ @Mock protected ViewGroup mQsHeader;
+ @Mock protected ViewParent mPanelViewParent;
+ @Mock protected QsFrameTranslateController mQsFrameTranslateController;
+ @Mock protected ShadeTransitionController mShadeTransitionController;
+ @Mock protected PulseExpansionHandler mPulseExpansionHandler;
+ @Mock protected NotificationRemoteInputManager mNotificationRemoteInputManager;
+ @Mock protected StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
+ @Mock protected LightBarController mLightBarController;
+ @Mock protected NotificationStackScrollLayoutController
+ mNotificationStackScrollLayoutController;
+ @Mock protected LockscreenShadeTransitionController mLockscreenShadeTransitionController;
+ @Mock protected NotificationShadeDepthController mNotificationShadeDepthController;
+ @Mock protected ShadeHeaderController mShadeHeaderController;
+ @Mock protected StatusBarTouchableRegionManager mStatusBarTouchableRegionManager;
+ @Mock protected KeyguardStateController mKeyguardStateController;
+ @Mock protected KeyguardBypassController mKeyguardBypassController;
+ @Mock protected KeyguardUpdateMonitor mKeyguardUpdateMonitor;
+ @Mock protected ScrimController mScrimController;
+ @Mock protected MediaDataManager mMediaDataManager;
+ @Mock protected MediaHierarchyManager mMediaHierarchyManager;
+ @Mock protected AmbientState mAmbientState;
+ @Mock protected RecordingController mRecordingController;
+ @Mock protected FalsingManager mFalsingManager;
+ @Mock protected FalsingCollector mFalsingCollector;
+ @Mock protected AccessibilityManager mAccessibilityManager;
+ @Mock protected LockscreenGestureLogger mLockscreenGestureLogger;
+ @Mock protected MetricsLogger mMetricsLogger;
+ @Mock protected FeatureFlags mFeatureFlags;
+ @Mock protected InteractionJankMonitor mInteractionJankMonitor;
+ @Mock protected ShadeLogger mShadeLogger;
+ @Mock protected DumpManager mDumpManager;
+ @Mock protected UiEventLogger mUiEventLogger;
+ @Mock protected CastController mCastController;
+ @Mock protected DeviceProvisionedController mDeviceProvisionedController;
+ @Mock protected UserInteractor mUserInteractor;
+ protected FakeDisableFlagsRepository mDisableFlagsRepository =
+ new FakeDisableFlagsRepository();
+ protected FakeKeyguardRepository mKeyguardRepository = new FakeKeyguardRepository();
+
+ protected SysuiStatusBarStateController mStatusBarStateController;
+ protected ShadeInteractor mShadeInteractor;
+
+ protected Handler mMainHandler;
+ protected LockscreenShadeTransitionController.Callback mLockscreenShadeTransitionCallback;
+
+ protected final ShadeExpansionStateManager mShadeExpansionStateManager =
+ new ShadeExpansionStateManager();
+
+ protected FragmentHostManager.FragmentListener mFragmentListener;
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ when(mPanelViewControllerLazy.get()).thenReturn(mNotificationPanelViewController);
+ mStatusBarStateController = new StatusBarStateControllerImpl(mUiEventLogger, mDumpManager,
+ mInteractionJankMonitor, mShadeExpansionStateManager);
+
+ when(mDeviceProvisionedController.isDeviceProvisioned()).thenReturn(true);
+ mShadeInteractor =
+ new ShadeInteractor(
+ mDisableFlagsRepository,
+ mKeyguardRepository,
+ new FakeUserSetupRepository(),
+ mDeviceProvisionedController,
+ mUserInteractor
+ );
+
+ KeyguardStatusView keyguardStatusView = new KeyguardStatusView(mContext);
+ keyguardStatusView.setId(R.id.keyguard_status_view);
+
+ when(mResources.getDimensionPixelSize(
+ R.dimen.lockscreen_shade_qs_transition_distance)).thenReturn(DEFAULT_HEIGHT);
+ when(mPanelView.getResources()).thenReturn(mResources);
+ when(mPanelView.getContext()).thenReturn(getContext());
+ when(mPanelView.findViewById(R.id.keyguard_header)).thenReturn(mKeyguardStatusBar);
+ when(mNotificationStackScrollLayoutController.getHeight()).thenReturn(1000);
+ when(mPanelView.findViewById(R.id.qs_frame)).thenReturn(mQsFrame);
+ when(mQsFrame.getX()).thenReturn(QS_FRAME_START_X);
+ when(mQsFrame.getWidth()).thenReturn(QS_FRAME_WIDTH);
+ when(mQsHeader.getTop()).thenReturn(QS_FRAME_TOP);
+ when(mQsHeader.getBottom()).thenReturn(QS_FRAME_BOTTOM);
+ when(mPanelView.getY()).thenReturn((float) QS_FRAME_TOP);
+ when(mPanelView.getHeight()).thenReturn(QS_FRAME_BOTTOM);
+ when(mPanelView.findViewById(R.id.keyguard_status_view))
+ .thenReturn(mock(KeyguardStatusView.class));
+ when(mQs.getView()).thenReturn(mPanelView);
+ when(mQSFragment.getView()).thenReturn(mPanelView);
+
+ when(mNotificationRemoteInputManager.isRemoteInputActive())
+ .thenReturn(false);
+ when(mInteractionJankMonitor.begin(any(), anyInt()))
+ .thenReturn(true);
+ when(mInteractionJankMonitor.end(anyInt()))
+ .thenReturn(true);
+
+ when(mPanelView.getParent()).thenReturn(mPanelViewParent);
+ when(mQs.getHeader()).thenReturn(mQsHeader);
+
+ doAnswer(invocation -> {
+ mLockscreenShadeTransitionCallback = invocation.getArgument(0);
+ return null;
+ }).when(mLockscreenShadeTransitionController).addCallback(any());
+
+
+ mMainHandler = new Handler(Looper.getMainLooper());
+
+ mQsController = new QuickSettingsController(
+ mPanelViewControllerLazy,
+ mPanelView,
+ mQsFrameTranslateController,
+ mShadeTransitionController,
+ mPulseExpansionHandler,
+ mNotificationRemoteInputManager,
+ mShadeExpansionStateManager,
+ mStatusBarKeyguardViewManager,
+ mLightBarController,
+ mNotificationStackScrollLayoutController,
+ mLockscreenShadeTransitionController,
+ mNotificationShadeDepthController,
+ mShadeHeaderController,
+ mStatusBarTouchableRegionManager,
+ mKeyguardStateController,
+ mKeyguardBypassController,
+ mKeyguardUpdateMonitor,
+ mScrimController,
+ mMediaDataManager,
+ mMediaHierarchyManager,
+ mAmbientState,
+ mRecordingController,
+ mFalsingManager,
+ mFalsingCollector,
+ mAccessibilityManager,
+ mLockscreenGestureLogger,
+ mMetricsLogger,
+ mFeatureFlags,
+ mInteractionJankMonitor,
+ mShadeLogger,
+ mDumpManager,
+ mock(KeyguardFaceAuthInteractor.class),
+ mock(ShadeRepository.class),
+ mShadeInteractor,
+ new JavaAdapter(mTestScope.getBackgroundScope()),
+ mCastController
+ );
+ mQsController.init();
+
+ mFragmentListener = mQsController.getQsFragmentListener();
+ }
+
+ @After
+ public void tearDown() {
+ mMainHandler.removeCallbacksAndMessages(null);
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerTest.java
index ff047aa..6d288e1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerTest.java
@@ -28,238 +28,32 @@
import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyFloat;
-import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.atLeastOnce;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-import android.content.res.Resources;
-import android.os.Handler;
-import android.os.Looper;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.view.MotionEvent;
-import android.view.ViewGroup;
-import android.view.ViewParent;
-import android.view.accessibility.AccessibilityManager;
import androidx.test.filters.SmallTest;
-import com.android.internal.jank.InteractionJankMonitor;
-import com.android.internal.logging.MetricsLogger;
-import com.android.internal.logging.UiEventLogger;
-import com.android.keyguard.KeyguardStatusView;
-import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.R;
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.classifier.FalsingCollector;
-import com.android.systemui.dump.DumpManager;
-import com.android.systemui.flags.FeatureFlags;
-import com.android.systemui.fragments.FragmentHostManager;
-import com.android.systemui.keyguard.domain.interactor.KeyguardFaceAuthInteractor;
-import com.android.systemui.media.controls.pipeline.MediaDataManager;
-import com.android.systemui.media.controls.ui.MediaHierarchyManager;
-import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.qs.QS;
-import com.android.systemui.qs.QSFragment;
-import com.android.systemui.screenrecord.RecordingController;
-import com.android.systemui.shade.data.repository.ShadeRepository;
-import com.android.systemui.shade.transition.ShadeTransitionController;
-import com.android.systemui.statusbar.LockscreenShadeTransitionController;
-import com.android.systemui.statusbar.NotificationRemoteInputManager;
-import com.android.systemui.statusbar.NotificationShadeDepthController;
-import com.android.systemui.statusbar.PulseExpansionHandler;
-import com.android.systemui.statusbar.QsFrameTranslateController;
-import com.android.systemui.statusbar.StatusBarStateControllerImpl;
-import com.android.systemui.statusbar.SysuiStatusBarStateController;
-import com.android.systemui.statusbar.notification.stack.AmbientState;
-import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
-import com.android.systemui.statusbar.phone.KeyguardBottomAreaView;
-import com.android.systemui.statusbar.phone.KeyguardBypassController;
-import com.android.systemui.statusbar.phone.KeyguardStatusBarView;
-import com.android.systemui.statusbar.phone.LightBarController;
-import com.android.systemui.statusbar.phone.LockscreenGestureLogger;
-import com.android.systemui.statusbar.phone.ScrimController;
-import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
-import com.android.systemui.statusbar.phone.StatusBarTouchableRegionManager;
-import com.android.systemui.statusbar.policy.CastController;
-import com.android.systemui.statusbar.policy.KeyguardStateController;
-import dagger.Lazy;
-
-import org.junit.After;
-import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
import java.util.List;
@SmallTest
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
-public class QuickSettingsControllerTest extends SysuiTestCase {
-
- private static final float QS_FRAME_START_X = 0f;
- private static final int QS_FRAME_WIDTH = 1000;
- private static final int QS_FRAME_TOP = 0;
- private static final int QS_FRAME_BOTTOM = 1000;
- private static final int DEFAULT_HEIGHT = 1000;
- // In split shade min = max
- private static final int DEFAULT_MIN_HEIGHT_SPLIT_SHADE = DEFAULT_HEIGHT;
- private static final int DEFAULT_MIN_HEIGHT = 300;
-
- private QuickSettingsController mQsController;
-
- @Mock private Resources mResources;
- @Mock private KeyguardBottomAreaView mQsFrame;
- @Mock private KeyguardStatusBarView mKeyguardStatusBar;
- @Mock private QS mQs;
- @Mock private QSFragment mQSFragment;
- @Mock private Lazy<NotificationPanelViewController> mPanelViewControllerLazy;
- @Mock private NotificationPanelViewController mNotificationPanelViewController;
- @Mock private NotificationPanelView mPanelView;
- @Mock private ViewGroup mQsHeader;
- @Mock private ViewParent mPanelViewParent;
- @Mock private QsFrameTranslateController mQsFrameTranslateController;
- @Mock private ShadeTransitionController mShadeTransitionController;
- @Mock private PulseExpansionHandler mPulseExpansionHandler;
- @Mock private NotificationRemoteInputManager mNotificationRemoteInputManager;
- @Mock private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
- @Mock private LightBarController mLightBarController;
- @Mock private NotificationStackScrollLayoutController mNotificationStackScrollLayoutController;
- @Mock private LockscreenShadeTransitionController mLockscreenShadeTransitionController;
- @Mock private NotificationShadeDepthController mNotificationShadeDepthController;
- @Mock private ShadeHeaderController mShadeHeaderController;
- @Mock private StatusBarTouchableRegionManager mStatusBarTouchableRegionManager;
- @Mock private KeyguardStateController mKeyguardStateController;
- @Mock private KeyguardBypassController mKeyguardBypassController;
- @Mock private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
- @Mock private ScrimController mScrimController;
- @Mock private MediaDataManager mMediaDataManager;
- @Mock private MediaHierarchyManager mMediaHierarchyManager;
- @Mock private AmbientState mAmbientState;
- @Mock private RecordingController mRecordingController;
- @Mock private FalsingManager mFalsingManager;
- @Mock private FalsingCollector mFalsingCollector;
- @Mock private AccessibilityManager mAccessibilityManager;
- @Mock private LockscreenGestureLogger mLockscreenGestureLogger;
- @Mock private MetricsLogger mMetricsLogger;
- @Mock private FeatureFlags mFeatureFlags;
- @Mock private InteractionJankMonitor mInteractionJankMonitor;
- @Mock private ShadeLogger mShadeLogger;
- @Mock private DumpManager mDumpManager;
- @Mock private UiEventLogger mUiEventLogger;
- @Mock private CastController mCastController;
-
- private SysuiStatusBarStateController mStatusBarStateController;
-
- private Handler mMainHandler;
- private LockscreenShadeTransitionController.Callback mLockscreenShadeTransitionCallback;
-
- private final ShadeExpansionStateManager mShadeExpansionStateManager =
- new ShadeExpansionStateManager();
-
- private FragmentHostManager.FragmentListener mFragmentListener;
-
- @Before
- public void setup() {
- MockitoAnnotations.initMocks(this);
- when(mPanelViewControllerLazy.get()).thenReturn(mNotificationPanelViewController);
- mStatusBarStateController = new StatusBarStateControllerImpl(mUiEventLogger, mDumpManager,
- mInteractionJankMonitor, mShadeExpansionStateManager);
-
- KeyguardStatusView keyguardStatusView = new KeyguardStatusView(mContext);
- keyguardStatusView.setId(R.id.keyguard_status_view);
-
- when(mResources.getDimensionPixelSize(
- R.dimen.lockscreen_shade_qs_transition_distance)).thenReturn(DEFAULT_HEIGHT);
- when(mPanelView.getResources()).thenReturn(mResources);
- when(mPanelView.getContext()).thenReturn(getContext());
- when(mPanelView.findViewById(R.id.keyguard_header)).thenReturn(mKeyguardStatusBar);
- when(mNotificationStackScrollLayoutController.getHeight()).thenReturn(1000);
- when(mPanelView.findViewById(R.id.qs_frame)).thenReturn(mQsFrame);
- when(mQsFrame.getX()).thenReturn(QS_FRAME_START_X);
- when(mQsFrame.getWidth()).thenReturn(QS_FRAME_WIDTH);
- when(mQsHeader.getTop()).thenReturn(QS_FRAME_TOP);
- when(mQsHeader.getBottom()).thenReturn(QS_FRAME_BOTTOM);
- when(mPanelView.getY()).thenReturn((float) QS_FRAME_TOP);
- when(mPanelView.getHeight()).thenReturn(QS_FRAME_BOTTOM);
- when(mPanelView.findViewById(R.id.keyguard_status_view))
- .thenReturn(mock(KeyguardStatusView.class));
- when(mQs.getView()).thenReturn(mPanelView);
- when(mQSFragment.getView()).thenReturn(mPanelView);
-
- when(mNotificationRemoteInputManager.isRemoteInputActive())
- .thenReturn(false);
- when(mInteractionJankMonitor.begin(any(), anyInt()))
- .thenReturn(true);
- when(mInteractionJankMonitor.end(anyInt()))
- .thenReturn(true);
-
- when(mPanelView.getParent()).thenReturn(mPanelViewParent);
- when(mQs.getHeader()).thenReturn(mQsHeader);
-
- doAnswer(invocation -> {
- mLockscreenShadeTransitionCallback = invocation.getArgument(0);
- return null;
- }).when(mLockscreenShadeTransitionController).addCallback(any());
-
-
- mMainHandler = new Handler(Looper.getMainLooper());
-
- mQsController = new QuickSettingsController(
- mPanelViewControllerLazy,
- mPanelView,
- mQsFrameTranslateController,
- mShadeTransitionController,
- mPulseExpansionHandler,
- mNotificationRemoteInputManager,
- mShadeExpansionStateManager,
- mStatusBarKeyguardViewManager,
- mLightBarController,
- mNotificationStackScrollLayoutController,
- mLockscreenShadeTransitionController,
- mNotificationShadeDepthController,
- mShadeHeaderController,
- mStatusBarTouchableRegionManager,
- mKeyguardStateController,
- mKeyguardBypassController,
- mKeyguardUpdateMonitor,
- mScrimController,
- mMediaDataManager,
- mMediaHierarchyManager,
- mAmbientState,
- mRecordingController,
- mFalsingManager,
- mFalsingCollector,
- mAccessibilityManager,
- mLockscreenGestureLogger,
- mMetricsLogger,
- mFeatureFlags,
- mInteractionJankMonitor,
- mShadeLogger,
- mDumpManager,
- mock(KeyguardFaceAuthInteractor.class),
- mock(ShadeRepository.class),
- mCastController
- );
-
- mFragmentListener = mQsController.getQsFragmentListener();
- }
-
- @After
- public void tearDown() {
- mMainHandler.removeCallbacksAndMessages(null);
- }
+public class QuickSettingsControllerTest extends QuickSettingsControllerBaseTest {
@Test
public void testCloseQsSideEffects() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerWithCoroutinesTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerWithCoroutinesTest.kt
new file mode 100644
index 0000000..cc4a063
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerWithCoroutinesTest.kt
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.shade
+
+import android.app.StatusBarManager
+import androidx.test.filters.SmallTest
+import com.android.systemui.statusbar.disableflags.data.model.DisableFlagsModel
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Test
+
+@SmallTest
+@OptIn(ExperimentalCoroutinesApi::class)
+class QuickSettingsControllerWithCoroutinesTest : QuickSettingsControllerBaseTest() {
+
+ @Test
+ fun isExpansionEnabled_dozing_false() =
+ mTestScope.runTest {
+ mKeyguardRepository.setIsDozing(true)
+ runCurrent()
+
+ assertThat(mQsController.isExpansionEnabled).isFalse()
+ }
+
+ @Test
+ fun isExpansionEnabled_notDozing_true() =
+ mTestScope.runTest {
+ mKeyguardRepository.setIsDozing(false)
+ runCurrent()
+
+ assertThat(mQsController.isExpansionEnabled).isTrue()
+ }
+
+ @Test
+ fun isExpansionEnabled_qsDisabled_false() =
+ mTestScope.runTest {
+ mDisableFlagsRepository.disableFlags.value =
+ DisableFlagsModel(
+ StatusBarManager.DISABLE_NONE,
+ StatusBarManager.DISABLE2_QUICK_SETTINGS
+ )
+ runCurrent()
+
+ assertThat(mQsController.isExpansionEnabled).isFalse()
+ }
+
+ @Test
+ fun isExpansionEnabled_shadeDisabled_false() =
+ mTestScope.runTest {
+ mDisableFlagsRepository.disableFlags.value =
+ DisableFlagsModel(
+ StatusBarManager.DISABLE_NONE,
+ StatusBarManager.DISABLE2_NOTIFICATION_SHADE
+ )
+ runCurrent()
+
+ assertThat(mQsController.isExpansionEnabled).isFalse()
+ }
+
+ @Test
+ fun isExpansionEnabled_qsAndShadeEnabled_true() =
+ mTestScope.runTest {
+ mDisableFlagsRepository.disableFlags.value =
+ DisableFlagsModel(StatusBarManager.DISABLE_NONE, StatusBarManager.DISABLE2_NONE)
+ runCurrent()
+
+ assertThat(mQsController.isExpansionEnabled).isTrue()
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/data/repository/ShadeInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/data/repository/ShadeInteractorTest.kt
new file mode 100644
index 0000000..7392a94
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/data/repository/ShadeInteractorTest.kt
@@ -0,0 +1,321 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.shade.data.repository
+
+import android.app.ActivityManager
+import android.app.StatusBarManager.DISABLE2_NONE
+import android.app.StatusBarManager.DISABLE2_NOTIFICATION_SHADE
+import android.app.StatusBarManager.DISABLE2_QUICK_SETTINGS
+import android.os.UserManager
+import androidx.test.filters.SmallTest
+import com.android.internal.logging.UiEventLogger
+import com.android.keyguard.KeyguardUpdateMonitor
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.flags.FakeFeatureFlags
+import com.android.systemui.flags.Flags
+import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
+import com.android.systemui.keyguard.domain.interactor.KeyguardInteractorFactory
+import com.android.systemui.plugins.ActivityStarter
+import com.android.systemui.shade.domain.interactor.ShadeInteractor
+import com.android.systemui.statusbar.disableflags.data.model.DisableFlagsModel
+import com.android.systemui.statusbar.disableflags.data.repository.FakeDisableFlagsRepository
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeUserSetupRepository
+import com.android.systemui.statusbar.policy.DeviceProvisionedController
+import com.android.systemui.telephony.data.repository.FakeTelephonyRepository
+import com.android.systemui.telephony.domain.interactor.TelephonyInteractor
+import com.android.systemui.user.data.model.UserSwitcherSettingsModel
+import com.android.systemui.user.data.repository.FakeUserRepository
+import com.android.systemui.user.domain.interactor.GuestUserInteractor
+import com.android.systemui.user.domain.interactor.HeadlessSystemUserMode
+import com.android.systemui.user.domain.interactor.RefreshUsersScheduler
+import com.android.systemui.user.domain.interactor.UserInteractor
+import com.android.systemui.util.mockito.whenever
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.StandardTestDispatcher
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.mockito.Mock
+import org.mockito.MockitoAnnotations
+
+@SmallTest
+@OptIn(ExperimentalCoroutinesApi::class)
+class ShadeInteractorTest : SysuiTestCase() {
+ private lateinit var underTest: ShadeInteractor
+
+ private val testDispatcher = StandardTestDispatcher()
+ private val testScope = TestScope(testDispatcher)
+ private val featureFlags = FakeFeatureFlags()
+ private val userSetupRepository = FakeUserSetupRepository()
+ private val userRepository = FakeUserRepository()
+ private val disableFlagsRepository = FakeDisableFlagsRepository()
+ private val keyguardRepository = FakeKeyguardRepository()
+
+ @Mock private lateinit var manager: UserManager
+ @Mock private lateinit var headlessSystemUserMode: HeadlessSystemUserMode
+ @Mock private lateinit var deviceProvisionedController: DeviceProvisionedController
+ @Mock private lateinit var activityStarter: ActivityStarter
+ @Mock private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor
+ @Mock private lateinit var activityManager: ActivityManager
+ @Mock private lateinit var uiEventLogger: UiEventLogger
+ @Mock private lateinit var guestInteractor: GuestUserInteractor
+
+ private lateinit var userInteractor: UserInteractor
+
+ @Before
+ fun setUp() {
+ MockitoAnnotations.initMocks(this)
+
+ featureFlags.set(Flags.FACE_AUTH_REFACTOR, false)
+
+ val refreshUsersScheduler =
+ RefreshUsersScheduler(
+ applicationScope = testScope.backgroundScope,
+ mainDispatcher = testDispatcher,
+ repository = userRepository,
+ )
+ userInteractor =
+ UserInteractor(
+ applicationContext = context,
+ repository = userRepository,
+ activityStarter = activityStarter,
+ keyguardInteractor =
+ KeyguardInteractorFactory.create(featureFlags = featureFlags)
+ .keyguardInteractor,
+ featureFlags = featureFlags,
+ manager = manager,
+ headlessSystemUserMode = headlessSystemUserMode,
+ applicationScope = testScope.backgroundScope,
+ telephonyInteractor =
+ TelephonyInteractor(
+ repository = FakeTelephonyRepository(),
+ ),
+ broadcastDispatcher = fakeBroadcastDispatcher,
+ keyguardUpdateMonitor = keyguardUpdateMonitor,
+ backgroundDispatcher = testDispatcher,
+ activityManager = activityManager,
+ refreshUsersScheduler = refreshUsersScheduler,
+ guestUserInteractor = guestInteractor,
+ uiEventLogger = uiEventLogger,
+ )
+ underTest =
+ ShadeInteractor(
+ disableFlagsRepository,
+ keyguardRepository,
+ userSetupRepository,
+ deviceProvisionedController,
+ userInteractor,
+ )
+ }
+
+ @Test
+ fun isExpandToQsEnabled_deviceNotProvisioned_false() =
+ testScope.runTest {
+ whenever(deviceProvisionedController.isDeviceProvisioned).thenReturn(false)
+
+ val actual by collectLastValue(underTest.isExpandToQsEnabled)
+
+ assertThat(actual).isFalse()
+ }
+
+ @Test
+ fun isExpandToQsEnabled_userNotSetupAndSimpleUserSwitcher_false() =
+ testScope.runTest {
+ whenever(deviceProvisionedController.isDeviceProvisioned).thenReturn(true)
+
+ userSetupRepository.setUserSetup(false)
+ userRepository.setSettings(UserSwitcherSettingsModel(isSimpleUserSwitcher = true))
+
+ val actual by collectLastValue(underTest.isExpandToQsEnabled)
+
+ assertThat(actual).isFalse()
+ }
+
+ @Test
+ fun isExpandToQsEnabled_shadeNotEnabled_false() =
+ testScope.runTest {
+ whenever(deviceProvisionedController.isDeviceProvisioned).thenReturn(true)
+ userSetupRepository.setUserSetup(true)
+
+ disableFlagsRepository.disableFlags.value =
+ DisableFlagsModel(
+ disable2 = DISABLE2_NOTIFICATION_SHADE,
+ )
+
+ val actual by collectLastValue(underTest.isExpandToQsEnabled)
+
+ assertThat(actual).isFalse()
+ }
+
+ @Test
+ fun isExpandToQsEnabled_quickSettingsNotEnabled_false() =
+ testScope.runTest {
+ whenever(deviceProvisionedController.isDeviceProvisioned).thenReturn(true)
+ userSetupRepository.setUserSetup(true)
+
+ disableFlagsRepository.disableFlags.value =
+ DisableFlagsModel(
+ disable2 = DISABLE2_QUICK_SETTINGS,
+ )
+ val actual by collectLastValue(underTest.isExpandToQsEnabled)
+
+ assertThat(actual).isFalse()
+ }
+
+ @Test
+ fun isExpandToQsEnabled_dozing_false() =
+ testScope.runTest {
+ whenever(deviceProvisionedController.isDeviceProvisioned).thenReturn(true)
+ userSetupRepository.setUserSetup(true)
+ disableFlagsRepository.disableFlags.value =
+ DisableFlagsModel(
+ disable2 = DISABLE2_NONE,
+ )
+
+ keyguardRepository.setIsDozing(true)
+
+ val actual by collectLastValue(underTest.isExpandToQsEnabled)
+
+ assertThat(actual).isFalse()
+ }
+
+ @Test
+ fun isExpandToQsEnabled_userSetup_true() =
+ testScope.runTest {
+ whenever(deviceProvisionedController.isDeviceProvisioned).thenReturn(true)
+ keyguardRepository.setIsDozing(false)
+ disableFlagsRepository.disableFlags.value =
+ DisableFlagsModel(
+ disable2 = DISABLE2_NONE,
+ )
+
+ userSetupRepository.setUserSetup(true)
+
+ val actual by collectLastValue(underTest.isExpandToQsEnabled)
+
+ assertThat(actual).isTrue()
+ }
+
+ @Test
+ fun isExpandToQsEnabled_notSimpleUserSwitcher_true() =
+ testScope.runTest {
+ whenever(deviceProvisionedController.isDeviceProvisioned).thenReturn(true)
+ keyguardRepository.setIsDozing(false)
+ disableFlagsRepository.disableFlags.value =
+ DisableFlagsModel(
+ disable2 = DISABLE2_NONE,
+ )
+
+ userRepository.setSettings(UserSwitcherSettingsModel(isSimpleUserSwitcher = false))
+
+ val actual by collectLastValue(underTest.isExpandToQsEnabled)
+
+ assertThat(actual).isTrue()
+ }
+
+ @Test
+ fun isExpandToQsEnabled_respondsToDozingUpdates() =
+ testScope.runTest {
+ whenever(deviceProvisionedController.isDeviceProvisioned).thenReturn(true)
+ keyguardRepository.setIsDozing(false)
+ disableFlagsRepository.disableFlags.value =
+ DisableFlagsModel(
+ disable2 = DISABLE2_NONE,
+ )
+ userSetupRepository.setUserSetup(true)
+
+ val actual by collectLastValue(underTest.isExpandToQsEnabled)
+
+ assertThat(actual).isTrue()
+
+ // WHEN dozing starts
+ keyguardRepository.setIsDozing(true)
+
+ // THEN expand is disabled
+ assertThat(actual).isFalse()
+
+ // WHEN dozing stops
+ keyguardRepository.setIsDozing(false)
+
+ // THEN expand is enabled
+ assertThat(actual).isTrue()
+ }
+
+ @Test
+ fun isExpandToQsEnabled_respondsToDisableUpdates() =
+ testScope.runTest {
+ whenever(deviceProvisionedController.isDeviceProvisioned).thenReturn(true)
+ keyguardRepository.setIsDozing(false)
+ disableFlagsRepository.disableFlags.value =
+ DisableFlagsModel(
+ disable2 = DISABLE2_NONE,
+ )
+ userSetupRepository.setUserSetup(true)
+
+ val actual by collectLastValue(underTest.isExpandToQsEnabled)
+
+ assertThat(actual).isTrue()
+
+ // WHEN QS is disabled
+ disableFlagsRepository.disableFlags.value =
+ DisableFlagsModel(
+ disable2 = DISABLE2_QUICK_SETTINGS,
+ )
+ // THEN expand is disabled
+ assertThat(actual).isFalse()
+
+ // WHEN QS is enabled
+ disableFlagsRepository.disableFlags.value =
+ DisableFlagsModel(
+ disable2 = DISABLE2_NONE,
+ )
+ // THEN expand is enabled
+ assertThat(actual).isTrue()
+ }
+
+ @Test
+ fun isExpandToQsEnabled_respondsToUserUpdates() =
+ testScope.runTest {
+ whenever(deviceProvisionedController.isDeviceProvisioned).thenReturn(true)
+ keyguardRepository.setIsDozing(false)
+ disableFlagsRepository.disableFlags.value =
+ DisableFlagsModel(
+ disable2 = DISABLE2_NONE,
+ )
+ userSetupRepository.setUserSetup(true)
+
+ val actual by collectLastValue(underTest.isExpandToQsEnabled)
+
+ assertThat(actual).isTrue()
+
+ // WHEN the user is no longer setup
+ userSetupRepository.setUserSetup(false)
+ userRepository.setSettings(UserSwitcherSettingsModel(isSimpleUserSwitcher = true))
+
+ // THEN expand is disabled
+ assertThat(actual).isFalse()
+
+ // WHEN the user is setup again
+ userSetupRepository.setUserSetup(true)
+
+ // THEN expand is enabled
+ assertThat(actual).isTrue()
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/ClockRegistryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/ClockRegistryTest.kt
index 04c93cb..9495fdd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/ClockRegistryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/ClockRegistryTest.kt
@@ -21,6 +21,8 @@
import android.testing.AndroidTestingRunner
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
+import com.android.systemui.flags.FakeFeatureFlags
+import com.android.systemui.flags.Flags.TRANSIT_CLOCK
import com.android.systemui.plugins.ClockController
import com.android.systemui.plugins.ClockId
import com.android.systemui.plugins.ClockMetadata
@@ -68,6 +70,7 @@
private lateinit var fakeDefaultProvider: FakeClockPlugin
private lateinit var pluginListener: PluginListener<ClockProviderPlugin>
private lateinit var registry: ClockRegistry
+ private val featureFlags = FakeFeatureFlags()
companion object {
private fun failFactory(clockId: ClockId): ClockController {
@@ -448,4 +451,44 @@
val actual = ClockSettings.serialize(ClockSettings("ID", null))
assertEquals(expected, actual)
}
+
+ @Test
+ fun testTransitClockEnabled_hasTransitClock() {
+ testTransitClockFlag(true)
+ }
+
+ @Test
+ fun testTransitClockDisabled_noTransitClock() {
+ testTransitClockFlag(false)
+ }
+
+ private fun testTransitClockFlag(flag: Boolean) {
+ featureFlags.set(TRANSIT_CLOCK, flag)
+ registry.isTransitClockEnabled = featureFlags.isEnabled(TRANSIT_CLOCK)
+ val mockPluginLifecycle = mock<PluginLifecycleManager<ClockProviderPlugin>>()
+ val plugin = FakeClockPlugin()
+ .addClock("clock_1", "clock 1")
+ .addClock("DIGITAL_CLOCK_METRO", "metro clock")
+ pluginListener.onPluginLoaded(plugin, mockContext, mockPluginLifecycle)
+
+ val list = registry.getClocks()
+ if (flag) {
+ assertEquals(
+ setOf(
+ ClockMetadata(DEFAULT_CLOCK_ID, DEFAULT_CLOCK_NAME),
+ ClockMetadata("clock_1", "clock 1"),
+ ClockMetadata("DIGITAL_CLOCK_METRO", "metro clock")
+ ),
+ list.toSet()
+ )
+ } else {
+ assertEquals(
+ setOf(
+ ClockMetadata(DEFAULT_CLOCK_ID, DEFAULT_CLOCK_NAME),
+ ClockMetadata("clock_1", "clock 1")
+ ),
+ list.toSet()
+ )
+ }
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
index 25efea1..66f8b80 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
@@ -72,6 +72,7 @@
import android.content.pm.UserInfo;
import android.graphics.Color;
import android.hardware.biometrics.BiometricFaceConstants;
+import android.hardware.biometrics.BiometricFingerprintConstants;
import android.hardware.biometrics.BiometricSourceType;
import android.hardware.fingerprint.FingerprintManager;
import android.os.BatteryManager;
@@ -99,14 +100,15 @@
import com.android.systemui.SysuiTestCase;
import com.android.systemui.biometrics.AuthController;
import com.android.systemui.biometrics.FaceHelpMessageDeferral;
+import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor;
+import com.android.systemui.bouncer.domain.interactor.BouncerMessageInteractor;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.dock.DockManager;
import com.android.systemui.flags.FakeFeatureFlags;
import com.android.systemui.keyguard.KeyguardIndication;
import com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController;
import com.android.systemui.keyguard.ScreenLifecycle;
-import com.android.systemui.bouncer.domain.interactor.BouncerMessageInteractor;
-import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor;
+import com.android.systemui.keyguard.util.IndicationHelper;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.settings.UserTracker;
@@ -214,6 +216,7 @@
private StatusBarStateController.StateListener mStatusBarStateListener;
private ScreenLifecycle.Observer mScreenObserver;
private BroadcastReceiver mBroadcastReceiver;
+ private IndicationHelper mIndicationHelper;
private FakeExecutor mExecutor = new FakeExecutor(new FakeSystemClock());
private TestableLooper mTestableLooper;
private final int mCurrentUserId = 1;
@@ -263,13 +266,14 @@
when(mDevicePolicyManager.getDeviceOwnerType(DEVICE_OWNER_COMPONENT))
.thenReturn(DEVICE_OWNER_TYPE_DEFAULT);
-
when(mDevicePolicyResourcesManager.getString(anyString(), any()))
.thenReturn(mDisclosureGeneric);
when(mDevicePolicyResourcesManager.getString(anyString(), any(), anyString()))
.thenReturn(mDisclosureWithOrganization);
when(mUserTracker.getUserId()).thenReturn(mCurrentUserId);
+ mIndicationHelper = new IndicationHelper(mKeyguardUpdateMonitor);
+
mWakeLock = new WakeLockFake();
mWakeLockBuilder = new WakeLockFake.Builder(mContext);
mWakeLockBuilder.setWakeLock(mWakeLock);
@@ -305,7 +309,8 @@
mAlarmManager,
mUserTracker,
mock(BouncerMessageInteractor.class),
- flags
+ flags,
+ mIndicationHelper
);
mController.init();
mController.setIndicationArea(mIndicationArea);
@@ -807,36 +812,22 @@
}
@Test
- public void transientIndication_visibleWhenDozing_ignoresFingerprintCancellation() {
+ public void transientIndication_visibleWhenDozing_ignoresFingerprintErrorMsg() {
createController();
-
mController.setVisible(true);
reset(mRotateTextViewController);
+
+ // WHEN a fingerprint error user cancelled message is received
mController.getKeyguardCallback().onBiometricError(
- FingerprintManager.FINGERPRINT_ERROR_USER_CANCELED, "foo",
- BiometricSourceType.FINGERPRINT);
- mController.getKeyguardCallback().onBiometricError(
- FingerprintManager.FINGERPRINT_ERROR_CANCELED, "bar",
+ BiometricFingerprintConstants.FINGERPRINT_ERROR_USER_CANCELED, "foo",
BiometricSourceType.FINGERPRINT);
+ // THEN no message is shown
verifyNoMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE);
verifyNoMessage(INDICATION_TYPE_TRANSIENT);
}
@Test
- public void transientIndication_visibleWhenDozing_ignoresPowerPressed() {
- createController();
-
- mController.setVisible(true);
- reset(mRotateTextViewController);
- mController.getKeyguardCallback().onBiometricError(
- FingerprintManager.BIOMETRIC_ERROR_POWER_PRESSED, "foo",
- BiometricSourceType.FINGERPRINT);
-
- verifyNoMessage(INDICATION_TYPE_BIOMETRIC_MESSAGE);
- }
-
- @Test
public void transientIndication_swipeUpToRetry() {
createController();
String message = mContext.getString(R.string.keyguard_retry);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java
index ced0734..305f48b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java
@@ -33,25 +33,21 @@
import com.android.systemui.SysuiTestCase;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.power.domain.interactor.PowerInteractor;
import com.android.systemui.statusbar.notification.NotifPipelineFlags;
import com.android.systemui.statusbar.notification.RemoteInputControllerLogger;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
-import com.android.systemui.statusbar.phone.CentralSurfaces;
import com.android.systemui.statusbar.policy.RemoteInputUriController;
-import dagger.Lazy;
-
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-import java.util.Optional;
-
@SmallTest
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper
@@ -69,6 +65,7 @@
@Mock private RemoteInputUriController mRemoteInputUriController;
@Mock private NotificationClickNotifier mClickNotifier;
@Mock private NotificationLockscreenUserManager mLockscreenUserManager;
+ @Mock private PowerInteractor mPowerInteractor;
private TestableNotificationRemoteInputManager mRemoteInputManager;
private NotificationEntry mEntry;
@@ -82,7 +79,7 @@
mLockscreenUserManager,
mSmartReplyController,
mVisibilityProvider,
- () -> Optional.of(mock(CentralSurfaces.class)),
+ mPowerInteractor,
mStateController,
mRemoteInputUriController,
mock(RemoteInputControllerLogger.class),
@@ -140,7 +137,7 @@
NotificationLockscreenUserManager lockscreenUserManager,
SmartReplyController smartReplyController,
NotificationVisibilityProvider visibilityProvider,
- Lazy<Optional<CentralSurfaces>> centralSurfacesOptionalLazy,
+ PowerInteractor powerInteractor,
StatusBarStateController statusBarStateController,
RemoteInputUriController remoteInputUriController,
RemoteInputControllerLogger remoteInputControllerLogger,
@@ -153,7 +150,7 @@
lockscreenUserManager,
smartReplyController,
visibilityProvider,
- centralSurfacesOptionalLazy,
+ powerInteractor,
statusBarStateController,
remoteInputUriController,
remoteInputControllerLogger,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/disableflags/data/repository/DisableFlagsRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/disableflags/data/repository/DisableFlagsRepositoryTest.kt
new file mode 100644
index 0000000..580463a
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/disableflags/data/repository/DisableFlagsRepositoryTest.kt
@@ -0,0 +1,274 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.systemui.statusbar.disableflags.data.repository
+
+import android.app.StatusBarManager.DISABLE2_NONE
+import android.app.StatusBarManager.DISABLE2_NOTIFICATION_SHADE
+import android.app.StatusBarManager.DISABLE2_QUICK_SETTINGS
+import android.app.StatusBarManager.DISABLE_CLOCK
+import android.app.StatusBarManager.DISABLE_NONE
+import android.app.StatusBarManager.DISABLE_NOTIFICATION_ALERTS
+import android.content.res.Configuration
+import androidx.test.filters.SmallTest
+import com.android.systemui.R
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.dump.DumpManager
+import com.android.systemui.log.LogBufferFactory
+import com.android.systemui.statusbar.CommandQueue
+import com.android.systemui.statusbar.disableflags.DisableFlagsLogger
+import com.android.systemui.statusbar.disableflags.data.model.DisableFlagsModel
+import com.android.systemui.statusbar.policy.ConfigurationController
+import com.android.systemui.statusbar.policy.RemoteInputQuickSettingsDisabler
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.argumentCaptor
+import com.android.systemui.util.mockito.mock
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.UnconfinedTestDispatcher
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.mockito.Mockito.verify
+
+@SmallTest
+@OptIn(ExperimentalCoroutinesApi::class)
+class DisableFlagsRepositoryTest : SysuiTestCase() {
+
+ private lateinit var underTest: DisableFlagsRepository
+
+ private val testScope = TestScope(UnconfinedTestDispatcher())
+ private val commandQueue: CommandQueue = mock()
+ private val configurationController: ConfigurationController = mock()
+ private val remoteInputQuickSettingsDisabler =
+ RemoteInputQuickSettingsDisabler(
+ context,
+ commandQueue,
+ configurationController,
+ )
+ private val logBuffer = LogBufferFactory(DumpManager(), mock()).create("buffer", 10)
+ private val disableFlagsLogger = DisableFlagsLogger()
+
+ @Before
+ fun setUp() {
+ underTest =
+ DisableFlagsRepositoryImpl(
+ commandQueue,
+ DISPLAY_ID,
+ testScope.backgroundScope,
+ remoteInputQuickSettingsDisabler,
+ logBuffer,
+ disableFlagsLogger,
+ )
+ }
+
+ @Test
+ fun disableFlags_initialValue_none() {
+ assertThat(underTest.disableFlags.value)
+ .isEqualTo(DisableFlagsModel(DISABLE_NONE, DISABLE2_NONE))
+ }
+
+ @Test
+ fun disableFlags_noSubscribers_callbackStillRegistered() =
+ testScope.runTest { verify(commandQueue).addCallback(any()) }
+
+ @Test
+ fun disableFlags_notifAlertsNotDisabled_notifAlertsEnabledTrue() =
+ testScope.runTest {
+ getCommandQueueCallback()
+ .disable(DISPLAY_ID, DISABLE_NONE, DISABLE2_NONE, /* animate= */ false)
+
+ assertThat(underTest.disableFlags.value.areNotificationAlertsEnabled()).isTrue()
+ }
+
+ @Test
+ fun disableFlags_notifAlertsDisabled_notifAlertsEnabledFalse() =
+ testScope.runTest {
+ getCommandQueueCallback()
+ .disable(
+ DISPLAY_ID,
+ DISABLE_NOTIFICATION_ALERTS,
+ DISABLE2_NONE,
+ /* animate= */ false,
+ )
+
+ assertThat(underTest.disableFlags.value.areNotificationAlertsEnabled()).isFalse()
+ }
+
+ @Test
+ fun disableFlags_notifAlertsDisabled_differentDisplay_notifAlertsEnabledTrue() =
+ testScope.runTest {
+ val wrongDisplayId = DISPLAY_ID + 10
+
+ getCommandQueueCallback()
+ .disable(
+ wrongDisplayId,
+ DISABLE_NOTIFICATION_ALERTS,
+ DISABLE2_NONE,
+ /* animate= */ false,
+ )
+
+ // THEN our repo reports them as still enabled
+ assertThat(underTest.disableFlags.value.areNotificationAlertsEnabled()).isTrue()
+ }
+
+ @Test
+ fun disableFlags_shadeNotDisabled_shadeEnabledTrue() =
+ testScope.runTest {
+ getCommandQueueCallback()
+ .disable(DISPLAY_ID, DISABLE_NONE, DISABLE2_NONE, /* animate= */ false)
+
+ assertThat(underTest.disableFlags.value.isShadeEnabled()).isTrue()
+ }
+
+ @Test
+ fun disableFlags_shadeDisabled_shadeEnabledFalse() =
+ testScope.runTest {
+ getCommandQueueCallback()
+ .disable(
+ DISPLAY_ID,
+ DISABLE_NONE,
+ DISABLE2_NOTIFICATION_SHADE,
+ /* animate= */ false,
+ )
+
+ assertThat(underTest.disableFlags.value.isShadeEnabled()).isFalse()
+ }
+
+ @Test
+ fun disableFlags_shadeDisabled_differentDisplay_shadeEnabledTrue() =
+ testScope.runTest {
+ val wrongDisplayId = DISPLAY_ID + 10
+
+ getCommandQueueCallback()
+ .disable(
+ wrongDisplayId,
+ DISABLE_NONE,
+ DISABLE2_NOTIFICATION_SHADE,
+ /* animate= */ false,
+ )
+
+ // THEN our repo reports them as still enabled
+ assertThat(underTest.disableFlags.value.isShadeEnabled()).isTrue()
+ }
+
+ @Test
+ fun disableFlags_quickSettingsNotDisabled_quickSettingsEnabledTrue() =
+ testScope.runTest {
+ getCommandQueueCallback()
+ .disable(DISPLAY_ID, DISABLE_NONE, DISABLE2_NONE, /* animate= */ false)
+
+ assertThat(underTest.disableFlags.value.isQuickSettingsEnabled()).isTrue()
+ }
+
+ @Test
+ fun disableFlags_quickSettingsDisabled_quickSettingsEnabledFalse() =
+ testScope.runTest {
+ getCommandQueueCallback()
+ .disable(
+ DISPLAY_ID,
+ DISABLE_NONE,
+ DISABLE2_QUICK_SETTINGS,
+ /* animate= */ false,
+ )
+
+ assertThat(underTest.disableFlags.value.isQuickSettingsEnabled()).isFalse()
+ }
+
+ @Test
+ fun disableFlags_quickSettingsDisabled_differentDisplay_quickSettingsEnabledTrue() =
+ testScope.runTest {
+ val wrongDisplayId = DISPLAY_ID + 10
+
+ getCommandQueueCallback()
+ .disable(
+ wrongDisplayId,
+ DISABLE_NONE,
+ DISABLE2_QUICK_SETTINGS,
+ /* animate= */ false,
+ )
+
+ // THEN our repo reports them as still enabled
+ assertThat(underTest.disableFlags.value.isQuickSettingsEnabled()).isTrue()
+ }
+
+ @Test
+ fun disableFlags_remoteInputActive_quickSettingsEnabledFalse() =
+ testScope.runTest {
+ // WHEN remote input is set up to be active
+ val configuration = Configuration(mContext.resources.configuration)
+ configuration.orientation = Configuration.ORIENTATION_LANDSCAPE
+ mContext.orCreateTestableResources.addOverride(
+ R.bool.config_use_split_notification_shade,
+ /* value= */ false
+ )
+ remoteInputQuickSettingsDisabler.setRemoteInputActive(true)
+ remoteInputQuickSettingsDisabler.onConfigChanged(configuration)
+
+ getCommandQueueCallback()
+ .disable(
+ DISPLAY_ID,
+ DISABLE_NONE,
+ DISABLE2_NONE,
+ /* animate= */ false,
+ )
+
+ // THEN quick settings is disabled (even if the disable flags don't say so)
+ assertThat(underTest.disableFlags.value.isQuickSettingsEnabled()).isFalse()
+ }
+
+ @Test
+ fun disableFlags_reactsToChanges() =
+ testScope.runTest {
+ getCommandQueueCallback()
+ .disable(
+ DISPLAY_ID,
+ DISABLE_NOTIFICATION_ALERTS,
+ DISABLE2_NONE,
+ /* animate= */ false,
+ )
+ assertThat(underTest.disableFlags.value.areNotificationAlertsEnabled()).isFalse()
+
+ getCommandQueueCallback()
+ .disable(
+ DISPLAY_ID,
+ DISABLE_CLOCK, // Unrelated to notifications
+ DISABLE2_NONE,
+ /* animate= */ false,
+ )
+ assertThat(underTest.disableFlags.value.areNotificationAlertsEnabled()).isTrue()
+
+ getCommandQueueCallback()
+ .disable(
+ DISPLAY_ID,
+ DISABLE_NOTIFICATION_ALERTS,
+ DISABLE2_QUICK_SETTINGS or DISABLE2_NOTIFICATION_SHADE,
+ /* animate= */ false,
+ )
+ assertThat(underTest.disableFlags.value.areNotificationAlertsEnabled()).isFalse()
+ assertThat(underTest.disableFlags.value.isShadeEnabled()).isFalse()
+ assertThat(underTest.disableFlags.value.isQuickSettingsEnabled()).isFalse()
+ }
+
+ private fun getCommandQueueCallback(): CommandQueue.Callbacks {
+ val callbackCaptor = argumentCaptor<CommandQueue.Callbacks>()
+ verify(commandQueue).addCallback(callbackCaptor.capture())
+ return callbackCaptor.value
+ }
+
+ private companion object {
+ const val DISPLAY_ID = 1
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/disableflags/data/repository/FakeDisableFlagsRepository.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/disableflags/data/repository/FakeDisableFlagsRepository.kt
new file mode 100644
index 0000000..b66231c
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/disableflags/data/repository/FakeDisableFlagsRepository.kt
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.systemui.statusbar.disableflags.data.repository
+
+import com.android.systemui.statusbar.disableflags.data.model.DisableFlagsModel
+import kotlinx.coroutines.flow.MutableStateFlow
+
+class FakeDisableFlagsRepository : DisableFlagsRepository {
+ override val disableFlags = MutableStateFlow(DisableFlagsModel())
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifCollectionTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifCollectionTest.java
index 540bda6..9037df8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifCollectionTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifCollectionTest.java
@@ -1675,11 +1675,21 @@
}
@Test
+ public void testCanDismissOtherNotificationChildren() {
+ // GIVEN an ongoing notification
+ final NotificationEntry container = new NotificationEntryBuilder()
+ .setGroup(mContext, "group")
+ .build();
+
+ // THEN its children are dismissible
+ assertTrue(mCollection.shouldAutoDismissChildren(
+ container, container.getSbn().getGroupKey()));
+ }
+
+ @Test
public void testCannotDismissOngoingNotificationChildren() {
// GIVEN an ongoing notification
final NotificationEntry container = new NotificationEntryBuilder()
- .setPkg(TEST_PACKAGE)
- .setId(47)
.setGroup(mContext, "group")
.setFlag(mContext, FLAG_ONGOING_EVENT, true)
.build();
@@ -1693,6 +1703,7 @@
public void testCannotDismissNoClearNotifications() {
// GIVEN an no-clear notification
final NotificationEntry container = new NotificationEntryBuilder()
+ .setGroup(mContext, "group")
.setFlag(mContext, FLAG_NO_CLEAR, true)
.build();
@@ -1702,11 +1713,25 @@
}
@Test
+ public void testCannotDismissPriorityConversations() {
+ // GIVEN an no-clear notification
+ NotificationChannel channel =
+ new NotificationChannel("foo", "Foo", NotificationManager.IMPORTANCE_HIGH);
+ channel.setImportantConversation(true);
+ final NotificationEntry container = new NotificationEntryBuilder()
+ .setGroup(mContext, "group")
+ .setChannel(channel)
+ .build();
+
+ // THEN its children are not dismissible
+ assertFalse(mCollection.shouldAutoDismissChildren(
+ container, container.getSbn().getGroupKey()));
+ }
+
+ @Test
public void testCanDismissFgsNotificationChildren() {
// GIVEN an FGS but not ongoing notification
final NotificationEntry container = new NotificationEntryBuilder()
- .setPkg(TEST_PACKAGE)
- .setId(47)
.setGroup(mContext, "group")
.setFlag(mContext, FLAG_FOREGROUND_SERVICE, true)
.build();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationsInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationsInteractorTest.kt
new file mode 100644
index 0000000..fe49016
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationsInteractorTest.kt
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.domain.interactor
+
+import android.app.StatusBarManager
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.dump.DumpManager
+import com.android.systemui.log.LogBufferFactory
+import com.android.systemui.statusbar.CommandQueue
+import com.android.systemui.statusbar.disableflags.DisableFlagsLogger
+import com.android.systemui.statusbar.disableflags.data.repository.DisableFlagsRepository
+import com.android.systemui.statusbar.disableflags.data.repository.DisableFlagsRepositoryImpl
+import com.android.systemui.util.mockito.argumentCaptor
+import com.android.systemui.util.mockito.mock
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.UnconfinedTestDispatcher
+import org.junit.Before
+import org.junit.Test
+import org.mockito.Mockito.verify
+
+@SmallTest
+@OptIn(ExperimentalCoroutinesApi::class)
+class NotificationsInteractorTest : SysuiTestCase() {
+
+ private lateinit var underTest: NotificationsInteractor
+
+ private val testScope = TestScope(UnconfinedTestDispatcher())
+ private val commandQueue: CommandQueue = mock()
+ private val logBuffer = LogBufferFactory(DumpManager(), mock()).create("buffer", 10)
+ private val disableFlagsLogger = DisableFlagsLogger()
+ private lateinit var disableFlagsRepository: DisableFlagsRepository
+
+ @Before
+ fun setUp() {
+ disableFlagsRepository =
+ DisableFlagsRepositoryImpl(
+ commandQueue,
+ DISPLAY_ID,
+ testScope.backgroundScope,
+ mock(),
+ logBuffer,
+ disableFlagsLogger,
+ )
+ underTest = NotificationsInteractor(disableFlagsRepository)
+ }
+
+ @Test
+ fun disableFlags_notifAlertsNotDisabled_notifAlertsEnabledTrue() {
+ val callback = getCommandQueueCallback()
+
+ callback.disable(
+ DISPLAY_ID,
+ StatusBarManager.DISABLE_NONE,
+ StatusBarManager.DISABLE2_NONE,
+ /* animate= */ false
+ )
+
+ assertThat(underTest.areNotificationAlertsEnabled()).isTrue()
+ }
+
+ @Test
+ fun disableFlags_notifAlertsDisabled_notifAlertsEnabledFalse() {
+ val callback = getCommandQueueCallback()
+
+ callback.disable(
+ DISPLAY_ID,
+ StatusBarManager.DISABLE_NOTIFICATION_ALERTS,
+ StatusBarManager.DISABLE2_NONE,
+ /* animate= */ false
+ )
+
+ assertThat(underTest.areNotificationAlertsEnabled()).isFalse()
+ }
+
+ private fun getCommandQueueCallback(): CommandQueue.Callbacks {
+ val callbackCaptor = argumentCaptor<CommandQueue.Callbacks>()
+ verify(commandQueue).addCallback(callbackCaptor.capture())
+ return callbackCaptor.value
+ }
+
+ private companion object {
+ const val DISPLAY_ID = 1
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/StackStateLoggerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/StackStateLoggerTest.kt
new file mode 100644
index 0000000..7707a7e
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/StackStateLoggerTest.kt
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.logging
+
+import android.testing.AndroidTestingRunner
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.log.LogBuffer
+import com.android.systemui.log.LogLevel
+import com.android.systemui.log.LogcatEchoTracker
+import com.android.systemui.statusbar.notification.stack.StackStateLogger
+import com.google.common.truth.Truth
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidTestingRunner::class)
+@SmallTest
+class StackStateLoggerTest : SysuiTestCase() {
+ private val logBufferCounter = LogBufferCounter()
+ private lateinit var logger: StackStateLogger
+
+ @Before
+ fun setup() {
+ logger = StackStateLogger(logBufferCounter.logBuffer, logBufferCounter.logBuffer)
+ }
+
+ @Test
+ fun groupChildRemovalEvent() {
+ logger.groupChildRemovalEventProcessed(KEY)
+ verifyDidLog(1)
+ logger.groupChildRemovalAnimationEnded(KEY)
+ verifyDidLog(1)
+ }
+
+ class LogBufferCounter {
+ val recentLogs = mutableListOf<Pair<String, LogLevel>>()
+ val tracker =
+ object : LogcatEchoTracker {
+ override val logInBackgroundThread: Boolean = false
+ override fun isBufferLoggable(bufferName: String, level: LogLevel): Boolean = false
+ override fun isTagLoggable(tagName: String, level: LogLevel): Boolean {
+ recentLogs.add(tagName to level)
+ return true
+ }
+ }
+ val logBuffer =
+ LogBuffer(name = "test", maxSize = 1, logcatEchoTracker = tracker, systrace = false)
+
+ fun verifyDidLog(times: Int) {
+ Truth.assertThat(recentLogs).hasSize(times)
+ recentLogs.clear()
+ }
+ }
+
+ private fun verifyDidLog(times: Int) {
+ logBufferCounter.verifyDidLog(times)
+ }
+
+ companion object {
+ private val KEY = "PACKAGE_NAME"
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowControllerTest.kt
index c2f1f61..2e68cec 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowControllerTest.kt
@@ -36,6 +36,7 @@
import com.android.systemui.statusbar.notification.logging.NotificationLogger
import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier
import com.android.systemui.statusbar.notification.stack.NotificationChildrenContainer
+import com.android.systemui.statusbar.notification.stack.NotificationChildrenContainerLogger
import com.android.systemui.statusbar.notification.stack.NotificationListContainer
import com.android.systemui.statusbar.phone.KeyguardBypassController
import com.android.systemui.statusbar.policy.HeadsUpManager
@@ -107,6 +108,7 @@
rivSubComponentFactory,
metricsLogger,
logBufferLogger,
+ mock<NotificationChildrenContainerLogger>(),
listContainer,
smartReplyConstants,
smartReplyController,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
index 813bae8..df47071 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
@@ -76,7 +76,7 @@
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow.ExpandableNotificationRowLogger;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow.OnExpandClickListener;
import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.InflationFlag;
-import com.android.systemui.statusbar.notification.stack.StackScrollAlgorithm;
+import com.android.systemui.statusbar.notification.stack.NotificationChildrenContainerLogger;
import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.policy.InflatedSmartReplyState;
@@ -581,6 +581,7 @@
mock(NotificationGutsManager.class),
mDismissibilityProvider,
mock(MetricsLogger.class),
+ mock(NotificationChildrenContainerLogger.class),
mock(SmartReplyConstants.class),
mock(SmartReplyController.class),
mFeatureFlags,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java
index bb9937b..6ae7dca 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java
@@ -24,6 +24,7 @@
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.argThat;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.mock;
@@ -32,10 +33,14 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import static kotlinx.coroutines.flow.FlowKt.emptyFlow;
+
import android.content.res.Resources;
import android.metrics.LogMaker;
import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
import android.view.View;
+import android.view.ViewTreeObserver;
import androidx.test.filters.SmallTest;
@@ -49,8 +54,12 @@
import com.android.systemui.classifier.FalsingManagerFake;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.flags.FakeFeatureFlags;
+import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.flags.Flags;
+import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository;
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor;
+import com.android.systemui.keyguard.shared.model.KeyguardState;
+import com.android.systemui.keyguard.shared.model.TransitionStep;
import com.android.systemui.media.controls.ui.KeyguardMediaController;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
@@ -105,6 +114,7 @@
* Tests for {@link NotificationStackScrollLayoutController}.
*/
@SmallTest
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
@RunWith(AndroidTestingRunner.class)
public class NotificationStackScrollLayoutControllerTest extends SysuiTestCase {
@@ -151,6 +161,7 @@
@Mock private SecureSettings mSecureSettings;
@Mock private NotificationIconAreaController mIconAreaController;
@Mock private ActivityStarter mActivityStarter;
+ @Mock private KeyguardTransitionRepository mKeyguardTransitionRepo;
@Captor
private ArgumentCaptor<StatusBarStateController.StateListener> mStateListenerArgumentCaptor;
@@ -162,11 +173,13 @@
@Before
public void setUp() {
+ allowTestableLooperAsMainThread();
MockitoAnnotations.initMocks(this);
mFeatureFlags.set(Flags.USE_REPOS_FOR_BOUNCER_SHOWING, false);
when(mNotificationSwipeHelperBuilder.build()).thenReturn(mNotificationSwipeHelper);
+ when(mKeyguardTransitionRepo.getTransitions()).thenReturn(emptyFlow());
}
@Test
@@ -572,17 +585,33 @@
.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
}
+ @Test
+ public void updateEmptyShadeView_onKeyguardTransitionToAod_hidesView() {
+ initController(/* viewIsAttached= */ true);
+ mController.onKeyguardTransitionChanged(
+ new TransitionStep(
+ /* from= */ KeyguardState.GONE,
+ /* to= */ KeyguardState.AOD));
+ verify(mNotificationStackScrollLayout).updateEmptyShadeView(eq(false), anyBoolean());
+ }
+
private LogMaker logMatcher(int category, int type) {
return argThat(new LogMatcher(category, type));
}
private void setupShowEmptyShadeViewState(boolean toShow) {
if (toShow) {
- when(mSysuiStatusBarStateController.getCurrentOrUpcomingState()).thenReturn(SHADE);
+ mController.onKeyguardTransitionChanged(
+ new TransitionStep(
+ /* from= */ KeyguardState.LOCKSCREEN,
+ /* to= */ KeyguardState.GONE));
mController.setQsFullScreen(false);
mController.getView().removeAllViews();
} else {
- when(mSysuiStatusBarStateController.getCurrentOrUpcomingState()).thenReturn(KEYGUARD);
+ mController.onKeyguardTransitionChanged(
+ new TransitionStep(
+ /* from= */ KeyguardState.GONE,
+ /* to= */ KeyguardState.AOD));
mController.setQsFullScreen(true);
mController.getView().addContainerView(mock(ExpandableNotificationRow.class));
}
@@ -590,7 +619,9 @@
private void initController(boolean viewIsAttached) {
when(mNotificationStackScrollLayout.isAttachedToWindow()).thenReturn(viewIsAttached);
-
+ ViewTreeObserver viewTreeObserver = mock(ViewTreeObserver.class);
+ when(mNotificationStackScrollLayout.getViewTreeObserver())
+ .thenReturn(viewTreeObserver);
mController = new NotificationStackScrollLayoutController(
mNotificationStackScrollLayout,
true,
@@ -608,6 +639,7 @@
mKeyguardBypassController,
mKeyguardInteractor,
mPrimaryBouncerInteractor,
+ mKeyguardTransitionRepo,
mZenModeController,
mNotificationLockscreenUserManager,
Optional.<NotificationListViewModel>empty(),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java
index cb71fb8..036b8be 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java
@@ -150,7 +150,6 @@
mSbcqCallbacks.disable(DEFAULT_DISPLAY, StatusBarManager.DISABLE_NONE,
StatusBarManager.DISABLE2_NOTIFICATION_SHADE, false);
- verify(mCentralSurfaces).updateQsExpansionEnabled();
verify(mShadeController).animateCollapseShade();
}
@@ -162,7 +161,6 @@
when(mCommandQueue.panelsEnabled()).thenReturn(true);
mSbcqCallbacks.disable(DEFAULT_DISPLAY, StatusBarManager.DISABLE_NONE,
StatusBarManager.DISABLE2_NONE, false);
- verify(mCentralSurfaces).updateQsExpansionEnabled();
verify(mShadeController, never()).animateCollapseShade();
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
index cc8324b..1ffffe4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
@@ -29,7 +29,6 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.clearInvocations;
@@ -510,6 +509,7 @@
configurationController,
mNotificationShadeWindowController,
mNotificationShelfController,
+ mStackScrollerController,
mDozeParameters,
mScrimController,
mLockscreenWallpaperLazy,
@@ -593,8 +593,6 @@
mCentralSurfaces.mPresenter = mNotificationPresenter;
mCentralSurfaces.mKeyguardIndicationController = mKeyguardIndicationController;
mCentralSurfaces.mBarService = mBarService;
- mCentralSurfaces.mStackScrollerController = mStackScrollerController;
- mCentralSurfaces.mStackScroller = mStackScroller;
mCentralSurfaces.mGestureWakeLock = mPowerManager.newWakeLock(
PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "sysui:GestureWakeLock");
mCentralSurfaces.startKeyguard();
@@ -1253,34 +1251,6 @@
}
@Test
- public void dozing_wakeUp() throws RemoteException {
- // GIVEN can wakeup when dozing & is dozing
- when(mScreenOffAnimationController.allowWakeUpIfDozing()).thenReturn(true);
- setDozing(true);
-
- // WHEN wakeup is requested
- final int wakeReason = PowerManager.WAKE_REASON_TAP;
- mCentralSurfaces.wakeUpIfDozing(0, "", wakeReason);
-
- // THEN power manager receives wakeup
- verify(mPowerManagerService).wakeUp(eq(0L), eq(wakeReason), anyString(), anyString());
- }
-
- @Test
- public void notDozing_noWakeUp() throws RemoteException {
- // GIVEN can wakeup when dozing and NOT dozing
- when(mScreenOffAnimationController.allowWakeUpIfDozing()).thenReturn(true);
- setDozing(false);
-
- // WHEN wakeup is requested
- final int wakeReason = PowerManager.WAKE_REASON_TAP;
- mCentralSurfaces.wakeUpIfDozing(0, "", wakeReason);
-
- // THEN power manager receives wakeup
- verify(mPowerManagerService, never()).wakeUp(anyLong(), anyInt(), anyString(), anyString());
- }
-
- @Test
public void frpLockedDevice_shadeDisabled() {
when(mDeviceProvisionedController.isFrpActive()).thenReturn(true);
when(mDozeServiceHost.isPulsing()).thenReturn(true);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LetterboxAppearanceCalculatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LetterboxAppearanceCalculatorTest.kt
index c0243dc..b2dc0dc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LetterboxAppearanceCalculatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LetterboxAppearanceCalculatorTest.kt
@@ -105,6 +105,30 @@
expect.that(letterboxAppearance.appearanceRegions).isEqualTo(TEST_APPEARANCE_REGIONS)
}
+ /** Regression test for b/287508741 */
+ @Test
+ fun getLetterboxAppearance_withOverlap_doesNotMutateOriginalBounds() {
+ val statusBarStartSideBounds = Rect(left = 0, top = 0, right = 100, bottom = 100)
+ val statusBarEndSideBounds = Rect(left = 200, top = 0, right = 300, bottom = 100)
+ val letterBoxInnerBounds = Rect(left = 150, top = 50, right = 250, bottom = 150)
+ val statusBarStartSideBoundsCopy = Rect(statusBarStartSideBounds)
+ val statusBarEndSideBoundsCopy = Rect(statusBarEndSideBounds)
+ val letterBoxInnerBoundsCopy = Rect(letterBoxInnerBounds)
+ whenever(statusBarBoundsProvider.visibleStartSideBounds)
+ .thenReturn(statusBarStartSideBounds)
+ whenever(statusBarBoundsProvider.visibleEndSideBounds).thenReturn(statusBarEndSideBounds)
+
+ calculator.getLetterboxAppearance(
+ TEST_APPEARANCE,
+ TEST_APPEARANCE_REGIONS,
+ arrayOf(letterboxWithInnerBounds(letterBoxInnerBounds))
+ )
+
+ expect.that(statusBarStartSideBounds).isEqualTo(statusBarStartSideBoundsCopy)
+ expect.that(statusBarEndSideBounds).isEqualTo(statusBarEndSideBoundsCopy)
+ expect.that(letterBoxInnerBounds).isEqualTo(letterBoxInnerBoundsCopy)
+ }
+
@Test
fun getLetterboxAppearance_noOverlap_BackgroundMultiColor_returnsAppearanceWithScrim() {
whenever(letterboxBackgroundProvider.isLetterboxBackgroundMultiColored).thenReturn(true)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java
index 1724f27..5bd6ff4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java
@@ -37,6 +37,7 @@
import com.android.systemui.SysuiTestCase;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.power.domain.interactor.PowerInteractor;
import com.android.systemui.settings.FakeDisplayTracker;
import com.android.systemui.shade.NotificationShadeWindowView;
import com.android.systemui.shade.QuickSettingsController;
@@ -55,6 +56,7 @@
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
import com.android.systemui.statusbar.notification.collection.render.NotifShadeEventSource;
+import com.android.systemui.statusbar.notification.domain.interactor.NotificationsInteractor;
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider;
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptSuppressor;
import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
@@ -80,6 +82,8 @@
private FakeMetricsLogger mMetricsLogger;
private final ShadeController mShadeController = mock(ShadeController.class);
private final CentralSurfaces mCentralSurfaces = mock(CentralSurfaces.class);
+ private final NotificationsInteractor mNotificationsInteractor =
+ mock(NotificationsInteractor.class);
private final KeyguardStateController mKeyguardStateController =
mock(KeyguardStateController.class);
private final NotifPipelineFlags mNotifPipelineFlags = mock(NotifPipelineFlags.class);
@@ -122,7 +126,9 @@
mock(DynamicPrivacyController.class),
mKeyguardStateController,
mCentralSurfaces,
+ mNotificationsInteractor,
mock(LockscreenShadeTransitionController.class),
+ mock(PowerInteractor.class),
mCommandQueue,
mock(NotificationLockscreenUserManager.class),
mock(SysuiStatusBarStateController.class),
@@ -233,9 +239,9 @@
.setTag("a")
.setNotification(n)
.build();
- when(mCentralSurfaces.areNotificationAlertsDisabled()).thenReturn(true);
+ when(mNotificationsInteractor.areNotificationAlertsEnabled()).thenReturn(false);
- assertTrue("CentralSurfaces alerts disabled shouldn't allow interruptions",
+ assertTrue("When alerts aren't enabled, interruptions are suppressed",
mInterruptSuppressor.suppressInterruptions(entry));
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/CarrierConfigRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/CarrierConfigRepositoryTest.kt
index 6e3af26..932c4a1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/CarrierConfigRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/CarrierConfigRepositoryTest.kt
@@ -152,13 +152,11 @@
}
private fun sendConfig(subId: Int) {
- fakeBroadcastDispatcher.registeredReceivers.forEach { receiver ->
- receiver.onReceive(
- context,
- Intent(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED)
- .putExtra(CarrierConfigManager.EXTRA_SUBSCRIPTION_INDEX, subId)
- )
- }
+ fakeBroadcastDispatcher.sendIntentToMatchingReceiversOnly(
+ context,
+ Intent(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED)
+ .putExtra(CarrierConfigManager.EXTRA_SUBSCRIPTION_INDEX, subId),
+ )
}
companion object {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt
index d1df6e3..cf832b4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt
@@ -379,9 +379,10 @@
var latest: Int? = null
val job = underTest.carrierId.onEach { latest = it }.launchIn(this)
- fakeBroadcastDispatcher.registeredReceivers.forEach { receiver ->
- receiver.onReceive(context, carrierIdIntent(carrierId = 4321))
- }
+ fakeBroadcastDispatcher.sendIntentToMatchingReceiversOnly(
+ context,
+ carrierIdIntent(carrierId = 4321),
+ )
assertThat(latest).isEqualTo(4321)
@@ -653,10 +654,7 @@
val job = underTest.networkName.onEach { latest = it }.launchIn(this)
val intent = spnIntent()
-
- fakeBroadcastDispatcher.registeredReceivers.forEach { receiver ->
- receiver.onReceive(context, intent)
- }
+ fakeBroadcastDispatcher.sendIntentToMatchingReceiversOnly(context, intent)
assertThat(latest).isEqualTo(intent.toNetworkNameModel(SEP))
@@ -670,17 +668,13 @@
val job = underTest.networkName.onEach { latest = it }.launchIn(this)
val intent = spnIntent()
- fakeBroadcastDispatcher.registeredReceivers.forEach { receiver ->
- receiver.onReceive(context, intent)
- }
+ fakeBroadcastDispatcher.sendIntentToMatchingReceiversOnly(context, intent)
assertThat(latest).isEqualTo(intent.toNetworkNameModel(SEP))
// WHEN an intent with a different subId is sent
val wrongSubIntent = spnIntent(subId = 101)
- fakeBroadcastDispatcher.registeredReceivers.forEach { receiver ->
- receiver.onReceive(context, wrongSubIntent)
- }
+ fakeBroadcastDispatcher.sendIntentToMatchingReceiversOnly(context, wrongSubIntent)
// THEN the previous intent's name is still used
assertThat(latest).isEqualTo(intent.toNetworkNameModel(SEP))
@@ -695,9 +689,7 @@
val job = underTest.networkName.onEach { latest = it }.launchIn(this)
val intent = spnIntent()
- fakeBroadcastDispatcher.registeredReceivers.forEach { receiver ->
- receiver.onReceive(context, intent)
- }
+ fakeBroadcastDispatcher.sendIntentToMatchingReceiversOnly(context, intent)
assertThat(latest).isEqualTo(intent.toNetworkNameModel(SEP))
val intentWithoutInfo =
@@ -706,9 +698,7 @@
showPlmn = false,
)
- fakeBroadcastDispatcher.registeredReceivers.forEach { receiver ->
- receiver.onReceive(context, intentWithoutInfo)
- }
+ fakeBroadcastDispatcher.sendIntentToMatchingReceiversOnly(context, intentWithoutInfo)
assertThat(latest).isEqualTo(DEFAULT_NAME)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryTest.kt
index fd156d8..74bcdee 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryTest.kt
@@ -626,23 +626,17 @@
assertThat(latest).isEqualTo(INVALID_SUBSCRIPTION_ID)
- fakeBroadcastDispatcher.registeredReceivers.forEach { receiver ->
- receiver.onReceive(
- context,
- Intent(TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED)
- .putExtra(PhoneConstants.SUBSCRIPTION_KEY, SUB_2_ID)
- )
- }
+ val intent2 =
+ Intent(TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED)
+ .putExtra(PhoneConstants.SUBSCRIPTION_KEY, SUB_2_ID)
+ fakeBroadcastDispatcher.sendIntentToMatchingReceiversOnly(context, intent2)
assertThat(latest).isEqualTo(SUB_2_ID)
- fakeBroadcastDispatcher.registeredReceivers.forEach { receiver ->
- receiver.onReceive(
- context,
- Intent(TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED)
- .putExtra(PhoneConstants.SUBSCRIPTION_KEY, SUB_1_ID)
- )
- }
+ val intent1 =
+ Intent(TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED)
+ .putExtra(PhoneConstants.SUBSCRIPTION_KEY, SUB_1_ID)
+ fakeBroadcastDispatcher.sendIntentToMatchingReceiversOnly(context, intent1)
assertThat(latest).isEqualTo(SUB_1_ID)
}
@@ -1074,13 +1068,10 @@
assertThat(configFromContext.showAtLeast3G).isTrue()
// WHEN the change event is fired
- fakeBroadcastDispatcher.registeredReceivers.forEach { receiver ->
- receiver.onReceive(
- context,
- Intent(TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED)
- .putExtra(PhoneConstants.SUBSCRIPTION_KEY, SUB_1_ID)
- )
- }
+ val intent =
+ Intent(TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED)
+ .putExtra(PhoneConstants.SUBSCRIPTION_KEY, SUB_1_ID)
+ fakeBroadcastDispatcher.sendIntentToMatchingReceiversOnly(context, intent)
// THEN the config is updated
assertTrue(latest!!.areEqual(configFromContext))
@@ -1099,12 +1090,10 @@
assertThat(configFromContext.showAtLeast3G).isTrue()
// WHEN the change event is fired
- fakeBroadcastDispatcher.registeredReceivers.forEach { receiver ->
- receiver.onReceive(
- context,
- Intent(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED)
- )
- }
+ fakeBroadcastDispatcher.sendIntentToMatchingReceiversOnly(
+ context,
+ Intent(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED),
+ )
// THEN the config is updated
assertThat(latest!!.areEqual(configFromContext)).isTrue()
@@ -1123,12 +1112,10 @@
assertThat(configFromContext.showAtLeast3G).isTrue()
// WHEN the change event is fired
- fakeBroadcastDispatcher.registeredReceivers.forEach { receiver ->
- receiver.onReceive(
- context,
- Intent(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED)
- )
- }
+ fakeBroadcastDispatcher.sendIntentToMatchingReceiversOnly(
+ context,
+ Intent(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED),
+ )
// WHEN collection starts AFTER the broadcast is sent out
val latest by collectLastValue(underTest.defaultDataSubRatConfig)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImplTest.kt
index dc68180..5ed3a5c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImplTest.kt
@@ -16,6 +16,7 @@
package com.android.systemui.statusbar.pipeline.wifi.data.repository.prod
+import android.content.Intent
import android.net.ConnectivityManager
import android.net.Network
import android.net.NetworkCapabilities
@@ -33,7 +34,6 @@
import android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
-import com.android.systemui.broadcast.BroadcastDispatcher
import com.android.systemui.log.table.TableLogBuffer
import com.android.systemui.statusbar.pipeline.shared.data.model.ConnectivitySlots
import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel
@@ -46,13 +46,10 @@
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.argumentCaptor
import com.android.systemui.util.mockito.mock
-import com.android.systemui.util.mockito.nullable
import com.android.systemui.util.time.FakeSystemClock
import com.google.common.truth.Truth.assertThat
import java.util.concurrent.Executor
import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.flow.MutableSharedFlow
-import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.test.TestScope
@@ -60,7 +57,6 @@
import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
-import org.mockito.ArgumentMatchers.anyInt
import org.mockito.Mock
import org.mockito.Mockito.verify
import org.mockito.Mockito.`when` as whenever
@@ -73,7 +69,6 @@
private lateinit var underTest: WifiRepositoryImpl
- @Mock private lateinit var broadcastDispatcher: BroadcastDispatcher
@Mock private lateinit var logger: WifiInputLogger
@Mock private lateinit var tableLogger: TableLogBuffer
@Mock private lateinit var connectivityManager: ConnectivityManager
@@ -86,15 +81,6 @@
@Before
fun setUp() {
MockitoAnnotations.initMocks(this)
- whenever(
- broadcastDispatcher.broadcastFlow(
- any(),
- nullable(),
- anyInt(),
- nullable(),
- )
- )
- .thenReturn(flowOf(Unit))
executor = FakeExecutor(FakeSystemClock())
connectivityRepository =
@@ -168,27 +154,23 @@
@Test
fun isWifiEnabled_intentsReceived_valueUpdated() =
testScope.runTest {
- val intentFlow = MutableSharedFlow<Unit>()
- whenever(
- broadcastDispatcher.broadcastFlow(
- any(),
- nullable(),
- anyInt(),
- nullable(),
- )
- )
- .thenReturn(intentFlow)
underTest = createRepo()
val job = underTest.isWifiEnabled.launchIn(this)
whenever(wifiManager.isWifiEnabled).thenReturn(true)
- intentFlow.emit(Unit)
+ fakeBroadcastDispatcher.sendIntentToMatchingReceiversOnly(
+ context,
+ Intent(WifiManager.WIFI_STATE_CHANGED_ACTION),
+ )
assertThat(underTest.isWifiEnabled.value).isTrue()
whenever(wifiManager.isWifiEnabled).thenReturn(false)
- intentFlow.emit(Unit)
+ fakeBroadcastDispatcher.sendIntentToMatchingReceiversOnly(
+ context,
+ Intent(WifiManager.WIFI_STATE_CHANGED_ACTION),
+ )
assertThat(underTest.isWifiEnabled.value).isFalse()
@@ -198,23 +180,16 @@
@Test
fun isWifiEnabled_bothIntentAndNetworkUpdates_valueAlwaysUpdated() =
testScope.runTest {
- val intentFlow = MutableSharedFlow<Unit>()
- whenever(
- broadcastDispatcher.broadcastFlow(
- any(),
- nullable(),
- anyInt(),
- nullable(),
- )
- )
- .thenReturn(intentFlow)
underTest = createRepo()
val networkJob = underTest.wifiNetwork.launchIn(this)
val enabledJob = underTest.isWifiEnabled.launchIn(this)
whenever(wifiManager.isWifiEnabled).thenReturn(false)
- intentFlow.emit(Unit)
+ fakeBroadcastDispatcher.sendIntentToMatchingReceiversOnly(
+ context,
+ Intent(WifiManager.WIFI_STATE_CHANGED_ACTION),
+ )
assertThat(underTest.isWifiEnabled.value).isFalse()
whenever(wifiManager.isWifiEnabled).thenReturn(true)
@@ -227,7 +202,10 @@
assertThat(underTest.isWifiEnabled.value).isFalse()
whenever(wifiManager.isWifiEnabled).thenReturn(true)
- intentFlow.emit(Unit)
+ fakeBroadcastDispatcher.sendIntentToMatchingReceiversOnly(
+ context,
+ Intent(WifiManager.WIFI_STATE_CHANGED_ACTION),
+ )
assertThat(underTest.isWifiEnabled.value).isTrue()
networkJob.cancel()
@@ -1317,7 +1295,7 @@
private fun createRepo(): WifiRepositoryImpl {
return WifiRepositoryImpl(
- broadcastDispatcher,
+ fakeBroadcastDispatcher,
connectivityManager,
connectivityRepository,
logger,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/UserInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/UserInteractorTest.kt
index 3fbbeda..89dce61 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/UserInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/UserInteractorTest.kt
@@ -633,13 +633,11 @@
userRepository.setSelectedUserInfo(userInfos[1])
runCurrent()
- fakeBroadcastDispatcher.registeredReceivers.forEach {
- it.onReceive(
- context,
- Intent(Intent.ACTION_USER_SWITCHED)
- .putExtra(Intent.EXTRA_USER_HANDLE, userInfos[1].id),
- )
- }
+ fakeBroadcastDispatcher.sendIntentToMatchingReceiversOnly(
+ context,
+ Intent(Intent.ACTION_USER_SWITCHED)
+ .putExtra(Intent.EXTRA_USER_HANDLE, userInfos[1].id),
+ )
runCurrent()
verify(callback1, atLeastOnce()).onUserStateChanged()
@@ -656,12 +654,10 @@
userRepository.setSelectedUserInfo(userInfos[0])
val refreshUsersCallCount = userRepository.refreshUsersCallCount
- fakeBroadcastDispatcher.registeredReceivers.forEach {
- it.onReceive(
- context,
- Intent(Intent.ACTION_USER_INFO_CHANGED),
- )
- }
+ fakeBroadcastDispatcher.sendIntentToMatchingReceiversOnly(
+ context,
+ Intent(Intent.ACTION_USER_INFO_CHANGED),
+ )
runCurrent()
@@ -676,13 +672,11 @@
userRepository.setSelectedUserInfo(userInfos[0])
val refreshUsersCallCount = userRepository.refreshUsersCallCount
- fakeBroadcastDispatcher.registeredReceivers.forEach {
- it.onReceive(
- context,
- Intent(Intent.ACTION_USER_UNLOCKED)
- .putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_SYSTEM),
- )
- }
+ fakeBroadcastDispatcher.sendIntentToMatchingReceiversOnly(
+ context,
+ Intent(Intent.ACTION_USER_UNLOCKED)
+ .putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_SYSTEM),
+ )
runCurrent()
assertThat(userRepository.refreshUsersCallCount).isEqualTo(refreshUsersCallCount + 1)
@@ -696,12 +690,10 @@
userRepository.setSelectedUserInfo(userInfos[0])
val refreshUsersCallCount = userRepository.refreshUsersCallCount
- fakeBroadcastDispatcher.registeredReceivers.forEach {
- it.onReceive(
- context,
- Intent(Intent.ACTION_USER_UNLOCKED).putExtra(Intent.EXTRA_USER_HANDLE, 1337),
- )
- }
+ fakeBroadcastDispatcher.sendIntentToMatchingReceiversOnly(
+ context,
+ Intent(Intent.ACTION_USER_UNLOCKED).putExtra(Intent.EXTRA_USER_HANDLE, 1337),
+ )
assertThat(userRepository.refreshUsersCallCount).isEqualTo(refreshUsersCallCount)
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
index 5ca9362..a09af00 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
@@ -35,6 +35,7 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyList;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.atLeastOnce;
@@ -133,15 +134,19 @@
import com.android.wm.shell.bubbles.BubbleDataRepository;
import com.android.wm.shell.bubbles.BubbleEntry;
import com.android.wm.shell.bubbles.BubbleLogger;
+import com.android.wm.shell.bubbles.BubbleOverflow;
import com.android.wm.shell.bubbles.BubbleStackView;
import com.android.wm.shell.bubbles.BubbleViewInfoTask;
+import com.android.wm.shell.bubbles.BubbleViewProvider;
import com.android.wm.shell.bubbles.Bubbles;
import com.android.wm.shell.bubbles.StackEducationViewKt;
+import com.android.wm.shell.bubbles.properties.BubbleProperties;
import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.FloatingContentCoordinator;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.common.TaskStackListenerImpl;
+import com.android.wm.shell.common.bubbles.BubbleBarUpdate;
import com.android.wm.shell.draganddrop.DragAndDropController;
import com.android.wm.shell.onehanded.OneHandedController;
import com.android.wm.shell.sysui.ShellCommandHandler;
@@ -299,6 +304,8 @@
private UserHandle mUser0;
+ private FakeBubbleProperties mBubbleProperties;
+
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
@@ -360,6 +367,7 @@
mock(UserTracker.class)
);
when(mShellTaskOrganizer.getExecutor()).thenReturn(syncExecutor);
+ mBubbleProperties = new FakeBubbleProperties();
mBubbleController = new TestableBubbleController(
mContext,
mShellInit,
@@ -384,7 +392,8 @@
mock(Handler.class),
mTaskViewTransitions,
mock(SyncTransactionQueue.class),
- mock(IWindowManager.class));
+ mock(IWindowManager.class),
+ mBubbleProperties);
mBubbleController.setExpandListener(mBubbleExpandListener);
spyOn(mBubbleController);
@@ -475,7 +484,7 @@
public void testAddBubble() {
mBubbleController.updateBubble(mBubbleEntry);
assertTrue(mBubbleController.hasBubbles());
- assertSysuiStates(false /* stackExpanded */, false /* mangeMenuExpanded */);
+ assertSysuiStates(false /* stackExpanded */, false /* manageMenuExpanded */);
}
@Test
@@ -483,7 +492,7 @@
assertFalse(mBubbleController.hasBubbles());
mBubbleController.updateBubble(mBubbleEntry);
assertTrue(mBubbleController.hasBubbles());
- assertSysuiStates(false /* stackExpanded */, false /* mangeMenuExpanded */);
+ assertSysuiStates(false /* stackExpanded */, false /* manageMenuExpanded */);
}
@Test
@@ -498,7 +507,7 @@
assertNull(mBubbleData.getBubbleInStackWithKey(mRow.getKey()));
verify(mNotifCallback, times(2)).invalidateNotifications(anyString());
- assertSysuiStates(false /* stackExpanded */, false /* mangeMenuExpanded */);
+ assertSysuiStates(false /* stackExpanded */, false /* manageMenuExpanded */);
}
@Test
@@ -561,7 +570,7 @@
assertNull(mBubbleData.getBubbleInStackWithKey(mRow.getKey()));
assertNull(mBubbleData.getBubbleInStackWithKey(mRow2.getKey()));
- assertSysuiStates(false /* stackExpanded */, false /* mangeMenuExpanded */);
+ assertSysuiStates(false /* stackExpanded */, false /* manageMenuExpanded */);
}
@Test
@@ -580,7 +589,7 @@
mBubbleData.setExpanded(true);
assertStackExpanded();
verify(mBubbleExpandListener).onBubbleExpandChanged(true, mRow.getKey());
- assertSysuiStates(true /* stackExpanded */, false /* mangeMenuExpanded */);
+ assertSysuiStates(true /* stackExpanded */, false /* manageMenuExpanded */);
// Make sure the notif is suppressed
assertBubbleNotificationSuppressedFromShade(mBubbleEntry);
@@ -589,7 +598,7 @@
mBubbleController.collapseStack();
verify(mBubbleExpandListener).onBubbleExpandChanged(false, mRow.getKey());
assertStackCollapsed();
- assertSysuiStates(false /* stackExpanded */, false /* mangeMenuExpanded */);
+ assertSysuiStates(false /* stackExpanded */, false /* manageMenuExpanded */);
}
@Test
@@ -611,7 +620,7 @@
assertStackExpanded();
verify(mBubbleExpandListener, atLeastOnce()).onBubbleExpandChanged(
true, mRow2.getKey());
- assertSysuiStates(true /* stackExpanded */, false /* mangeMenuExpanded */);
+ assertSysuiStates(true /* stackExpanded */, false /* manageMenuExpanded */);
// Last added is the one that is expanded
assertEquals(mRow2.getKey(), mBubbleData.getSelectedBubble().getKey());
@@ -636,7 +645,7 @@
// Collapse
mBubbleController.collapseStack();
assertStackCollapsed();
- assertSysuiStates(false /* stackExpanded */, false /* mangeMenuExpanded */);
+ assertSysuiStates(false /* stackExpanded */, false /* manageMenuExpanded */);
}
@Test
@@ -656,7 +665,7 @@
mBubbleData.setExpanded(true);
assertStackExpanded();
verify(mBubbleExpandListener).onBubbleExpandChanged(true, mRow.getKey());
- assertSysuiStates(true /* stackExpanded */, false /* mangeMenuExpanded */);
+ assertSysuiStates(true /* stackExpanded */, false /* manageMenuExpanded */);
// Notif is suppressed after expansion
assertBubbleNotificationSuppressedFromShade(mBubbleEntry);
@@ -681,7 +690,7 @@
mBubbleData.setExpanded(true);
assertStackExpanded();
verify(mBubbleExpandListener).onBubbleExpandChanged(true, mRow.getKey());
- assertSysuiStates(true /* stackExpanded */, false /* mangeMenuExpanded */);
+ assertSysuiStates(true /* stackExpanded */, false /* manageMenuExpanded */);
// Notif is suppressed after expansion
assertBubbleNotificationSuppressedFromShade(mBubbleEntry);
@@ -710,7 +719,7 @@
BubbleStackView stackView = mBubbleController.getStackView();
mBubbleData.setExpanded(true);
- assertSysuiStates(true /* stackExpanded */, false /* mangeMenuExpanded */);
+ assertSysuiStates(true /* stackExpanded */, false /* manageMenuExpanded */);
assertStackExpanded();
verify(mBubbleExpandListener).onBubbleExpandChanged(true, mRow2.getKey());
@@ -741,7 +750,7 @@
// We should be collapsed
verify(mBubbleExpandListener).onBubbleExpandChanged(false, mRow.getKey());
assertFalse(mBubbleController.hasBubbles());
- assertSysuiStates(false /* stackExpanded */, false /* mangeMenuExpanded */);
+ assertSysuiStates(false /* stackExpanded */, false /* manageMenuExpanded */);
}
@Test
@@ -754,7 +763,7 @@
BubbleStackView stackView = mBubbleController.getStackView();
mBubbleData.setExpanded(true);
- assertSysuiStates(true /* stackExpanded */, false /* mangeMenuExpanded */);
+ assertSysuiStates(true /* stackExpanded */, false /* manageMenuExpanded */);
assertStackExpanded();
verify(mBubbleExpandListener).onBubbleExpandChanged(true, mRow.getKey());
@@ -769,7 +778,7 @@
// We should be collapsed
verify(mBubbleExpandListener).onBubbleExpandChanged(false, mRow.getKey());
assertFalse(mBubbleController.hasBubbles());
- assertSysuiStates(false /* stackExpanded */, false /* mangeMenuExpanded */);
+ assertSysuiStates(false /* stackExpanded */, false /* manageMenuExpanded */);
}
@@ -787,7 +796,7 @@
verify(mBubbleExpandListener, never()).onBubbleExpandChanged(false /* expanded */,
mRow.getKey());
assertStackCollapsed();
- assertSysuiStates(false /* stackExpanded */, false /* mangeMenuExpanded */);
+ assertSysuiStates(false /* stackExpanded */, false /* manageMenuExpanded */);
}
@Test
@@ -803,7 +812,7 @@
verify(mBubbleExpandListener).onBubbleExpandChanged(true /* expanded */,
mRow.getKey());
assertStackExpanded();
- assertSysuiStates(true /* stackExpanded */, false /* mangeMenuExpanded */);
+ assertSysuiStates(true /* stackExpanded */, false /* manageMenuExpanded */);
}
@Test
@@ -820,7 +829,7 @@
// Dot + flyout is hidden because notif is suppressed
assertFalse(mBubbleData.getBubbleInStackWithKey(mRow.getKey()).showDot());
assertFalse(mBubbleData.getBubbleInStackWithKey(mRow.getKey()).showFlyout());
- assertSysuiStates(false /* stackExpanded */, false /* mangeMenuExpanded */);
+ assertSysuiStates(false /* stackExpanded */, false /* manageMenuExpanded */);
}
@Test
@@ -842,7 +851,7 @@
// Dot + flyout is hidden because notif is suppressed
assertFalse(mBubbleData.getBubbleInStackWithKey(mRow.getKey()).showDot());
assertFalse(mBubbleData.getBubbleInStackWithKey(mRow.getKey()).showFlyout());
- assertSysuiStates(false /* stackExpanded */, false /* mangeMenuExpanded */);
+ assertSysuiStates(false /* stackExpanded */, false /* manageMenuExpanded */);
}
@Test
@@ -1123,7 +1132,7 @@
assertThat(mBubbleData.getOverflowBubbleWithKey(mBubbleEntry2User11.getKey())).isNotNull();
// Would have loaded bubbles twice because of user switch
- verify(mDataRepository, times(2)).loadBubbles(anyInt(), any());
+ verify(mDataRepository, times(2)).loadBubbles(anyInt(), anyList(), any());
}
@Test
@@ -1179,7 +1188,7 @@
mEntryListener.onEntryRemoved(mRow2, REASON_APP_CANCEL);
assertThat(mBubbleData.getOverflowBubbles()).isEmpty();
- verify(mDataRepository, times(1)).loadBubbles(anyInt(), any());
+ verify(mDataRepository, times(1)).loadBubbles(anyInt(), anyList(), any());
}
/**
@@ -1247,11 +1256,11 @@
BubbleStackView stackView = mBubbleController.getStackView();
mBubbleData.setExpanded(true);
assertStackExpanded();
- assertSysuiStates(true /* stackExpanded */, false /* mangeMenuExpanded */);
+ assertSysuiStates(true /* stackExpanded */, false /* manageMenuExpanded */);
// Show the menu
stackView.showManageMenu(true);
- assertSysuiStates(true /* stackExpanded */, true /* mangeMenuExpanded */);
+ assertSysuiStates(true /* stackExpanded */, true /* manageMenuExpanded */);
assertTrue(stackView.isManageMenuSettingsVisible());
assertTrue(stackView.isManageMenuDontBubbleVisible());
}
@@ -1265,11 +1274,11 @@
BubbleStackView stackView = mBubbleController.getStackView();
mBubbleData.setExpanded(true);
assertStackExpanded();
- assertSysuiStates(true /* stackExpanded */, false /* mangeMenuExpanded */);
+ assertSysuiStates(true /* stackExpanded */, false /* manageMenuExpanded */);
// Show the menu
stackView.showManageMenu(true);
- assertSysuiStates(true /* stackExpanded */, true /* mangeMenuExpanded */);
+ assertSysuiStates(true /* stackExpanded */, true /* manageMenuExpanded */);
assertFalse(stackView.isManageMenuSettingsVisible());
assertFalse(stackView.isManageMenuDontBubbleVisible());
}
@@ -1283,15 +1292,15 @@
BubbleStackView stackView = mBubbleController.getStackView();
mBubbleData.setExpanded(true);
assertStackExpanded();
- assertSysuiStates(true /* stackExpanded */, false /* mangeMenuExpanded */);
+ assertSysuiStates(true /* stackExpanded */, false /* manageMenuExpanded */);
// Show the menu
stackView.showManageMenu(true);
- assertSysuiStates(true /* stackExpanded */, true /* mangeMenuExpanded */);
+ assertSysuiStates(true /* stackExpanded */, true /* manageMenuExpanded */);
// Hide the menu
stackView.showManageMenu(false);
- assertSysuiStates(true /* stackExpanded */, false /* mangeMenuExpanded */);
+ assertSysuiStates(true /* stackExpanded */, false /* manageMenuExpanded */);
}
@Test
@@ -1303,16 +1312,16 @@
BubbleStackView stackView = mBubbleController.getStackView();
mBubbleData.setExpanded(true);
assertStackExpanded();
- assertSysuiStates(true /* stackExpanded */, false /* mangeMenuExpanded */);
+ assertSysuiStates(true /* stackExpanded */, false /* manageMenuExpanded */);
// Show the menu
stackView.showManageMenu(true);
- assertSysuiStates(true /* stackExpanded */, true /* mangeMenuExpanded */);
+ assertSysuiStates(true /* stackExpanded */, true /* manageMenuExpanded */);
// Collapse the stack
mBubbleData.setExpanded(false);
- assertSysuiStates(false /* stackExpanded */, false /* mangeMenuExpanded */);
+ assertSysuiStates(false /* stackExpanded */, false /* manageMenuExpanded */);
}
@Test
@@ -1574,7 +1583,7 @@
NotificationListenerService.RankingMap rankingMap =
mock(NotificationListenerService.RankingMap.class);
- when(rankingMap.getOrderedKeys()).thenReturn(new String[] { mBubbleEntry.getKey() });
+ when(rankingMap.getOrderedKeys()).thenReturn(new String[]{mBubbleEntry.getKey()});
mBubbleController.onRankingUpdated(rankingMap, entryDataByKey);
// Should no longer be in the stack
@@ -1882,7 +1891,111 @@
);
}
- /** Creates a bubble using the userId and package. */
+ @Test
+ public void registerBubbleBarListener_barDisabled_largeScreen_shouldBeIgnored() {
+ mBubbleProperties.mIsBubbleBarEnabled = false;
+ mPositioner.setIsLargeScreen(true);
+ mEntryListener.onEntryAdded(mRow);
+ mBubbleController.updateBubble(mBubbleEntry);
+ assertTrue(mBubbleController.hasBubbles());
+
+ assertStackMode();
+
+ FakeBubbleStateListener bubbleStateListener = new FakeBubbleStateListener();
+ mBubbleController.registerBubbleStateListener(bubbleStateListener);
+
+ assertStackMode();
+
+ assertThat(mBubbleController.getStackView().getBubbleCount()).isEqualTo(1);
+ }
+
+ @Test
+ public void registerBubbleBarListener_barEnabled_smallScreen_shouldBeIgnored() {
+ mBubbleProperties.mIsBubbleBarEnabled = true;
+ mPositioner.setIsLargeScreen(false);
+ mEntryListener.onEntryAdded(mRow);
+ mBubbleController.updateBubble(mBubbleEntry);
+ assertTrue(mBubbleController.hasBubbles());
+
+ assertStackMode();
+
+ FakeBubbleStateListener bubbleStateListener = new FakeBubbleStateListener();
+ mBubbleController.registerBubbleStateListener(bubbleStateListener);
+
+ assertStackMode();
+
+ assertThat(mBubbleController.getStackView().getBubbleCount()).isEqualTo(1);
+ }
+
+ @Test
+ public void registerBubbleBarListener_switchToBarAndBackToStack() {
+ mBubbleProperties.mIsBubbleBarEnabled = true;
+ mPositioner.setIsLargeScreen(true);
+ mEntryListener.onEntryAdded(mRow);
+ mBubbleController.updateBubble(mBubbleEntry);
+ assertTrue(mBubbleController.hasBubbles());
+
+ assertStackMode();
+
+ assertThat(mBubbleData.getBubbles()).hasSize(1);
+ assertBubbleIsInflatedForStack(mBubbleData.getBubbles().get(0));
+ assertBubbleIsInflatedForStack(mBubbleData.getOverflow());
+
+ FakeBubbleStateListener bubbleStateListener = new FakeBubbleStateListener();
+ mBubbleController.registerBubbleStateListener(bubbleStateListener);
+
+ assertBarMode();
+
+ assertThat(mBubbleData.getBubbles()).hasSize(1);
+ assertBubbleIsInflatedForBar(mBubbleData.getBubbles().get(0));
+ assertBubbleIsInflatedForBar(mBubbleData.getOverflow());
+
+ mBubbleController.unregisterBubbleStateListener();
+
+ assertStackMode();
+
+ assertThat(mBubbleData.getBubbles()).hasSize(1);
+ assertBubbleIsInflatedForStack(mBubbleData.getBubbles().get(0));
+ assertBubbleIsInflatedForStack(mBubbleData.getOverflow());
+ }
+
+ @Test
+ public void switchBetweenBarAndStack_noBubbles_shouldBeIgnored() {
+ mBubbleProperties.mIsBubbleBarEnabled = false;
+ mPositioner.setIsLargeScreen(true);
+ assertFalse(mBubbleController.hasBubbles());
+
+ assertNoBubbleContainerViews();
+
+ FakeBubbleStateListener bubbleStateListener = new FakeBubbleStateListener();
+ mBubbleController.registerBubbleStateListener(bubbleStateListener);
+
+ assertNoBubbleContainerViews();
+
+ mBubbleController.unregisterBubbleStateListener();
+
+ assertNoBubbleContainerViews();
+ }
+
+ @Test
+ public void bubbleBarBubbleExpandedAndCollapsed() {
+ mBubbleProperties.mIsBubbleBarEnabled = true;
+ mPositioner.setIsLargeScreen(true);
+ mEntryListener.onEntryAdded(mRow);
+ mBubbleController.updateBubble(mBubbleEntry);
+
+ FakeBubbleStateListener bubbleStateListener = new FakeBubbleStateListener();
+ mBubbleController.registerBubbleStateListener(bubbleStateListener);
+ mBubbleController.expandStackAndSelectBubbleFromLauncher(mBubbleEntry.getKey(), true);
+
+ assertThat(mBubbleController.getLayerView().isExpanded()).isTrue();
+
+ mBubbleController.collapseStack();
+
+ assertThat(mBubbleController.getLayerView().isExpanded()).isFalse();
+ }
+
+ /** Creates a bubble using the userId and package. */
private Bubble createBubble(int userId, String pkg) {
final UserHandle userHandle = new UserHandle(userId);
NotificationEntry workEntry = new NotificationEntryBuilder()
@@ -1998,6 +2111,44 @@
assertFalse(mBubbleController.getImplCachedState().isStackExpanded());
}
+ /** Asserts that both the bubble stack and bar views don't exist. */
+ private void assertNoBubbleContainerViews() {
+ assertThat(mBubbleController.getStackView()).isNull();
+ assertThat(mBubbleController.getLayerView()).isNull();
+ }
+
+ /** Asserts that the stack is created and the bar is null. */
+ private void assertStackMode() {
+ assertThat(mBubbleController.getStackView()).isNotNull();
+ assertThat(mBubbleController.getLayerView()).isNull();
+ }
+
+ /** Asserts that the given bubble has the stack expanded view inflated. */
+ private void assertBubbleIsInflatedForStack(BubbleViewProvider b) {
+ assertThat(b.getIconView()).isNotNull();
+ assertThat(b.getExpandedView()).isNotNull();
+ assertThat(b.getBubbleBarExpandedView()).isNull();
+ }
+
+ /** Asserts that the bar is created and the stack is null. */
+ private void assertBarMode() {
+ assertThat(mBubbleController.getStackView()).isNull();
+ assertThat(mBubbleController.getLayerView()).isNotNull();
+ }
+
+ /** Asserts that the given bubble has the bar expanded view inflated. */
+ private void assertBubbleIsInflatedForBar(BubbleViewProvider b) {
+ // the icon view should be inflated for the overflow but not for other bubbles when showing
+ // in the bar
+ if (b instanceof Bubble) {
+ assertThat(b.getIconView()).isNull();
+ } else if (b instanceof BubbleOverflow) {
+ assertThat(b.getIconView()).isNotNull();
+ }
+ assertThat(b.getExpandedView()).isNull();
+ assertThat(b.getBubbleBarExpandedView()).isNotNull();
+ }
+
/**
* Asserts that a bubble notification is suppressed from the shade and also validates the cached
* state is updated.
@@ -2027,4 +2178,19 @@
assertThat(mSysUiStateBubblesExpanded).isEqualTo(stackExpanded);
assertThat(mSysUiStateBubblesManageMenuExpanded).isEqualTo(manageMenuExpanded);
}
+
+ private static class FakeBubbleStateListener implements Bubbles.BubbleStateListener {
+ @Override
+ public void onBubbleStateChange(BubbleBarUpdate update) {
+ }
+ }
+
+ private static class FakeBubbleProperties implements BubbleProperties {
+ boolean mIsBubbleBarEnabled = false;
+
+ @Override
+ public boolean isBubbleBarEnabled() {
+ return mIsBubbleBarEnabled;
+ }
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/TestableBubbleController.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/TestableBubbleController.java
index 14c3f3c..5855347 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/TestableBubbleController.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/TestableBubbleController.java
@@ -31,6 +31,7 @@
import com.android.wm.shell.bubbles.BubbleDataRepository;
import com.android.wm.shell.bubbles.BubbleLogger;
import com.android.wm.shell.bubbles.BubblePositioner;
+import com.android.wm.shell.bubbles.properties.BubbleProperties;
import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.FloatingContentCoordinator;
import com.android.wm.shell.common.ShellExecutor;
@@ -74,13 +75,14 @@
Handler shellMainHandler,
TaskViewTransitions taskViewTransitions,
SyncTransactionQueue syncQueue,
- IWindowManager wmService) {
+ IWindowManager wmService,
+ BubbleProperties bubbleProperties) {
super(context, shellInit, shellCommandHandler, shellController, data, Runnable::run,
floatingContentCoordinator, dataRepository, statusBarService, windowManager,
windowManagerShellWrapper, userManager, launcherApps, bubbleLogger,
taskStackListener, shellTaskOrganizer, positioner, displayController,
oneHandedOptional, dragAndDropController, shellMainExecutor, shellMainHandler,
- new SyncExecutor(), taskViewTransitions, syncQueue, wmService);
+ new SyncExecutor(), taskViewTransitions, syncQueue, wmService, bubbleProperties);
setInflateSynchronously(true);
onInit();
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/TestableBubblePositioner.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/TestableBubblePositioner.java
index 6edc373..047dc65 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/TestableBubblePositioner.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/TestableBubblePositioner.java
@@ -27,6 +27,7 @@
public class TestableBubblePositioner extends BubblePositioner {
private int mMaxBubbles;
+ private boolean mIsLargeScreen = false;
public TestableBubblePositioner(Context context,
WindowManager windowManager) {
@@ -46,4 +47,13 @@
public int getMaxBubbles() {
return mMaxBubbles;
}
+
+ public void setIsLargeScreen(boolean isLargeScreen) {
+ mIsLargeScreen = isLargeScreen;
+ }
+
+ @Override
+ public boolean isLargeScreen() {
+ return mIsLargeScreen;
+ }
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/broadcast/FakeBroadcastDispatcher.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/broadcast/FakeBroadcastDispatcher.kt
index af940e4..21a5eb7 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/broadcast/FakeBroadcastDispatcher.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/broadcast/FakeBroadcastDispatcher.kt
@@ -18,6 +18,7 @@
import android.content.BroadcastReceiver
import android.content.Context
+import android.content.Intent
import android.content.IntentFilter
import android.os.Handler
import android.os.Looper
@@ -31,6 +32,14 @@
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.Executor
+/**
+ * A fake instance of [BroadcastDispatcher] for tests.
+ *
+ * Important: The *real* broadcast dispatcher will only send intents to receivers if the intent
+ * matches the [IntentFilter] that the [BroadcastReceiver] was registered with. This fake class
+ * exposes [sendIntentToMatchingReceiversOnly] to get the same matching behavior as the real
+ * broadcast dispatcher.
+ */
class FakeBroadcastDispatcher(
context: SysuiTestableContext,
mainExecutor: Executor,
@@ -52,7 +61,7 @@
PendingRemovalStore(logger)
) {
- val registeredReceivers: MutableSet<BroadcastReceiver> = ConcurrentHashMap.newKeySet()
+ private val receivers: MutableSet<InternalReceiver> = ConcurrentHashMap.newKeySet()
override fun registerReceiverWithHandler(
receiver: BroadcastReceiver,
@@ -62,7 +71,7 @@
@Context.RegisterReceiverFlags flags: Int,
permission: String?
) {
- registeredReceivers.add(receiver)
+ receivers.add(InternalReceiver(receiver, filter))
}
override fun registerReceiver(
@@ -73,24 +82,52 @@
@Context.RegisterReceiverFlags flags: Int,
permission: String?
) {
- registeredReceivers.add(receiver)
+ receivers.add(InternalReceiver(receiver, filter))
}
override fun unregisterReceiver(receiver: BroadcastReceiver) {
- registeredReceivers.remove(receiver)
+ receivers.removeIf { it.receiver == receiver }
}
override fun unregisterReceiverForUser(receiver: BroadcastReceiver, user: UserHandle) {
- registeredReceivers.remove(receiver)
+ receivers.removeIf { it.receiver == receiver }
}
- fun cleanUpReceivers(testName: String) {
- registeredReceivers.forEach {
- Log.i(testName, "Receiver not unregistered from dispatcher: $it")
- if (shouldFailOnLeakedReceiver) {
- throw IllegalStateException("Receiver not unregistered from dispatcher: $it")
+ /**
+ * Sends the given [intent] to *only* the receivers that were registered with an [IntentFilter]
+ * that matches the intent.
+ */
+ fun sendIntentToMatchingReceiversOnly(context: Context, intent: Intent) {
+ receivers.forEach {
+ if (
+ it.filter.match(
+ context.contentResolver,
+ intent,
+ /* resolve= */ false,
+ /* logTag= */ "FakeBroadcastDispatcher",
+ ) > 0
+ ) {
+ it.receiver.onReceive(context, intent)
}
}
- registeredReceivers.clear()
}
+
+ val numReceiversRegistered: Int
+ get() = receivers.size
+
+ fun cleanUpReceivers(testName: String) {
+ receivers.forEach {
+ val receiver = it.receiver
+ Log.i(testName, "Receiver not unregistered from dispatcher: $receiver")
+ if (shouldFailOnLeakedReceiver) {
+ throw IllegalStateException("Receiver not unregistered from dispatcher: $receiver")
+ }
+ }
+ receivers.clear()
+ }
+
+ private data class InternalReceiver(
+ val receiver: BroadcastReceiver,
+ val filter: IntentFilter,
+ )
}
diff --git a/packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperBackupAgent.java b/packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperBackupAgent.java
index 308e2cf..3406102 100644
--- a/packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperBackupAgent.java
+++ b/packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperBackupAgent.java
@@ -359,11 +359,7 @@
final File infoStage = new File(filesDir, WALLPAPER_INFO_STAGE);
final File imageStage = new File(filesDir, SYSTEM_WALLPAPER_STAGE);
final File lockImageStage = new File(filesDir, LOCK_WALLPAPER_STAGE);
-
- // If we restored separate lock imagery, the system wallpaper should be
- // applied as system-only; but if there's no separate lock image, make
- // sure to apply the restored system wallpaper as both.
- final int sysWhich = FLAG_SYSTEM | (lockImageStage.exists() ? 0 : FLAG_LOCK);
+ boolean lockImageStageExists = lockImageStage.exists();
try {
// First parse the live component name so that we know for logging if we care about
@@ -371,14 +367,31 @@
ComponentName wpService = parseWallpaperComponent(infoStage, "wp");
mSystemHasLiveComponent = wpService != null;
+ ComponentName kwpService = null;
+ boolean lockscreenLiveWallpaper = mWallpaperManager.isLockscreenLiveWallpaperEnabled();
+ if (lockscreenLiveWallpaper) {
+ kwpService = parseWallpaperComponent(infoStage, "kwp");
+ }
+ mLockHasLiveComponent = kwpService != null;
+ boolean separateLockWallpaper = mLockHasLiveComponent || lockImageStage.exists();
+
+ // if there's no separate lock wallpaper, apply the system wallpaper to both screens.
+ final int sysWhich = separateLockWallpaper ? FLAG_SYSTEM : FLAG_SYSTEM | FLAG_LOCK;
+
// It is valid for the imagery to be absent; it means that we were not permitted
// to back up the original image on the source device, or there was no user-supplied
// wallpaper image present.
- restoreFromStage(imageStage, infoStage, "wp", sysWhich);
- restoreFromStage(lockImageStage, infoStage, "kwp", FLAG_LOCK);
+ if (!lockscreenLiveWallpaper) restoreFromStage(imageStage, infoStage, "wp", sysWhich);
+ if (lockImageStageExists) {
+ restoreFromStage(lockImageStage, infoStage, "kwp", FLAG_LOCK);
+ }
+ if (lockscreenLiveWallpaper) restoreFromStage(imageStage, infoStage, "wp", sysWhich);
// And reset to the wallpaper service we should be using
- updateWallpaperComponent(wpService, !lockImageStage.exists());
+ if (lockscreenLiveWallpaper && mLockHasLiveComponent) {
+ updateWallpaperComponent(kwpService, false, FLAG_LOCK);
+ }
+ updateWallpaperComponent(wpService, !lockImageStageExists, sysWhich);
} catch (Exception e) {
Slog.e(TAG, "Unable to restore wallpaper: " + e.getMessage());
mEventLogger.onRestoreException(e);
@@ -397,9 +410,21 @@
}
@VisibleForTesting
- void updateWallpaperComponent(ComponentName wpService, boolean applyToLock) throws IOException {
+ void updateWallpaperComponent(ComponentName wpService, boolean applyToLock, int which)
+ throws IOException {
+ boolean lockscreenLiveWallpaper = mWallpaperManager.isLockscreenLiveWallpaperEnabled();
if (servicePackageExists(wpService)) {
Slog.i(TAG, "Using wallpaper service " + wpService);
+ if (lockscreenLiveWallpaper) {
+ mWallpaperManager.setWallpaperComponentWithFlags(wpService, which);
+ if ((which & FLAG_LOCK) != 0) {
+ mEventLogger.onLockLiveWallpaperRestored(wpService);
+ }
+ if ((which & FLAG_SYSTEM) != 0) {
+ mEventLogger.onSystemLiveWallpaperRestored(wpService);
+ }
+ return;
+ }
mWallpaperManager.setWallpaperComponent(wpService);
if (applyToLock) {
// We have a live wallpaper and no static lock image,
@@ -414,7 +439,7 @@
// in reports from users
if (wpService != null) {
// TODO(b/268471749): Handle delayed case
- applyComponentAtInstall(wpService, applyToLock);
+ applyComponentAtInstall(wpService, applyToLock, which);
Slog.w(TAG, "Wallpaper service " + wpService + " isn't available. "
+ " Will try to apply later");
}
@@ -437,7 +462,8 @@
// And log the success
if ((which & FLAG_SYSTEM) > 0) {
mEventLogger.onSystemImageWallpaperRestored();
- } else {
+ }
+ if ((which & FLAG_LOCK) > 0) {
mEventLogger.onLockImageWallpaperRestored();
}
}
@@ -460,7 +486,8 @@
private void logRestoreError(int which, String error) {
if ((which & FLAG_SYSTEM) == FLAG_SYSTEM) {
mEventLogger.onSystemImageWallpaperRestoreFailed(error);
- } else if ((which & FLAG_LOCK) == FLAG_LOCK) {
+ }
+ if ((which & FLAG_LOCK) == FLAG_LOCK) {
mEventLogger.onLockImageWallpaperRestoreFailed(error);
}
}
@@ -552,16 +579,21 @@
// Intentionally blank
}
- private void applyComponentAtInstall(ComponentName componentName, boolean applyToLock) {
- PackageMonitor packageMonitor = getWallpaperPackageMonitor(componentName, applyToLock);
+ private void applyComponentAtInstall(ComponentName componentName, boolean applyToLock,
+ int which) {
+ PackageMonitor packageMonitor = getWallpaperPackageMonitor(
+ componentName, applyToLock, which);
packageMonitor.register(getBaseContext(), null, UserHandle.ALL, true);
}
@VisibleForTesting
- PackageMonitor getWallpaperPackageMonitor(ComponentName componentName, boolean applyToLock) {
+ PackageMonitor getWallpaperPackageMonitor(ComponentName componentName, boolean applyToLock,
+ int which) {
return new PackageMonitor() {
@Override
public void onPackageAdded(String packageName, int uid) {
+ boolean lockscreenLiveWallpaper =
+ mWallpaperManager.isLockscreenLiveWallpaperEnabled();
if (!isDeviceInRestore()) {
// We don't want to reapply the wallpaper outside a restore.
unregister();
@@ -582,16 +614,29 @@
if (componentName.getPackageName().equals(packageName)) {
Slog.d(TAG, "Applying component " + componentName);
- boolean sysResult = mWallpaperManager.setWallpaperComponent(componentName);
+ boolean success = lockscreenLiveWallpaper
+ ? mWallpaperManager.setWallpaperComponentWithFlags(componentName, which)
+ : mWallpaperManager.setWallpaperComponent(componentName);
WallpaperEventLogger logger = new WallpaperEventLogger(
mBackupManager.getDelayedRestoreLogger());
- if (sysResult) {
- logger.onSystemLiveWallpaperRestored(componentName);
+ if (success) {
+ if (!lockscreenLiveWallpaper || (which & FLAG_SYSTEM) != 0) {
+ logger.onSystemLiveWallpaperRestored(componentName);
+ }
+ if (lockscreenLiveWallpaper && (which & FLAG_LOCK) != 0) {
+ logger.onLockLiveWallpaperRestored(componentName);
+ }
} else {
- logger.onSystemLiveWallpaperRestoreFailed(
- WallpaperEventLogger.ERROR_SET_COMPONENT_EXCEPTION);
+ if (!lockscreenLiveWallpaper || (which & FLAG_SYSTEM) != 0) {
+ logger.onSystemLiveWallpaperRestoreFailed(
+ WallpaperEventLogger.ERROR_SET_COMPONENT_EXCEPTION);
+ }
+ if (lockscreenLiveWallpaper && (which & FLAG_LOCK) != 0) {
+ logger.onLockLiveWallpaperRestoreFailed(
+ WallpaperEventLogger.ERROR_SET_COMPONENT_EXCEPTION);
+ }
}
- if (applyToLock) {
+ if (applyToLock && !lockscreenLiveWallpaper) {
try {
mWallpaperManager.clear(FLAG_LOCK);
logger.onLockLiveWallpaperRestored(componentName);
diff --git a/packages/WallpaperBackup/test/src/com/android/wallpaperbackup/WallpaperBackupAgentTest.java b/packages/WallpaperBackup/test/src/com/android/wallpaperbackup/WallpaperBackupAgentTest.java
index 9b07ad4..dc1126e 100644
--- a/packages/WallpaperBackup/test/src/com/android/wallpaperbackup/WallpaperBackupAgentTest.java
+++ b/packages/WallpaperBackup/test/src/com/android/wallpaperbackup/WallpaperBackupAgentTest.java
@@ -117,6 +117,7 @@
public void setUp() {
MockitoAnnotations.initMocks(this);
+ when(mWallpaperManager.isLockscreenLiveWallpaperEnabled()).thenReturn(true);
when(mWallpaperManager.isWallpaperBackupEligible(eq(FLAG_SYSTEM))).thenReturn(true);
when(mWallpaperManager.isWallpaperBackupEligible(eq(FLAG_LOCK))).thenReturn(true);
@@ -364,14 +365,23 @@
mWallpaperBackupAgent.mIsDeviceInRestore = true;
mWallpaperBackupAgent.updateWallpaperComponent(mWallpaperComponent,
- /* applyToLock */ true);
+ /* applyToLock */ true, FLAG_LOCK | FLAG_SYSTEM);
// Imitate wallpaper component installation.
mWallpaperBackupAgent.mWallpaperPackageMonitor.onPackageAdded(TEST_WALLPAPER_PACKAGE,
/* uid */0);
-
- verify(mWallpaperManager, times(1)).setWallpaperComponent(mWallpaperComponent);
- verify(mWallpaperManager, times(1)).clear(eq(FLAG_LOCK));
+ if (mWallpaperManager.isLockscreenLiveWallpaperEnabled()) {
+ verify(mWallpaperManager, times(1))
+ .setWallpaperComponentWithFlags(mWallpaperComponent, FLAG_LOCK | FLAG_SYSTEM);
+ verify(mWallpaperManager, never())
+ .setWallpaperComponentWithFlags(mWallpaperComponent, FLAG_SYSTEM);
+ verify(mWallpaperManager, never())
+ .setWallpaperComponentWithFlags(mWallpaperComponent, FLAG_LOCK);
+ verify(mWallpaperManager, never()).clear(anyInt());
+ } else {
+ verify(mWallpaperManager, times(1)).setWallpaperComponent(mWallpaperComponent);
+ verify(mWallpaperManager, times(1)).clear(eq(FLAG_LOCK));
+ }
}
@Test
@@ -380,14 +390,24 @@
mWallpaperBackupAgent.mIsDeviceInRestore = true;
mWallpaperBackupAgent.updateWallpaperComponent(mWallpaperComponent,
- /* applyToLock */ false);
+ /* applyToLock */ false, FLAG_SYSTEM);
// Imitate wallpaper component installation.
mWallpaperBackupAgent.mWallpaperPackageMonitor.onPackageAdded(TEST_WALLPAPER_PACKAGE,
/* uid */0);
- verify(mWallpaperManager, times(1)).setWallpaperComponent(mWallpaperComponent);
- verify(mWallpaperManager, never()).clear(eq(FLAG_LOCK));
+ if (mWallpaperManager.isLockscreenLiveWallpaperEnabled()) {
+ verify(mWallpaperManager, times(1))
+ .setWallpaperComponentWithFlags(mWallpaperComponent, FLAG_SYSTEM);
+ verify(mWallpaperManager, never())
+ .setWallpaperComponentWithFlags(mWallpaperComponent, FLAG_LOCK);
+ verify(mWallpaperManager, never())
+ .setWallpaperComponentWithFlags(mWallpaperComponent, FLAG_LOCK | FLAG_SYSTEM);
+ verify(mWallpaperManager, never()).clear(anyInt());
+ } else {
+ verify(mWallpaperManager, times(1)).setWallpaperComponent(mWallpaperComponent);
+ verify(mWallpaperManager, never()).clear(eq(FLAG_LOCK));
+ }
}
@Test
@@ -396,7 +416,7 @@
mWallpaperBackupAgent.mIsDeviceInRestore = false;
mWallpaperBackupAgent.updateWallpaperComponent(mWallpaperComponent,
- /* applyToLock */ true);
+ /* applyToLock */ true, FLAG_LOCK | FLAG_SYSTEM);
// Imitate wallpaper component installation.
mWallpaperBackupAgent.mWallpaperPackageMonitor.onPackageAdded(TEST_WALLPAPER_PACKAGE,
@@ -412,7 +432,7 @@
mWallpaperBackupAgent.mIsDeviceInRestore = false;
mWallpaperBackupAgent.updateWallpaperComponent(mWallpaperComponent,
- /* applyToLock */ true);
+ /* applyToLock */ true, FLAG_LOCK | FLAG_SYSTEM);
// Imitate "wrong" wallpaper component installation.
mWallpaperBackupAgent.mWallpaperPackageMonitor.onPackageAdded(/* packageName */"",
@@ -614,6 +634,13 @@
mWallpaperBackupAgent.getBackupRestoreEventLogger().getLoggingResults());
assertThat(result).isNotNull();
assertThat(result.getSuccessCount()).isEqualTo(1);
+
+ if (mWallpaperManager.isLockscreenLiveWallpaperEnabled()) {
+ result = getLoggingResult(WALLPAPER_IMG_LOCK,
+ mWallpaperBackupAgent.getBackupRestoreEventLogger().getLoggingResults());
+ assertThat(result).isNotNull();
+ assertThat(result.getSuccessCount()).isEqualTo(1);
+ }
}
@Test
@@ -649,19 +676,20 @@
}
@Test
- public void testOnRestore_lockWallpaperImgMissingAndNoLive_logsFailure() throws Exception {
+ public void testOnRestore_wallpaperImgMissingAndNoLive_logsFailure() throws Exception {
mockStagedWallpaperFile(WALLPAPER_INFO_STAGE);
- mockStagedWallpaperFile(SYSTEM_WALLPAPER_STAGE);
mWallpaperBackupAgent.onCreate(USER_HANDLE, BackupAnnotations.BackupDestination.CLOUD,
BackupAnnotations.OperationType.RESTORE);
mWallpaperBackupAgent.onRestoreFinished();
- DataTypeResult result = getLoggingResult(WALLPAPER_IMG_LOCK,
- mWallpaperBackupAgent.getBackupRestoreEventLogger().getLoggingResults());
- assertThat(result).isNotNull();
- assertThat(result.getFailCount()).isEqualTo(1);
- assertThat(result.getErrors()).containsKey(ERROR_NO_WALLPAPER);
+ for (String wallpaper: List.of(WALLPAPER_IMG_LOCK, WALLPAPER_IMG_SYSTEM)) {
+ DataTypeResult result = getLoggingResult(wallpaper,
+ mWallpaperBackupAgent.getBackupRestoreEventLogger().getLoggingResults());
+ assertThat(result).isNotNull();
+ assertThat(result.getFailCount()).isEqualTo(1);
+ assertThat(result.getErrors()).containsKey(ERROR_NO_WALLPAPER);
+ }
}
@Test
@@ -722,13 +750,15 @@
public void testUpdateWallpaperComponent_delayedRestore_logsSuccess() throws Exception {
mWallpaperBackupAgent.mIsDeviceInRestore = true;
when(mWallpaperManager.setWallpaperComponent(any())).thenReturn(true);
+ when(mWallpaperManager.setWallpaperComponentWithFlags(any(), eq(FLAG_LOCK | FLAG_SYSTEM)))
+ .thenReturn(true);
BackupRestoreEventLogger logger = new BackupRestoreEventLogger(
BackupAnnotations.OperationType.RESTORE);
when(mBackupManager.getDelayedRestoreLogger()).thenReturn(logger);
mWallpaperBackupAgent.setBackupManagerForTesting(mBackupManager);
mWallpaperBackupAgent.updateWallpaperComponent(mWallpaperComponent,
- /* applyToLock */ true);
+ /* applyToLock */ true, FLAG_LOCK | FLAG_SYSTEM);
// Imitate wallpaper component installation.
mWallpaperBackupAgent.mWallpaperPackageMonitor.onPackageAdded(TEST_WALLPAPER_PACKAGE,
/* uid */0);
@@ -752,7 +782,7 @@
mWallpaperBackupAgent.setBackupManagerForTesting(mBackupManager);
mWallpaperBackupAgent.updateWallpaperComponent(mWallpaperComponent,
- /* applyToLock */ true);
+ /* applyToLock */ true, FLAG_LOCK | FLAG_SYSTEM);
// Imitate wallpaper component installation.
mWallpaperBackupAgent.mWallpaperPackageMonitor.onPackageAdded(TEST_WALLPAPER_PACKAGE,
/* uid */0);
@@ -774,7 +804,7 @@
mWallpaperBackupAgent.setBackupManagerForTesting(mBackupManager);
mWallpaperBackupAgent.updateWallpaperComponent(mWallpaperComponent,
- /* applyToLock */ true);
+ /* applyToLock */ true, FLAG_LOCK | FLAG_SYSTEM);
// Imitate wallpaper component installation.
mWallpaperBackupAgent.mWallpaperPackageMonitor.onPackageAdded(TEST_WALLPAPER_PACKAGE,
@@ -909,8 +939,9 @@
@Override
PackageMonitor getWallpaperPackageMonitor(ComponentName componentName,
- boolean applyToLock) {
- mWallpaperPackageMonitor = super.getWallpaperPackageMonitor(componentName, applyToLock);
+ boolean applyToLock, int which) {
+ mWallpaperPackageMonitor = super.getWallpaperPackageMonitor(
+ componentName, applyToLock, which);
return mWallpaperPackageMonitor;
}
diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
index 2d60716..819f8a1 100644
--- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
+++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
@@ -158,7 +158,6 @@
private static final String TAG = "AppWidgetServiceImpl";
private static final boolean DEBUG = false;
- static final boolean DEBUG_PROVIDER_INFO_CACHE = true;
private static final String OLD_KEYGUARD_HOST_PACKAGE = "android";
private static final String NEW_KEYGUARD_HOST_PACKAGE = "com.android.keyguard";
@@ -255,7 +254,6 @@
private boolean mSafeMode;
private int mMaxWidgetBitmapMemory;
- private boolean mIsProviderInfoPersisted;
private boolean mIsCombinedBroadcastEnabled;
// Mark widget lifecycle broadcasts as 'interactive'
@@ -281,14 +279,8 @@
mCallbackHandler = new CallbackHandler(serviceThread.getLooper());
mBackupRestoreController = new BackupRestoreController();
mSecurityPolicy = new SecurityPolicy();
- mIsProviderInfoPersisted = !ActivityManager.isLowRamDeviceStatic()
- && DeviceConfig.getBoolean(NAMESPACE_SYSTEMUI,
- SystemUiDeviceConfigFlags.PERSISTS_WIDGET_PROVIDER_INFO, true);
mIsCombinedBroadcastEnabled = DeviceConfig.getBoolean(NAMESPACE_SYSTEMUI,
SystemUiDeviceConfigFlags.COMBINED_BROADCAST_ENABLED, true);
- if (DEBUG_PROVIDER_INFO_CACHE && !mIsProviderInfoPersisted) {
- Slog.d(TAG, "App widget provider info will not be persisted on this device");
- }
BroadcastOptions opts = BroadcastOptions.makeBasic();
opts.setBackgroundActivityStartsAllowed(false);
@@ -2528,21 +2520,7 @@
}
}
- private static void serializeProvider(
- @NonNull final TypedXmlSerializer out, @NonNull final Provider p) throws IOException {
- Objects.requireNonNull(out);
- Objects.requireNonNull(p);
- serializeProviderInner(out, p, false /* persistsProviderInfo */);
- }
-
- private static void serializeProviderWithProviderInfo(
- @NonNull final TypedXmlSerializer out, @NonNull final Provider p) throws IOException {
- Objects.requireNonNull(out);
- Objects.requireNonNull(p);
- serializeProviderInner(out, p, true /* persistsProviderInfo */);
- }
-
- private static void serializeProviderInner(@NonNull final TypedXmlSerializer out,
+ private static void serializeProvider(@NonNull final TypedXmlSerializer out,
@NonNull final Provider p, final boolean persistsProviderInfo) throws IOException {
Objects.requireNonNull(out);
Objects.requireNonNull(p);
@@ -2553,9 +2531,6 @@
if (!TextUtils.isEmpty(p.infoTag)) {
out.attribute(null, "info_tag", p.infoTag);
}
- if (DEBUG_PROVIDER_INFO_CACHE && persistsProviderInfo && !p.mInfoParsed) {
- Slog.d(TAG, "Provider info from " + p.id.componentName + " won't be persisted.");
- }
if (persistsProviderInfo && p.mInfoParsed) {
AppWidgetXmlUtil.writeAppWidgetProviderInfoLocked(out, p.info);
}
@@ -3172,11 +3147,7 @@
if (provider.getUserId() != userId) {
continue;
}
- if (mIsProviderInfoPersisted) {
- serializeProviderWithProviderInfo(out, provider);
- } else if (provider.shouldBePersisted()) {
- serializeProvider(out, provider);
- }
+ serializeProvider(out, provider, true /* persistsProviderInfo */);
}
N = mHosts.size();
@@ -3274,10 +3245,10 @@
provider.zombie = true;
provider.id = providerId;
mProviders.add(provider);
- } else if (mIsProviderInfoPersisted) {
+ } else {
final AppWidgetProviderInfo info =
AppWidgetXmlUtil.readAppWidgetProviderInfoLocked(parser);
- if (DEBUG_PROVIDER_INFO_CACHE && info == null) {
+ if (DEBUG && info == null) {
Slog.d(TAG, "Unable to load widget provider info from xml for "
+ providerId.componentName);
}
@@ -4601,7 +4572,7 @@
&& (provider.isInPackageForUser(backedupPackage, userId)
|| provider.hostedByPackageForUser(backedupPackage, userId))) {
provider.tag = index;
- serializeProvider(out, provider);
+ serializeProvider(out, provider, false /* persistsProviderInfo*/);
index++;
}
}
diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetXmlUtil.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetXmlUtil.java
index 7d8bb51..69b738a 100644
--- a/services/appwidget/java/com/android/server/appwidget/AppWidgetXmlUtil.java
+++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetXmlUtil.java
@@ -22,7 +22,6 @@
import android.content.ComponentName;
import android.os.Build;
import android.text.TextUtils;
-import android.util.Slog;
import com.android.modules.utils.TypedXmlPullParser;
import com.android.modules.utils.TypedXmlSerializer;
@@ -84,8 +83,6 @@
}
if (info.label != null) {
out.attribute(null, ATTR_LABEL, info.label);
- } else if (AppWidgetServiceImpl.DEBUG_PROVIDER_INFO_CACHE) {
- Slog.e(TAG, "Label is empty in " + info.provider);
}
out.attributeInt(null, ATTR_ICON, info.icon);
out.attributeInt(null, ATTR_PREVIEW_IMAGE, info.previewImage);
diff --git a/services/companion/OWNERS b/services/companion/OWNERS
index cb4cc56..734d8b6 100644
--- a/services/companion/OWNERS
+++ b/services/companion/OWNERS
@@ -1,4 +1 @@
-evanxinchen@google.com
-ewol@google.com
-guojing@google.com
-svetoslavganov@google.com
\ No newline at end of file
+include /core/java/android/companion/OWNERS
\ No newline at end of file
diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
index ebcd572..89e8a18 100644
--- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
+++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
@@ -67,6 +67,7 @@
import android.companion.IOnMessageReceivedListener;
import android.companion.IOnTransportsChangedListener;
import android.companion.ISystemDataTransferCallback;
+import android.companion.utils.FeatureUtils;
import android.content.ComponentName;
import android.content.Context;
import android.content.SharedPreferences;
@@ -761,6 +762,11 @@
@Override
public PendingIntent buildPermissionTransferUserConsentIntent(String packageName,
int userId, int associationId) {
+ if (!FeatureUtils.isPermSyncEnabled()) {
+ throw new UnsupportedOperationException("Calling"
+ + " buildPermissionTransferUserConsentIntent, but this API is disabled by"
+ + " the system.");
+ }
return mSystemDataTransferProcessor.buildPermissionTransferUserConsentIntent(
packageName, userId, associationId);
}
@@ -768,6 +774,10 @@
@Override
public void startSystemDataTransfer(String packageName, int userId, int associationId,
ISystemDataTransferCallback callback) {
+ if (!FeatureUtils.isPermSyncEnabled()) {
+ throw new UnsupportedOperationException("Calling startSystemDataTransfer, but this"
+ + " API is disabled by the system.");
+ }
mSystemDataTransferProcessor.startSystemDataTransfer(packageName, userId,
associationId, callback);
}
diff --git a/services/companion/java/com/android/server/companion/datatransfer/contextsync/CallMetadataSyncConnectionService.java b/services/companion/java/com/android/server/companion/datatransfer/contextsync/CallMetadataSyncConnectionService.java
index fac1c89..3187de5 100644
--- a/services/companion/java/com/android/server/companion/datatransfer/contextsync/CallMetadataSyncConnectionService.java
+++ b/services/companion/java/com/android/server/companion/datatransfer/contextsync/CallMetadataSyncConnectionService.java
@@ -175,7 +175,8 @@
: handle.getComponentName().getShortClassName(),
phoneAccount != null ? phoneAccount.getExtras().getString(
CrossDeviceSyncController.EXTRA_CALL_FACILITATOR_ID)
- : handle.getComponentName().getPackageName());
+ : handle.getComponentName().getPackageName(),
+ handle.getComponentName().flattenToString());
call.setFacilitator(callFacilitator);
call.setDirection(android.companion.Telecom.Call.OUTGOING);
call.setCallerId(connectionRequest.getAddress().getSchemeSpecificPart());
diff --git a/services/companion/java/com/android/server/companion/datatransfer/contextsync/CallMetadataSyncData.java b/services/companion/java/com/android/server/companion/datatransfer/contextsync/CallMetadataSyncData.java
index 74641a4..08811ba 100644
--- a/services/companion/java/com/android/server/companion/datatransfer/contextsync/CallMetadataSyncData.java
+++ b/services/companion/java/com/android/server/companion/datatransfer/contextsync/CallMetadataSyncData.java
@@ -75,13 +75,15 @@
public static class CallFacilitator {
private String mName;
private String mIdentifier;
+ private String mExtendedIdentifier;
private boolean mIsTel;
CallFacilitator() {}
- CallFacilitator(String name, String identifier) {
+ CallFacilitator(String name, String identifier, String extendedIdentifier) {
mName = name;
mIdentifier = identifier;
+ mExtendedIdentifier = extendedIdentifier;
}
public String getName() {
@@ -92,6 +94,10 @@
return mIdentifier;
}
+ public String getExtendedIdentifier() {
+ return mExtendedIdentifier;
+ }
+
public boolean isTel() {
return mIsTel;
}
@@ -104,6 +110,10 @@
mIdentifier = identifier;
}
+ public void setExtendedIdentifier(String extendedIdentifier) {
+ mExtendedIdentifier = extendedIdentifier;
+ }
+
public void setIsTel(boolean isTel) {
mIsTel = isTel;
}
@@ -170,6 +180,8 @@
"com.android.server.companion.datatransfer.contextsync.extra.FACILITATOR_NAME";
private static final String EXTRA_FACILITATOR_ID =
"com.android.server.companion.datatransfer.contextsync.extra.FACILITATOR_ID";
+ private static final String EXTRA_FACILITATOR_EXT_ID =
+ "com.android.server.companion.datatransfer.contextsync.extra.FACILITATOR_EXT_ID";
private static final String EXTRA_STATUS =
"com.android.server.companion.datatransfer.contextsync.extra.STATUS";
private static final String EXTRA_DIRECTION =
@@ -192,7 +204,10 @@
call.setAppIcon(bundle.getByteArray(EXTRA_APP_ICON));
final String facilitatorName = bundle.getString(EXTRA_FACILITATOR_NAME);
final String facilitatorIdentifier = bundle.getString(EXTRA_FACILITATOR_ID);
- call.setFacilitator(new CallFacilitator(facilitatorName, facilitatorIdentifier));
+ final String facilitatorExtendedIdentifier =
+ bundle.getString(EXTRA_FACILITATOR_EXT_ID);
+ call.setFacilitator(new CallFacilitator(facilitatorName, facilitatorIdentifier,
+ facilitatorExtendedIdentifier));
call.setStatus(bundle.getInt(EXTRA_STATUS));
call.setDirection(bundle.getInt(EXTRA_DIRECTION));
call.setControls(new HashSet<>(bundle.getIntegerArrayList(EXTRA_CONTROLS)));
@@ -207,6 +222,7 @@
bundle.putByteArray(EXTRA_APP_ICON, mAppIcon);
bundle.putString(EXTRA_FACILITATOR_NAME, mFacilitator.getName());
bundle.putString(EXTRA_FACILITATOR_ID, mFacilitator.getIdentifier());
+ bundle.putString(EXTRA_FACILITATOR_EXT_ID, mFacilitator.getExtendedIdentifier());
bundle.putInt(EXTRA_STATUS, mStatus);
bundle.putInt(EXTRA_DIRECTION, mDirection);
bundle.putIntegerArrayList(EXTRA_CONTROLS, new ArrayList<>(mControls));
diff --git a/services/companion/java/com/android/server/companion/datatransfer/contextsync/CrossDeviceCall.java b/services/companion/java/com/android/server/companion/datatransfer/contextsync/CrossDeviceCall.java
index e8392d2..2a50799 100644
--- a/services/companion/java/com/android/server/companion/datatransfer/contextsync/CrossDeviceCall.java
+++ b/services/companion/java/com/android/server/companion/datatransfer/contextsync/CrossDeviceCall.java
@@ -48,6 +48,7 @@
private final int mUserId;
@VisibleForTesting boolean mIsEnterprise;
private final String mCallingAppPackageName;
+ private final String mSerializedPhoneAccountHandle;
private String mCallingAppName;
private byte[] mCallingAppIcon;
private String mCallerDisplayName;
@@ -89,6 +90,8 @@
.equals(handle.getComponentName());
mCallingAppPackageName = handle != null
? callDetails.getAccountHandle().getComponentName().getPackageName() : "";
+ mSerializedPhoneAccountHandle = handle != null
+ ? handle.getId() + SEPARATOR + handle.getComponentName().flattenToString() : "";
mIsEnterprise = (callDetails.getCallProperties() & Call.Details.PROPERTY_ENTERPRISE_CALL)
== Call.Details.PROPERTY_ENTERPRISE_CALL;
final PackageManager packageManager = context.getPackageManager();
@@ -247,6 +250,10 @@
return mCallingAppPackageName;
}
+ public String getSerializedPhoneAccountHandle() {
+ return mSerializedPhoneAccountHandle;
+ }
+
/**
* Get a human-readable "caller id" to display as the origin of the call.
*
diff --git a/services/companion/java/com/android/server/companion/datatransfer/contextsync/CrossDeviceSyncController.java b/services/companion/java/com/android/server/companion/datatransfer/contextsync/CrossDeviceSyncController.java
index 3169459..9bd5af9 100644
--- a/services/companion/java/com/android/server/companion/datatransfer/contextsync/CrossDeviceSyncController.java
+++ b/services/companion/java/com/android/server/companion/datatransfer/contextsync/CrossDeviceSyncController.java
@@ -280,7 +280,7 @@
mCallFacilitators.add(
new CallMetadataSyncData.CallFacilitator(
defaultOutgoingTelAccount.getLabel().toString(),
- FACILITATOR_ID_SYSTEM));
+ FACILITATOR_ID_SYSTEM, FACILITATOR_ID_SYSTEM));
}
}
}
@@ -574,6 +574,10 @@
case (int) Telecom.CallFacilitator.IDENTIFIER:
facilitator.setIdentifier(pis.readString(Telecom.CallFacilitator.IDENTIFIER));
break;
+ case (int) Telecom.CallFacilitator.EXTENDED_IDENTIFIER:
+ facilitator.setExtendedIdentifier(
+ pis.readString(Telecom.CallFacilitator.EXTENDED_IDENTIFIER));
+ break;
default:
Slog.e(TAG, "Unhandled field in Facilitator:"
+ ProtoUtils.currentFieldToString(pis));
@@ -649,6 +653,8 @@
final long facilitatorToken = pos.start(Telecom.Call.Origin.FACILITATOR);
pos.write(Telecom.CallFacilitator.NAME, call.getCallingAppName());
pos.write(Telecom.CallFacilitator.IDENTIFIER, call.getCallingAppPackageName());
+ pos.write(Telecom.CallFacilitator.EXTENDED_IDENTIFIER,
+ call.getSerializedPhoneAccountHandle());
pos.end(facilitatorToken);
pos.end(originToken);
pos.write(Telecom.Call.STATUS, call.getStatus());
@@ -662,6 +668,8 @@
final long facilitatorsToken = pos.start(Telecom.FACILITATORS);
pos.write(Telecom.CallFacilitator.NAME, facilitator.getName());
pos.write(Telecom.CallFacilitator.IDENTIFIER, facilitator.getIdentifier());
+ pos.write(Telecom.CallFacilitator.EXTENDED_IDENTIFIER,
+ facilitator.getExtendedIdentifier());
pos.end(facilitatorsToken);
}
pos.end(telecomToken);
diff --git a/services/companion/java/com/android/server/companion/securechannel/SecureChannel.java b/services/companion/java/com/android/server/companion/securechannel/SecureChannel.java
index 5a3db4b..3cb9ac8 100644
--- a/services/companion/java/com/android/server/companion/securechannel/SecureChannel.java
+++ b/services/companion/java/com/android/server/companion/securechannel/SecureChannel.java
@@ -130,6 +130,7 @@
if (DEBUG) {
Slog.d(TAG, "Starting secure channel.");
}
+ mStopped = false;
new Thread(() -> {
try {
// 1. Wait for the next handshake message and process it.
@@ -185,6 +186,17 @@
}
/**
+ * Return true if the channel is currently inactive.
+ * The channel could have been stopped by either {@link SecureChannel#stop()} or by
+ * encountering a fatal error.
+ *
+ * @return true if the channel is currently inactive.
+ */
+ public boolean isStopped() {
+ return mStopped;
+ }
+
+ /**
* Start exchanging handshakes to create a secure layer asynchronously. When the handshake is
* completed successfully, then the {@link Callback#onSecureConnection()} will trigger. Any
* error that occurs during the handshake will be passed by {@link Callback#onError(Throwable)}.
@@ -290,6 +302,7 @@
try {
data = new byte[length];
} catch (OutOfMemoryError error) {
+ Streams.skipByReading(mInput, Long.MAX_VALUE);
throw new SecureChannelException("Payload is too large.", error);
}
diff --git a/services/companion/java/com/android/server/companion/transport/CompanionTransportManager.java b/services/companion/java/com/android/server/companion/transport/CompanionTransportManager.java
index bc537ac..41867f9 100644
--- a/services/companion/java/com/android/server/companion/transport/CompanionTransportManager.java
+++ b/services/companion/java/com/android/server/companion/transport/CompanionTransportManager.java
@@ -20,14 +20,10 @@
import android.annotation.NonNull;
import android.annotation.SuppressLint;
-import android.app.ActivityManagerInternal;
import android.companion.AssociationInfo;
import android.companion.IOnMessageReceivedListener;
import android.companion.IOnTransportsChangedListener;
import android.content.Context;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.os.Binder;
import android.os.Build;
import android.os.ParcelFileDescriptor;
import android.os.RemoteCallbackList;
@@ -36,7 +32,6 @@
import android.util.SparseArray;
import com.android.internal.annotations.GuardedBy;
-import com.android.server.LocalServices;
import com.android.server.companion.AssociationStore;
import java.io.FileDescriptor;
@@ -135,42 +130,14 @@
synchronized (mTransports) {
for (int i = 0; i < associationIds.length; i++) {
if (mTransports.contains(associationIds[i])) {
- try {
- mTransports.get(associationIds[i]).sendMessage(message, data);
- } catch (IOException e) {
- Slog.e(TAG, "Failed to send message 0x" + Integer.toHexString(message)
- + " data length " + data.length + " to association "
- + associationIds[i]);
- }
+ mTransports.get(associationIds[i]).requestForResponse(message, data);
}
}
}
}
- /**
- * For the moment, we only offer transporting of system data to built-in
- * companion apps; future work will improve the security model to support
- * third-party companion apps.
- */
- private void enforceCallerCanTransportSystemData(String packageName, int userId) {
- try {
- final ApplicationInfo info = mContext.getPackageManager().getApplicationInfoAsUser(
- packageName, 0, userId);
- final int instrumentationUid = LocalServices.getService(ActivityManagerInternal.class)
- .getInstrumentationSourceUid(Binder.getCallingUid());
- if (!Build.isDebuggable() && !info.isSystemApp()
- && instrumentationUid == android.os.Process.INVALID_UID) {
- throw new SecurityException("Transporting of system data currently only available "
- + "to built-in companion apps or tests");
- }
- } catch (NameNotFoundException e) {
- throw new IllegalArgumentException(e);
- }
- }
-
public void attachSystemDataTransport(String packageName, int userId, int associationId,
ParcelFileDescriptor fd) {
- enforceCallerCanTransportSystemData(packageName, userId);
synchronized (mTransports) {
if (mTransports.contains(associationId)) {
detachSystemDataTransport(packageName, userId, associationId);
@@ -184,7 +151,6 @@
}
public void detachSystemDataTransport(String packageName, int userId, int associationId) {
- enforceCallerCanTransportSystemData(packageName, userId);
synchronized (mTransports) {
final Transport transport = mTransports.get(associationId);
if (transport != null) {
@@ -240,6 +206,7 @@
}
addMessageListenersToTransport(transport);
+ transport.setOnTransportClosedListener(this::detachSystemDataTransport);
transport.start();
synchronized (mTransports) {
mTransports.put(associationId, transport);
@@ -317,4 +284,14 @@
transport.addListener(mMessageListeners.keyAt(i), mMessageListeners.valueAt(i));
}
}
+
+ void detachSystemDataTransport(Transport transport) {
+ int associationId = transport.mAssociationId;
+ AssociationInfo association = mAssociationStore.getAssociationById(associationId);
+ if (association != null) {
+ detachSystemDataTransport(association.getPackageName(),
+ association.getUserId(),
+ association.getId());
+ }
+ }
}
diff --git a/services/companion/java/com/android/server/companion/transport/RawTransport.java b/services/companion/java/com/android/server/companion/transport/RawTransport.java
index e64509f..ca169aac 100644
--- a/services/companion/java/com/android/server/companion/transport/RawTransport.java
+++ b/services/companion/java/com/android/server/companion/transport/RawTransport.java
@@ -70,6 +70,8 @@
}
IoUtils.closeQuietly(mRemoteIn);
IoUtils.closeQuietly(mRemoteOut);
+
+ super.close();
}
@Override
diff --git a/services/companion/java/com/android/server/companion/transport/SecureTransport.java b/services/companion/java/com/android/server/companion/transport/SecureTransport.java
index 2d856b9..a0301a9 100644
--- a/services/companion/java/com/android/server/companion/transport/SecureTransport.java
+++ b/services/companion/java/com/android/server/companion/transport/SecureTransport.java
@@ -21,7 +21,6 @@
import android.os.ParcelFileDescriptor;
import android.util.Slog;
-import com.android.internal.annotations.GuardedBy;
import com.android.server.companion.securechannel.AttestationVerifier;
import com.android.server.companion.securechannel.SecureChannel;
@@ -35,7 +34,6 @@
private volatile boolean mShouldProcessRequests = false;
- @GuardedBy("mRequestQueue")
private final BlockingQueue<byte[]> mRequestQueue = new ArrayBlockingQueue<>(100);
SecureTransport(int associationId, ParcelFileDescriptor fd, Context context) {
@@ -64,6 +62,8 @@
void close() {
mSecureChannel.close();
mShouldProcessRequests = false;
+
+ super.close();
}
@Override
@@ -81,13 +81,19 @@
}
// Queue up a message to send
- synchronized (mRequestQueue) {
+ try {
mRequestQueue.add(ByteBuffer.allocate(HEADER_LENGTH + data.length)
.putInt(message)
.putInt(sequence)
.putInt(data.length)
.put(data)
.array());
+ } catch (IllegalStateException e) {
+ // Request buffer can only be full if too many requests are being added or
+ // the request processing thread is dead. Assume latter and detach the transport.
+ Slog.w(TAG, "Failed to queue message 0x" + Integer.toHexString(message)
+ + " . Request buffer is full; detaching transport.", e);
+ close();
}
}
@@ -96,8 +102,8 @@
try {
mSecureChannel.establishSecureConnection();
} catch (Exception e) {
- Slog.w(TAG, "Failed to initiate secure channel handshake.", e);
- onError(e);
+ Slog.e(TAG, "Failed to initiate secure channel handshake.", e);
+ close();
}
}
@@ -108,17 +114,14 @@
// TODO: find a better way to handle incoming requests than a dedicated thread.
new Thread(() -> {
- try {
- while (mShouldProcessRequests) {
- synchronized (mRequestQueue) {
- byte[] request = mRequestQueue.poll();
- if (request != null) {
- mSecureChannel.sendSecureMessage(request);
- }
- }
+ while (mShouldProcessRequests) {
+ try {
+ byte[] request = mRequestQueue.take();
+ mSecureChannel.sendSecureMessage(request);
+ } catch (Exception e) {
+ Slog.e(TAG, "Failed to send secure message.", e);
+ close();
}
- } catch (IOException e) {
- onError(e);
}
}).start();
}
@@ -135,13 +138,18 @@
try {
handleMessage(message, sequence, content);
} catch (IOException error) {
- onError(error);
+ // IOException won't be thrown here because a separate thread is handling
+ // the write operations inside onSecureConnection().
}
}
@Override
public void onError(Throwable error) {
- mShouldProcessRequests = false;
- Slog.e(TAG, error.getMessage(), error);
+ Slog.e(TAG, "Secure transport encountered an error.", error);
+
+ // If the channel was stopped as a result of the error, then detach itself.
+ if (mSecureChannel.isStopped()) {
+ close();
+ }
}
}
diff --git a/services/companion/java/com/android/server/companion/transport/Transport.java b/services/companion/java/com/android/server/companion/transport/Transport.java
index 6ad6d3a..5af3b98 100644
--- a/services/companion/java/com/android/server/companion/transport/Transport.java
+++ b/services/companion/java/com/android/server/companion/transport/Transport.java
@@ -19,7 +19,6 @@
import android.annotation.NonNull;
import android.companion.IOnMessageReceivedListener;
import android.content.Context;
-import android.content.pm.PackageManager;
import android.os.Build;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
@@ -70,6 +69,8 @@
*/
private final Map<Integer, IOnMessageReceivedListener> mListeners;
+ private OnTransportClosedListener mOnTransportClosed;
+
private static boolean isRequest(int message) {
return (message & 0xFF000000) == 0x63000000;
}
@@ -120,20 +121,18 @@
abstract void stop();
/**
- * Stop listening to the incoming data and close the streams.
+ * Stop listening to the incoming data and close the streams. If a listener for closed event
+ * is set, then trigger it to assist with its clean-up.
*/
- abstract void close();
+ void close() {
+ if (mOnTransportClosed != null) {
+ mOnTransportClosed.onClosed(this);
+ }
+ }
protected abstract void sendMessage(int message, int sequence, @NonNull byte[] data)
throws IOException;
- /**
- * Send a message.
- */
- public void sendMessage(int message, @NonNull byte[] data) throws IOException {
- sendMessage(message, mNextSequence.incrementAndGet(), data);
- }
-
public Future<byte[]> requestForResponse(int message, byte[] data) {
if (DEBUG) Slog.d(TAG, "Requesting for response");
final int sequence = mNextSequence.incrementAndGet();
@@ -188,12 +187,6 @@
break;
}
case MESSAGE_REQUEST_PERMISSION_RESTORE: {
- if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH)
- && !Build.isDebuggable()) {
- Slog.w(TAG, "Restoring permissions only supported on watches");
- sendMessage(MESSAGE_RESPONSE_FAILURE, sequence, EmptyArray.BYTE);
- break;
- }
try {
callback(message, data);
sendMessage(MESSAGE_RESPONSE_SUCCESS, sequence, EmptyArray.BYTE);
@@ -247,4 +240,14 @@
}
}
}
+
+ void setOnTransportClosedListener(OnTransportClosedListener callback) {
+ this.mOnTransportClosed = callback;
+ }
+
+ // Interface to pass transport to the transport manager to assist with detachment.
+ @FunctionalInterface
+ interface OnTransportClosedListener {
+ void onClosed(Transport transport);
+ }
}
diff --git a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java
index a0c80a5..bbe7289 100644
--- a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java
+++ b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java
@@ -687,6 +687,17 @@
}
@Override
+ public int getAssociationIdForDevice(int deviceId) {
+ VirtualDeviceImpl virtualDevice;
+ synchronized (mVirtualDeviceManagerLock) {
+ virtualDevice = mVirtualDevices.get(deviceId);
+ }
+ return virtualDevice == null
+ ? VirtualDeviceManager.ASSOCIATION_ID_INVALID
+ : virtualDevice.getAssociationId();
+ }
+
+ @Override
public void registerVirtualDisplayListener(
@NonNull VirtualDisplayListener listener) {
synchronized (mVirtualDeviceManagerLock) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerConstants.java b/services/core/java/com/android/server/am/ActivityManagerConstants.java
index c2a2423..9bf8bf4 100644
--- a/services/core/java/com/android/server/am/ActivityManagerConstants.java
+++ b/services/core/java/com/android/server/am/ActivityManagerConstants.java
@@ -1349,7 +1349,7 @@
mService.initDropboxRateLimiter();
}
- private void loadDeviceConfigConstants() {
+ void loadDeviceConfigConstants() {
mOnDeviceConfigChangedListener.onPropertiesChanged(
DeviceConfig.getProperties(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER));
mOnDeviceConfigChangedForComponentAliasListener.onPropertiesChanged(
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 1abff86..359c3cd 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -4580,14 +4580,8 @@
EventLogTags.writeAmProcBound(app.userId, pid, app.processName);
synchronized (mProcLock) {
- app.mState.setCurAdj(ProcessList.INVALID_ADJ);
- app.mState.setSetAdj(ProcessList.INVALID_ADJ);
- app.mState.setVerifiedAdj(ProcessList.INVALID_ADJ);
- mOomAdjuster.setAttachingSchedGroupLSP(app);
- app.mState.setForcingToImportant(null);
+ mOomAdjuster.setAttachingProcessStatesLSP(app);
clearProcessForegroundLocked(app);
- app.mState.setHasShownUi(false);
- app.mState.setCached(false);
app.setDebugging(false);
app.setKilledByAm(false);
app.setKilled(false);
@@ -4756,8 +4750,14 @@
app.makeActive(thread, mProcessStats);
checkTime(startTime, "attachApplicationLocked: immediately after bindApplication");
}
+ app.setPendingFinishAttach(true);
+
updateLruProcessLocked(app, false, null);
checkTime(startTime, "attachApplicationLocked: after updateLruProcessLocked");
+
+ updateOomAdjLocked(app, OOM_ADJ_REASON_PROCESS_BEGIN);
+ checkTime(startTime, "attachApplicationLocked: after updateOomAdjLocked");
+
final long now = SystemClock.uptimeMillis();
synchronized (mAppProfiler.mProfilerLock) {
app.mProfile.setLastRequestedGc(now);
@@ -4773,8 +4773,6 @@
if (!mConstants.mEnableWaitForFinishAttachApplication) {
finishAttachApplicationInner(startSeq, callingUid, pid);
- } else {
- app.setPendingFinishAttach(true);
}
} catch (Exception e) {
// We need kill the process group here. (b/148588589)
@@ -8597,10 +8595,7 @@
t.traceEnd();
}
- t.traceBegin("showSystemReadyErrorDialogs");
- mAtmInternal.showSystemReadyErrorDialogsIfNeeded();
- t.traceEnd();
-
+ mHandler.post(mAtmInternal::showSystemReadyErrorDialogsIfNeeded);
if (isBootingSystemUser) {
// Need to send the broadcasts for the system user here because
@@ -9686,6 +9681,10 @@
public void onShellCommand(FileDescriptor in, FileDescriptor out,
FileDescriptor err, String[] args, ShellCallback callback,
ResultReceiver resultReceiver) {
+ final int callingUid = Binder.getCallingUid();
+ if (callingUid != ROOT_UID && callingUid != Process.SHELL_UID) {
+ throw new SecurityException("Shell commands are only callable by root or shell");
+ }
(new ActivityManagerShellCommand(this, false)).exec(
this, in, out, err, args, callback, resultReceiver);
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index d32f67e..c0ac1f8 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -3702,14 +3702,11 @@
if (foregroundActivities) {
try {
int prcState = mIam.getUidProcessState(uid, "android");
- ProcessRecord topApp = mInternal.getTopApp();
- if (topApp == null) {
- mPw.println("No top app found");
+
+ if (prcState == ProcessStateEnum.TOP) {
+ mPw.println("New foreground process: " + pid);
} else {
- int topPid = topApp.getPid();
- if (prcState == ProcessStateEnum.TOP && topPid == pid) {
- mPw.println("New foreground process: " + pid);
- }
+ mPw.println("No top app found");
}
mPw.flush();
} catch (RemoteException e) {
diff --git a/services/core/java/com/android/server/am/AppBatteryTracker.java b/services/core/java/com/android/server/am/AppBatteryTracker.java
index c2326f6..128bbdf 100644
--- a/services/core/java/com/android/server/am/AppBatteryTracker.java
+++ b/services/core/java/com/android/server/am/AppBatteryTracker.java
@@ -58,6 +58,7 @@
import android.os.BatteryUsageStatsQuery;
import android.os.PowerExemptionManager;
import android.os.PowerExemptionManager.ReasonCode;
+import android.os.Process;
import android.os.SystemClock;
import android.os.UidBatteryConsumer;
import android.os.UserHandle;
@@ -1975,15 +1976,15 @@
if (!mBgCurrentDrainHighThresholdByBgLocation) {
return false;
}
- final AppRestrictionController controller = mTracker.mAppRestrictionController;
- if (mInjector.getPermissionManagerServiceInternal().checkUidPermission(
- uid, ACCESS_BACKGROUND_LOCATION) == PERMISSION_GRANTED) {
+ if (mTracker.mContext.checkPermission(ACCESS_BACKGROUND_LOCATION,
+ Process.INVALID_PID, uid) == PERMISSION_GRANTED) {
return true;
}
if (!mBgCurrentDrainEventDurationBasedThresholdEnabled) {
return false;
}
final long since = Math.max(0, now - window);
+ final AppRestrictionController controller = mTracker.mAppRestrictionController;
final long locationDuration = controller.getForegroundServiceTotalDurationsSince(
uid, since, now, ServiceInfo.FOREGROUND_SERVICE_TYPE_LOCATION);
return locationDuration >= mBgCurrentDrainLocationMinDuration;
diff --git a/services/core/java/com/android/server/am/AppPermissionTracker.java b/services/core/java/com/android/server/am/AppPermissionTracker.java
index 722d0d4..18a9153 100644
--- a/services/core/java/com/android/server/am/AppPermissionTracker.java
+++ b/services/core/java/com/android/server/am/AppPermissionTracker.java
@@ -43,6 +43,7 @@
import android.content.pm.PackageManagerInternal;
import android.os.Handler;
import android.os.Message;
+import android.os.Process;
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.UserHandle;
@@ -292,8 +293,8 @@
mPermissionGranted = true;
return;
}
- mPermissionGranted = mInjector.getPermissionManagerServiceInternal()
- .checkUidPermission(mUid, mPermission) == PERMISSION_GRANTED;
+ mPermissionGranted = mContext.checkPermission(mPermission, Process.INVALID_PID, mUid)
+ == PERMISSION_GRANTED;
}
void updateAppOps() {
diff --git a/services/core/java/com/android/server/am/BroadcastProcessQueue.java b/services/core/java/com/android/server/am/BroadcastProcessQueue.java
index 58f62b6..0fcec6f 100644
--- a/services/core/java/com/android/server/am/BroadcastProcessQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastProcessQueue.java
@@ -25,6 +25,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UptimeMillisLong;
+import android.app.ActivityManager;
import android.app.BroadcastOptions;
import android.content.Intent;
import android.content.pm.ResolveInfo;
@@ -1045,6 +1046,7 @@
static final int REASON_CONTAINS_MANIFEST = 17;
static final int REASON_FOREGROUND = 18;
static final int REASON_CORE_UID = 19;
+ static final int REASON_TOP_PROCESS = 20;
@IntDef(flag = false, prefix = { "REASON_" }, value = {
REASON_EMPTY,
@@ -1066,6 +1068,7 @@
REASON_CONTAINS_MANIFEST,
REASON_FOREGROUND,
REASON_CORE_UID,
+ REASON_TOP_PROCESS,
})
@Retention(RetentionPolicy.SOURCE)
public @interface Reason {}
@@ -1091,6 +1094,7 @@
case REASON_CONTAINS_MANIFEST: return "CONTAINS_MANIFEST";
case REASON_FOREGROUND: return "FOREGROUND";
case REASON_CORE_UID: return "CORE_UID";
+ case REASON_TOP_PROCESS: return "TOP_PROCESS";
default: return Integer.toString(reason);
}
}
@@ -1132,6 +1136,11 @@
} else if (mUidForeground) {
mRunnableAt = runnableAt + constants.DELAY_FOREGROUND_PROC_MILLIS;
mRunnableAtReason = REASON_FOREGROUND;
+ } else if (app != null && app.getSetProcState() == ActivityManager.PROCESS_STATE_TOP) {
+ // TODO (b/287676625): Use a callback to check when a process goes in and out of
+ // the TOP state.
+ mRunnableAt = runnableAt + constants.DELAY_FOREGROUND_PROC_MILLIS;
+ mRunnableAtReason = REASON_TOP_PROCESS;
} else if (mProcessPersistent) {
mRunnableAt = runnableAt + constants.DELAY_PERSISTENT_PROC_MILLIS;
mRunnableAtReason = REASON_PERSISTENT;
diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java
index f21ad22..e51fc0a 100644
--- a/services/core/java/com/android/server/am/OomAdjuster.java
+++ b/services/core/java/com/android/server/am/OomAdjuster.java
@@ -1293,12 +1293,19 @@
for (int i = numLru - 1; i >= 0; i--) {
ProcessRecord app = lruList.get(i);
final ProcessStateRecord state = app.mState;
- if (!app.isKilledByAm() && app.getThread() != null && !app.isPendingFinishAttach()) {
+ if (!app.isKilledByAm() && app.getThread() != null) {
// We don't need to apply the update for the process which didn't get computed
if (state.getCompletedAdjSeq() == mAdjSeq) {
applyOomAdjLSP(app, true, now, nowElapsed, oomAdjReason);
}
+ if (app.isPendingFinishAttach()) {
+ // Avoid trimming processes that are still initializing. If they aren't
+ // hosting any components yet because they may be unfairly killed.
+ // We however apply the oom scores set at #setAttachingProcessStatesLSP.
+ continue;
+ }
+
final ProcessServiceRecord psr = app.mServices;
// Count the number of process types.
switch (state.getCurProcState()) {
@@ -2806,6 +2813,18 @@
capability &= ~PROCESS_CAPABILITY_BFSL;
}
+
+ if (app.isPendingFinishAttach()) {
+ // If the app is still starting up. We reset the computations to the
+ // hardcoded values in setAttachingProcessStatesLSP. This ensures that the app keeps
+ // hard-coded default 'startup' oom scores while starting up. When it finishes startup,
+ // we'll recompute oom scores based on it's actual hosted compoenents.
+ setAttachingProcessStatesLSP(app);
+ state.setAdjSeq(mAdjSeq);
+ state.setCompletedAdjSeq(state.getAdjSeq());
+ return false;
+ }
+
// Do final modification to adj. Everything we do between here and applying
// the final setAdj must be done in this function, because we will also use
// it when computing the final cached adj later. Note that we don't need to
@@ -3243,8 +3262,11 @@
}
@GuardedBy({"mService", "mProcLock"})
- void setAttachingSchedGroupLSP(ProcessRecord app) {
+ void setAttachingProcessStatesLSP(ProcessRecord app) {
int initialSchedGroup = SCHED_GROUP_DEFAULT;
+ int initialProcState = PROCESS_STATE_CACHED_EMPTY;
+ int initialCapability = PROCESS_CAPABILITY_NONE;
+ boolean initialCached = true;
final ProcessStateRecord state = app.mState;
// If the process has been marked as foreground, it is starting as the top app (with
// Zygote#START_AS_TOP_APP_ARG), so boost the thread priority of its default UI thread.
@@ -3260,13 +3282,24 @@
setThreadPriority(app.getPid(), THREAD_PRIORITY_TOP_APP_BOOST);
}
initialSchedGroup = SCHED_GROUP_TOP_APP;
+ initialProcState = PROCESS_STATE_TOP;
+ initialCapability = PROCESS_CAPABILITY_ALL;
+ initialCached = false;
} catch (Exception e) {
Slog.w(TAG, "Failed to pre-set top priority to " + app + " " + e);
}
}
- state.setSetSchedGroup(initialSchedGroup);
state.setCurrentSchedulingGroup(initialSchedGroup);
+ state.setCurProcState(initialProcState);
+ state.setCurRawProcState(initialProcState);
+ state.setCurCapability(initialCapability);
+ state.setCached(initialCached);
+
+ state.setCurAdj(ProcessList.FOREGROUND_APP_ADJ);
+ state.setCurRawAdj(ProcessList.FOREGROUND_APP_ADJ);
+ state.setForcingToImportant(null);
+ state.setHasShownUi(false);
}
// ONLY used for unit testing in OomAdjusterTests.java
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
index f814c3b..f532122c1 100644
--- a/services/core/java/com/android/server/am/ProcessRecord.java
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
@@ -674,6 +674,11 @@
return mState.getCurProcState();
}
+ @GuardedBy(anyOf = {"mService", "mProcLock"})
+ int getSetProcState() {
+ return mState.getSetProcState();
+ }
+
@GuardedBy({"mService", "mProcLock"})
public void makeActive(IApplicationThread thread, ProcessStatsService tracker) {
mProfile.onProcessActive(thread, tracker);
diff --git a/services/core/java/com/android/server/audio/AudioDeviceBroker.java b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
index 84fe12e..e4dd4a4 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceBroker.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
@@ -30,6 +30,8 @@
import android.media.AudioDeviceAttributes;
import android.media.AudioDeviceInfo;
import android.media.AudioManager;
+import android.media.AudioPlaybackConfiguration;
+import android.media.AudioRecordingConfiguration;
import android.media.AudioRoutesInfo;
import android.media.AudioSystem;
import android.media.BluetoothProfileConnectionInfo;
@@ -289,37 +291,38 @@
* @param on
* @param eventSource for logging purposes
*/
- /*package*/ void setSpeakerphoneOn(IBinder cb, int pid, boolean on, String eventSource) {
+ /*package*/ void setSpeakerphoneOn(
+ IBinder cb, int uid, boolean on, boolean isPrivileged, String eventSource) {
if (AudioService.DEBUG_COMM_RTE) {
- Log.v(TAG, "setSpeakerphoneOn, on: " + on + " pid: " + pid);
+ Log.v(TAG, "setSpeakerphoneOn, on: " + on + " uid: " + uid);
}
postSetCommunicationDeviceForClient(new CommunicationDeviceInfo(
- cb, pid, new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_SPEAKER, ""),
- on, BtHelper.SCO_MODE_UNDEFINED, eventSource, false));
+ cb, uid, new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_SPEAKER, ""),
+ on, BtHelper.SCO_MODE_UNDEFINED, eventSource, false, isPrivileged));
}
/**
* Select device for use for communication use cases.
* @param cb Client binder for death detection
- * @param pid Client pid
+ * @param uid Client uid
* @param device Device selected or null to unselect.
* @param eventSource for logging purposes
*/
private static final long SET_COMMUNICATION_DEVICE_TIMEOUT_MS = 3000;
- /*package*/ boolean setCommunicationDevice(
- IBinder cb, int pid, AudioDeviceInfo device, String eventSource) {
+ /*package*/ boolean setCommunicationDevice(IBinder cb, int uid, AudioDeviceInfo device,
+ boolean isPrivileged, String eventSource) {
if (AudioService.DEBUG_COMM_RTE) {
- Log.v(TAG, "setCommunicationDevice, device: " + device + ", pid: " + pid);
+ Log.v(TAG, "setCommunicationDevice, device: " + device + ", uid: " + uid);
}
AudioDeviceAttributes deviceAttr =
(device != null) ? new AudioDeviceAttributes(device) : null;
- CommunicationDeviceInfo deviceInfo = new CommunicationDeviceInfo(cb, pid, deviceAttr,
- device != null, BtHelper.SCO_MODE_UNDEFINED, eventSource, true);
+ CommunicationDeviceInfo deviceInfo = new CommunicationDeviceInfo(cb, uid, deviceAttr,
+ device != null, BtHelper.SCO_MODE_UNDEFINED, eventSource, true, isPrivileged);
postSetCommunicationDeviceForClient(deviceInfo);
boolean status;
synchronized (deviceInfo) {
@@ -353,7 +356,7 @@
Log.v(TAG, "onSetCommunicationDeviceForClient: " + deviceInfo);
}
if (!deviceInfo.mOn) {
- CommunicationRouteClient client = getCommunicationRouteClientForPid(deviceInfo.mPid);
+ CommunicationRouteClient client = getCommunicationRouteClientForUid(deviceInfo.mUid);
if (client == null || (deviceInfo.mDevice != null
&& !deviceInfo.mDevice.equals(client.getDevice()))) {
return false;
@@ -361,22 +364,23 @@
}
AudioDeviceAttributes device = deviceInfo.mOn ? deviceInfo.mDevice : null;
- setCommunicationRouteForClient(deviceInfo.mCb, deviceInfo.mPid, device,
- deviceInfo.mScoAudioMode, deviceInfo.mEventSource);
+ setCommunicationRouteForClient(deviceInfo.mCb, deviceInfo.mUid, device,
+ deviceInfo.mScoAudioMode, deviceInfo.mIsPrivileged, deviceInfo.mEventSource);
return true;
}
@GuardedBy("mDeviceStateLock")
/*package*/ void setCommunicationRouteForClient(
- IBinder cb, int pid, AudioDeviceAttributes device,
- int scoAudioMode, String eventSource) {
+ IBinder cb, int uid, AudioDeviceAttributes device,
+ int scoAudioMode, boolean isPrivileged, String eventSource) {
if (AudioService.DEBUG_COMM_RTE) {
- Log.v(TAG, "setCommunicationRouteForClient: device: " + device);
+ Log.v(TAG, "setCommunicationRouteForClient: device: " + device
+ + ", eventSource: " + eventSource);
}
AudioService.sDeviceLogger.enqueue((new EventLogger.StringEvent(
- "setCommunicationRouteForClient for pid: " + pid
- + " device: " + device
+ "setCommunicationRouteForClient for uid: " + uid
+ + " device: " + device + " isPrivileged: " + isPrivileged
+ " from API: " + eventSource)).printLog(TAG));
final boolean wasBtScoRequested = isBluetoothScoRequested();
@@ -385,16 +389,18 @@
// Save previous client route in case of failure to start BT SCO audio
AudioDeviceAttributes prevClientDevice = null;
- client = getCommunicationRouteClientForPid(pid);
+ boolean prevPrivileged = false;
+ client = getCommunicationRouteClientForUid(uid);
if (client != null) {
prevClientDevice = client.getDevice();
+ prevPrivileged = client.isPrivileged();
}
if (device != null) {
- client = addCommunicationRouteClient(cb, pid, device);
+ client = addCommunicationRouteClient(cb, uid, device, isPrivileged);
if (client == null) {
- Log.w(TAG, "setCommunicationRouteForClient: could not add client for pid: "
- + pid + " and device: " + device);
+ Log.w(TAG, "setCommunicationRouteForClient: could not add client for uid: "
+ + uid + " and device: " + device);
}
} else {
client = removeCommunicationRouteClient(cb, true);
@@ -406,11 +412,11 @@
boolean isBtScoRequested = isBluetoothScoRequested();
if (isBtScoRequested && (!wasBtScoRequested || !isBluetoothScoActive())) {
if (!mBtHelper.startBluetoothSco(scoAudioMode, eventSource)) {
- Log.w(TAG, "setCommunicationRouteForClient: failure to start BT SCO for pid: "
- + pid);
+ Log.w(TAG, "setCommunicationRouteForClient: failure to start BT SCO for uid: "
+ + uid);
// clean up or restore previous client selection
if (prevClientDevice != null) {
- addCommunicationRouteClient(cb, pid, prevClientDevice);
+ addCommunicationRouteClient(cb, uid, prevClientDevice, prevPrivileged);
} else {
removeCommunicationRouteClient(cb, true);
}
@@ -447,11 +453,12 @@
@GuardedBy("mDeviceStateLock")
private CommunicationRouteClient topCommunicationRouteClient() {
for (CommunicationRouteClient crc : mCommunicationRouteClients) {
- if (crc.getPid() == mAudioModeOwner.mPid) {
+ if (crc.getUid() == mAudioModeOwner.mUid) {
return crc;
}
}
- if (!mCommunicationRouteClients.isEmpty() && mAudioModeOwner.mPid == 0) {
+ if (!mCommunicationRouteClients.isEmpty() && mAudioModeOwner.mPid == 0
+ && mCommunicationRouteClients.get(0).isActive()) {
return mCommunicationRouteClients.get(0);
}
return null;
@@ -491,14 +498,48 @@
};
/*package */ static boolean isValidCommunicationDevice(AudioDeviceInfo device) {
+ return isValidCommunicationDeviceType(device.getType());
+ }
+
+ private static boolean isValidCommunicationDeviceType(int deviceType) {
for (int type : VALID_COMMUNICATION_DEVICE_TYPES) {
- if (device.getType() == type) {
+ if (deviceType == type) {
return true;
}
}
return false;
}
+ /*package */
+ void postCheckCommunicationDeviceRemoval(@NonNull AudioDeviceAttributes device) {
+ if (!isValidCommunicationDeviceType(
+ AudioDeviceInfo.convertInternalDeviceToDeviceType(device.getInternalType()))) {
+ return;
+ }
+ sendLMsgNoDelay(MSG_L_CHECK_COMMUNICATION_DEVICE_REMOVAL, SENDMSG_QUEUE, device);
+ }
+
+ @GuardedBy("mDeviceStateLock")
+ void onCheckCommunicationDeviceRemoval(@NonNull AudioDeviceAttributes device) {
+ if (AudioService.DEBUG_COMM_RTE) {
+ Log.v(TAG, "onCheckCommunicationDeviceRemoval device: " + device.toString());
+ }
+ for (CommunicationRouteClient crc : mCommunicationRouteClients) {
+ if (device.equals(crc.getDevice())) {
+ if (AudioService.DEBUG_COMM_RTE) {
+ Log.v(TAG, "onCheckCommunicationDeviceRemoval removing client: "
+ + crc.toString());
+ }
+ // Cancelling the route for this client will remove it from the stack and update
+ // the communication route.
+ CommunicationDeviceInfo deviceInfo = new CommunicationDeviceInfo(
+ crc.getBinder(), crc.getUid(), device, false,
+ BtHelper.SCO_MODE_UNDEFINED, "onCheckCommunicationDeviceRemoval",
+ false, crc.isPrivileged());
+ postSetCommunicationDeviceForClient(deviceInfo);
+ }
+ }
+ }
/* package */ static List<AudioDeviceInfo> getAvailableCommunicationDevices() {
ArrayList<AudioDeviceInfo> commDevices = new ArrayList<>();
AudioDeviceInfo[] allDevices =
@@ -1107,26 +1148,26 @@
sendLMsgNoDelay(MSG_L_BLUETOOTH_DEVICE_CONFIG_CHANGE, SENDMSG_QUEUE, info);
}
- /*package*/ void startBluetoothScoForClient(IBinder cb, int pid, int scoAudioMode,
- @NonNull String eventSource) {
+ /*package*/ void startBluetoothScoForClient(IBinder cb, int uid, int scoAudioMode,
+ boolean isPrivileged, @NonNull String eventSource) {
if (AudioService.DEBUG_COMM_RTE) {
- Log.v(TAG, "startBluetoothScoForClient, pid: " + pid);
+ Log.v(TAG, "startBluetoothScoForClient, uid: " + uid);
}
postSetCommunicationDeviceForClient(new CommunicationDeviceInfo(
- cb, pid, new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_BLUETOOTH_SCO, ""),
- true, scoAudioMode, eventSource, false));
+ cb, uid, new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_BLUETOOTH_SCO, ""),
+ true, scoAudioMode, eventSource, false, isPrivileged));
}
/*package*/ void stopBluetoothScoForClient(
- IBinder cb, int pid, @NonNull String eventSource) {
+ IBinder cb, int uid, boolean isPrivileged, @NonNull String eventSource) {
if (AudioService.DEBUG_COMM_RTE) {
- Log.v(TAG, "stopBluetoothScoForClient, pid: " + pid);
+ Log.v(TAG, "stopBluetoothScoForClient, uid: " + uid);
}
postSetCommunicationDeviceForClient(new CommunicationDeviceInfo(
- cb, pid, new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_BLUETOOTH_SCO, ""),
- false, BtHelper.SCO_MODE_UNDEFINED, eventSource, false));
+ cb, uid, new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_BLUETOOTH_SCO, ""),
+ false, BtHelper.SCO_MODE_UNDEFINED, eventSource, false, isPrivileged));
}
/*package*/ int setPreferredDevicesForStrategySync(int strategy,
@@ -1367,22 +1408,24 @@
/*package*/ static final class CommunicationDeviceInfo {
final @NonNull IBinder mCb; // Identifies the requesting client for death handler
- final int mPid; // Requester process ID
+ final int mUid; // Requester UID
final @Nullable AudioDeviceAttributes mDevice; // Device being set or reset.
final boolean mOn; // true if setting, false if resetting
final int mScoAudioMode; // only used for SCO: requested audio mode
+ final boolean mIsPrivileged; // true if the client app has MODIFY_PHONE_STATE permission
final @NonNull String mEventSource; // caller identifier for logging
boolean mWaitForStatus; // true if the caller waits for a completion status (API dependent)
boolean mStatus = false; // completion status only used if mWaitForStatus is true
- CommunicationDeviceInfo(@NonNull IBinder cb, int pid,
+ CommunicationDeviceInfo(@NonNull IBinder cb, int uid,
@Nullable AudioDeviceAttributes device, boolean on, int scoAudioMode,
- @NonNull String eventSource, boolean waitForStatus) {
+ @NonNull String eventSource, boolean waitForStatus, boolean isPrivileged) {
mCb = cb;
- mPid = pid;
+ mUid = uid;
mDevice = device;
mOn = on;
mScoAudioMode = scoAudioMode;
+ mIsPrivileged = isPrivileged;
mEventSource = eventSource;
mWaitForStatus = waitForStatus;
}
@@ -1401,16 +1444,17 @@
}
return mCb.equals(((CommunicationDeviceInfo) o).mCb)
- && mPid == ((CommunicationDeviceInfo) o).mPid;
+ && mUid == ((CommunicationDeviceInfo) o).mUid;
}
@Override
public String toString() {
return "CommunicationDeviceInfo mCb=" + mCb.toString()
- + " mPid=" + mPid
+ + " mUid=" + mUid
+ " mDevice=[" + (mDevice != null ? mDevice.toString() : "null") + "]"
+ " mOn=" + mOn
+ " mScoAudioMode=" + mScoAudioMode
+ + " mIsPrivileged=" + mIsPrivileged
+ " mEventSource=" + mEventSource
+ " mWaitForStatus=" + mWaitForStatus
+ " mStatus=" + mStatus;
@@ -1440,7 +1484,7 @@
}
}
- /*package*/ boolean handleDeviceConnection(AudioDeviceAttributes attributes,
+ /*package*/ boolean handleDeviceConnection(@NonNull AudioDeviceAttributes attributes,
boolean connect, @Nullable BluetoothDevice btDevice) {
synchronized (mDeviceStateLock) {
return mDeviceInventory.handleDeviceConnection(
@@ -1507,8 +1551,7 @@
pw.println("\n" + prefix + "Communication route clients:");
mCommunicationRouteClients.forEach((cl) -> {
- pw.println(" " + prefix + "pid: " + cl.getPid() + " device: "
- + cl.getDevice() + " cb: " + cl.getBinder()); });
+ pw.println(" " + prefix + cl.toString()); });
pw.println("\n" + prefix + "Computed Preferred communication device: "
+ preferredCommunicationDevice());
@@ -1850,6 +1893,15 @@
final BluetoothDevice btDevice = (BluetoothDevice) msg.obj;
BtHelper.onNotifyPreferredAudioProfileApplied(btDevice);
} break;
+
+ case MSG_L_CHECK_COMMUNICATION_DEVICE_REMOVAL: {
+ synchronized (mSetModeLock) {
+ synchronized (mDeviceStateLock) {
+ onCheckCommunicationDeviceRemoval((AudioDeviceAttributes) msg.obj);
+ }
+ }
+ } break;
+
default:
Log.wtf(TAG, "Invalid message " + msg.what);
}
@@ -1926,6 +1978,7 @@
private static final int MSG_IL_BTLEAUDIO_TIMEOUT = 49;
private static final int MSG_L_NOTIFY_PREFERRED_AUDIOPROFILE_APPLIED = 52;
+ private static final int MSG_L_CHECK_COMMUNICATION_DEVICE_REMOVAL = 53;
private static boolean isMessageHandledUnderWakelock(int msgId) {
switch(msgId) {
@@ -2101,13 +2154,20 @@
private class CommunicationRouteClient implements IBinder.DeathRecipient {
private final IBinder mCb;
- private final int mPid;
+ private final int mUid;
+ private final boolean mIsPrivileged;
private AudioDeviceAttributes mDevice;
+ private boolean mPlaybackActive;
+ private boolean mRecordingActive;
- CommunicationRouteClient(IBinder cb, int pid, AudioDeviceAttributes device) {
+ CommunicationRouteClient(IBinder cb, int uid, AudioDeviceAttributes device,
+ boolean isPrivileged) {
mCb = cb;
- mPid = pid;
+ mUid = uid;
mDevice = device;
+ mIsPrivileged = isPrivileged;
+ mPlaybackActive = mAudioService.isPlaybackActiveForUid(uid);
+ mRecordingActive = mAudioService.isRecordingActiveForUid(uid);
}
public boolean registerDeathRecipient() {
@@ -2138,13 +2198,38 @@
return mCb;
}
- int getPid() {
- return mPid;
+ int getUid() {
+ return mUid;
+ }
+
+ boolean isPrivileged() {
+ return mIsPrivileged;
}
AudioDeviceAttributes getDevice() {
return mDevice;
}
+
+ public void setPlaybackActive(boolean active) {
+ mPlaybackActive = active;
+ }
+
+ public void setRecordingActive(boolean active) {
+ mRecordingActive = active;
+ }
+
+ public boolean isActive() {
+ return mIsPrivileged || mRecordingActive || mPlaybackActive;
+ }
+
+ @Override
+ public String toString() {
+ return "[CommunicationRouteClient: mUid: " + mUid
+ + " mDevice: " + mDevice.toString()
+ + " mIsPrivileged: " + mIsPrivileged
+ + " mPlaybackActive: " + mPlaybackActive
+ + " mRecordingActive: " + mRecordingActive + "]";
+ }
}
// @GuardedBy("mSetModeLock")
@@ -2154,8 +2239,9 @@
return;
}
Log.w(TAG, "Communication client died");
- setCommunicationRouteForClient(client.getBinder(), client.getPid(), null,
- BtHelper.SCO_MODE_UNDEFINED, "onCommunicationRouteClientDied");
+ setCommunicationRouteForClient(client.getBinder(), client.getUid(), null,
+ BtHelper.SCO_MODE_UNDEFINED, client.isPrivileged(),
+ "onCommunicationRouteClientDied");
}
/**
@@ -2242,8 +2328,8 @@
+ crc + " eventSource: " + eventSource);
}
if (crc != null) {
- setCommunicationRouteForClient(crc.getBinder(), crc.getPid(), crc.getDevice(),
- BtHelper.SCO_MODE_UNDEFINED, eventSource);
+ setCommunicationRouteForClient(crc.getBinder(), crc.getUid(), crc.getDevice(),
+ BtHelper.SCO_MODE_UNDEFINED, crc.isPrivileged(), eventSource);
}
}
@@ -2267,6 +2353,7 @@
dispatchCommunicationDevice();
}
+ @GuardedBy("mDeviceStateLock")
private CommunicationRouteClient removeCommunicationRouteClient(
IBinder cb, boolean unregister) {
for (CommunicationRouteClient cl : mCommunicationRouteClients) {
@@ -2282,11 +2369,12 @@
}
@GuardedBy("mDeviceStateLock")
- private CommunicationRouteClient addCommunicationRouteClient(
- IBinder cb, int pid, AudioDeviceAttributes device) {
+ private CommunicationRouteClient addCommunicationRouteClient(IBinder cb, int uid,
+ AudioDeviceAttributes device, boolean isPrivileged) {
// always insert new request at first position
removeCommunicationRouteClient(cb, true);
- CommunicationRouteClient client = new CommunicationRouteClient(cb, pid, device);
+ CommunicationRouteClient client =
+ new CommunicationRouteClient(cb, uid, device, isPrivileged);
if (client.registerDeathRecipient()) {
mCommunicationRouteClients.add(0, client);
return client;
@@ -2295,9 +2383,9 @@
}
@GuardedBy("mDeviceStateLock")
- private CommunicationRouteClient getCommunicationRouteClientForPid(int pid) {
+ private CommunicationRouteClient getCommunicationRouteClientForUid(int uid) {
for (CommunicationRouteClient cl : mCommunicationRouteClients) {
- if (cl.getPid() == pid) {
+ if (cl.getUid() == uid) {
return cl;
}
}
@@ -2330,6 +2418,45 @@
return device;
}
+ void updateCommunicationRouteClientsActivity(
+ List<AudioPlaybackConfiguration> playbackConfigs,
+ List<AudioRecordingConfiguration> recordConfigs) {
+ synchronized (mSetModeLock) {
+ synchronized (mDeviceStateLock) {
+ boolean updateCommunicationRoute = false;
+ for (CommunicationRouteClient crc : mCommunicationRouteClients) {
+ boolean wasActive = crc.isActive();
+ if (playbackConfigs != null) {
+ crc.setPlaybackActive(false);
+ for (AudioPlaybackConfiguration config : playbackConfigs) {
+ if (config.getClientUid() == crc.getUid()
+ && config.isActive()) {
+ crc.setPlaybackActive(true);
+ break;
+ }
+ }
+ }
+ if (recordConfigs != null) {
+ crc.setRecordingActive(false);
+ for (AudioRecordingConfiguration config : recordConfigs) {
+ if (config.getClientUid() == crc.getUid()
+ && !config.isClientSilenced()) {
+ crc.setRecordingActive(true);
+ break;
+ }
+ }
+ }
+ if (wasActive != crc.isActive()) {
+ updateCommunicationRoute = true;
+ }
+ }
+ if (updateCommunicationRoute) {
+ postUpdateCommunicationRouteClient("updateCommunicationRouteClientsActivity");
+ }
+ }
+ }
+ }
+
@Nullable UUID getDeviceSensorUuid(AudioDeviceAttributes device) {
synchronized (mDeviceStateLock) {
return mDeviceInventory.getDeviceSensorUuid(device);
diff --git a/services/core/java/com/android/server/audio/AudioDeviceInventory.java b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
index 0c7f11f..b70e11d 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceInventory.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
@@ -1245,8 +1245,9 @@
* @param btDevice the corresponding Bluetooth device when relevant.
* @return false if an error was reported by AudioSystem
*/
- /*package*/ boolean handleDeviceConnection(AudioDeviceAttributes attributes, boolean connect,
- boolean isForTesting, @Nullable BluetoothDevice btDevice) {
+ /*package*/ boolean handleDeviceConnection(@NonNull AudioDeviceAttributes attributes,
+ boolean connect, boolean isForTesting,
+ @Nullable BluetoothDevice btDevice) {
int device = attributes.getInternalType();
String address = attributes.getAddress();
String deviceName = attributes.getName();
@@ -1297,6 +1298,7 @@
AudioSystem.DEVICE_STATE_UNAVAILABLE, AudioSystem.AUDIO_FORMAT_DEFAULT);
// always remove even if disconnection failed
mConnectedDevices.remove(deviceKey);
+ mDeviceBroker.postCheckCommunicationDeviceRemoval(attributes);
status = true;
}
if (status) {
@@ -1801,8 +1803,9 @@
// device to remove was visible by APM, update APM
mDeviceBroker.clearAvrcpAbsoluteVolumeSupported();
- final int res = mAudioSystem.setDeviceConnectionState(new AudioDeviceAttributes(
- AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, address),
+ AudioDeviceAttributes ada = new AudioDeviceAttributes(
+ AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, address);
+ final int res = mAudioSystem.setDeviceConnectionState(ada,
AudioSystem.DEVICE_STATE_UNAVAILABLE, a2dpCodec);
if (res != AudioSystem.AUDIO_STATUS_OK) {
@@ -1816,11 +1819,13 @@
"A2DP device addr=" + address + " made unavailable")).printLog(TAG));
}
mApmConnectedDevices.remove(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP);
+
// Remove A2DP routes as well
setCurrentAudioRouteNameIfPossible(null, true /*fromA2dp*/);
mmi.record();
updateBluetoothPreferredModes_l(null /*connectedDevice*/);
purgeDevicesRoles_l();
+ mDeviceBroker.postCheckCommunicationDeviceRemoval(ada);
}
@GuardedBy("mDevicesLock")
@@ -1855,12 +1860,14 @@
@GuardedBy("mDevicesLock")
private void makeA2dpSrcUnavailable(String address) {
- mAudioSystem.setDeviceConnectionState(new AudioDeviceAttributes(
- AudioSystem.DEVICE_IN_BLUETOOTH_A2DP, address),
+ AudioDeviceAttributes ada = new AudioDeviceAttributes(
+ AudioSystem.DEVICE_IN_BLUETOOTH_A2DP, address);
+ mAudioSystem.setDeviceConnectionState(ada,
AudioSystem.DEVICE_STATE_UNAVAILABLE,
AudioSystem.AUDIO_FORMAT_DEFAULT);
mConnectedDevices.remove(
DeviceInfo.makeDeviceListKey(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP, address));
+ mDeviceBroker.postCheckCommunicationDeviceRemoval(ada);
}
@GuardedBy("mDevicesLock")
@@ -1893,8 +1900,9 @@
@GuardedBy("mDevicesLock")
private void makeHearingAidDeviceUnavailable(String address) {
- mAudioSystem.setDeviceConnectionState(new AudioDeviceAttributes(
- AudioSystem.DEVICE_OUT_HEARING_AID, address),
+ AudioDeviceAttributes ada = new AudioDeviceAttributes(
+ AudioSystem.DEVICE_OUT_HEARING_AID, address);
+ mAudioSystem.setDeviceConnectionState(ada,
AudioSystem.DEVICE_STATE_UNAVAILABLE,
AudioSystem.AUDIO_FORMAT_DEFAULT);
mConnectedDevices.remove(
@@ -1906,6 +1914,7 @@
.set(MediaMetrics.Property.DEVICE,
AudioSystem.getDeviceName(AudioSystem.DEVICE_OUT_HEARING_AID))
.record();
+ mDeviceBroker.postCheckCommunicationDeviceRemoval(ada);
}
/**
@@ -2002,9 +2011,10 @@
@GuardedBy("mDevicesLock")
private void makeLeAudioDeviceUnavailableNow(String address, int device) {
+ AudioDeviceAttributes ada = null;
if (device != AudioSystem.DEVICE_NONE) {
- final int res = AudioSystem.setDeviceConnectionState(new AudioDeviceAttributes(
- device, address),
+ ada = new AudioDeviceAttributes(device, address);
+ final int res = AudioSystem.setDeviceConnectionState(ada,
AudioSystem.DEVICE_STATE_UNAVAILABLE,
AudioSystem.AUDIO_FORMAT_DEFAULT);
@@ -2024,6 +2034,9 @@
setCurrentAudioRouteNameIfPossible(null, false /*fromA2dp*/);
updateBluetoothPreferredModes_l(null /*connectedDevice*/);
purgeDevicesRoles_l();
+ if (ada != null) {
+ mDeviceBroker.postCheckCommunicationDeviceRemoval(ada);
+ }
}
@GuardedBy("mDevicesLock")
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 6d390f7..7404b19 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -392,6 +392,7 @@
private static final int MSG_DISPATCH_PREFERRED_MIXER_ATTRIBUTES = 52;
private static final int MSG_LOWER_VOLUME_TO_RS1 = 53;
private static final int MSG_CONFIGURATION_CHANGED = 54;
+ private static final int MSG_BROADCAST_MASTER_MUTE = 55;
/** Messages handled by the {@link SoundDoseHelper}. */
/*package*/ static final int SAFE_MEDIA_VOLUME_MSG_START = 1000;
@@ -974,6 +975,9 @@
@GuardedBy("mSettingsLock")
private boolean mRttEnabled = false;
+ private AtomicBoolean mMasterMute = new AtomicBoolean(false);
+
+
///////////////////////////////////////////////////////////////////////////
// Construction
///////////////////////////////////////////////////////////////////////////
@@ -2734,21 +2738,18 @@
}
final int currentUser = getCurrentUserId();
+ if (mUseFixedVolume) {
+ AudioSystem.setMasterVolume(1.0f);
+ }
+
// Check the current user restriction.
boolean masterMute =
mUserManagerInternal.getUserRestriction(currentUser,
UserManager.DISALLOW_UNMUTE_DEVICE)
|| mUserManagerInternal.getUserRestriction(currentUser,
UserManager.DISALLOW_ADJUST_VOLUME);
- if (mUseFixedVolume) {
- masterMute = false;
- AudioSystem.setMasterVolume(1.0f);
- }
- if (DEBUG_VOL) {
- Log.d(TAG, String.format("Master mute %s, user=%d", masterMute, currentUser));
- }
- AudioSystem.setMasterMute(masterMute);
- broadcastMasterMuteStatus(masterMute);
+ setMasterMuteInternalNoCallerCheck(
+ masterMute, /* flags =*/ 0, currentUser, "readUserRestrictions");
mMicMuteFromRestrictions = mUserManagerInternal.getUserRestriction(
currentUser, UserManager.DISALLOW_UNMUTE_MICROPHONE);
@@ -4262,22 +4263,41 @@
// When the audio mode owner becomes active, replace any delayed MSG_UPDATE_AUDIO_MODE
// and request an audio mode update immediately. Upon any other change, queue the message
// and request an audio mode update after a grace period.
+ updateAudioModeHandlers(
+ configs /* playbackConfigs */, null /* recordConfigs */);
+ mDeviceBroker.updateCommunicationRouteClientsActivity(
+ configs /* playbackConfigs */, null /* recordConfigs */);
+ }
+
+ void updateAudioModeHandlers(List<AudioPlaybackConfiguration> playbackConfigs,
+ List<AudioRecordingConfiguration> recordConfigs) {
synchronized (mDeviceBroker.mSetModeLock) {
boolean updateAudioMode = false;
int existingMsgPolicy = SENDMSG_QUEUE;
int delay = CHECK_MODE_FOR_UID_PERIOD_MS;
for (SetModeDeathHandler h : mSetModeDeathHandlers) {
boolean wasActive = h.isActive();
- h.setPlaybackActive(false);
- for (AudioPlaybackConfiguration config : configs) {
- final int usage = config.getAudioAttributes().getUsage();
- if (config.getClientUid() == h.getUid()
- && (usage == AudioAttributes.USAGE_VOICE_COMMUNICATION
+ if (playbackConfigs != null) {
+ h.setPlaybackActive(false);
+ for (AudioPlaybackConfiguration config : playbackConfigs) {
+ final int usage = config.getAudioAttributes().getUsage();
+ if (config.getClientUid() == h.getUid()
+ && (usage == AudioAttributes.USAGE_VOICE_COMMUNICATION
|| usage == AudioAttributes.USAGE_VOICE_COMMUNICATION_SIGNALLING)
- && config.getPlayerState()
- == AudioPlaybackConfiguration.PLAYER_STATE_STARTED) {
- h.setPlaybackActive(true);
- break;
+ && config.isActive()) {
+ h.setPlaybackActive(true);
+ break;
+ }
+ }
+ }
+ if (recordConfigs != null) {
+ h.setRecordingActive(false);
+ for (AudioRecordingConfiguration config : recordConfigs) {
+ if (config.getClientUid() == h.getUid() && !config.isClientSilenced()
+ && config.getAudioSource() == AudioSource.VOICE_COMMUNICATION) {
+ h.setRecordingActive(true);
+ break;
+ }
}
}
if (wasActive != h.isActive()) {
@@ -4315,38 +4335,10 @@
// When the audio mode owner becomes active, replace any delayed MSG_UPDATE_AUDIO_MODE
// and request an audio mode update immediately. Upon any other change, queue the message
// and request an audio mode update after a grace period.
- synchronized (mDeviceBroker.mSetModeLock) {
- boolean updateAudioMode = false;
- int existingMsgPolicy = SENDMSG_QUEUE;
- int delay = CHECK_MODE_FOR_UID_PERIOD_MS;
- for (SetModeDeathHandler h : mSetModeDeathHandlers) {
- boolean wasActive = h.isActive();
- h.setRecordingActive(false);
- for (AudioRecordingConfiguration config : configs) {
- if (config.getClientUid() == h.getUid()
- && config.getAudioSource() == AudioSource.VOICE_COMMUNICATION) {
- h.setRecordingActive(true);
- break;
- }
- }
- if (wasActive != h.isActive()) {
- updateAudioMode = true;
- if (h.isActive() && h == getAudioModeOwnerHandler()) {
- existingMsgPolicy = SENDMSG_REPLACE;
- delay = 0;
- }
- }
- }
- if (updateAudioMode) {
- sendMsg(mAudioHandler,
- MSG_UPDATE_AUDIO_MODE,
- existingMsgPolicy,
- AudioSystem.MODE_CURRENT,
- android.os.Process.myPid(),
- mContext.getPackageName(),
- delay);
- }
- }
+ updateAudioModeHandlers(
+ null /* playbackConfigs */, configs /* recordConfigs */);
+ mDeviceBroker.updateCommunicationRouteClientsActivity(
+ null /* playbackConfigs */, configs /* recordConfigs */);
}
private void dumpAudioMode(PrintWriter pw) {
@@ -4762,16 +4754,10 @@
// UI update and Broadcast Intent
private void sendMasterMuteUpdate(boolean muted, int flags) {
mVolumeController.postMasterMuteChanged(updateFlagsForTvPlatform(flags));
- broadcastMasterMuteStatus(muted);
+ sendMsg(mAudioHandler, MSG_BROADCAST_MASTER_MUTE,
+ SENDMSG_QUEUE, muted ? 1 : 0, 0, null, 0);
}
- private void broadcastMasterMuteStatus(boolean muted) {
- Intent intent = new Intent(AudioManager.MASTER_MUTE_CHANGED_ACTION);
- intent.putExtra(AudioManager.EXTRA_MASTER_VOLUME_MUTED, muted);
- intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
- | Intent.FLAG_RECEIVER_REPLACE_PENDING);
- sendStickyBroadcastToAll(intent);
- }
/**
* Sets the stream state's index, and posts a message to set system volume.
@@ -4938,18 +4924,21 @@
!= PackageManager.PERMISSION_GRANTED) {
return;
}
- setMasterMuteInternalNoCallerCheck(mute, flags, userId);
+ setMasterMuteInternalNoCallerCheck(mute, flags, userId, "setMasterMute");
}
- private void setMasterMuteInternalNoCallerCheck(boolean mute, int flags, int userId) {
+ private void setMasterMuteInternalNoCallerCheck(
+ boolean mute, int flags, int userId, String eventSource) {
if (DEBUG_VOL) {
- Log.d(TAG, String.format("Master mute %s, %d, user=%d", mute, flags, userId));
+ Log.d(TAG, TextUtils.formatSimple("Master mute %s, %d, user=%d from %s",
+ mute, flags, userId, eventSource));
}
+
if (!isPlatformAutomotive() && mUseFixedVolume) {
// If using fixed volume, we don't mute.
// TODO: remove the isPlatformAutomotive check here.
// The isPlatformAutomotive check is added for safety but may not be necessary.
- return;
+ mute = false;
}
// For automotive,
// - the car service is always running as system user
@@ -4958,8 +4947,10 @@
// Therefore, the getCurrentUser() is always different to the foreground user.
if ((isPlatformAutomotive() && userId == UserHandle.USER_SYSTEM)
|| (getCurrentUserId() == userId)) {
- if (mute != AudioSystem.getMasterMute()) {
- AudioSystem.setMasterMute(mute);
+ if (mute != mMasterMute.getAndSet(mute)) {
+ sVolumeLogger.enqueue(new VolumeEvent(
+ VolumeEvent.VOL_MASTER_MUTE, mute));
+ mAudioSystem.setMasterMute(mute);
sendMasterMuteUpdate(mute, flags);
}
}
@@ -4967,7 +4958,7 @@
/** get global mute state. */
public boolean isMasterMute() {
- return AudioSystem.getMasterMute();
+ return mMasterMute.get();
}
@android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
@@ -6299,10 +6290,12 @@
? MediaMetrics.Value.CONNECTED : MediaMetrics.Value.DISCONNECTED)
.record();
}
-
+ final boolean isPrivileged = mContext.checkCallingOrSelfPermission(
+ android.Manifest.permission.MODIFY_PHONE_STATE)
+ == PackageManager.PERMISSION_GRANTED;
final long ident = Binder.clearCallingIdentity();
try {
- return mDeviceBroker.setCommunicationDevice(cb, pid, device, eventSource);
+ return mDeviceBroker.setCommunicationDevice(cb, uid, device, isPrivileged, eventSource);
} finally {
Binder.restoreCallingIdentity(ident);
}
@@ -6348,6 +6341,9 @@
if (!checkAudioSettingsPermission("setSpeakerphoneOn()")) {
return;
}
+ final boolean isPrivileged = mContext.checkCallingOrSelfPermission(
+ android.Manifest.permission.MODIFY_PHONE_STATE)
+ == PackageManager.PERMISSION_GRANTED;
// for logging only
final int uid = Binder.getCallingUid();
@@ -6363,9 +6359,10 @@
.set(MediaMetrics.Property.STATE, on
? MediaMetrics.Value.ON : MediaMetrics.Value.OFF)
.record();
+
final long ident = Binder.clearCallingIdentity();
try {
- mDeviceBroker.setSpeakerphoneOn(cb, pid, on, eventSource);
+ mDeviceBroker.setSpeakerphoneOn(cb, uid, on, isPrivileged, eventSource);
} finally {
Binder.restoreCallingIdentity(ident);
}
@@ -6490,7 +6487,7 @@
.set(MediaMetrics.Property.SCO_AUDIO_MODE,
BtHelper.scoAudioModeToString(scoAudioMode))
.record();
- startBluetoothScoInt(cb, pid, scoAudioMode, eventSource);
+ startBluetoothScoInt(cb, uid, scoAudioMode, eventSource);
}
@@ -6513,10 +6510,10 @@
.set(MediaMetrics.Property.SCO_AUDIO_MODE,
BtHelper.scoAudioModeToString(BtHelper.SCO_MODE_VIRTUAL_CALL))
.record();
- startBluetoothScoInt(cb, pid, BtHelper.SCO_MODE_VIRTUAL_CALL, eventSource);
+ startBluetoothScoInt(cb, uid, BtHelper.SCO_MODE_VIRTUAL_CALL, eventSource);
}
- void startBluetoothScoInt(IBinder cb, int pid, int scoAudioMode, @NonNull String eventSource) {
+ void startBluetoothScoInt(IBinder cb, int uid, int scoAudioMode, @NonNull String eventSource) {
MediaMetrics.Item mmi = new MediaMetrics.Item(MediaMetrics.Name.AUDIO_BLUETOOTH)
.set(MediaMetrics.Property.EVENT, "startBluetoothScoInt")
.set(MediaMetrics.Property.SCO_AUDIO_MODE,
@@ -6527,9 +6524,13 @@
mmi.set(MediaMetrics.Property.EARLY_RETURN, "permission or systemReady").record();
return;
}
+ final boolean isPrivileged = mContext.checkCallingOrSelfPermission(
+ android.Manifest.permission.MODIFY_PHONE_STATE)
+ == PackageManager.PERMISSION_GRANTED;
final long ident = Binder.clearCallingIdentity();
try {
- mDeviceBroker.startBluetoothScoForClient(cb, pid, scoAudioMode, eventSource);
+ mDeviceBroker.startBluetoothScoForClient(
+ cb, uid, scoAudioMode, isPrivileged, eventSource);
} finally {
Binder.restoreCallingIdentity(ident);
}
@@ -6547,9 +6548,12 @@
final String eventSource = new StringBuilder("stopBluetoothSco()")
.append(") from u/pid:").append(uid).append("/")
.append(pid).toString();
+ final boolean isPrivileged = mContext.checkCallingOrSelfPermission(
+ android.Manifest.permission.MODIFY_PHONE_STATE)
+ == PackageManager.PERMISSION_GRANTED;
final long ident = Binder.clearCallingIdentity();
try {
- mDeviceBroker.stopBluetoothScoForClient(cb, pid, eventSource);
+ mDeviceBroker.stopBluetoothScoForClient(cb, uid, isPrivileged, eventSource);
} finally {
Binder.restoreCallingIdentity(ident);
}
@@ -9270,6 +9274,10 @@
mSystemServer.sendMicrophoneMuteChangedIntent();
break;
+ case MSG_BROADCAST_MASTER_MUTE:
+ mSystemServer.broadcastMasterMuteStatus(msg.arg1 == 1);
+ break;
+
case MSG_CHECK_MODE_FOR_UID:
synchronized (mDeviceBroker.mSetModeLock) {
if (msg.obj == null) {
@@ -9282,8 +9290,8 @@
break;
}
boolean wasActive = h.isActive();
- h.setPlaybackActive(mPlaybackMonitor.isPlaybackActiveForUid(h.getUid()));
- h.setRecordingActive(mRecordMonitor.isRecordingActiveForUid(h.getUid()));
+ h.setPlaybackActive(isPlaybackActiveForUid(h.getUid()));
+ h.setRecordingActive(isRecordingActiveForUid(h.getUid()));
if (wasActive != h.isActive()) {
onUpdateAudioMode(AudioSystem.MODE_CURRENT, android.os.Process.myPid(),
mContext.getPackageName(), false /*force*/);
@@ -9667,7 +9675,8 @@
newRestrictions.getBoolean(UserManager.DISALLOW_ADJUST_VOLUME)
|| newRestrictions.getBoolean(UserManager.DISALLOW_UNMUTE_DEVICE);
if (wasRestricted != isRestricted) {
- setMasterMuteInternalNoCallerCheck(isRestricted, /* flags =*/ 0, userId);
+ setMasterMuteInternalNoCallerCheck(
+ isRestricted, /* flags =*/ 0, userId, "onUserRestrictionsChanged");
}
}
}
@@ -11060,10 +11069,11 @@
pw.print(" mHdmiCecVolumeControlEnabled="); pw.println(mHdmiCecVolumeControlEnabled);
}
pw.print(" mIsCallScreeningModeSupported="); pw.println(mIsCallScreeningModeSupported);
- pw.print(" mic mute FromSwitch=" + mMicMuteFromSwitch
+ pw.println(" mic mute FromSwitch=" + mMicMuteFromSwitch
+ " FromRestrictions=" + mMicMuteFromRestrictions
+ " FromApi=" + mMicMuteFromApi
+ " from system=" + mMicMuteFromSystemCached);
+ pw.print(" mMasterMute="); pw.println(mMasterMute.get());
dumpAccessibilityServiceUids(pw);
dumpAssistantServicesUids(pw);
@@ -12381,6 +12391,16 @@
}
}
+ /* package */
+ boolean isPlaybackActiveForUid(int uid) {
+ return mPlaybackMonitor.isPlaybackActiveForUid(uid);
+ }
+
+ /* package */
+ boolean isRecordingActiveForUid(int uid) {
+ return mRecordMonitor.isRecordingActiveForUid(uid);
+ }
+
//======================
// Audio device management
//======================
diff --git a/services/core/java/com/android/server/audio/AudioServiceEvents.java b/services/core/java/com/android/server/audio/AudioServiceEvents.java
index 6ebb42e..aac868f 100644
--- a/services/core/java/com/android/server/audio/AudioServiceEvents.java
+++ b/services/core/java/com/android/server/audio/AudioServiceEvents.java
@@ -228,6 +228,7 @@
static final int VOL_MUTE_STREAM_INT = 9;
static final int VOL_SET_LE_AUDIO_VOL = 10;
static final int VOL_ADJUST_GROUP_VOL = 11;
+ static final int VOL_MASTER_MUTE = 12;
final int mOp;
final int mStream;
@@ -321,6 +322,17 @@
logMetricEvent();
}
+ /** used for VOL_MASTER_MUTE */
+ VolumeEvent(int op, boolean state) {
+ mOp = op;
+ mStream = -1;
+ mVal1 = state ? 1 : 0;
+ mVal2 = 0;
+ mCaller = null;
+ mGroupName = null;
+ logMetricEvent();
+ }
+
/**
* Audio Analytics unique Id.
@@ -429,6 +441,9 @@
case VOL_MUTE_STREAM_INT:
// No value in logging metrics for this internal event
return;
+ case VOL_MASTER_MUTE:
+ // No value in logging metrics for this internal event
+ return;
default:
return;
}
@@ -510,6 +525,10 @@
.append(AudioSystem.streamToString(mStream))
.append(mVal1 == 1 ? ", muted)" : ", unmuted)")
.toString();
+ case VOL_MASTER_MUTE:
+ return new StringBuilder("Master mute:")
+ .append(mVal1 == 1 ? " muted)" : " unmuted)")
+ .toString();
default: return new StringBuilder("FIXME invalid op:").append(mOp).toString();
}
}
diff --git a/services/core/java/com/android/server/audio/AudioSystemAdapter.java b/services/core/java/com/android/server/audio/AudioSystemAdapter.java
index 4343894..e70b649 100644
--- a/services/core/java/com/android/server/audio/AudioSystemAdapter.java
+++ b/services/core/java/com/android/server/audio/AudioSystemAdapter.java
@@ -685,6 +685,15 @@
}
/**
+ * Sets master mute state in audio flinger
+ * @param mute the mute state to set
+ * @return operation status
+ */
+ public int setMasterMute(boolean mute) {
+ return AudioSystem.setMasterMute(mute);
+ }
+
+ /**
* Part of AudioService dump
* @param pw
*/
diff --git a/services/core/java/com/android/server/audio/RecordingActivityMonitor.java b/services/core/java/com/android/server/audio/RecordingActivityMonitor.java
index 652ea52..4332fdd 100644
--- a/services/core/java/com/android/server/audio/RecordingActivityMonitor.java
+++ b/services/core/java/com/android/server/audio/RecordingActivityMonitor.java
@@ -227,8 +227,8 @@
synchronized (mRecordStates) {
for (RecordingState state : mRecordStates) {
// Note: isActiveConfiguration() == true => state.getConfig() != null
- if (state.isActiveConfiguration()
- && state.getConfig().getClientUid() == uid) {
+ if (state.isActiveConfiguration() && state.getConfig().getClientUid() == uid
+ && !state.getConfig().isClientSilenced()) {
return true;
}
}
diff --git a/services/core/java/com/android/server/audio/SystemServerAdapter.java b/services/core/java/com/android/server/audio/SystemServerAdapter.java
index 22456bc..dfcd2e9 100644
--- a/services/core/java/com/android/server/audio/SystemServerAdapter.java
+++ b/services/core/java/com/android/server/audio/SystemServerAdapter.java
@@ -145,4 +145,18 @@
ActivityManager.broadcastStickyIntent(intent, profileId);
}
}
+
+ /*package*/ void broadcastMasterMuteStatus(boolean muted) {
+ Intent intent = new Intent(AudioManager.MASTER_MUTE_CHANGED_ACTION);
+ intent.putExtra(AudioManager.EXTRA_MASTER_VOLUME_MUTED, muted);
+ intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
+ | Intent.FLAG_RECEIVER_REPLACE_PENDING
+ | Intent.FLAG_RECEIVER_FOREGROUND);
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
index 3d6a156..ea6bb62 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
@@ -913,7 +913,6 @@
}
provider.onPointerDown(requestId, sensorId, pc);
}
-
@android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override
@@ -1184,4 +1183,15 @@
}
}
}
+
+ void simulateVhalFingerDown() {
+ if (Utils.isVirtualEnabled(getContext())) {
+ Slog.i(TAG, "Simulate virtual HAL finger down event");
+ final Pair<Integer, ServiceProvider> provider = mRegistry.getSingleProvider();
+ if (provider != null) {
+ provider.second.simulateVhalFingerDown(UserHandle.getCallingUserId(),
+ provider.first);
+ }
+ }
+ }
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintShellCommand.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintShellCommand.java
index 636413f..dc6a63f 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintShellCommand.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintShellCommand.java
@@ -45,6 +45,8 @@
return doHelp();
case "sync":
return doSync();
+ case "fingerdown":
+ return doSimulateVhalFingerDown();
default:
getOutPrintWriter().println("Unrecognized command: " + cmd);
}
@@ -62,6 +64,8 @@
pw.println(" Print this help text.");
pw.println(" sync");
pw.println(" Sync enrollments now (virtualized sensors only).");
+ pw.println(" fingerdown");
+ pw.println(" Simulate finger down event (virtualized sensors only).");
}
private int doHelp() {
@@ -73,4 +77,9 @@
mService.syncEnrollmentsNow();
return 0;
}
+
+ private int doSimulateVhalFingerDown() {
+ mService.simulateVhalFingerDown();
+ return 0;
+ }
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/ServiceProvider.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/ServiceProvider.java
index 26701c1..d70ca8c 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/ServiceProvider.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/ServiceProvider.java
@@ -157,4 +157,11 @@
* @param sensorId sensor ID of the associated operation
*/
default void scheduleWatchdog(int sensorId) {}
+
+ /**
+ * Simulate fingerprint down touch event for virtual HAL
+ * @param userId user ID
+ * @param sensorId sensor ID
+ */
+ default void simulateVhalFingerDown(int userId, int sensorId) {};
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java
index e682fe7..f8d2566 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java
@@ -857,4 +857,18 @@
}
biometricScheduler.startWatchdog();
}
+
+ @Override
+ public void simulateVhalFingerDown(int userId, int sensorId) {
+ Slog.d(getTag(), "Simulate virtual HAL finger down event");
+ final AidlSession session = mFingerprintSensors.get(sensorId).getSessionForUser(userId);
+ final PointerContext pc = new PointerContext();
+ try {
+ session.getSession().onPointerDownWithContext(pc);
+ session.getSession().onUiReady();
+ session.getSession().onPointerUpWithContext(pc);
+ } catch (RemoteException e) {
+ Slog.e(getTag(), "failed hal operation ", e);
+ }
+ }
}
diff --git a/services/core/java/com/android/server/companion/virtual/VirtualDeviceManagerInternal.java b/services/core/java/com/android/server/companion/virtual/VirtualDeviceManagerInternal.java
index 4d12574..ee323f9 100644
--- a/services/core/java/com/android/server/companion/virtual/VirtualDeviceManagerInternal.java
+++ b/services/core/java/com/android/server/companion/virtual/VirtualDeviceManagerInternal.java
@@ -156,4 +156,14 @@
* @return the set of display ids for all VirtualDisplays owned by the device
*/
public abstract @NonNull ArraySet<Integer> getDisplayIdsForDevice(int deviceId);
+
+ /**
+ * Gets the CDM association ID for the VirtualDevice with the given device ID.
+ *
+ * @param deviceId which device we're asking about
+ * @return the CDM association ID for this device, or
+ * {@link android.companion.virtual.VirtualDeviceManager#ASSOCIATION_ID_INVALID} if no such
+ * association exists.
+ */
+ public abstract int getAssociationIdForDevice(int deviceId);
}
diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
index e85eee81..6b69e1c 100644
--- a/services/core/java/com/android/server/connectivity/Vpn.java
+++ b/services/core/java/com/android/server/connectivity/Vpn.java
@@ -1389,7 +1389,7 @@
}
// Check that the caller is authorized.
- enforceControlPermission();
+ enforceControlPermissionOrInternalCaller();
// Stop an existing always-on VPN from being dethroned by other apps.
if (mAlwaysOn && !isCurrentPreparedPackage(newPackage)) {
diff --git a/services/core/java/com/android/server/display/DisplayDeviceConfig.java b/services/core/java/com/android/server/display/DisplayDeviceConfig.java
index 7ccfb44..d9cb299 100644
--- a/services/core/java/com/android/server/display/DisplayDeviceConfig.java
+++ b/services/core/java/com/android/server/display/DisplayDeviceConfig.java
@@ -515,7 +515,9 @@
private final SensorData mScreenOffBrightnessSensor = new SensorData();
// The details of the proximity sensor associated with this display.
- private final SensorData mProximitySensor = new SensorData();
+ // Is null when no sensor should be used for that display
+ @Nullable
+ private SensorData mProximitySensor = new SensorData();
private final List<RefreshRateLimitation> mRefreshRateLimitations =
new ArrayList<>(2 /*initialCapacity*/);
@@ -1337,7 +1339,8 @@
return mScreenOffBrightnessSensor;
}
- SensorData getProximitySensor() {
+ @Nullable
+ public SensorData getProximitySensor() {
return mProximitySensor;
}
@@ -2563,46 +2566,51 @@
private void loadAmbientLightSensorFromDdc(DisplayConfiguration config) {
final SensorDetails sensorDetails = config.getLightSensor();
if (sensorDetails != null) {
- mAmbientLightSensor.type = sensorDetails.getType();
- mAmbientLightSensor.name = sensorDetails.getName();
- final RefreshRateRange rr = sensorDetails.getRefreshRate();
- if (rr != null) {
- mAmbientLightSensor.minRefreshRate = rr.getMinimum().floatValue();
- mAmbientLightSensor.maxRefreshRate = rr.getMaximum().floatValue();
- }
+ loadSensorData(sensorDetails, mAmbientLightSensor);
} else {
loadAmbientLightSensorFromConfigXml();
}
}
private void setProxSensorUnspecified() {
- mProximitySensor.name = null;
- mProximitySensor.type = null;
+ mProximitySensor = new SensorData();
}
private void loadScreenOffBrightnessSensorFromDdc(DisplayConfiguration config) {
final SensorDetails sensorDetails = config.getScreenOffBrightnessSensor();
if (sensorDetails != null) {
- mScreenOffBrightnessSensor.type = sensorDetails.getType();
- mScreenOffBrightnessSensor.name = sensorDetails.getName();
+ loadSensorData(sensorDetails, mScreenOffBrightnessSensor);
}
}
private void loadProxSensorFromDdc(DisplayConfiguration config) {
SensorDetails sensorDetails = config.getProxSensor();
if (sensorDetails != null) {
- mProximitySensor.name = sensorDetails.getName();
- mProximitySensor.type = sensorDetails.getType();
- final RefreshRateRange rr = sensorDetails.getRefreshRate();
- if (rr != null) {
- mProximitySensor.minRefreshRate = rr.getMinimum().floatValue();
- mProximitySensor.maxRefreshRate = rr.getMaximum().floatValue();
+ String name = sensorDetails.getName();
+ String type = sensorDetails.getType();
+ if ("".equals(name) && "".equals(type)) {
+ // <proxSensor> with empty values to the config means no sensor should be used
+ mProximitySensor = null;
+ } else {
+ mProximitySensor = new SensorData();
+ loadSensorData(sensorDetails, mProximitySensor);
}
} else {
setProxSensorUnspecified();
}
}
+ private void loadSensorData(@NonNull SensorDetails sensorDetails,
+ @NonNull SensorData sensorData) {
+ sensorData.name = sensorDetails.getName();
+ sensorData.type = sensorDetails.getType();
+ final RefreshRateRange rr = sensorDetails.getRefreshRate();
+ if (rr != null) {
+ sensorData.minRefreshRate = rr.getMinimum().floatValue();
+ sensorData.maxRefreshRate = rr.getMaximum().floatValue();
+ }
+ }
+
private void loadBrightnessChangeThresholdsFromXml() {
loadBrightnessChangeThresholds(/* config= */ null);
}
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 1162231..7e8771e 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -4230,6 +4230,13 @@
}
@VisibleForTesting
+ void overrideSensorManager(SensorManager sensorManager) {
+ synchronized (mSyncRoot) {
+ mSensorManager = sensorManager;
+ }
+ }
+
+ @VisibleForTesting
final class LocalService extends DisplayManagerInternal {
@Override
@@ -4482,7 +4489,7 @@
}
final DisplayDeviceConfig config = device.getDisplayDeviceConfig();
SensorData sensorData = config.getProximitySensor();
- if (sensorData.matches(sensorName, sensorType)) {
+ if (sensorData != null && sensorData.matches(sensorName, sensorType)) {
return new RefreshRateRange(sensorData.minRefreshRate,
sensorData.maxRefreshRate);
}
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index 19e8a5e..ffecf2b 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -1590,12 +1590,12 @@
mAllowAutoBrightnessWhileDozingConfig && Display.isDozeState(state);
final boolean autoBrightnessEnabled = mUseAutoBrightness
&& (state == Display.STATE_ON || autoBrightnessEnabledInDoze)
- && Float.isNaN(brightnessState)
- && mAutomaticBrightnessController != null
- && mBrightnessReasonTemp.getReason() != BrightnessReason.REASON_FOLLOWER;
+ && mBrightnessReasonTemp.getReason() != BrightnessReason.REASON_OVERRIDE
+ && mAutomaticBrightnessController != null;
final boolean autoBrightnessDisabledDueToDisplayOff = mUseAutoBrightness
&& !(state == Display.STATE_ON || autoBrightnessEnabledInDoze);
final int autoBrightnessState = autoBrightnessEnabled
+ && mBrightnessReasonTemp.getReason() != BrightnessReason.REASON_FOLLOWER
? AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED
: autoBrightnessDisabledDueToDisplayOff
? AutomaticBrightnessController.AUTO_BRIGHTNESS_OFF_DUE_TO_DISPLAY_STATE
@@ -1655,9 +1655,11 @@
mShouldResetShortTermModel);
mShouldResetShortTermModel = false;
}
- mBrightnessRangeController.setAutoBrightnessEnabled(mUseAutoBrightness
+ mBrightnessRangeController.setAutoBrightnessEnabled(autoBrightnessEnabled
? AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED
- : AutomaticBrightnessController.AUTO_BRIGHTNESS_DISABLED);
+ : autoBrightnessDisabledDueToDisplayOff
+ ? AutomaticBrightnessController.AUTO_BRIGHTNESS_OFF_DUE_TO_DISPLAY_STATE
+ : AutomaticBrightnessController.AUTO_BRIGHTNESS_DISABLED);
if (mBrightnessTracker != null) {
mBrightnessTracker.setShouldCollectColorSample(mBrightnessConfiguration != null
@@ -2301,29 +2303,23 @@
}
private void loadAmbientLightSensor() {
- DisplayDeviceConfig.SensorData lightSensor = mDisplayDeviceConfig.getAmbientLightSensor();
final int fallbackType = mDisplayId == Display.DEFAULT_DISPLAY
? Sensor.TYPE_LIGHT : SensorUtils.NO_FALLBACK;
- mLightSensor = SensorUtils.findSensor(mSensorManager, lightSensor.type, lightSensor.name,
- fallbackType);
+ mLightSensor = SensorUtils.findSensor(mSensorManager,
+ mDisplayDeviceConfig.getAmbientLightSensor(), fallbackType);
}
private void loadScreenOffBrightnessSensor() {
- DisplayDeviceConfig.SensorData screenOffBrightnessSensor =
- mDisplayDeviceConfig.getScreenOffBrightnessSensor();
mScreenOffBrightnessSensor = SensorUtils.findSensor(mSensorManager,
- screenOffBrightnessSensor.type, screenOffBrightnessSensor.name,
- SensorUtils.NO_FALLBACK);
+ mDisplayDeviceConfig.getScreenOffBrightnessSensor(), SensorUtils.NO_FALLBACK);
}
private void loadProximitySensor() {
if (DEBUG_PRETEND_PROXIMITY_SENSOR_ABSENT || mDisplayId != Display.DEFAULT_DISPLAY) {
return;
}
- final DisplayDeviceConfig.SensorData proxSensor =
- mDisplayDeviceConfig.getProximitySensor();
- mProximitySensor = SensorUtils.findSensor(mSensorManager, proxSensor.type, proxSensor.name,
- Sensor.TYPE_PROXIMITY);
+ mProximitySensor = SensorUtils.findSensor(mSensorManager,
+ mDisplayDeviceConfig.getProximitySensor(), Sensor.TYPE_PROXIMITY);
if (mProximitySensor != null) {
mProximityThreshold = Math.min(mProximitySensor.getMaximumRange(),
TYPICAL_PROXIMITY_THRESHOLD);
diff --git a/services/core/java/com/android/server/display/DisplayPowerController2.java b/services/core/java/com/android/server/display/DisplayPowerController2.java
index 1471ab2..7043af8 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController2.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController2.java
@@ -1296,7 +1296,7 @@
mAutomaticBrightnessStrategy.isShortTermModelActive();
mAutomaticBrightnessStrategy.setAutoBrightnessState(state,
mDisplayBrightnessController.isAllowAutoBrightnessWhileDozingConfig(),
- brightnessState, mBrightnessReasonTemp.getReason(), mPowerRequest.policy,
+ mBrightnessReasonTemp.getReason(), mPowerRequest.policy,
mDisplayBrightnessController.getLastUserSetScreenBrightness(),
userSetBrightnessChanged);
@@ -1306,10 +1306,12 @@
&& (mAutomaticBrightnessStrategy.getAutoBrightnessAdjustmentChanged()
|| userSetBrightnessChanged);
- mBrightnessRangeController.setAutoBrightnessEnabled(mAutomaticBrightnessStrategy
- .shouldUseAutoBrightness()
+ mBrightnessRangeController.setAutoBrightnessEnabled(
+ mAutomaticBrightnessStrategy.isAutoBrightnessEnabled()
? AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED
- : AutomaticBrightnessController.AUTO_BRIGHTNESS_DISABLED);
+ : mAutomaticBrightnessStrategy.isAutoBrightnessDisabledDueToDisplayOff()
+ ? AutomaticBrightnessController.AUTO_BRIGHTNESS_OFF_DUE_TO_DISPLAY_STATE
+ : AutomaticBrightnessController.AUTO_BRIGHTNESS_DISABLED);
boolean updateScreenBrightnessSetting = false;
float currentBrightnessSetting = mDisplayBrightnessController.getCurrentBrightness();
@@ -1948,19 +1950,15 @@
}
private void loadAmbientLightSensor() {
- DisplayDeviceConfig.SensorData lightSensor = mDisplayDeviceConfig.getAmbientLightSensor();
final int fallbackType = mDisplayId == Display.DEFAULT_DISPLAY
? Sensor.TYPE_LIGHT : SensorUtils.NO_FALLBACK;
- mLightSensor = SensorUtils.findSensor(mSensorManager, lightSensor.type, lightSensor.name,
- fallbackType);
+ mLightSensor = SensorUtils.findSensor(mSensorManager,
+ mDisplayDeviceConfig.getAmbientLightSensor(), fallbackType);
}
private void loadScreenOffBrightnessSensor() {
- DisplayDeviceConfig.SensorData screenOffBrightnessSensor =
- mDisplayDeviceConfig.getScreenOffBrightnessSensor();
mScreenOffBrightnessSensor = SensorUtils.findSensor(mSensorManager,
- screenOffBrightnessSensor.type, screenOffBrightnessSensor.name,
- SensorUtils.NO_FALLBACK);
+ mDisplayDeviceConfig.getScreenOffBrightnessSensor(), SensorUtils.NO_FALLBACK);
}
private float clampScreenBrightness(float value) {
diff --git a/services/core/java/com/android/server/display/DisplayPowerProximityStateController.java b/services/core/java/com/android/server/display/DisplayPowerProximityStateController.java
index c074786..882c02f 100644
--- a/services/core/java/com/android/server/display/DisplayPowerProximityStateController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerProximityStateController.java
@@ -358,10 +358,8 @@
if (DEBUG_PRETEND_PROXIMITY_SENSOR_ABSENT || mDisplayId != Display.DEFAULT_DISPLAY) {
return;
}
- final DisplayDeviceConfig.SensorData proxSensor =
- mDisplayDeviceConfig.getProximitySensor();
- mProximitySensor = SensorUtils.findSensor(mSensorManager, proxSensor.type, proxSensor.name,
- Sensor.TYPE_PROXIMITY);
+ mProximitySensor = SensorUtils.findSensor(mSensorManager,
+ mDisplayDeviceConfig.getProximitySensor(), Sensor.TYPE_PROXIMITY);
if (mProximitySensor != null) {
mProximityThreshold = Math.min(mProximitySensor.getMaximumRange(),
TYPICAL_PROXIMITY_THRESHOLD);
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 9b39a7d..bcd5259 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
@@ -73,6 +73,9 @@
// the user has enabled the auto-brightness from the settings, it is disabled because the
// display is off
private boolean mIsAutoBrightnessEnabled = false;
+ // Indicates if auto-brightness is disabled due to the display being off. Needed for metric
+ // purposes.
+ private boolean mAutoBrightnessDisabledDueToDisplayOff;
// If the auto-brightness model for the last manual changes done by the user.
private boolean mIsShortTermModelActive = false;
@@ -96,24 +99,21 @@
* AutomaticBrightnessController accounting for any manual changes made by the user.
*/
public void setAutoBrightnessState(int targetDisplayState,
- boolean allowAutoBrightnessWhileDozingConfig,
- float brightnessState, int brightnessReason, int policy,
+ boolean allowAutoBrightnessWhileDozingConfig, int brightnessReason, int policy,
float lastUserSetScreenBrightness, boolean userSetBrightnessChanged) {
final boolean autoBrightnessEnabledInDoze =
allowAutoBrightnessWhileDozingConfig
&& Display.isDozeState(targetDisplayState);
mIsAutoBrightnessEnabled = shouldUseAutoBrightness()
&& (targetDisplayState == Display.STATE_ON || autoBrightnessEnabledInDoze)
- && (Float.isNaN(brightnessState)
- || brightnessReason == BrightnessReason.REASON_TEMPORARY
- || brightnessReason == BrightnessReason.REASON_BOOST)
- && mAutomaticBrightnessController != null
- && brightnessReason != BrightnessReason.REASON_FOLLOWER;
- final boolean autoBrightnessDisabledDueToDisplayOff = shouldUseAutoBrightness()
+ && brightnessReason != BrightnessReason.REASON_OVERRIDE
+ && mAutomaticBrightnessController != null;
+ mAutoBrightnessDisabledDueToDisplayOff = shouldUseAutoBrightness()
&& !(targetDisplayState == Display.STATE_ON || autoBrightnessEnabledInDoze);
final int autoBrightnessState = mIsAutoBrightnessEnabled
+ && brightnessReason != BrightnessReason.REASON_FOLLOWER
? AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED
- : autoBrightnessDisabledDueToDisplayOff
+ : mAutoBrightnessDisabledDueToDisplayOff
? AutomaticBrightnessController.AUTO_BRIGHTNESS_OFF_DUE_TO_DISPLAY_STATE
: AutomaticBrightnessController.AUTO_BRIGHTNESS_DISABLED;
@@ -125,6 +125,10 @@
return mIsAutoBrightnessEnabled;
}
+ public boolean isAutoBrightnessDisabledDueToDisplayOff() {
+ return mAutoBrightnessDisabledDueToDisplayOff;
+ }
+
/**
* Updates the {@link BrightnessConfiguration} that is currently being used by the associated
* display.
diff --git a/services/core/java/com/android/server/display/utils/SensorUtils.java b/services/core/java/com/android/server/display/utils/SensorUtils.java
index 48bc46c..56321cd 100644
--- a/services/core/java/com/android/server/display/utils/SensorUtils.java
+++ b/services/core/java/com/android/server/display/utils/SensorUtils.java
@@ -16,10 +16,13 @@
package com.android.server.display.utils;
+import android.annotation.Nullable;
import android.hardware.Sensor;
import android.hardware.SensorManager;
import android.text.TextUtils;
+import com.android.server.display.DisplayDeviceConfig;
+
import java.util.List;
/**
@@ -29,17 +32,26 @@
public static final int NO_FALLBACK = 0;
/**
+ * Finds the specified sensor for SensorData from DisplayDeviceConfig.
+ */
+ @Nullable
+ public static Sensor findSensor(@Nullable SensorManager sensorManager,
+ @Nullable DisplayDeviceConfig.SensorData sensorData, int fallbackType) {
+ if (sensorData == null) {
+ return null;
+ } else {
+ return findSensor(sensorManager, sensorData.type, sensorData.name, fallbackType);
+ }
+ }
+ /**
* Finds the specified sensor by type and name using SensorManager.
*/
- public static Sensor findSensor(SensorManager sensorManager, String sensorType,
- String sensorName, int fallbackType) {
+ @Nullable
+ public static Sensor findSensor(@Nullable SensorManager sensorManager,
+ @Nullable String sensorType, @Nullable String sensorName, int fallbackType) {
if (sensorManager == null) {
return null;
}
-
- if ("".equals(sensorName) && "".equals(sensorType)) {
- return null;
- }
final boolean isNameSpecified = !TextUtils.isEmpty(sensorName);
final boolean isTypeSpecified = !TextUtils.isEmpty(sensorType);
if (isNameSpecified || isTypeSpecified) {
diff --git a/services/core/java/com/android/server/lights/LightsService.java b/services/core/java/com/android/server/lights/LightsService.java
index 89dad26..6124b55 100644
--- a/services/core/java/com/android/server/lights/LightsService.java
+++ b/services/core/java/com/android/server/lights/LightsService.java
@@ -468,9 +468,10 @@
}
for (int i = mLightsById.size() - 1; i >= 0; i--) {
- final int type = mLightsById.keyAt(i);
+ LightImpl light = mLightsById.valueAt(i);
+ final int type = light.mHwLight.type;
if (0 <= type && type < mLightsByType.length) {
- mLightsByType[type] = mLightsById.valueAt(i);
+ mLightsByType[type] = light;
}
}
}
diff --git a/services/core/java/com/android/server/locksettings/recoverablekeystore/PlatformKeyManager.java b/services/core/java/com/android/server/locksettings/recoverablekeystore/PlatformKeyManager.java
index 7009a41..ce3fb85 100644
--- a/services/core/java/com/android/server/locksettings/recoverablekeystore/PlatformKeyManager.java
+++ b/services/core/java/com/android/server/locksettings/recoverablekeystore/PlatformKeyManager.java
@@ -166,6 +166,7 @@
* @param userId The ID of the user to whose lock screen the platform key must be bound.
* @throws NoSuchAlgorithmException if AES is unavailable - should never happen.
* @throws KeyStoreException if there is an error in AndroidKeyStore.
+ * @throws InsecureUserException if the user does not have a lock screen set.
* @throws IOException if there was an issue with local database update.
* @throws RemoteException if there was an issue communicating with {@link IGateKeeperService}.
*
@@ -174,7 +175,7 @@
@VisibleForTesting
void regenerate(int userId)
throws NoSuchAlgorithmException, KeyStoreException, IOException,
- RemoteException {
+ RemoteException, InsecureUserException {
int generationId = getGenerationId(userId);
int nextId;
if (generationId == -1) {
@@ -195,13 +196,14 @@
* @throws UnrecoverableKeyException if the key could not be recovered.
* @throws NoSuchAlgorithmException if AES is unavailable - should never occur.
* @throws IOException if there was an issue with local database update.
+ * @throws InsecureUserException if the user does not have a lock screen set.
* @throws RemoteException if there was an issue communicating with {@link IGateKeeperService}.
*
* @hide
*/
public PlatformEncryptionKey getEncryptKey(int userId)
throws KeyStoreException, UnrecoverableKeyException, NoSuchAlgorithmException,
- IOException, RemoteException {
+ IOException, RemoteException, InsecureUserException {
init(userId);
try {
// Try to see if the decryption key is still accessible before using the encryption key.
@@ -254,7 +256,7 @@
*/
public PlatformDecryptionKey getDecryptKey(int userId)
throws KeyStoreException, UnrecoverableKeyException, NoSuchAlgorithmException,
- IOException, RemoteException {
+ IOException, InsecureUserException, RemoteException {
init(userId);
try {
PlatformDecryptionKey decryptionKey = getDecryptKeyInternal(userId);
@@ -328,7 +330,7 @@
*/
void init(int userId)
throws KeyStoreException, NoSuchAlgorithmException, IOException,
- RemoteException {
+ RemoteException, InsecureUserException {
int generationId = getGenerationId(userId);
if (isKeyLoaded(userId, generationId)) {
Log.i(TAG, String.format(
@@ -414,7 +416,8 @@
* @throws RemoteException if there was an issue communicating with {@link IGateKeeperService}.
*/
private void generateAndLoadKey(int userId, int generationId)
- throws NoSuchAlgorithmException, KeyStoreException, IOException, RemoteException {
+ throws NoSuchAlgorithmException, KeyStoreException, IOException, RemoteException,
+ InsecureUserException {
String encryptAlias = getEncryptAlias(userId, generationId);
String decryptAlias = getDecryptAlias(userId, generationId);
// SecretKey implementation doesn't provide reliable way to destroy the secret
@@ -427,23 +430,31 @@
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE);
// Skip UserAuthenticationRequired for main user
if (userId == UserHandle.USER_SYSTEM) {
+ // attempt to store key will fail if screenlock is not set.
decryptionKeyProtection.setUnlockedDeviceRequired(true);
} else {
// Don't set protection params to prevent losing key.
}
// Store decryption key first since it is more likely to fail.
- mKeyStore.setEntry(
- decryptAlias,
- new KeyStore.SecretKeyEntry(secretKey),
- decryptionKeyProtection.build());
- mKeyStore.setEntry(
- encryptAlias,
- new KeyStore.SecretKeyEntry(secretKey),
- new KeyProtection.Builder(KeyProperties.PURPOSE_ENCRYPT)
- .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
- .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
- .build());
-
+ try {
+ mKeyStore.setEntry(
+ decryptAlias,
+ new KeyStore.SecretKeyEntry(secretKey),
+ decryptionKeyProtection.build());
+ mKeyStore.setEntry(
+ encryptAlias,
+ new KeyStore.SecretKeyEntry(secretKey),
+ new KeyProtection.Builder(KeyProperties.PURPOSE_ENCRYPT)
+ .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
+ .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
+ .build());
+ } catch (KeyStoreException e) {
+ if (!isDeviceSecure(userId)) {
+ throw new InsecureUserException("Screenlock is not set");
+ } else {
+ throw e;
+ }
+ }
setGenerationId(userId, generationId);
}
@@ -477,4 +488,8 @@
return keyStore;
}
+ private boolean isDeviceSecure(int userId) {
+ return mContext.getSystemService(KeyguardManager.class).isDeviceSecure(userId);
+ }
+
}
diff --git a/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java b/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java
index 24dbce4..0cfdaf2 100644
--- a/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java
+++ b/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java
@@ -19,6 +19,7 @@
import static android.security.keystore.recovery.RecoveryController.ERROR_BAD_CERTIFICATE_FORMAT;
import static android.security.keystore.recovery.RecoveryController.ERROR_DECRYPTION_FAILED;
import static android.security.keystore.recovery.RecoveryController.ERROR_DOWNGRADE_CERTIFICATE;
+import static android.security.keystore.recovery.RecoveryController.ERROR_INSECURE_USER;
import static android.security.keystore.recovery.RecoveryController.ERROR_INVALID_CERTIFICATE;
import static android.security.keystore.recovery.RecoveryController.ERROR_INVALID_KEY_FORMAT;
import static android.security.keystore.recovery.RecoveryController.ERROR_NO_SNAPSHOT_PENDING;
@@ -750,6 +751,8 @@
throw new RuntimeException(e);
} catch (KeyStoreException | UnrecoverableKeyException | IOException e) {
throw new ServiceSpecificException(ERROR_SERVICE_INTERNAL_ERROR, e.getMessage());
+ } catch (InsecureUserException e) {
+ throw new ServiceSpecificException(ERROR_INSECURE_USER, e.getMessage());
}
try {
@@ -817,6 +820,8 @@
throw new RuntimeException(e);
} catch (KeyStoreException | UnrecoverableKeyException | IOException e) {
throw new ServiceSpecificException(ERROR_SERVICE_INTERNAL_ERROR, e.getMessage());
+ } catch (InsecureUserException e) {
+ throw new ServiceSpecificException(ERROR_INSECURE_USER, e.getMessage());
}
try {
diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java
index 47f6485..9185a00 100644
--- a/services/core/java/com/android/server/media/MediaSessionRecord.java
+++ b/services/core/java/com/android/server/media/MediaSessionRecord.java
@@ -16,6 +16,7 @@
package com.android.server.media;
+import static android.media.MediaRoute2Info.PLAYBACK_VOLUME_FIXED;
import static android.media.VolumeProvider.VOLUME_CONTROL_ABSOLUTE;
import static android.media.VolumeProvider.VOLUME_CONTROL_FIXED;
import static android.media.VolumeProvider.VOLUME_CONTROL_RELATIVE;
@@ -44,7 +45,9 @@
import android.media.AudioManager;
import android.media.AudioSystem;
import android.media.MediaMetadata;
+import android.media.MediaRouter2Manager;
import android.media.Rating;
+import android.media.RoutingSessionInfo;
import android.media.VolumeProvider;
import android.media.session.ISession;
import android.media.session.ISessionCallback;
@@ -510,7 +513,33 @@
@Override
public boolean canHandleVolumeKey() {
- return mVolumeControlType != VOLUME_CONTROL_FIXED;
+ if (isPlaybackTypeLocal()) {
+ return true;
+ }
+ if (mVolumeControlType == VOLUME_CONTROL_FIXED) {
+ return false;
+ }
+ if (mVolumeAdjustmentForRemoteGroupSessions) {
+ return true;
+ }
+ // See b/228021646 for details.
+ MediaRouter2Manager mRouter2Manager = MediaRouter2Manager.getInstance(mContext);
+ List<RoutingSessionInfo> sessions = mRouter2Manager.getRoutingSessions(mPackageName);
+ boolean foundNonSystemSession = false;
+ boolean remoteSessionAllowVolumeAdjustment = true;
+ for (RoutingSessionInfo session : sessions) {
+ if (!session.isSystemSession()) {
+ foundNonSystemSession = true;
+ if (session.getVolumeHandling() == PLAYBACK_VOLUME_FIXED) {
+ remoteSessionAllowVolumeAdjustment = false;
+ }
+ }
+ }
+ if (!foundNonSystemSession) {
+ Log.d(TAG, "Package " + mPackageName
+ + " has a remote media session but no associated routing session");
+ }
+ return foundNonSystemSession && remoteSessionAllowVolumeAdjustment;
}
@Override
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 ae6e83a..fc506b6 100644
--- a/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
+++ b/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
@@ -1048,7 +1048,7 @@
// Tear down projection here; necessary to ensure (among other reasons) that
// stop is dispatched to client and cast icon disappears from status bar.
mProjectionGrant.stop();
- throw new IllegalStateException("Don't re-use the resultData to retrieve "
+ throw new SecurityException("Don't re-use the resultData to retrieve "
+ "the same projection instance, and don't use a token that has "
+ "timed out. Don't take multiple captures by invoking "
+ "MediaProjection#createVirtualDisplay multiple times on the "
diff --git a/services/core/java/com/android/server/os/BugreportManagerServiceImpl.java b/services/core/java/com/android/server/os/BugreportManagerServiceImpl.java
index 0605345..3ba307b 100644
--- a/services/core/java/com/android/server/os/BugreportManagerServiceImpl.java
+++ b/services/core/java/com/android/server/os/BugreportManagerServiceImpl.java
@@ -22,6 +22,7 @@
import android.app.ActivityManager;
import android.app.AppOpsManager;
import android.app.admin.DevicePolicyManager;
+import android.app.role.RoleManager;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.pm.UserInfo;
@@ -64,6 +65,8 @@
private static final int LOCAL_LOG_SIZE = 20;
private static final String TAG = "BugreportManagerService";
private static final boolean DEBUG = false;
+ private static final String ROLE_SYSTEM_AUTOMOTIVE_PROJECTION =
+ "android.app.role.SYSTEM_AUTOMOTIVE_PROJECTION";
private static final String BUGREPORT_SERVICE = "bugreportd";
private static final long DEFAULT_BUGREPORT_SERVICE_TIMEOUT_MILLIS = 30 * 1000;
@@ -326,11 +329,22 @@
// To gain access through the DUMP permission, the OEM has to allow this package explicitly
// via sysconfig and privileged permissions.
- if (mBugreportAllowlistedPackages.contains(callingPackage)
- && mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
- == PackageManager.PERMISSION_GRANTED) {
+ boolean allowlisted = mBugreportAllowlistedPackages.contains(callingPackage);
+ if (!allowlisted) {
+ final long token = Binder.clearCallingIdentity();
+ try {
+ allowlisted = mContext.getSystemService(RoleManager.class).getRoleHolders(
+ ROLE_SYSTEM_AUTOMOTIVE_PROJECTION).contains(callingPackage);
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+
+ if (allowlisted && mContext.checkCallingOrSelfPermission(
+ android.Manifest.permission.DUMP) == PackageManager.PERMISSION_GRANTED) {
return;
}
+
// For carrier privileges, this can include user-installed apps. This is essentially a
// function of the current active SIM(s) in the device to let carrier apps through.
final long token = Binder.clearCallingIdentity();
@@ -346,7 +360,8 @@
String message =
callingPackage
- + " does not hold the DUMP permission or is not bugreport-whitelisted "
+ + " does not hold the DUMP permission or is not bugreport-whitelisted or "
+ + "does not have an allowed role "
+ (checkCarrierPrivileges ? "and does not have carrier privileges " : "")
+ "to request a bugreport";
Slog.w(TAG, message);
diff --git a/services/core/java/com/android/server/pm/AppsFilterBase.java b/services/core/java/com/android/server/pm/AppsFilterBase.java
index 12f6a18..5b32a94 100644
--- a/services/core/java/com/android/server/pm/AppsFilterBase.java
+++ b/services/core/java/com/android/server/pm/AppsFilterBase.java
@@ -197,6 +197,7 @@
protected volatile boolean mCacheReady = false;
protected volatile boolean mCacheEnabled = true;
+ protected volatile boolean mNeedToUpdateCacheForImplicitAccess = false;
protected static final boolean CACHE_VALID = true;
protected static final boolean CACHE_INVALID = false;
diff --git a/services/core/java/com/android/server/pm/AppsFilterImpl.java b/services/core/java/com/android/server/pm/AppsFilterImpl.java
index ba5907c..a5fa81d 100644
--- a/services/core/java/com/android/server/pm/AppsFilterImpl.java
+++ b/services/core/java/com/android/server/pm/AppsFilterImpl.java
@@ -465,6 +465,9 @@
changed = retainOnUpdate
? mRetainedImplicitlyQueryable.add(recipientUid, visibleUid)
: mImplicitlyQueryable.add(recipientUid, visibleUid);
+ if (!mCacheReady && changed) {
+ mNeedToUpdateCacheForImplicitAccess = true;
+ }
}
if (changed && DEBUG_LOGGING) {
Slog.i(TAG, (retainOnUpdate ? "retained " : "") + "implicit access granted: "
@@ -476,8 +479,6 @@
// Update the cache in a one-off manner since we've got all the information we need.
mShouldFilterCache.put(recipientUid, visibleUid, false);
}
- } else if (changed) {
- invalidateCache("grantImplicitAccess: " + recipientUid + " -> " + visibleUid);
}
if (changed) {
onChanged();
@@ -833,7 +834,12 @@
}
updateEntireShouldFilterCacheInner(snapshot, settings, usersRef[0], USER_ALL);
- onChanged();
+ synchronized (mImplicitlyQueryableLock) {
+ if (mNeedToUpdateCacheForImplicitAccess) {
+ updateShouldFilterCacheForImplicitAccess();
+ mNeedToUpdateCacheForImplicitAccess = false;
+ }
+ }
logCacheRebuilt(reason, SystemClock.currentTimeMicro() - currentTimeUs,
users.length, settings.size());
@@ -845,6 +851,7 @@
}
mCacheReady = true;
+ onChanged();
}, delayMs);
}
@@ -875,6 +882,25 @@
snapshot.getPackageStates().size());
}
+ @GuardedBy("mImplicitlyQueryableLock")
+ private void updateShouldFilterCacheForImplicitAccess() {
+ updateShouldFilterCacheForImplicitAccess(mRetainedImplicitlyQueryable);
+ updateShouldFilterCacheForImplicitAccess(mImplicitlyQueryable);
+ }
+
+ private void updateShouldFilterCacheForImplicitAccess(
+ WatchedSparseSetArray<Integer> queriesMap) {
+ synchronized (mCacheLock) {
+ for (int i = 0; i < queriesMap.size(); i++) {
+ Integer callingUid = queriesMap.keyAt(i);
+ ArraySet<Integer> targetUids = queriesMap.get(callingUid);
+ for (Integer targetUid : targetUids) {
+ mShouldFilterCache.put(callingUid, targetUid, false);
+ }
+ }
+ }
+ }
+
private void updateShouldFilterCacheForPackage(Computer snapshot,
String packageName) {
if (!mCacheReady) {
diff --git a/services/core/java/com/android/server/pm/DeletePackageHelper.java b/services/core/java/com/android/server/pm/DeletePackageHelper.java
index 2e85c97..9f3ee1c 100644
--- a/services/core/java/com/android/server/pm/DeletePackageHelper.java
+++ b/services/core/java/com/android/server/pm/DeletePackageHelper.java
@@ -134,10 +134,6 @@
final int removeUser = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0
? UserHandle.USER_ALL : userId;
- if (mPm.isPackageDeviceAdmin(packageName, removeUser)) {
- Slog.w(TAG, "Not removing package " + packageName + ": has active device admin");
- return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER;
- }
final PackageSetting uninstalledPs;
final PackageSetting disabledSystemPs;
@@ -699,18 +695,6 @@
final String packageName = versionedPackage.getPackageName();
final long versionCode = versionedPackage.getLongVersionCode();
- if (mPm.mProtectedPackages.isPackageDataProtected(userId, packageName)) {
- mPm.mHandler.post(() -> {
- try {
- Slog.w(TAG, "Attempted to delete protected package: " + packageName);
- observer.onPackageDeleted(packageName,
- PackageManager.DELETE_FAILED_INTERNAL_ERROR, null);
- } catch (RemoteException re) {
- }
- });
- return;
- }
-
try {
if (mPm.mInjector.getLocalService(ActivityTaskManagerInternal.class)
.isBaseOfLockedTask(packageName)) {
@@ -751,6 +735,41 @@
"deletePackage for user " + userId);
}
+ final long token = Binder.clearCallingIdentity();
+ try {
+ // If a package is device admin, or is data protected for any user, it should not be
+ // uninstalled from that user, or from any users if DELETE_ALL_USERS flag is passed.
+ for (int user : users) {
+ if (mPm.isPackageDeviceAdmin(packageName, user)) {
+ mPm.mHandler.post(() -> {
+ try {
+ Slog.w(TAG, "Not removing package " + packageName
+ + ": has active device admin");
+ observer.onPackageDeleted(packageName,
+ PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER, null);
+ } catch (RemoteException e) {
+ // no-op
+ }
+ });
+ return;
+ }
+ if (mPm.mProtectedPackages.isPackageDataProtected(user, packageName)) {
+ mPm.mHandler.post(() -> {
+ try {
+ Slog.w(TAG, "Attempted to delete protected package: " + packageName);
+ observer.onPackageDeleted(packageName,
+ PackageManager.DELETE_FAILED_INTERNAL_ERROR, null);
+ } catch (RemoteException re) {
+ // no-op
+ }
+ });
+ return;
+ }
+ }
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+
if (mPm.isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) {
mPm.mHandler.post(() -> {
try {
diff --git a/services/core/java/com/android/server/pm/PackageSetting.java b/services/core/java/com/android/server/pm/PackageSetting.java
index 7fda092..2411820 100644
--- a/services/core/java/com/android/server/pm/PackageSetting.java
+++ b/services/core/java/com/android/server/pm/PackageSetting.java
@@ -337,7 +337,7 @@
final long previousFirstInstallTime =
replacedPkgSetting.getUserStateOrDefault(userId).getFirstInstallTimeMillis();
if (previousFirstInstallTime != 0) {
- modifyUserState(userId).setFirstInstallTime(previousFirstInstallTime);
+ modifyUserState(userId).setFirstInstallTimeMillis(previousFirstInstallTime);
}
}
onChanged();
@@ -352,10 +352,10 @@
if (userId == UserHandle.USER_ALL) {
int userStateCount = mUserStates.size();
for (int i = 0; i < userStateCount; i++) {
- mUserStates.valueAt(i).setFirstInstallTime(firstInstallTime);
+ mUserStates.valueAt(i).setFirstInstallTimeMillis(firstInstallTime);
}
} else {
- modifyUserState(userId).setFirstInstallTime(firstInstallTime);
+ modifyUserState(userId).setFirstInstallTimeMillis(firstInstallTime);
}
onChanged();
return this;
@@ -894,7 +894,7 @@
.setVirtualPreload(virtualPreload)
.setHarmfulAppWarning(harmfulAppWarning)
.setSplashScreenTheme(splashScreenTheme)
- .setFirstInstallTime(firstInstallTime);
+ .setFirstInstallTimeMillis(firstInstallTime);
onChanged();
}
diff --git a/services/core/java/com/android/server/pm/pkg/PackageUserStateImpl.java b/services/core/java/com/android/server/pm/pkg/PackageUserStateImpl.java
index ed4aab9..e8e2d41 100644
--- a/services/core/java/com/android/server/pm/pkg/PackageUserStateImpl.java
+++ b/services/core/java/com/android/server/pm/pkg/PackageUserStateImpl.java
@@ -16,6 +16,7 @@
package com.android.server.pm.pkg;
+import android.annotation.CurrentTimeMillisLong;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.ComponentName;
@@ -61,6 +62,7 @@
private int mDistractionFlags;
private boolean mInstantApp;
private boolean mVirtualPreload;
+ @PackageManager.EnabledState
private int mEnabledState = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
@PackageManager.InstallReason
private int mInstallReason = PackageManager.INSTALL_REASON_UNKNOWN;
@@ -90,7 +92,7 @@
@Nullable
private WatchedArrayMap<ComponentName, Pair<String, Integer>> mComponentLabelIconOverrideMap;
- private long mFirstInstallTime;
+ private @CurrentTimeMillisLong long mFirstInstallTimeMillis;
// TODO(b/239050028): Remove, enforce notifying parent through PMS commit method
@Nullable
@@ -147,7 +149,7 @@
mSuspendParams = other.mSuspendParams == null ? null : other.mSuspendParams.snapshot();
mComponentLabelIconOverrideMap = other.mComponentLabelIconOverrideMap == null
? null : other.mComponentLabelIconOverrideMap.snapshot();
- mFirstInstallTime = other.mFirstInstallTime;
+ mFirstInstallTimeMillis = other.mFirstInstallTimeMillis;
mSnapshot = new SnapshotCache.Sealed<>();
}
@@ -538,8 +540,8 @@
return this;
}
- public @NonNull PackageUserStateImpl setFirstInstallTime(long value) {
- mFirstInstallTime = value;
+ public @NonNull PackageUserStateImpl setFirstInstallTimeMillis(long value) {
+ mFirstInstallTimeMillis = value;
onChanged();
return this;
}
@@ -643,7 +645,7 @@
}
@DataClass.Generated.Member
- public int getEnabledState() {
+ public @PackageManager.EnabledState int getEnabledState() {
return mEnabledState;
}
@@ -691,8 +693,8 @@
}
@DataClass.Generated.Member
- public long getFirstInstallTimeMillis() {
- return mFirstInstallTime;
+ public @CurrentTimeMillisLong long getFirstInstallTimeMillis() {
+ return mFirstInstallTimeMillis;
}
@DataClass.Generated.Member
@@ -766,7 +768,7 @@
&& Objects.equals(mSplashScreenTheme, that.mSplashScreenTheme)
&& Objects.equals(mSuspendParams, that.mSuspendParams)
&& Objects.equals(mComponentLabelIconOverrideMap, that.mComponentLabelIconOverrideMap)
- && mFirstInstallTime == that.mFirstInstallTime
+ && mFirstInstallTimeMillis == that.mFirstInstallTimeMillis
&& watchableEquals(that.mWatchable)
&& snapshotEquals(that.mSnapshot);
}
@@ -798,17 +800,17 @@
_hash = 31 * _hash + Objects.hashCode(mSplashScreenTheme);
_hash = 31 * _hash + Objects.hashCode(mSuspendParams);
_hash = 31 * _hash + Objects.hashCode(mComponentLabelIconOverrideMap);
- _hash = 31 * _hash + Long.hashCode(mFirstInstallTime);
+ _hash = 31 * _hash + Long.hashCode(mFirstInstallTimeMillis);
_hash = 31 * _hash + watchableHashCode();
_hash = 31 * _hash + snapshotHashCode();
return _hash;
}
@DataClass.Generated(
- time = 1668033772891L,
+ time = 1686952839807L,
codegenVersion = "1.0.23",
sourceFile = "frameworks/base/services/core/java/com/android/server/pm/pkg/PackageUserStateImpl.java",
- inputSignatures = "protected @android.annotation.Nullable com.android.server.utils.WatchedArraySet<java.lang.String> mDisabledComponentsWatched\nprotected @android.annotation.Nullable com.android.server.utils.WatchedArraySet<java.lang.String> mEnabledComponentsWatched\nprivate long mCeDataInode\nprivate boolean mInstalled\nprivate boolean mStopped\nprivate boolean mNotLaunched\nprivate boolean mHidden\nprivate int mDistractionFlags\nprivate boolean mInstantApp\nprivate boolean mVirtualPreload\nprivate int mEnabledState\nprivate @android.content.pm.PackageManager.InstallReason int mInstallReason\nprivate @android.content.pm.PackageManager.UninstallReason int mUninstallReason\nprivate @android.annotation.Nullable java.lang.String mHarmfulAppWarning\nprivate @android.annotation.Nullable java.lang.String mLastDisableAppCaller\nprivate @android.annotation.Nullable android.content.pm.overlay.OverlayPaths mOverlayPaths\nprotected @android.annotation.Nullable com.android.server.utils.WatchedArrayMap<java.lang.String,android.content.pm.overlay.OverlayPaths> mSharedLibraryOverlayPaths\nprivate @android.annotation.Nullable java.lang.String mSplashScreenTheme\nprivate @android.annotation.Nullable com.android.server.utils.WatchedArrayMap<java.lang.String,com.android.server.pm.pkg.SuspendParams> mSuspendParams\nprivate @android.annotation.Nullable com.android.server.utils.WatchedArrayMap<android.content.ComponentName,android.util.Pair<java.lang.String,java.lang.Integer>> mComponentLabelIconOverrideMap\nprivate long mFirstInstallTime\nprivate @android.annotation.Nullable com.android.server.utils.Watchable mWatchable\nfinal @android.annotation.NonNull com.android.server.utils.SnapshotCache<com.android.server.pm.pkg.PackageUserStateImpl> mSnapshot\nprivate com.android.server.utils.SnapshotCache<com.android.server.pm.pkg.PackageUserStateImpl> makeCache()\nprivate void onChanged()\npublic @android.annotation.NonNull @java.lang.Override com.android.server.pm.pkg.PackageUserStateImpl snapshot()\npublic @android.annotation.Nullable boolean setOverlayPaths(android.content.pm.overlay.OverlayPaths)\npublic boolean setSharedLibraryOverlayPaths(java.lang.String,android.content.pm.overlay.OverlayPaths)\npublic @android.annotation.Nullable @java.lang.Override com.android.server.utils.WatchedArraySet<java.lang.String> getDisabledComponentsNoCopy()\npublic @android.annotation.Nullable @java.lang.Override com.android.server.utils.WatchedArraySet<java.lang.String> getEnabledComponentsNoCopy()\npublic @android.annotation.NonNull @java.lang.Override android.util.ArraySet<java.lang.String> getDisabledComponents()\npublic @android.annotation.NonNull @java.lang.Override android.util.ArraySet<java.lang.String> getEnabledComponents()\npublic @java.lang.Override boolean isComponentEnabled(java.lang.String)\npublic @java.lang.Override boolean isComponentDisabled(java.lang.String)\npublic @java.lang.Override android.content.pm.overlay.OverlayPaths getAllOverlayPaths()\npublic @com.android.internal.annotations.VisibleForTesting boolean overrideLabelAndIcon(android.content.ComponentName,java.lang.String,java.lang.Integer)\npublic void resetOverrideComponentLabelIcon()\npublic @android.annotation.Nullable android.util.Pair<java.lang.String,java.lang.Integer> getOverrideLabelIconForComponent(android.content.ComponentName)\npublic @java.lang.Override boolean isSuspended()\npublic com.android.server.pm.pkg.PackageUserStateImpl putSuspendParams(java.lang.String,com.android.server.pm.pkg.SuspendParams)\npublic com.android.server.pm.pkg.PackageUserStateImpl removeSuspension(java.lang.String)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setDisabledComponents(android.util.ArraySet<java.lang.String>)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setEnabledComponents(android.util.ArraySet<java.lang.String>)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setEnabledComponents(com.android.server.utils.WatchedArraySet<java.lang.String>)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setDisabledComponents(com.android.server.utils.WatchedArraySet<java.lang.String>)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setCeDataInode(long)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setInstalled(boolean)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setStopped(boolean)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setNotLaunched(boolean)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setHidden(boolean)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setDistractionFlags(int)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setInstantApp(boolean)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setVirtualPreload(boolean)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setEnabledState(int)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setInstallReason(int)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setUninstallReason(int)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setHarmfulAppWarning(java.lang.String)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setLastDisableAppCaller(java.lang.String)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setSharedLibraryOverlayPaths(android.util.ArrayMap<java.lang.String,android.content.pm.overlay.OverlayPaths>)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setSplashScreenTheme(java.lang.String)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setSuspendParams(android.util.ArrayMap<java.lang.String,com.android.server.pm.pkg.SuspendParams>)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setComponentLabelIconOverrideMap(android.util.ArrayMap<android.content.ComponentName,android.util.Pair<java.lang.String,java.lang.Integer>>)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setFirstInstallTime(long)\npublic @android.annotation.NonNull @java.lang.Override java.util.Map<java.lang.String,android.content.pm.overlay.OverlayPaths> getSharedLibraryOverlayPaths()\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setWatchable(com.android.server.utils.Watchable)\nprivate boolean watchableEquals(com.android.server.utils.Watchable)\nprivate int watchableHashCode()\nprivate boolean snapshotEquals(com.android.server.utils.SnapshotCache<com.android.server.pm.pkg.PackageUserStateImpl>)\nprivate int snapshotHashCode()\nclass PackageUserStateImpl extends com.android.server.utils.WatchableImpl implements [com.android.server.pm.pkg.PackageUserStateInternal, com.android.server.utils.Snappable]\n@com.android.internal.util.DataClass(genConstructor=false, genBuilder=false, genEqualsHashCode=true)")
+ inputSignatures = "protected @android.annotation.Nullable com.android.server.utils.WatchedArraySet<java.lang.String> mDisabledComponentsWatched\nprotected @android.annotation.Nullable com.android.server.utils.WatchedArraySet<java.lang.String> mEnabledComponentsWatched\nprivate long mCeDataInode\nprivate boolean mInstalled\nprivate boolean mStopped\nprivate boolean mNotLaunched\nprivate boolean mHidden\nprivate int mDistractionFlags\nprivate boolean mInstantApp\nprivate boolean mVirtualPreload\nprivate @android.content.pm.PackageManager.EnabledState int mEnabledState\nprivate @android.content.pm.PackageManager.InstallReason int mInstallReason\nprivate @android.content.pm.PackageManager.UninstallReason int mUninstallReason\nprivate @android.annotation.Nullable java.lang.String mHarmfulAppWarning\nprivate @android.annotation.Nullable java.lang.String mLastDisableAppCaller\nprivate @android.annotation.Nullable android.content.pm.overlay.OverlayPaths mOverlayPaths\nprotected @android.annotation.Nullable com.android.server.utils.WatchedArrayMap<java.lang.String,android.content.pm.overlay.OverlayPaths> mSharedLibraryOverlayPaths\nprivate @android.annotation.Nullable java.lang.String mSplashScreenTheme\nprivate @android.annotation.Nullable com.android.server.utils.WatchedArrayMap<java.lang.String,com.android.server.pm.pkg.SuspendParams> mSuspendParams\nprivate @android.annotation.Nullable com.android.server.utils.WatchedArrayMap<android.content.ComponentName,android.util.Pair<java.lang.String,java.lang.Integer>> mComponentLabelIconOverrideMap\nprivate @android.annotation.CurrentTimeMillisLong long mFirstInstallTimeMillis\nprivate @android.annotation.Nullable com.android.server.utils.Watchable mWatchable\nfinal @android.annotation.NonNull com.android.server.utils.SnapshotCache<com.android.server.pm.pkg.PackageUserStateImpl> mSnapshot\nprivate com.android.server.utils.SnapshotCache<com.android.server.pm.pkg.PackageUserStateImpl> makeCache()\nprivate void onChanged()\npublic @android.annotation.NonNull @java.lang.Override com.android.server.pm.pkg.PackageUserStateImpl snapshot()\npublic @android.annotation.Nullable boolean setOverlayPaths(android.content.pm.overlay.OverlayPaths)\npublic boolean setSharedLibraryOverlayPaths(java.lang.String,android.content.pm.overlay.OverlayPaths)\npublic @android.annotation.Nullable @java.lang.Override com.android.server.utils.WatchedArraySet<java.lang.String> getDisabledComponentsNoCopy()\npublic @android.annotation.Nullable @java.lang.Override com.android.server.utils.WatchedArraySet<java.lang.String> getEnabledComponentsNoCopy()\npublic @android.annotation.NonNull @java.lang.Override android.util.ArraySet<java.lang.String> getDisabledComponents()\npublic @android.annotation.NonNull @java.lang.Override android.util.ArraySet<java.lang.String> getEnabledComponents()\npublic @java.lang.Override boolean isComponentEnabled(java.lang.String)\npublic @java.lang.Override boolean isComponentDisabled(java.lang.String)\npublic @java.lang.Override android.content.pm.overlay.OverlayPaths getAllOverlayPaths()\npublic @com.android.internal.annotations.VisibleForTesting boolean overrideLabelAndIcon(android.content.ComponentName,java.lang.String,java.lang.Integer)\npublic void resetOverrideComponentLabelIcon()\npublic @android.annotation.Nullable android.util.Pair<java.lang.String,java.lang.Integer> getOverrideLabelIconForComponent(android.content.ComponentName)\npublic @java.lang.Override boolean isSuspended()\npublic com.android.server.pm.pkg.PackageUserStateImpl putSuspendParams(java.lang.String,com.android.server.pm.pkg.SuspendParams)\npublic com.android.server.pm.pkg.PackageUserStateImpl removeSuspension(java.lang.String)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setDisabledComponents(android.util.ArraySet<java.lang.String>)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setEnabledComponents(android.util.ArraySet<java.lang.String>)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setEnabledComponents(com.android.server.utils.WatchedArraySet<java.lang.String>)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setDisabledComponents(com.android.server.utils.WatchedArraySet<java.lang.String>)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setCeDataInode(long)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setInstalled(boolean)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setStopped(boolean)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setNotLaunched(boolean)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setHidden(boolean)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setDistractionFlags(int)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setInstantApp(boolean)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setVirtualPreload(boolean)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setEnabledState(int)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setInstallReason(int)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setUninstallReason(int)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setHarmfulAppWarning(java.lang.String)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setLastDisableAppCaller(java.lang.String)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setSharedLibraryOverlayPaths(android.util.ArrayMap<java.lang.String,android.content.pm.overlay.OverlayPaths>)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setSplashScreenTheme(java.lang.String)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setSuspendParams(android.util.ArrayMap<java.lang.String,com.android.server.pm.pkg.SuspendParams>)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setComponentLabelIconOverrideMap(android.util.ArrayMap<android.content.ComponentName,android.util.Pair<java.lang.String,java.lang.Integer>>)\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setFirstInstallTimeMillis(long)\npublic @android.annotation.NonNull @java.lang.Override java.util.Map<java.lang.String,android.content.pm.overlay.OverlayPaths> getSharedLibraryOverlayPaths()\npublic @android.annotation.NonNull com.android.server.pm.pkg.PackageUserStateImpl setWatchable(com.android.server.utils.Watchable)\nprivate boolean watchableEquals(com.android.server.utils.Watchable)\nprivate int watchableHashCode()\nprivate boolean snapshotEquals(com.android.server.utils.SnapshotCache<com.android.server.pm.pkg.PackageUserStateImpl>)\nprivate int snapshotHashCode()\nclass PackageUserStateImpl extends com.android.server.utils.WatchableImpl implements [com.android.server.pm.pkg.PackageUserStateInternal, com.android.server.utils.Snappable]\n@com.android.internal.util.DataClass(genConstructor=false, genBuilder=false, genEqualsHashCode=true)")
@Deprecated
private void __metadata() {}
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 9009e31..4957eaf 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -4779,11 +4779,6 @@
return true;
}
- // Watches consume all key events during ambient when keyguard is not showing.
- if (mHasFeatureWatch) {
- return false;
- }
-
// TODO(b/123372519): Refine when dream can support multi display.
if (isDefaultDisplay) {
// Send events to a dozing dream since the dream is in control of the state of the
diff --git a/services/core/java/com/android/server/servicewatcher/CurrentUserServiceSupplier.java b/services/core/java/com/android/server/servicewatcher/CurrentUserServiceSupplier.java
index 00bedac..6677e7e 100644
--- a/services/core/java/com/android/server/servicewatcher/CurrentUserServiceSupplier.java
+++ b/services/core/java/com/android/server/servicewatcher/CurrentUserServiceSupplier.java
@@ -37,8 +37,8 @@
import android.content.pm.ServiceInfo;
import android.content.res.Resources;
import android.os.Bundle;
+import android.os.Process;
import android.os.UserHandle;
-import android.permission.PermissionManager;
import android.util.Log;
import com.android.internal.util.Preconditions;
@@ -294,8 +294,8 @@
BoundServiceInfo serviceInfo = new BoundServiceInfo(mIntent.getAction(), resolveInfo);
if (mServicePermission != null) {
- if (PermissionManager.checkPackageNamePermission(mServicePermission,
- service.packageName, serviceInfo.getUserId()) != PERMISSION_GRANTED) {
+ if (mContext.checkPermission(mServicePermission, Process.INVALID_PID,
+ serviceInfo.mUid) != PERMISSION_GRANTED) {
Log.d(TAG, serviceInfo.getComponentName().flattenToShortString()
+ " disqualified due to not holding " + mCallerPermission);
continue;
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperCropper.java b/services/core/java/com/android/server/wallpaper/WallpaperCropper.java
index 49b125c..b773ade 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperCropper.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperCropper.java
@@ -81,7 +81,7 @@
if (DEBUG) {
Slog.v(TAG, "Generating crop for new wallpaper(s): 0x"
+ Integer.toHexString(wallpaper.mWhich)
- + " to " + wallpaper.cropFile.getName()
+ + " to " + wallpaper.getCropFile().getName()
+ " crop=(" + cropHint.width() + 'x' + cropHint.height()
+ ") dim=(" + wpData.mWidth + 'x' + wpData.mHeight + ')');
}
@@ -89,7 +89,7 @@
// Analyse the source; needed in multiple cases
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
- BitmapFactory.decodeFile(wallpaper.wallpaperFile.getAbsolutePath(), options);
+ BitmapFactory.decodeFile(wallpaper.getWallpaperFile().getAbsolutePath(), options);
if (options.outWidth <= 0 || options.outHeight <= 0) {
Slog.w(TAG, "Invalid wallpaper data");
success = false;
@@ -154,11 +154,10 @@
// may be we can try to remove this optimized way in the future,
// that means, we will always go into the 'else' block.
- success = FileUtils.copyFile(wallpaper.wallpaperFile, wallpaper.cropFile);
+ success = FileUtils.copyFile(wallpaper.getWallpaperFile(), wallpaper.getCropFile());
if (!success) {
- wallpaper.cropFile.delete();
- // TODO: fall back to default wallpaper in this case
+ wallpaper.getCropFile().delete();
}
if (DEBUG) {
@@ -226,7 +225,7 @@
//Create a record file and will delete if ImageDecoder work well.
final String recordName =
- (wallpaper.wallpaperFile.getName().equals(WALLPAPER)
+ (wallpaper.getWallpaperFile().getName().equals(WALLPAPER)
? RECORD_FILE : RECORD_LOCK_FILE);
final File record = new File(getWallpaperDir(wallpaper.userId), recordName);
record.createNewFile();
@@ -234,7 +233,7 @@
+ ", record name =" + record.getName());
final ImageDecoder.Source srcData =
- ImageDecoder.createSource(wallpaper.wallpaperFile);
+ ImageDecoder.createSource(wallpaper.getWallpaperFile());
final int sampleSize = scale;
Bitmap cropped = ImageDecoder.decodeBitmap(srcData, (decoder, info, src) -> {
decoder.setTargetSampleSize(sampleSize);
@@ -257,7 +256,7 @@
+ " h=" + finalCrop.getHeight());
}
- f = new FileOutputStream(wallpaper.cropFile);
+ f = new FileOutputStream(wallpaper.getCropFile());
bos = new BufferedOutputStream(f, 32 * 1024);
finalCrop.compress(Bitmap.CompressFormat.PNG, 100, bos);
// don't rely on the implicit flush-at-close when noting success
@@ -277,11 +276,11 @@
if (!success) {
Slog.e(TAG, "Unable to apply new wallpaper");
- wallpaper.cropFile.delete();
+ wallpaper.getCropFile().delete();
}
- if (wallpaper.cropFile.exists()) {
- boolean didRestorecon = SELinux.restorecon(wallpaper.cropFile.getAbsoluteFile());
+ if (wallpaper.getCropFile().exists()) {
+ boolean didRestorecon = SELinux.restorecon(wallpaper.getCropFile().getAbsoluteFile());
if (DEBUG) {
Slog.v(TAG, "restorecon() of crop file returned " + didRestorecon);
}
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperData.java b/services/core/java/com/android/server/wallpaper/WallpaperData.java
index d87fca4..b0b66cf 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperData.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperData.java
@@ -40,10 +40,7 @@
*/
class WallpaperData {
- int userId;
-
- final File wallpaperFile; // source image
- final File cropFile; // eventual destination
+ final int userId;
/**
* True while the client is writing a new wallpaper
@@ -133,14 +130,13 @@
*/
final Rect cropHint = new Rect(0, 0, 0, 0);
+ // map of which -> File
+ private final SparseArray<File> mWallpaperFiles = new SparseArray<>();
+ private final SparseArray<File> mCropFiles = new SparseArray<>();
+
WallpaperData(int userId, @SetWallpaperFlags int wallpaperType) {
this.userId = userId;
this.mWhich = wallpaperType;
- File wallpaperDir = getWallpaperDir(userId);
- String wallpaperFileName = (wallpaperType == FLAG_LOCK) ? WALLPAPER_LOCK_ORIG : WALLPAPER;
- String cropFileName = (wallpaperType == FLAG_LOCK) ? WALLPAPER_LOCK_CROP : WALLPAPER_CROP;
- this.wallpaperFile = new File(wallpaperDir, wallpaperFileName);
- this.cropFile = new File(wallpaperDir, cropFileName);
}
/**
@@ -154,8 +150,6 @@
*/
WallpaperData(WallpaperData source) {
this.userId = source.userId;
- this.wallpaperFile = source.wallpaperFile;
- this.cropFile = source.cropFile;
this.wallpaperComponent = source.wallpaperComponent;
this.mWhich = source.mWhich;
this.wallpaperId = source.wallpaperId;
@@ -169,6 +163,25 @@
}
}
+ File getWallpaperFile() {
+ String fileName = mWhich == FLAG_LOCK ? WALLPAPER_LOCK_ORIG : WALLPAPER;
+ return getFile(mWallpaperFiles, fileName);
+ }
+
+ File getCropFile() {
+ String fileName = mWhich == FLAG_LOCK ? WALLPAPER_LOCK_CROP : WALLPAPER_CROP;
+ return getFile(mCropFiles, fileName);
+ }
+
+ private File getFile(SparseArray<File> map, String fileName) {
+ File result = map.get(mWhich);
+ if (result == null) {
+ result = new File(getWallpaperDir(userId), fileName);
+ map.put(userId, result);
+ }
+ return result;
+ }
+
@Override
public String toString() {
StringBuilder out = new StringBuilder(defaultString(this));
@@ -177,7 +190,7 @@
out.append(", which: ");
out.append(mWhich);
out.append(", file mod: ");
- out.append(wallpaperFile != null ? wallpaperFile.lastModified() : "null");
+ out.append(getWallpaperFile() != null ? getWallpaperFile().lastModified() : "null");
if (connection == null) {
out.append(", no connection");
} else {
@@ -202,10 +215,10 @@
// Called during initialization of a given user's wallpaper bookkeeping
boolean cropExists() {
- return cropFile.exists();
+ return getCropFile().exists();
}
boolean sourceExists() {
- return wallpaperFile.exists();
+ return getWallpaperFile().exists();
}
}
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperDataParser.java b/services/core/java/com/android/server/wallpaper/WallpaperDataParser.java
index 1133dba..c54e3bd 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperDataParser.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperDataParser.java
@@ -542,12 +542,12 @@
}
res = r.openRawResource(resId);
- if (wallpaper.wallpaperFile.exists()) {
- wallpaper.wallpaperFile.delete();
- wallpaper.cropFile.delete();
+ if (wallpaper.getWallpaperFile().exists()) {
+ wallpaper.getWallpaperFile().delete();
+ wallpaper.getCropFile().delete();
}
- fos = new FileOutputStream(wallpaper.wallpaperFile);
- cos = new FileOutputStream(wallpaper.cropFile);
+ fos = new FileOutputStream(wallpaper.getWallpaperFile());
+ cos = new FileOutputStream(wallpaper.getCropFile());
byte[] buffer = new byte[32768];
int amt;
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index 712971f..11d1126 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -675,8 +675,8 @@
// Not having a wallpaperComponent means it's a lock screen wallpaper.
final boolean imageWallpaper = mImageWallpaper.equals(wallpaper.wallpaperComponent)
|| wallpaper.wallpaperComponent == null;
- if (imageWallpaper && wallpaper.cropFile != null && wallpaper.cropFile.exists()) {
- cropFile = wallpaper.cropFile.getAbsolutePath();
+ if (imageWallpaper && wallpaper.getCropFile().exists()) {
+ cropFile = wallpaper.getCropFile().getAbsolutePath();
} else if (imageWallpaper && !wallpaper.cropExists() && !wallpaper.sourceExists()) {
defaultImageWallpaper = true;
}
@@ -1839,8 +1839,8 @@
private boolean clearWallpaperBitmaps(WallpaperData wallpaper) {
boolean sourceExists = wallpaper.sourceExists();
boolean cropExists = wallpaper.cropExists();
- if (sourceExists) wallpaper.wallpaperFile.delete();
- if (cropExists) wallpaper.cropFile.delete();
+ if (sourceExists) wallpaper.getWallpaperFile().delete();
+ if (cropExists) wallpaper.getCropFile().delete();
return sourceExists || cropExists;
}
@@ -2439,13 +2439,13 @@
wallpaper.callbacks.register(cb);
}
- File fileToReturn = getCropped ? wallpaper.cropFile : wallpaper.wallpaperFile;
+ File result = getCropped ? wallpaper.getCropFile() : wallpaper.getWallpaperFile();
- if (!fileToReturn.exists()) {
+ if (!result.exists()) {
return null;
}
- return ParcelFileDescriptor.open(fileToReturn, MODE_READ_ONLY);
+ return ParcelFileDescriptor.open(result, MODE_READ_ONLY);
} catch (FileNotFoundException e) {
/* Shouldn't happen as we check to see if the file exists */
Slog.w(TAG, "Error getting wallpaper", e);
@@ -3206,16 +3206,17 @@
// Migrate the bitmap files outright; no need to copy
try {
- if (!mIsLockscreenLiveWallpaperEnabled || sysWP.wallpaperFile.exists()) {
- Os.rename(sysWP.wallpaperFile.getAbsolutePath(),
- lockWP.wallpaperFile.getAbsolutePath());
+ if (!mIsLockscreenLiveWallpaperEnabled || sysWP.getWallpaperFile().exists()) {
+ Os.rename(sysWP.getWallpaperFile().getAbsolutePath(),
+ lockWP.getWallpaperFile().getAbsolutePath());
}
- if (!mIsLockscreenLiveWallpaperEnabled || sysWP.cropFile.exists()) {
- Os.rename(sysWP.cropFile.getAbsolutePath(), lockWP.cropFile.getAbsolutePath());
+ if (!mIsLockscreenLiveWallpaperEnabled || sysWP.getCropFile().exists()) {
+ Os.rename(sysWP.getCropFile().getAbsolutePath(),
+ lockWP.getCropFile().getAbsolutePath());
}
mLockWallpaperMap.put(userId, lockWP);
if (mIsLockscreenLiveWallpaperEnabled) {
- SELinux.restorecon(lockWP.wallpaperFile);
+ SELinux.restorecon(lockWP.getWallpaperFile());
mLastLockWallpaper = lockWP;
}
} catch (ErrnoException e) {
@@ -3236,11 +3237,11 @@
FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
-1, -1);
}
- ParcelFileDescriptor fd = ParcelFileDescriptor.open(wallpaper.wallpaperFile,
+ ParcelFileDescriptor fd = ParcelFileDescriptor.open(wallpaper.getWallpaperFile(),
MODE_CREATE|MODE_READ_WRITE|MODE_TRUNCATE);
- if (!SELinux.restorecon(wallpaper.wallpaperFile)) {
+ if (!SELinux.restorecon(wallpaper.getWallpaperFile())) {
Slog.w(TAG, "restorecon failed for wallpaper file: " +
- wallpaper.wallpaperFile.getPath());
+ wallpaper.getWallpaperFile().getPath());
return null;
}
wallpaper.name = name;
@@ -3251,7 +3252,7 @@
// Nullify field to require new computation
wallpaper.primaryColors = null;
Slog.v(TAG, "updateWallpaperBitmapLocked() : id=" + wallpaper.wallpaperId
- + " name=" + name + " file=" + wallpaper.wallpaperFile.getName());
+ + " name=" + name + " file=" + wallpaper.getWallpaperFile().getName());
return fd;
} catch (FileNotFoundException e) {
Slog.w(TAG, "Error setting wallpaper", e);
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index dce3a38..d2715b6 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -1587,21 +1587,14 @@
newTransition = null;
}
}
- if (isTransientLaunch) {
- if (forceTransientTransition) {
- transitionController.collect(mLastStartActivityRecord);
- transitionController.collect(mPriorAboveTask);
- }
- // `started` isn't guaranteed to be the actual relevant activity, so we must wait
- // until after we launched to identify the relevant activity.
- transitionController.setTransientLaunch(mLastStartActivityRecord, mPriorAboveTask);
- if (forceTransientTransition) {
- final DisplayContent dc = mLastStartActivityRecord.getDisplayContent();
- // update wallpaper target to TransientHide
- dc.mWallpaperController.adjustWallpaperWindows();
- // execute transition because there is no change
- transitionController.setReady(dc, true /* ready */);
- }
+ if (forceTransientTransition) {
+ transitionController.collect(mLastStartActivityRecord);
+ transitionController.collect(mPriorAboveTask);
+ final DisplayContent dc = mLastStartActivityRecord.getDisplayContent();
+ // update wallpaper target to TransientHide
+ dc.mWallpaperController.adjustWallpaperWindows();
+ // execute transition because there is no change
+ transitionController.setReady(dc, true /* ready */);
}
if (!userLeaving) {
// no-user-leaving implies not entering PiP.
@@ -1711,6 +1704,7 @@
activity.destroyIfPossible("Removes redundant singleInstance");
}
}
+ recordTransientLaunchIfNeeded(targetTaskTop);
// Recycle the target task for this launch.
startResult = recycleTask(targetTask, targetTaskTop, reusedTask, intentGrants);
if (startResult != START_SUCCESS) {
@@ -1742,6 +1736,9 @@
addOrReparentStartingActivity(targetTask, "adding to task");
}
+ // After activity is attached to task, but before actual start
+ recordTransientLaunchIfNeeded(mLastStartActivityRecord);
+
if (!mAvoidMoveToFront && mDoResume) {
mTargetRootTask.getRootTask().moveToFront("reuseOrNewTask", targetTask);
if (!mTargetRootTask.isTopRootTaskInDisplayArea() && mService.isDreaming()
@@ -1838,6 +1835,14 @@
return START_SUCCESS;
}
+ private void recordTransientLaunchIfNeeded(ActivityRecord r) {
+ if (r == null || !mTransientLaunch) return;
+ final TransitionController controller = r.mTransitionController;
+ if (controller.isCollecting() && !controller.isTransientCollect(r)) {
+ controller.setTransientLaunch(r, mPriorAboveTask);
+ }
+ }
+
/** Returns the leaf task where the target activity may be placed. */
private Task computeTargetTask() {
if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 4a658d6..41b3aad 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -6068,6 +6068,12 @@
@Override
public void showSystemReadyErrorDialogsIfNeeded() {
+ if (Trace.isTagEnabled(TRACE_TAG_WINDOW_MANAGER)) {
+ Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "showSystemReadyErrorDialogs");
+ }
+ // Pull the check for build consistency outside the lock, to avoid holding the lock for
+ // too long, given that `Build.isBuildConsistent()` takes relatively long.
+ boolean isBuildConsistent = Build.isBuildConsistent();
synchronized (mGlobalLock) {
try {
if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
@@ -6090,7 +6096,7 @@
} catch (RemoteException e) {
}
- if (!Build.isBuildConsistent()) {
+ if (!isBuildConsistent) {
Slog.e(TAG, "Build fingerprint is not consistent, warning user");
mUiHandler.post(() -> {
if (mShowDialogs) {
@@ -6107,6 +6113,7 @@
});
}
}
+ Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
}
@Override
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 2dc133f..e1132db 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -1065,7 +1065,7 @@
if (obscuredChanged && w.isVisible() && mWallpaperController.isWallpaperTarget(w)) {
// This is the wallpaper target and its obscured state changed... make sure the
// current wallpaper's visibility has been updated accordingly.
- mWallpaperController.updateWallpaperVisibility();
+ mWallpaperController.updateWallpaperTokens(mDisplayContent.isKeyguardLocked());
}
w.handleWindowMovedIfNeeded();
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index c2c5947..a61be9e 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -1527,9 +1527,14 @@
}
} else if (win.isDimming()) {
if (mStatusBar != null) {
- if (addStatusBarAppearanceRegionsForDimmingWindow(
- win.mAttrs.insetsFlags.appearance & APPEARANCE_LIGHT_STATUS_BARS,
- mStatusBar.getFrame(), win.getBounds(), win.getFrame())) {
+ // If the dim window is below status bar window, we should update the appearance
+ // region if needed. Otherwise, leave it as it is.
+ final int statusBarLayer = mStatusBar.mToken.getWindowLayerFromType();
+ final int targetWindowLayer = win.mToken.getWindowLayerFromType();
+ if (targetWindowLayer < statusBarLayer
+ && addStatusBarAppearanceRegionsForDimmingWindow(
+ win.mAttrs.insetsFlags.appearance & APPEARANCE_LIGHT_STATUS_BARS,
+ mStatusBar.getFrame(), win.getBounds(), win.getFrame())) {
addSystemBarColorApp(win);
}
}
@@ -2583,7 +2588,8 @@
if (win == null) {
return false;
}
- if (win == getNotificationShade() || win.isActivityTypeDream()) {
+ if (win.mPolicy.getWindowLayerLw(win) > win.mPolicy.getWindowLayerFromTypeLw(
+ WindowManager.LayoutParams.TYPE_STATUS_BAR) || win.isActivityTypeDream()) {
return false;
}
return getInsetsPolicy().hasHiddenSources(Type.navigationBars());
diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java
index cea886f..825d38b 100644
--- a/services/core/java/com/android/server/wm/InputMonitor.java
+++ b/services/core/java/com/android/server/wm/InputMonitor.java
@@ -49,6 +49,7 @@
import static java.lang.Integer.MAX_VALUE;
import android.annotation.Nullable;
+import android.graphics.Rect;
import android.graphics.Region;
import android.os.Handler;
import android.os.IBinder;
@@ -558,7 +559,8 @@
private boolean mAddWallpaperInputConsumerHandle;
private boolean mAddRecentsAnimationInputConsumerHandle;
- boolean mInDrag;
+ private boolean mInDrag;
+ private final Rect mTmpRect = new Rect();
private void updateInputWindows(boolean inDrag) {
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "updateInputWindows");
@@ -582,8 +584,11 @@
layer = layer != null ? layer : activeRecents;
// Handle edge-case for SUW where windows don't exist yet
if (layer.getSurfaceControl() != null) {
- mRecentsAnimationInputConsumer.mWindowHandle
- .replaceTouchableRegionWithCrop(layer.getSurfaceControl());
+ final WindowState targetAppMainWindow = activeRecents.findMainWindow();
+ if (targetAppMainWindow != null) {
+ targetAppMainWindow.getBounds(mTmpRect);
+ mRecentsAnimationInputConsumer.mWindowHandle.touchableRegion.set(mTmpRect);
+ }
mRecentsAnimationInputConsumer.show(mInputTransaction, layer);
mAddRecentsAnimationInputConsumerHandle = false;
}
diff --git a/services/core/java/com/android/server/wm/KeyguardController.java b/services/core/java/com/android/server/wm/KeyguardController.java
index ad9c3b2..671400c 100644
--- a/services/core/java/com/android/server/wm/KeyguardController.java
+++ b/services/core/java/com/android/server/wm/KeyguardController.java
@@ -671,8 +671,7 @@
display.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
}
- if (mTopTurnScreenOnActivity != lastTurnScreenOnActivity
- && mTopTurnScreenOnActivity != null
+ if (mTopTurnScreenOnActivity != null
&& !mService.mWindowManager.mPowerManager.isInteractive()
&& (mRequestDismissKeyguard || occludedByActivity)) {
controller.mTaskSupervisor.wakeUp("handleTurnScreenOn");
diff --git a/services/core/java/com/android/server/wm/LetterboxConfiguration.java b/services/core/java/com/android/server/wm/LetterboxConfiguration.java
index 09cd6a5..fda22ca 100644
--- a/services/core/java/com/android/server/wm/LetterboxConfiguration.java
+++ b/services/core/java/com/android/server/wm/LetterboxConfiguration.java
@@ -78,6 +78,13 @@
private static final boolean DEFAULT_VALUE_ENABLE_LETTERBOX_TRANSLUCENT_ACTIVITY = true;
+ // Whether per-app user aspect ratio override settings is enabled
+ private static final String KEY_ENABLE_USER_ASPECT_RATIO_SETTINGS =
+ "enable_app_compat_user_aspect_ratio_settings";
+
+ // TODO(b/288142656): Enable user aspect ratio settings by default.
+ private static final boolean DEFAULT_VALUE_ENABLE_USER_ASPECT_RATIO_SETTINGS = false;
+
/**
* Override of aspect ratio for fixed orientation letterboxing that is set via ADB with
* set-fixed-orientation-letterbox-aspect-ratio or via {@link
@@ -242,6 +249,9 @@
// Allows to enable letterboxing strategy for translucent activities ignoring flags.
private boolean mTranslucentLetterboxingOverrideEnabled;
+ // Allows to enable user aspect ratio settings ignoring flags.
+ private boolean mUserAppAspectRatioSettingsOverrideEnabled;
+
// Whether we should use split screen aspect ratio for the activity when camera compat treatment
// is enabled and activity is connected to the camera in fullscreen.
private final boolean mIsCameraCompatSplitScreenAspectRatioEnabled;
@@ -345,6 +355,10 @@
DEFAULT_VALUE_ENABLE_LETTERBOX_TRANSLUCENT_ACTIVITY,
mContext.getResources().getBoolean(
R.bool.config_letterboxIsEnabledForTranslucentActivities))
+ .addDeviceConfigEntry(KEY_ENABLE_USER_ASPECT_RATIO_SETTINGS,
+ DEFAULT_VALUE_ENABLE_USER_ASPECT_RATIO_SETTINGS,
+ mContext.getResources().getBoolean(
+ R.bool.config_appCompatUserAppAspectRatioSettingsIsEnabled))
.build();
}
@@ -1207,4 +1221,24 @@
boolean isDisplayRotationImmersiveAppCompatPolicyEnabled() {
return mDeviceConfig.getFlagValue(KEY_ENABLE_DISPLAY_ROTATION_IMMERSIVE_APP_COMPAT_POLICY);
}
+
+ /**
+ * Whether per-app user aspect ratio override settings is enabled
+ */
+ boolean isUserAppAspectRatioSettingsEnabled() {
+ return mUserAppAspectRatioSettingsOverrideEnabled
+ || mDeviceConfig.getFlagValue(KEY_ENABLE_USER_ASPECT_RATIO_SETTINGS);
+ }
+
+ void setUserAppAspectRatioSettingsOverrideEnabled(boolean enabled) {
+ mUserAppAspectRatioSettingsOverrideEnabled = enabled;
+ }
+
+ /**
+ * Resets whether per-app user aspect ratio override settings is enabled
+ * {@code mDeviceConfig.getFlagValue(KEY_ENABLE_USER_ASPECT_RATIO_SETTINGS)}.
+ */
+ void resetUserAppAspectRatioSettingsEnabled() {
+ setUserAppAspectRatioSettingsOverrideEnabled(false);
+ }
}
diff --git a/services/core/java/com/android/server/wm/LetterboxConfigurationPersister.java b/services/core/java/com/android/server/wm/LetterboxConfigurationPersister.java
index 3b10deb..7563397 100644
--- a/services/core/java/com/android/server/wm/LetterboxConfigurationPersister.java
+++ b/services/core/java/com/android/server/wm/LetterboxConfigurationPersister.java
@@ -16,6 +16,8 @@
package com.android.server.wm;
+import static android.os.StrictMode.setThreadPolicy;
+
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
@@ -23,6 +25,8 @@
import android.annotation.Nullable;
import android.content.Context;
import android.os.Environment;
+import android.os.StrictMode;
+import android.os.StrictMode.ThreadPolicy;
import android.util.AtomicFile;
import android.util.Slog;
@@ -125,7 +129,7 @@
final File prefFiles = new File(configFolder, LETTERBOX_CONFIGURATION_FILENAME);
mConfigurationFile = new AtomicFile(prefFiles);
mPersisterQueue = persisterQueue;
- readCurrentConfiguration();
+ runWithDiskReadsThreadPolicy(this::readCurrentConfiguration);
}
/**
@@ -275,6 +279,20 @@
}
}
+ // The LetterboxConfigurationDeviceConfig needs to access the
+ // file with the current reachability position once when the
+ // device boots. Because DisplayThread uses allowIo=false
+ // accessing a file triggers a DiskReadViolation.
+ // Here we use StrictMode to allow the current thread to read
+ // the AtomicFile once in the current thread restoring the
+ // original ThreadPolicy after that.
+ private void runWithDiskReadsThreadPolicy(Runnable runnable) {
+ final ThreadPolicy currentPolicy = StrictMode.getThreadPolicy();
+ setThreadPolicy(new ThreadPolicy.Builder().permitDiskReads().build());
+ runnable.run();
+ setThreadPolicy(currentPolicy);
+ }
+
private static class UpdateValuesCommand implements
PersisterQueue.WriteQueueItem<UpdateValuesCommand> {
diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java
index 3d9edca..0059f0b 100644
--- a/services/core/java/com/android/server/wm/Transition.java
+++ b/services/core/java/com/android/server/wm/Transition.java
@@ -358,22 +358,30 @@
mTransientLaunches.put(activity, restoreBelow);
setTransientLaunchToChanges(activity);
- if (restoreBelow != null) {
- final Task transientRootTask = activity.getRootTask();
+ final Task transientRootTask = activity.getRootTask();
+ final WindowContainer<?> parent = restoreBelow != null ? restoreBelow.getParent()
+ : (transientRootTask != null ? transientRootTask.getParent() : null);
+ if (parent != null) {
// Collect all visible tasks which can be occluded by the transient activity to
// make sure they are in the participants so their visibilities can be updated when
// finishing transition.
- ((WindowContainer<?>) restoreBelow.getParent()).forAllTasks(t -> {
+ parent.forAllTasks(t -> {
+ // Skip transient-launch task
+ if (t == transientRootTask) return false;
if (t.isVisibleRequested() && !t.isAlwaysOnTop()
&& !t.getWindowConfiguration().tasksAreFloating()) {
- if (t.isRootTask() && t != transientRootTask) {
+ if (t.isRootTask()) {
mTransientHideTasks.add(t);
}
if (t.isLeafTask()) {
collect(t);
}
}
- return t == restoreBelow;
+ return restoreBelow != null
+ // Stop at the restoreBelow task
+ ? t == restoreBelow
+ // Or stop at the last visible task if no restore-below (new task)
+ : (t.isRootTask() && t.fillsParent());
});
// Add FLAG_ABOVE_TRANSIENT_LAUNCH to the tree of transient-hide tasks,
// so ChangeInfo#hasChanged() can return true to report the transition info.
@@ -979,7 +987,7 @@
}
if (ar.pictureInPictureArgs != null && ar.pictureInPictureArgs.isAutoEnterEnabled()) {
- if (didCommitTransientLaunch()) {
+ if (!ar.getTask().isVisibleRequested() || didCommitTransientLaunch()) {
// force enable pip-on-task-switch now that we've committed to actually launching
// to the transient activity.
ar.supportsEnterPipOnTaskSwitch = true;
@@ -1008,7 +1016,8 @@
}
// Legacy pip-entry (not via isAutoEnterEnabled).
- if (didCommitTransientLaunch() && ar.supportsPictureInPicture()) {
+ if ((!ar.getTask().isVisibleRequested() || didCommitTransientLaunch())
+ && ar.supportsPictureInPicture()) {
// force enable pip-on-task-switch now that we've committed to actually launching to the
// transient activity, and then recalculate whether we can attempt pip.
ar.supportsEnterPipOnTaskSwitch = true;
diff --git a/services/core/java/com/android/server/wm/WallpaperController.java b/services/core/java/com/android/server/wm/WallpaperController.java
index 0cf4e89..00bedcd 100644
--- a/services/core/java/com/android/server/wm/WallpaperController.java
+++ b/services/core/java/com/android/server/wm/WallpaperController.java
@@ -308,29 +308,12 @@
}
}
- private boolean shouldWallpaperBeVisible(WindowState wallpaperTarget) {
- if (DEBUG_WALLPAPER) {
- Slog.v(TAG, "Wallpaper vis: target " + wallpaperTarget + " prev="
- + mPrevWallpaperTarget);
- }
- return wallpaperTarget != null || mPrevWallpaperTarget != null;
- }
-
boolean isWallpaperTargetAnimating() {
return mWallpaperTarget != null && mWallpaperTarget.isAnimating(TRANSITION | PARENTS)
&& (mWallpaperTarget.mActivityRecord == null
|| !mWallpaperTarget.mActivityRecord.isWaitingForTransitionStart());
}
- void updateWallpaperVisibility() {
- final boolean visible = shouldWallpaperBeVisible(mWallpaperTarget);
-
- for (int curTokenNdx = mWallpaperTokens.size() - 1; curTokenNdx >= 0; curTokenNdx--) {
- final WallpaperWindowToken token = mWallpaperTokens.get(curTokenNdx);
- token.setVisibility(visible);
- }
- }
-
/**
* Make one wallpaper visible, according to {@attr showHome}.
* This is called during the keyguard unlocking transition
@@ -801,11 +784,20 @@
result.setWallpaperTarget(wallpaperTarget);
}
+ public void updateWallpaperTokens(boolean keyguardLocked) {
+ if (DEBUG_WALLPAPER) {
+ Slog.v(TAG, "Wallpaper vis: target " + mWallpaperTarget + " prev="
+ + mPrevWallpaperTarget);
+ }
+ updateWallpaperTokens(mWallpaperTarget != null || mPrevWallpaperTarget != null,
+ keyguardLocked);
+ }
+
/**
* Change the visibility of the top wallpaper to {@param visibility} and hide all the others.
*/
- private void updateWallpaperTokens(boolean visibility, boolean locked) {
- WindowState topWallpaper = mFindResults.getTopWallpaper(locked);
+ private void updateWallpaperTokens(boolean visibility, boolean keyguardLocked) {
+ WindowState topWallpaper = mFindResults.getTopWallpaper(keyguardLocked);
WallpaperWindowToken topWallpaperToken =
topWallpaper == null ? null : topWallpaper.mToken.asWallpaperToken();
for (int curTokenNdx = mWallpaperTokens.size() - 1; curTokenNdx >= 0; curTokenNdx--) {
diff --git a/services/core/java/com/android/server/wm/WindowManagerShellCommand.java b/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
index a153708..05e858d 100644
--- a/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
+++ b/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
@@ -1006,13 +1006,16 @@
runSetBooleanFlag(pw, mLetterboxConfiguration
::setTranslucentLetterboxingOverrideEnabled);
break;
+ case "--isUserAppAspectRatioSettingsEnabled":
+ runSetBooleanFlag(pw, mLetterboxConfiguration
+ ::setUserAppAspectRatioSettingsOverrideEnabled);
+ break;
case "--isCameraCompatRefreshEnabled":
- runSetBooleanFlag(pw, enabled -> mLetterboxConfiguration
- .setCameraCompatRefreshEnabled(enabled));
+ runSetBooleanFlag(pw, mLetterboxConfiguration::setCameraCompatRefreshEnabled);
break;
case "--isCameraCompatRefreshCycleThroughStopEnabled":
- runSetBooleanFlag(pw, enabled -> mLetterboxConfiguration
- .setCameraCompatRefreshCycleThroughStopEnabled(enabled));
+ runSetBooleanFlag(pw,
+ mLetterboxConfiguration::setCameraCompatRefreshCycleThroughStopEnabled);
break;
default:
getErrPrintWriter().println(
@@ -1084,6 +1087,9 @@
case "isTranslucentLetterboxingEnabled":
mLetterboxConfiguration.resetTranslucentLetterboxingEnabled();
break;
+ case "isUserAppAspectRatioSettingsEnabled":
+ mLetterboxConfiguration.resetUserAppAspectRatioSettingsEnabled();
+ break;
case "isCameraCompatRefreshEnabled":
mLetterboxConfiguration.resetCameraCompatRefreshEnabled();
break;
@@ -1194,6 +1200,7 @@
mLetterboxConfiguration.resetIsSplitScreenAspectRatioForUnresizableAppsEnabled();
mLetterboxConfiguration.resetIsDisplayAspectRatioEnabledForFixedOrientationLetterbox();
mLetterboxConfiguration.resetTranslucentLetterboxingEnabled();
+ mLetterboxConfiguration.resetUserAppAspectRatioSettingsEnabled();
mLetterboxConfiguration.resetCameraCompatRefreshEnabled();
mLetterboxConfiguration.resetCameraCompatRefreshCycleThroughStopEnabled();
}
@@ -1249,7 +1256,6 @@
+ mLetterboxConfiguration.isCameraCompatRefreshEnabled());
pw.println(" Refresh using \"stopped -> resumed\" cycle: "
+ mLetterboxConfiguration.isCameraCompatRefreshCycleThroughStopEnabled());
-
pw.println("Background type: "
+ LetterboxConfiguration.letterboxBackgroundTypeToString(
mLetterboxConfiguration.getLetterboxBackgroundType()));
@@ -1259,12 +1265,10 @@
+ mLetterboxConfiguration.getLetterboxBackgroundWallpaperBlurRadius());
pw.println(" Wallpaper dark scrim alpha: "
+ mLetterboxConfiguration.getLetterboxBackgroundWallpaperDarkScrimAlpha());
-
- if (mLetterboxConfiguration.isTranslucentLetterboxingEnabled()) {
- pw.println("Letterboxing for translucent activities: enabled");
- } else {
- pw.println("Letterboxing for translucent activities: disabled");
- }
+ pw.println("Is letterboxing for translucent activities enabled: "
+ + mLetterboxConfiguration.isTranslucentLetterboxingEnabled());
+ pw.println("Is the user aspect ratio settings enabled: "
+ + mLetterboxConfiguration.isUserAppAspectRatioSettingsEnabled());
}
return 0;
}
@@ -1462,6 +1466,8 @@
pw.println(" unresizable apps.");
pw.println(" --isTranslucentLetterboxingEnabled [true|1|false|0]");
pw.println(" Whether letterboxing for translucent activities is enabled.");
+ pw.println(" --isUserAppAspectRatioSettingsEnabled [true|1|false|0]");
+ pw.println(" Whether user aspect ratio settings are enabled.");
pw.println(" --isCameraCompatRefreshEnabled [true|1|false|0]");
pw.println(" Whether camera compatibility refresh is enabled.");
pw.println(" --isCameraCompatRefreshCycleThroughStopEnabled [true|1|false|0]");
@@ -1473,7 +1479,7 @@
pw.println(" |horizontalPositionMultiplier|verticalPositionMultiplier");
pw.println(" |isHorizontalReachabilityEnabled|isVerticalReachabilityEnabled");
pw.println(" |isEducationEnabled||defaultPositionMultiplierForHorizontalReachability");
- pw.println(" |isTranslucentLetterboxingEnabled");
+ pw.println(" |isTranslucentLetterboxingEnabled|isUserAppAspectRatioSettingsEnabled");
pw.println(" |defaultPositionMultiplierForVerticalReachability]");
pw.println(" Resets overrides to default values for specified properties separated");
pw.println(" by space, e.g. 'reset-letterbox-style aspectRatio cornerRadius'.");
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 5579e52..cf1e51f 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -3393,12 +3393,20 @@
// apps won't always be considered as foreground state.
// Exclude private presentations as they can only be shown on private virtual displays and
// shouldn't be the cause of an app be considered foreground.
- if (mAttrs.type >= FIRST_SYSTEM_WINDOW && mAttrs.type != TYPE_TOAST
- && mAttrs.type != TYPE_PRIVATE_PRESENTATION) {
+ // Exclude presentations on virtual displays as they are not actually visible.
+ if (mAttrs.type >= FIRST_SYSTEM_WINDOW
+ && mAttrs.type != TYPE_TOAST
+ && mAttrs.type != TYPE_PRIVATE_PRESENTATION
+ && !(mAttrs.type == TYPE_PRESENTATION && isOnVirtualDisplay())
+ ) {
mWmService.mAtmService.mActiveUids.onNonAppSurfaceVisibilityChanged(mOwnerUid, shown);
}
}
+ private boolean isOnVirtualDisplay() {
+ return getDisplayContent().mDisplay.getType() == Display.TYPE_VIRTUAL;
+ }
+
private void logExclusionRestrictions(int side) {
if (!logsGestureExclusionRestrictions(this)
|| SystemClock.uptimeMillis() < mLastExclusionLogUptimeMillis[side]
diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp
index a1f5318..cb0b9c9 100644
--- a/services/core/jni/com_android_server_input_InputManagerService.cpp
+++ b/services/core/jni/com_android_server_input_InputManagerService.cpp
@@ -277,7 +277,7 @@
base::Result<std::unique_ptr<InputChannel>> createInputChannel(const std::string& name);
base::Result<std::unique_ptr<InputChannel>> createInputMonitor(int32_t displayId,
const std::string& name,
- int32_t pid);
+ gui::Pid pid);
status_t removeInputChannel(const sp<IBinder>& connectionToken);
status_t pilferPointers(const sp<IBinder>& token);
@@ -328,9 +328,9 @@
void notifyConfigurationChanged(nsecs_t when) override;
// ANR-related callbacks -- start
void notifyNoFocusedWindowAnr(const std::shared_ptr<InputApplicationHandle>& handle) override;
- void notifyWindowUnresponsive(const sp<IBinder>& token, std::optional<int32_t> pid,
+ void notifyWindowUnresponsive(const sp<IBinder>& token, std::optional<gui::Pid> pid,
const std::string& reason) override;
- void notifyWindowResponsive(const sp<IBinder>& token, std::optional<int32_t> pid) override;
+ void notifyWindowResponsive(const sp<IBinder>& token, std::optional<gui::Pid> pid) override;
// ANR-related callbacks -- end
void notifyInputChannelBroken(const sp<IBinder>& token) override;
void notifyFocusChanged(const sp<IBinder>& oldToken, const sp<IBinder>& newToken) override;
@@ -353,7 +353,7 @@
void setPointerCapture(const PointerCaptureRequest& request) override;
void notifyDropWindow(const sp<IBinder>& token, float x, float y) override;
void notifyDeviceInteraction(int32_t deviceId, nsecs_t timestamp,
- const std::set<int32_t>& uids) override;
+ const std::set<gui::Uid>& uids) override;
/* --- PointerControllerPolicyInterface implementation --- */
@@ -538,7 +538,7 @@
}
base::Result<std::unique_ptr<InputChannel>> NativeInputManager::createInputMonitor(
- int32_t displayId, const std::string& name, int32_t pid) {
+ int32_t displayId, const std::string& name, gui::Pid pid) {
ATRACE_CALL();
return mInputManager->getDispatcher().createInputMonitor(displayId, name, pid);
}
@@ -882,7 +882,7 @@
}
void NativeInputManager::notifyWindowUnresponsive(const sp<IBinder>& token,
- std::optional<int32_t> pid,
+ std::optional<gui::Pid> pid,
const std::string& reason) {
#if DEBUG_INPUT_DISPATCHER_POLICY
ALOGD("notifyWindowUnresponsive");
@@ -896,12 +896,12 @@
ScopedLocalRef<jstring> reasonObj(env, env->NewStringUTF(reason.c_str()));
env->CallVoidMethod(mServiceObj, gServiceClassInfo.notifyWindowUnresponsive, tokenObj,
- pid.value_or(0), pid.has_value(), reasonObj.get());
+ pid.value_or(gui::Pid{0}).val(), pid.has_value(), reasonObj.get());
checkAndClearExceptionFromCallback(env, "notifyWindowUnresponsive");
}
void NativeInputManager::notifyWindowResponsive(const sp<IBinder>& token,
- std::optional<int32_t> pid) {
+ std::optional<gui::Pid> pid) {
#if DEBUG_INPUT_DISPATCHER_POLICY
ALOGD("notifyWindowResponsive");
#endif
@@ -913,7 +913,7 @@
jobject tokenObj = javaObjectForIBinder(env, token);
env->CallVoidMethod(mServiceObj, gServiceClassInfo.notifyWindowResponsive, tokenObj,
- pid.value_or(0), pid.has_value());
+ pid.value_or(gui::Pid{0}).val(), pid.has_value());
checkAndClearExceptionFromCallback(env, "notifyWindowResponsive");
}
@@ -966,7 +966,7 @@
}
void NativeInputManager::notifyDeviceInteraction(int32_t deviceId, nsecs_t timestamp,
- const std::set<int32_t>& uids) {
+ const std::set<gui::Uid>& uids) {
static const bool ENABLE_INPUT_DEVICE_USAGE_METRICS =
sysprop::InputProperties::enable_input_device_usage_metrics().value_or(true);
if (!ENABLE_INPUT_DEVICE_USAGE_METRICS) return;
@@ -1804,7 +1804,7 @@
std::string name = nameChars.c_str();
base::Result<std::unique_ptr<InputChannel>> inputChannel =
- im->createInputMonitor(displayId, name, pid);
+ im->createInputMonitor(displayId, name, gui::Pid{pid});
if (!inputChannel.ok()) {
std::string message = inputChannel.error().message();
@@ -1849,7 +1849,8 @@
jint pid, jint uid, jboolean hasPermission, jint displayId) {
NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
- return im->getInputManager()->getDispatcher().setInTouchMode(inTouchMode, pid, uid,
+ return im->getInputManager()->getDispatcher().setInTouchMode(inTouchMode, gui::Pid{pid},
+ gui::Uid{static_cast<uid_t>(uid)},
hasPermission, displayId);
}
@@ -1865,7 +1866,7 @@
jint timeoutMillis, jint policyFlags) {
NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
- const std::optional<int32_t> targetUid = injectIntoUid ? std::make_optional(uid) : std::nullopt;
+ const auto targetUid = injectIntoUid ? std::make_optional<gui::Uid>(uid) : std::nullopt;
// static_cast is safe because the value was already checked at the Java layer
InputEventInjectionSync mode = static_cast<InputEventInjectionSync>(syncMode);
diff --git a/services/credentials/java/com/android/server/credentials/GetRequestSession.java b/services/credentials/java/com/android/server/credentials/GetRequestSession.java
index aee4f58..c9e691e 100644
--- a/services/credentials/java/com/android/server/credentials/GetRequestSession.java
+++ b/services/credentials/java/com/android/server/credentials/GetRequestSession.java
@@ -28,6 +28,7 @@
import android.credentials.IGetCredentialCallback;
import android.credentials.ui.ProviderData;
import android.credentials.ui.RequestInfo;
+import android.os.Binder;
import android.os.CancellationSignal;
import android.os.RemoteException;
import android.service.credentials.CallingAppInfo;
@@ -98,8 +99,9 @@
protected void launchUiWithProviderData(ArrayList<ProviderData> providerDataList) {
mRequestSessionMetric.collectUiCallStartTime(System.nanoTime());
mCredentialManagerUi.setStatus(CredentialManagerUi.UiStatus.USER_INTERACTION);
- cancelExistingPendingIntent();
+ Binder.withCleanCallingIdentity(()-> {
try {
+ cancelExistingPendingIntent();
mPendingIntent = mCredentialManagerUi.createPendingIntent(
RequestInfo.newGetRequestInfo(
mRequestId, mClientRequest, mClientAppInfo.getPackageName(),
@@ -112,9 +114,9 @@
mCredentialManagerUi.setStatus(CredentialManagerUi.UiStatus.TERMINATED);
String exception = GetCredentialException.TYPE_UNKNOWN;
mRequestSessionMetric.collectFrameworkException(exception);
- respondToClientWithErrorAndFinish(
- exception, "Unable to instantiate selector");
- }
+ respondToClientWithErrorAndFinish(exception, "Unable to instantiate selector");
+ }
+ });
}
@Override
diff --git a/services/credentials/java/com/android/server/credentials/ProviderRegistryGetSession.java b/services/credentials/java/com/android/server/credentials/ProviderRegistryGetSession.java
index b0b72bc..46c90b4 100644
--- a/services/credentials/java/com/android/server/credentials/ProviderRegistryGetSession.java
+++ b/services/credentials/java/com/android/server/credentials/ProviderRegistryGetSession.java
@@ -38,11 +38,13 @@
import com.android.internal.annotations.VisibleForTesting;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.UUID;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -116,7 +118,7 @@
@NonNull String servicePackageName,
@NonNull CredentialOption requestOption) {
super(context, requestOption, session,
- new ComponentName(servicePackageName, servicePackageName),
+ new ComponentName(servicePackageName, UUID.randomUUID().toString()),
userId, null);
mCredentialDescriptionRegistry = CredentialDescriptionRegistry.forUser(userId);
mCallingAppInfo = callingAppInfo;
@@ -133,7 +135,7 @@
@NonNull String servicePackageName,
@NonNull CredentialOption requestOption) {
super(context, requestOption, session,
- new ComponentName(servicePackageName, servicePackageName),
+ new ComponentName(servicePackageName, UUID.randomUUID().toString()),
userId, null);
mCredentialDescriptionRegistry = CredentialDescriptionRegistry.forUser(userId);
mCallingAppInfo = callingAppInfo;
@@ -179,7 +181,9 @@
return null;
}
return new GetCredentialProviderData.Builder(
- mComponentName.flattenToString()).setActionChips(null)
+ mComponentName.flattenToString())
+ .setActionChips(Collections.EMPTY_LIST)
+ .setAuthenticationEntries(Collections.EMPTY_LIST)
.setCredentialEntries(prepareUiCredentialEntries(
mProviderResponse.stream().flatMap((Function<CredentialDescriptionRegistry
.FilterResult,
@@ -261,12 +265,12 @@
.getFilteredResultForProvider(mCredentialProviderPackageName,
mElementKeys);
mCredentialEntries = mProviderResponse.stream().flatMap(
- (Function<CredentialDescriptionRegistry.FilterResult,
- Stream<CredentialEntry>>) filterResult
- -> filterResult.mCredentialEntries.stream())
- .collect(Collectors.toList());
+ (Function<CredentialDescriptionRegistry.FilterResult,
+ Stream<CredentialEntry>>)
+ filterResult -> filterResult.mCredentialEntries.stream())
+ .collect(Collectors.toList());
updateStatusAndInvokeCallback(Status.CREDENTIALS_RECEIVED,
- /*source=*/ CredentialsSource.REGISTRY);
+ /*source=*/ CredentialsSource.REGISTRY);
mProviderSessionMetric.collectCandidateEntryMetrics(mCredentialEntries);
}
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 8a90079..3c9538a 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -2047,14 +2047,17 @@
t.traceEnd();
}
- t.traceBegin("StartPacProxyService");
- try {
- pacProxyService = new PacProxyService(context);
- ServiceManager.addService(Context.PAC_PROXY_SERVICE, pacProxyService);
- } catch (Throwable e) {
- reportWtf("starting PacProxyService", e);
+ // Devices without WebView/JavaScript cannot support PAC proxies.
+ if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WEBVIEW)) {
+ t.traceBegin("StartPacProxyService");
+ try {
+ pacProxyService = new PacProxyService(context);
+ ServiceManager.addService(Context.PAC_PROXY_SERVICE, pacProxyService);
+ } catch (Throwable e) {
+ reportWtf("starting PacProxyService", e);
+ }
+ t.traceEnd();
}
- t.traceEnd();
t.traceBegin("StartConnectivityService");
// This has to be called after NetworkManagementService, NetworkStatsService
diff --git a/services/permission/java/com/android/server/permission/access/AccessPolicy.kt b/services/permission/java/com/android/server/permission/access/AccessPolicy.kt
index c60f184..17474fb 100644
--- a/services/permission/java/com/android/server/permission/access/AccessPolicy.kt
+++ b/services/permission/java/com/android/server/permission/access/AccessPolicy.kt
@@ -469,7 +469,7 @@
companion object {
private val LOG_TAG = AccessPolicy::class.java.simpleName
- internal const val VERSION_LATEST = 14
+ internal const val VERSION_LATEST = 15
private const val TAG_ACCESS = "access"
private const val TAG_DEFAULT_PERMISSION_GRANT = "default-permission-grant"
diff --git a/services/permission/java/com/android/server/permission/access/permission/AppIdPermissionPolicy.kt b/services/permission/java/com/android/server/permission/access/permission/AppIdPermissionPolicy.kt
index b0a964a..b1369fe 100644
--- a/services/permission/java/com/android/server/permission/access/permission/AppIdPermissionPolicy.kt
+++ b/services/permission/java/com/android/server/permission/access/permission/AppIdPermissionPolicy.kt
@@ -519,9 +519,15 @@
val isPermissionChanged = oldPermission == null ||
newPackageName != oldPermission.packageName ||
newPermission.protectionLevel != oldPermission.protectionLevel || (
- oldPermission.isReconciled && newPermission.isRuntime &&
- newPermission.groupName != null &&
- newPermission.groupName != oldPermission.groupName
+ oldPermission.isReconciled && (
+ (
+ newPermission.isKnownSigner &&
+ newPermission.knownCerts != oldPermission.knownCerts
+ ) || (
+ newPermission.isRuntime && newPermission.groupName != null &&
+ newPermission.groupName != oldPermission.groupName
+ )
+ )
)
if (isPermissionChanged) {
changedPermissionNames += permissionName
diff --git a/services/permission/java/com/android/server/permission/access/permission/AppIdPermissionUpgrade.kt b/services/permission/java/com/android/server/permission/access/permission/AppIdPermissionUpgrade.kt
index 875183c..b644d8f 100644
--- a/services/permission/java/com/android/server/permission/access/permission/AppIdPermissionUpgrade.kt
+++ b/services/permission/java/com/android/server/permission/access/permission/AppIdPermissionUpgrade.kt
@@ -56,7 +56,7 @@
)
upgradeAccessMediaLocationPermission(packageState, userId)
}
- // Enable isAtLeastT check, when moving subsystem to mainline.
+ // TODO Enable isAtLeastT check, when moving subsystem to mainline.
if (version <= 12 /*&& SdkLevel.isAtLeastT()*/) {
Slog.v(
LOG_TAG, "Upgrading scoped permissions for package: $packageName" +
@@ -64,6 +64,14 @@
)
upgradeAuralVisualMediaPermissions(packageState, userId)
}
+ // TODO Enable isAtLeastU check, when moving subsystem to mainline.
+ if (version <= 14 /*&& SdkLevel.isAtLeastU()*/) {
+ Slog.v(
+ LOG_TAG, "Upgrading visual media permission for package: $packageName" +
+ ", version: $version, user: $userId"
+ )
+ upgradeUserSelectedVisualMediaPermission(packageState, userId)
+ }
// Add a new upgrade step: if (packageVersion <= LATEST_VERSION) { .... }
// Also increase LATEST_VERSION
}
@@ -127,6 +135,9 @@
}
}
+ /**
+ * Upgrade permissions based on storage permissions grant
+ */
private fun MutateStateScope.upgradeAuralVisualMediaPermissions(
packageState: PackageState,
userId: Int
@@ -154,6 +165,36 @@
}
}
+ /**
+ * Upgrade permission based on the grant in [Manifest.permission_group.READ_MEDIA_VISUAL]
+ */
+ private fun MutateStateScope.upgradeUserSelectedVisualMediaPermission(
+ packageState: PackageState,
+ userId: Int
+ ) {
+ val androidPackage = packageState.androidPackage!!
+ if (androidPackage.targetSdkVersion < Build.VERSION_CODES.TIRAMISU) {
+ return
+ }
+ val requestedPermissionNames = androidPackage.requestedPermissions
+ val isVisualMediaUserGranted = VISUAL_MEDIA_PERMISSIONS.anyIndexed { _, permissionName ->
+ if (permissionName !in requestedPermissionNames) {
+ return@anyIndexed false
+ }
+ val flags = with(policy) {
+ getPermissionFlags(packageState.appId, userId, permissionName)
+ }
+ PermissionFlags.isAppOpGranted(flags) && flags.hasBits(PermissionFlags.USER_SET)
+ }
+ if (isVisualMediaUserGranted) {
+ if (Manifest.permission.READ_MEDIA_VISUAL_USER_SELECTED in requestedPermissionNames) {
+ grantRuntimePermission(
+ packageState, userId, Manifest.permission.READ_MEDIA_VISUAL_USER_SELECTED
+ )
+ }
+ }
+ }
+
private fun MutateStateScope.grantRuntimePermission(
packageState: PackageState,
userId: Int,
@@ -218,7 +259,14 @@
Manifest.permission.READ_MEDIA_AUDIO,
Manifest.permission.READ_MEDIA_IMAGES,
Manifest.permission.READ_MEDIA_VIDEO,
+ Manifest.permission.ACCESS_MEDIA_LOCATION,
Manifest.permission.READ_MEDIA_VISUAL_USER_SELECTED
)
+ // Visual media permissions in T
+ private val VISUAL_MEDIA_PERMISSIONS = indexedSetOf(
+ Manifest.permission.READ_MEDIA_IMAGES,
+ Manifest.permission.READ_MEDIA_VIDEO,
+ Manifest.permission.ACCESS_MEDIA_LOCATION
+ )
}
}
diff --git a/services/permission/java/com/android/server/permission/access/util/PackageVersionMigration.kt b/services/permission/java/com/android/server/permission/access/util/PackageVersionMigration.kt
index fa6b6b1..a61489c 100644
--- a/services/permission/java/com/android/server/permission/access/util/PackageVersionMigration.kt
+++ b/services/permission/java/com/android/server/permission/access/util/PackageVersionMigration.kt
@@ -43,8 +43,9 @@
permissionVersion == -1 && appOpVersion == -1 ->
error("getVersion() called when there are no legacy files")
// merging combination of versions based on released android version
- // permissions version 1-8 were released in Q, 9 in S and 10 in T
+ // permissions version 1-8 were released in Q, 9 in S, 10 in T and 11 in U
// app ops version 1 was released in P, 3 in U.
+ permissionVersion >= 11 && appOpVersion >= 3 -> 15
permissionVersion >= 10 && appOpVersion >= 3 -> 14
permissionVersion >= 10 && appOpVersion >= 1 -> 13
permissionVersion >= 9 && appOpVersion >= 1 -> 12
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/AsyncProcessStartTest.java b/services/tests/mockingservicestests/src/com/android/server/am/AsyncProcessStartTest.java
index 70ee4f4..0abf46b 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/AsyncProcessStartTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/AsyncProcessStartTest.java
@@ -131,6 +131,7 @@
mRealAms = new ActivityManagerService(
new TestInjector(mContext), mServiceThreadRule.getThread());
+ mRealAms.mConstants.loadDeviceConfigConstants();
mRealAms.mActivityTaskManager = new ActivityTaskManagerService(mContext);
mRealAms.mActivityTaskManager.initialize(null, null, mContext.getMainLooper());
mRealAms.mAtmInternal = mActivityTaskManagerInt;
@@ -195,7 +196,9 @@
Log.v(TAG, "Intercepting bindApplication() for "
+ Arrays.toString(invocation.getArguments()));
if (!wedge) {
- mRealAms.finishAttachApplication(0);
+ if (mRealAms.mConstants.mEnableWaitForFinishAttachApplication) {
+ mRealAms.finishAttachApplication(0);
+ }
}
return null;
}).when(thread).bindApplication(
@@ -237,9 +240,10 @@
*/
@Test
public void testNormal() throws Exception {
- ProcessRecord app = startProcessAndWait(false);
-
- verify(app, never()).killLocked(any(), anyInt(), anyBoolean());
+ if (mRealAms.mConstants.mEnableWaitForFinishAttachApplication) {
+ ProcessRecord app = startProcessAndWait(false);
+ verify(app, never()).killLocked(any(), anyInt(), anyBoolean());
+ }
}
/**
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/BackgroundRestrictionTest.java b/services/tests/mockingservicestests/src/com/android/server/am/BackgroundRestrictionTest.java
index bad04dc..fe23eee 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/BackgroundRestrictionTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/BackgroundRestrictionTest.java
@@ -2439,6 +2439,13 @@
doReturn(granted ? PERMISSION_GRANTED : PERMISSION_DENIED)
.when(mPermissionManagerServiceInternal)
.checkPermission(packageName, perm, UserHandle.getUserId(uid));
+ try {
+ doReturn(granted ? PERMISSION_GRANTED : PERMISSION_DENIED)
+ .when(mIActivityManager)
+ .checkPermission(perm, Process.INVALID_PID, uid);
+ } catch (RemoteException e) {
+ // Ignore.
+ }
}
private void setAppOpState(String packageName, int uid, int op, boolean granted) {
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueModernImplTest.java b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueModernImplTest.java
index d937e7b..ff04728 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueModernImplTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueModernImplTest.java
@@ -66,6 +66,7 @@
import android.annotation.NonNull;
import android.app.Activity;
+import android.app.ActivityManager;
import android.app.AppOpsManager;
import android.app.BackgroundStartPrivileges;
import android.app.BroadcastOptions;
@@ -555,6 +556,33 @@
}
@Test
+ public void testRunnableAt_processTop() {
+ final BroadcastProcessQueue queue = new BroadcastProcessQueue(mConstants, PACKAGE_GREEN,
+ getUidForPackage(PACKAGE_GREEN));
+
+ doReturn(ActivityManager.PROCESS_STATE_TOP).when(mProcess).getSetProcState();
+ queue.setProcessAndUidState(mProcess, false, false);
+
+ final Intent timeTick = new Intent(Intent.ACTION_TIME_TICK);
+ final BroadcastRecord timeTickRecord = makeBroadcastRecord(timeTick,
+ List.of(makeMockRegisteredReceiver()));
+ enqueueOrReplaceBroadcast(queue, timeTickRecord, 0);
+
+ assertThat(queue.getRunnableAt()).isLessThan(timeTickRecord.enqueueTime);
+ assertEquals(BroadcastProcessQueue.REASON_TOP_PROCESS, queue.getRunnableAtReason());
+
+ doReturn(ActivityManager.PROCESS_STATE_SERVICE).when(mProcess).getSetProcState();
+ queue.setProcessAndUidState(mProcess, false, false);
+
+ // The new process state will only be taken into account the next time a broadcast
+ // is sent to the process.
+ enqueueOrReplaceBroadcast(queue, makeBroadcastRecord(timeTick,
+ List.of(makeMockRegisteredReceiver())), 0);
+ assertThat(queue.getRunnableAt()).isGreaterThan(timeTickRecord.enqueueTime);
+ assertEquals(BroadcastProcessQueue.REASON_NORMAL, queue.getRunnableAtReason());
+ }
+
+ @Test
public void testRunnableAt_persistentProc() {
final BroadcastProcessQueue queue = new BroadcastProcessQueue(mConstants, PACKAGE_GREEN,
getUidForPackage(PACKAGE_GREEN));
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
index 60e2af5..1f4563f 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
@@ -1971,6 +1971,36 @@
@SuppressWarnings("GuardedBy")
@Test
+ public void testUpdateOomAdj_DoOne_PendingFinishAttach() {
+ ProcessRecord app = spy(makeDefaultProcessRecord(MOCKAPP_PID, MOCKAPP_UID,
+ MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, false));
+ app.setPendingFinishAttach(true);
+ app.mState.setHasForegroundActivities(false);
+
+ sService.mOomAdjuster.setAttachingProcessStatesLSP(app);
+ updateOomAdj(app);
+
+ assertProcStates(app, PROCESS_STATE_CACHED_EMPTY, FOREGROUND_APP_ADJ,
+ SCHED_GROUP_DEFAULT);
+ }
+
+ @SuppressWarnings("GuardedBy")
+ @Test
+ public void testUpdateOomAdj_DoOne_TopApp_PendingFinishAttach() {
+ ProcessRecord app = spy(makeDefaultProcessRecord(MOCKAPP_PID, MOCKAPP_UID,
+ MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, false));
+ app.setPendingFinishAttach(true);
+ app.mState.setHasForegroundActivities(true);
+
+ sService.mOomAdjuster.setAttachingProcessStatesLSP(app);
+ updateOomAdj(app);
+
+ assertProcStates(app, PROCESS_STATE_TOP, FOREGROUND_APP_ADJ,
+ SCHED_GROUP_TOP_APP);
+ }
+
+ @SuppressWarnings("GuardedBy")
+ @Test
public void testUpdateOomAdj_UidIdle_StopService() {
final ProcessRecord app1 = spy(makeDefaultProcessRecord(MOCKAPP_PID, MOCKAPP_UID,
MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, false));
diff --git a/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerController2Test.java b/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerController2Test.java
index 7e85c25..434a75f 100644
--- a/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerController2Test.java
+++ b/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerController2Test.java
@@ -845,6 +845,155 @@
}
@Test
+ public void testAutoBrightnessEnabled_DisplayIsOn() {
+ Settings.System.putInt(mContext.getContentResolver(),
+ Settings.System.SCREEN_BRIGHTNESS_MODE,
+ Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
+
+ DisplayPowerRequest dpr = new DisplayPowerRequest();
+ dpr.policy = DisplayPowerRequest.POLICY_BRIGHT;
+ when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_ON);
+ 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_BRIGHT,
+ /* shouldResetShortTermModel= */ false
+ );
+ verify(mHolder.hbmController)
+ .setAutoBrightnessEnabled(AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED);
+ }
+
+ @Test
+ public void testAutoBrightnessEnabled_DisplayIsInDoze() {
+ 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);
+
+ 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,
+ /* 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,
+ Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL);
+
+ DisplayPowerRequest dpr = new DisplayPowerRequest();
+ dpr.policy = DisplayPowerRequest.POLICY_BRIGHT;
+ when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_ON);
+ mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+ advanceTime(1); // Run updatePowerState
+
+ // One triggered by the test, the other by handleBrightnessModeChange
+ verify(mHolder.automaticBrightnessController, times(2)).configure(
+ AutomaticBrightnessController.AUTO_BRIGHTNESS_DISABLED,
+ /* configuration= */ null, PowerManager.BRIGHTNESS_INVALID_FLOAT,
+ /* userChangedBrightness= */ false, /* adjustment= */ 0,
+ /* userChangedAutoBrightnessAdjustment= */ false, DisplayPowerRequest.POLICY_BRIGHT,
+ /* shouldResetShortTermModel= */ false
+ );
+ verify(mHolder.hbmController, times(2))
+ .setAutoBrightnessEnabled(AutomaticBrightnessController.AUTO_BRIGHTNESS_DISABLED);
+ }
+
+ @Test
+ public void testAutoBrightnessDisabled_DisplayIsOff() {
+ Settings.System.putInt(mContext.getContentResolver(),
+ Settings.System.SCREEN_BRIGHTNESS_MODE,
+ Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
+
+ DisplayPowerRequest dpr = new DisplayPowerRequest();
+ dpr.policy = DisplayPowerRequest.POLICY_OFF;
+ when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_OFF);
+ 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_OFF,
+ /* shouldResetShortTermModel= */ false
+ );
+ verify(mHolder.hbmController).setAutoBrightnessEnabled(
+ AutomaticBrightnessController.AUTO_BRIGHTNESS_OFF_DUE_TO_DISPLAY_STATE);
+ }
+
+ @Test
+ public void testAutoBrightnessDisabled_DisplayIsInDoze() {
+ 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);
+
+ 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,
+ /* 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,
+ Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
+ mHolder.dpc.setBrightnessToFollow(0.3f, -1, 0, /* slowChange= */ false);
+
+ DisplayPowerRequest dpr = new DisplayPowerRequest();
+ dpr.policy = DisplayPowerRequest.POLICY_BRIGHT;
+ when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_ON);
+ mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+ advanceTime(1); // Run updatePowerState
+
+ // One triggered by the test, the other by handleBrightnessModeChange
+ verify(mHolder.automaticBrightnessController, times(2)).configure(
+ AutomaticBrightnessController.AUTO_BRIGHTNESS_DISABLED,
+ /* configuration= */ null, PowerManager.BRIGHTNESS_INVALID_FLOAT,
+ /* userChangedBrightness= */ false, /* adjustment= */ 0,
+ /* userChangedAutoBrightnessAdjustment= */ false, DisplayPowerRequest.POLICY_BRIGHT,
+ /* shouldResetShortTermModel= */ false
+ );
+
+ // HBM should be allowed for the follower display
+ verify(mHolder.hbmController)
+ .setAutoBrightnessEnabled(AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED);
+ }
+
+ @Test
public void testBrightnessNitsPersistWhenDisplayDeviceChanges() {
float brightness = 0.3f;
float nits = 500;
diff --git a/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerControllerTest.java
index 4ce3625..db786bd 100644
--- a/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerControllerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerControllerTest.java
@@ -850,6 +850,155 @@
}
@Test
+ public void testAutoBrightnessEnabled_DisplayIsOn() {
+ Settings.System.putInt(mContext.getContentResolver(),
+ Settings.System.SCREEN_BRIGHTNESS_MODE,
+ Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
+
+ DisplayPowerRequest dpr = new DisplayPowerRequest();
+ dpr.policy = DisplayPowerRequest.POLICY_BRIGHT;
+ when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_ON);
+ 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_BRIGHT,
+ /* shouldResetShortTermModel= */ false
+ );
+ verify(mHolder.hbmController)
+ .setAutoBrightnessEnabled(AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED);
+ }
+
+ @Test
+ public void testAutoBrightnessEnabled_DisplayIsInDoze() {
+ 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);
+
+ 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,
+ /* 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,
+ Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL);
+
+ DisplayPowerRequest dpr = new DisplayPowerRequest();
+ dpr.policy = DisplayPowerRequest.POLICY_BRIGHT;
+ when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_ON);
+ mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+ advanceTime(1); // Run updatePowerState
+
+ // One triggered by the test, the other by handleBrightnessModeChange
+ verify(mHolder.automaticBrightnessController, times(2)).configure(
+ AutomaticBrightnessController.AUTO_BRIGHTNESS_DISABLED,
+ /* configuration= */ null, PowerManager.BRIGHTNESS_INVALID_FLOAT,
+ /* userChangedBrightness= */ false, /* adjustment= */ 0,
+ /* userChangedAutoBrightnessAdjustment= */ false, DisplayPowerRequest.POLICY_BRIGHT,
+ /* shouldResetShortTermModel= */ false
+ );
+ verify(mHolder.hbmController, times(2))
+ .setAutoBrightnessEnabled(AutomaticBrightnessController.AUTO_BRIGHTNESS_DISABLED);
+ }
+
+ @Test
+ public void testAutoBrightnessDisabled_DisplayIsOff() {
+ Settings.System.putInt(mContext.getContentResolver(),
+ Settings.System.SCREEN_BRIGHTNESS_MODE,
+ Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
+
+ DisplayPowerRequest dpr = new DisplayPowerRequest();
+ dpr.policy = DisplayPowerRequest.POLICY_OFF;
+ when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_OFF);
+ 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_OFF,
+ /* shouldResetShortTermModel= */ false
+ );
+ verify(mHolder.hbmController).setAutoBrightnessEnabled(
+ AutomaticBrightnessController.AUTO_BRIGHTNESS_OFF_DUE_TO_DISPLAY_STATE);
+ }
+
+ @Test
+ public void testAutoBrightnessDisabled_DisplayIsInDoze() {
+ 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);
+
+ 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,
+ /* 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,
+ Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
+ mHolder.dpc.setBrightnessToFollow(0.3f, -1, 0, /* slowChange= */ false);
+
+ DisplayPowerRequest dpr = new DisplayPowerRequest();
+ dpr.policy = DisplayPowerRequest.POLICY_BRIGHT;
+ when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_ON);
+ mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+ advanceTime(1); // Run updatePowerState
+
+ // One triggered by the test, the other by handleBrightnessModeChange
+ verify(mHolder.automaticBrightnessController, times(2)).configure(
+ AutomaticBrightnessController.AUTO_BRIGHTNESS_DISABLED,
+ /* configuration= */ null, PowerManager.BRIGHTNESS_INVALID_FLOAT,
+ /* userChangedBrightness= */ false, /* adjustment= */ 0,
+ /* userChangedAutoBrightnessAdjustment= */ false, DisplayPowerRequest.POLICY_BRIGHT,
+ /* shouldResetShortTermModel= */ false
+ );
+
+ // HBM should be allowed for the follower display
+ verify(mHolder.hbmController)
+ .setAutoBrightnessEnabled(AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED);
+ }
+
+ @Test
public void testBrightnessNitsPersistWhenDisplayDeviceChanges() {
float brightness = 0.3f;
float nits = 500;
diff --git a/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerProximityStateControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerProximityStateControllerTest.java
index 5b0b989..534a708 100644
--- a/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerProximityStateControllerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerProximityStateControllerTest.java
@@ -34,8 +34,8 @@
import android.os.test.TestLooper;
import android.view.Display;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
import com.android.server.testutils.OffsettableClock;
@@ -92,7 +92,7 @@
};
mDisplayPowerProximityStateController = new DisplayPowerProximityStateController(
mWakelockController, mDisplayDeviceConfig, mTestLooper.getLooper(),
- mNudgeUpdatePowerState, 0,
+ mNudgeUpdatePowerState, Display.DEFAULT_DISPLAY,
mSensorManager, injector);
mSensorEventListener = mDisplayPowerProximityStateController.getProximitySensorListener();
}
@@ -128,7 +128,7 @@
enableProximitySensor();
emitAndValidatePositiveProximityEvent();
mDisplayPowerProximityStateController.ignoreProximitySensorUntilChangedInternal();
- advanceTime(1);
+ advanceTime();
assertTrue(mDisplayPowerProximityStateController.shouldIgnoreProximityUntilChanged());
verify(mNudgeUpdatePowerState, times(2)).run();
@@ -170,7 +170,7 @@
}
@Test
- public void isProximitySensorAvailableReturnsFalseWhenNotAvailable() {
+ public void isProximitySensorAvailableReturnsFalseWhenNotAvailableAndNoDefault() {
when(mDisplayDeviceConfig.getProximitySensor()).thenReturn(
new DisplayDeviceConfig.SensorData() {
{
@@ -180,12 +180,63 @@
});
mDisplayPowerProximityStateController = new DisplayPowerProximityStateController(
mWakelockController, mDisplayDeviceConfig, mTestLooper.getLooper(),
+ mNudgeUpdatePowerState, Display.DEFAULT_DISPLAY,
+ mSensorManager, null);
+ assertFalse(mDisplayPowerProximityStateController.isProximitySensorAvailable());
+ }
+
+ @Test
+ public void isProximitySensorAvailableReturnsTrueWhenNotAvailableAndHasDefault()
+ throws Exception {
+ when(mDisplayDeviceConfig.getProximitySensor()).thenReturn(
+ new DisplayDeviceConfig.SensorData() {
+ {
+ type = null;
+ name = null;
+ }
+ });
+ when(mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY)).thenReturn(
+ TestUtils.createSensor(Sensor.TYPE_PROXIMITY, "proximity"));
+ mDisplayPowerProximityStateController = new DisplayPowerProximityStateController(
+ mWakelockController, mDisplayDeviceConfig, mTestLooper.getLooper(),
+ mNudgeUpdatePowerState, Display.DEFAULT_DISPLAY,
+ mSensorManager, null);
+ assertTrue(mDisplayPowerProximityStateController.isProximitySensorAvailable());
+ }
+
+ @Test
+ public void isProximitySensorAvailableReturnsFalseWhenNotAvailableHasDefaultNonDefaultDisplay()
+ throws Exception {
+ when(mDisplayDeviceConfig.getProximitySensor()).thenReturn(
+ new DisplayDeviceConfig.SensorData() {
+ {
+ type = null;
+ name = null;
+ }
+ });
+ when(mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY)).thenReturn(
+ TestUtils.createSensor(Sensor.TYPE_PROXIMITY, "proximity"));
+ mDisplayPowerProximityStateController = new DisplayPowerProximityStateController(
+ mWakelockController, mDisplayDeviceConfig, mTestLooper.getLooper(),
mNudgeUpdatePowerState, 1,
mSensorManager, null);
assertFalse(mDisplayPowerProximityStateController.isProximitySensorAvailable());
}
@Test
+ public void isProximitySensorAvailableReturnsTrueWhenNoSensorConfigured() throws Exception {
+ when(mDisplayDeviceConfig.getProximitySensor()).thenReturn(null);
+ when(mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY)).thenReturn(
+ TestUtils.createSensor(Sensor.TYPE_PROXIMITY, Sensor.STRING_TYPE_PROXIMITY));
+
+ mDisplayPowerProximityStateController = new DisplayPowerProximityStateController(
+ mWakelockController, mDisplayDeviceConfig, mTestLooper.getLooper(),
+ mNudgeUpdatePowerState, Display.DEFAULT_DISPLAY,
+ mSensorManager, null);
+ assertFalse(mDisplayPowerProximityStateController.isProximitySensorAvailable());
+ }
+
+ @Test
public void notifyDisplayDeviceChangedReloadsTheProximitySensor() throws Exception {
DisplayDeviceConfig updatedDisplayDeviceConfig = mock(DisplayDeviceConfig.class);
when(updatedDisplayDeviceConfig.getProximitySensor()).thenReturn(
@@ -326,8 +377,8 @@
assertEquals(mDisplayPowerProximityStateController.getPendingProximityDebounceTime(), -1);
}
- private void advanceTime(long timeMs) {
- mClock.fastForward(timeMs);
+ private void advanceTime() {
+ mClock.fastForward(1);
mTestLooper.dispatchAll();
}
diff --git a/services/tests/mockingservicestests/src/com/android/server/wallpaper/WallpaperManagerServiceTests.java b/services/tests/mockingservicestests/src/com/android/server/wallpaper/WallpaperManagerServiceTests.java
index bc5e720..eefe5af 100644
--- a/services/tests/mockingservicestests/src/com/android/server/wallpaper/WallpaperManagerServiceTests.java
+++ b/services/tests/mockingservicestests/src/com/android/server/wallpaper/WallpaperManagerServiceTests.java
@@ -31,7 +31,6 @@
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
import static com.android.server.wallpaper.WallpaperUtils.WALLPAPER;
-import static com.android.server.wallpaper.WallpaperUtils.WALLPAPER_CROP;
import static org.hamcrest.core.IsNot.not;
import static org.junit.Assert.assertEquals;
@@ -275,10 +274,10 @@
assertEquals(testUserId, newWallpaperData.userId);
WallpaperData wallpaperData = mService.getWallpaperSafeLocked(testUserId, which);
- assertEquals(wallpaperData.cropFile.getAbsolutePath(),
- newWallpaperData.cropFile.getAbsolutePath());
- assertEquals(wallpaperData.wallpaperFile.getAbsolutePath(),
- newWallpaperData.wallpaperFile.getAbsolutePath());
+ assertEquals(wallpaperData.getCropFile().getAbsolutePath(),
+ newWallpaperData.getCropFile().getAbsolutePath());
+ assertEquals(wallpaperData.getWallpaperFile().getAbsolutePath(),
+ newWallpaperData.getWallpaperFile().getAbsolutePath());
}
}
@@ -525,7 +524,8 @@
@Test
public void getWallpaperWithFeature_getCropped_returnsCropFile() throws Exception {
File cropSystemWallpaperFile =
- new File(WallpaperUtils.getWallpaperDir(USER_SYSTEM), WALLPAPER_CROP);
+ new WallpaperData(USER_SYSTEM, FLAG_SYSTEM).getCropFile();
+ cropSystemWallpaperFile.getParentFile().mkdirs();
cropSystemWallpaperFile.createNewFile();
try (FileOutputStream outputStream = new FileOutputStream(cropSystemWallpaperFile)) {
outputStream.write("Crop system wallpaper".getBytes());
@@ -547,7 +547,8 @@
@Test
public void getWallpaperWithFeature_notGetCropped_returnsOriginalFile() throws Exception {
File originalSystemWallpaperFile =
- new File(WallpaperUtils.getWallpaperDir(USER_SYSTEM), WALLPAPER);
+ new WallpaperData(USER_SYSTEM, FLAG_SYSTEM).getWallpaperFile();
+ originalSystemWallpaperFile.getParentFile().mkdirs();
originalSystemWallpaperFile.createNewFile();
try (FileOutputStream outputStream = new FileOutputStream(originalSystemWallpaperFile)) {
outputStream.write("Original system wallpaper".getBytes());
diff --git a/services/tests/servicestests/AndroidManifest.xml b/services/tests/servicestests/AndroidManifest.xml
index 107dde2..fa0a971 100644
--- a/services/tests/servicestests/AndroidManifest.xml
+++ b/services/tests/servicestests/AndroidManifest.xml
@@ -110,6 +110,7 @@
<uses-permission android:name="android.permission.ACCESS_CONTEXT_HUB" />
<uses-permission android:name="android.permission.USE_BIOMETRIC_INTERNAL" />
<uses-permission android:name="android.permission.MANAGE_MEDIA_PROJECTION" />
+ <uses-permission android:name="android.permission.MANAGE_ROLE_HOLDERS" />
<queries>
<package android:name="com.android.servicestests.apps.suspendtestapp" />
diff --git a/services/tests/servicestests/src/com/android/server/audio/AudioServiceTest.java b/services/tests/servicestests/src/com/android/server/audio/AudioServiceTest.java
index 88d57ac..e565faa 100644
--- a/services/tests/servicestests/src/com/android/server/audio/AudioServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/audio/AudioServiceTest.java
@@ -18,7 +18,7 @@
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.after;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
@@ -42,10 +42,10 @@
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.mockito.junit.MockitoJUnit;
-import org.mockito.junit.MockitoRule;
import org.mockito.Mock;
import org.mockito.Spy;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
@MediumTest
@RunWith(AndroidJUnit4.class)
@@ -58,7 +58,7 @@
public final MockitoRule mockito = MockitoJUnit.rule();
private Context mContext;
- private AudioSystemAdapter mAudioSystem;
+ private AudioSystemAdapter mSpyAudioSystem;
private SettingsAdapter mSettingsAdapter;
@Spy private NoOpSystemServerAdapter mSpySystemServer;
@@ -78,11 +78,11 @@
sLooperPrepared = true;
}
mContext = InstrumentationRegistry.getTargetContext();
- mAudioSystem = new NoOpAudioSystemAdapter();
+ mSpyAudioSystem = spy(new NoOpAudioSystemAdapter());
mSettingsAdapter = new NoOpSettingsAdapter();
when(mMockAppOpsManager.noteOp(anyInt(), anyInt(), anyString(), anyString(), anyString()))
.thenReturn(AppOpsManager.MODE_ALLOWED);
- mAudioService = new AudioService(mContext, mAudioSystem, mSpySystemServer,
+ mAudioService = new AudioService(mContext, mSpyAudioSystem, mSpySystemServer,
mSettingsAdapter, mMockAudioPolicy, null, mMockAppOpsManager,
mMockPermissionEnforcer);
}
@@ -95,7 +95,7 @@
public void testMuteMicrophone() throws Exception {
Log.i(TAG, "running testMuteMicrophone");
Assert.assertNotNull(mAudioService);
- final NoOpAudioSystemAdapter testAudioSystem = (NoOpAudioSystemAdapter) mAudioSystem;
+ final NoOpAudioSystemAdapter testAudioSystem = (NoOpAudioSystemAdapter) mSpyAudioSystem;
testAudioSystem.configureMuteMicrophoneToFail(false);
for (boolean muted : new boolean[] { true, false}) {
testAudioSystem.configureIsMicrophoneMuted(!muted);
@@ -120,7 +120,7 @@
public void testMuteMicrophoneWhenFail() throws Exception {
Log.i(TAG, "running testMuteMicrophoneWhenFail");
Assert.assertNotNull(mAudioService);
- final NoOpAudioSystemAdapter testAudioSystem = (NoOpAudioSystemAdapter) mAudioSystem;
+ final NoOpAudioSystemAdapter testAudioSystem = (NoOpAudioSystemAdapter) mSpyAudioSystem;
testAudioSystem.configureMuteMicrophoneToFail(true);
for (boolean muted : new boolean[] { true, false}) {
testAudioSystem.configureIsMicrophoneMuted(!muted);
@@ -175,4 +175,28 @@
Assert.assertEquals(false, mAudioService.isHotwordStreamSupported(false));
Assert.assertEquals(false, mAudioService.isHotwordStreamSupported(true));
}
+
+ /**
+ * Test master mute setter and getter
+ */
+ @Test
+ public void testMasterMute() throws Exception {
+ Log.i(TAG, "running testMasterMute");
+ Assert.assertNotNull(mAudioService);
+ for (boolean mute : new boolean[] { true, false}) {
+ boolean wasMute = mAudioService.isMasterMute();
+ mAudioService.setMasterMute(mute, 0 /* flags */, mContext.getOpPackageName(),
+ UserHandle.getCallingUserId(), null);
+
+ Assert.assertEquals("master mute reporting wrong value",
+ mute, mAudioService.isMasterMute());
+
+ verify(mSpyAudioSystem, times(wasMute == mute ? 0 : 1)).setMasterMute(mute);
+ // verify the intent for master mute changed is supposed to be fired
+ verify(mSpySystemServer,
+ after(MAX_MESSAGE_HANDLING_DELAY_MS).times(wasMute == mute ? 0 : 1))
+ .broadcastMasterMuteStatus(mute);
+ reset(mSpySystemServer);
+ }
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/audio/NoOpAudioSystemAdapter.java b/services/tests/servicestests/src/com/android/server/audio/NoOpAudioSystemAdapter.java
index 08a0878..0eac718 100644
--- a/services/tests/servicestests/src/com/android/server/audio/NoOpAudioSystemAdapter.java
+++ b/services/tests/servicestests/src/com/android/server/audio/NoOpAudioSystemAdapter.java
@@ -142,4 +142,9 @@
@NonNull AudioAttributes attributes, boolean forVolume) {
return new ArrayList<>();
}
+
+ @Override
+ public int setMasterMute(boolean muted) {
+ return AudioSystem.AUDIO_STATUS_OK;
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/audio/NoOpSystemServerAdapter.java b/services/tests/servicestests/src/com/android/server/audio/NoOpSystemServerAdapter.java
index 83c5663..a715f51 100644
--- a/services/tests/servicestests/src/com/android/server/audio/NoOpSystemServerAdapter.java
+++ b/services/tests/servicestests/src/com/android/server/audio/NoOpSystemServerAdapter.java
@@ -39,4 +39,9 @@
public void sendDeviceBecomingNoisyIntent() {
// no-op
}
+
+ @Override
+ public void broadcastMasterMuteStatus(boolean muted) {
+ // no-op
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java b/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java
index 0247ef3..41f7dbc 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java
@@ -180,6 +180,10 @@
when(mResources.getString(R.string.biometric_error_hw_unavailable))
.thenReturn(ERROR_HW_UNAVAILABLE);
+ when(mResources.getString(R.string.biometric_not_recognized))
+ .thenReturn(ERROR_NOT_RECOGNIZED);
+ when(mResources.getString(R.string.biometric_face_not_recognized))
+ .thenReturn(ERROR_NOT_RECOGNIZED);
when(mResources.getString(R.string.fingerprint_error_not_match))
.thenReturn(ERROR_NOT_RECOGNIZED);
when(mResources.getString(R.string.biometric_error_user_canceled))
diff --git a/services/tests/servicestests/src/com/android/server/companion/datatransfer/contextsync/CallMetadataSyncDataTest.java b/services/tests/servicestests/src/com/android/server/companion/datatransfer/contextsync/CallMetadataSyncDataTest.java
index dccc26a..7b5c57f 100644
--- a/services/tests/servicestests/src/com/android/server/companion/datatransfer/contextsync/CallMetadataSyncDataTest.java
+++ b/services/tests/servicestests/src/com/android/server/companion/datatransfer/contextsync/CallMetadataSyncDataTest.java
@@ -35,6 +35,7 @@
final byte[] appIcon = "appIcon".getBytes();
final String appName = "appName";
final String appIdentifier = "com.google.test";
+ final String extendedId = "com.google.test/.InCallService";
final int status = 1;
final int direction = android.companion.Telecom.Call.OUTGOING;
final int control1 = 2;
@@ -43,7 +44,7 @@
call.setCallerId(callerId);
call.setAppIcon(appIcon);
final CallMetadataSyncData.CallFacilitator callFacilitator =
- new CallMetadataSyncData.CallFacilitator(appName, appIdentifier);
+ new CallMetadataSyncData.CallFacilitator(appName, appIdentifier, extendedId);
call.setFacilitator(callFacilitator);
call.setStatus(status);
call.setDirection(direction);
@@ -59,6 +60,8 @@
assertThat(reconstructedCall.getAppIcon()).isEqualTo(appIcon);
assertThat(reconstructedCall.getFacilitator().getName()).isEqualTo(appName);
assertThat(reconstructedCall.getFacilitator().getIdentifier()).isEqualTo(appIdentifier);
+ assertThat(reconstructedCall.getFacilitator().getExtendedIdentifier())
+ .isEqualTo(extendedId);
assertThat(reconstructedCall.getStatus()).isEqualTo(status);
assertThat(reconstructedCall.getDirection()).isEqualTo(direction);
assertThat(reconstructedCall.getControls()).containsExactly(control1, control2);
diff --git a/services/tests/servicestests/src/com/android/server/companion/datatransfer/contextsync/CrossDeviceCallTest.java b/services/tests/servicestests/src/com/android/server/companion/datatransfer/contextsync/CrossDeviceCallTest.java
index 201d8f9..a13cc41 100644
--- a/services/tests/servicestests/src/com/android/server/companion/datatransfer/contextsync/CrossDeviceCallTest.java
+++ b/services/tests/servicestests/src/com/android/server/companion/datatransfer/contextsync/CrossDeviceCallTest.java
@@ -308,6 +308,18 @@
.isEqualTo(CONTACT_DISPLAY_NAME);
}
+ @Test
+ public void getSerializedPhoneAccountHandle_serializesCorrectly() {
+ final CrossDeviceCall crossDeviceCall = new CrossDeviceCall(
+ InstrumentationRegistry.getTargetContext(),
+ mUninitializedCallDetails, /* callAudioState= */ null);
+
+ final String result = crossDeviceCall.getSerializedPhoneAccountHandle();
+
+ assertWithMessage("Wrong phone account handle serialization").that(result)
+ .isEqualTo("label::com.google.test/com.google.test.Activity");
+ }
+
private Call.Details createCallDetails(int state, int capabilities) {
return createCallDetails(state, capabilities, /* hasContactName= */ true);
}
diff --git a/services/tests/servicestests/src/com/android/server/companion/datatransfer/contextsync/CrossDeviceSyncControllerTest.java b/services/tests/servicestests/src/com/android/server/companion/datatransfer/contextsync/CrossDeviceSyncControllerTest.java
index 7e392a4..e6cc343 100644
--- a/services/tests/servicestests/src/com/android/server/companion/datatransfer/contextsync/CrossDeviceSyncControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/companion/datatransfer/contextsync/CrossDeviceSyncControllerTest.java
@@ -195,7 +195,8 @@
new CrossDeviceSyncController.PhoneAccountManager(mMockContext);
final CallMetadataSyncData callMetadataSyncData = new CallMetadataSyncData();
callMetadataSyncData.addFacilitator(
- new CallMetadataSyncData.CallFacilitator("name", "com.google.test"));
+ new CallMetadataSyncData.CallFacilitator("name", "com.google.test",
+ "com.google.test/.InCallService"));
phoneAccountManager.updateFacilitators(0, callMetadataSyncData);
phoneAccountManager.updateFacilitators(0, callMetadataSyncData);
verify(mMockTelecomManager, times(1)).registerPhoneAccount(any());
@@ -208,10 +209,12 @@
new CrossDeviceSyncController.PhoneAccountManager(mMockContext);
final CallMetadataSyncData callMetadataSyncData = new CallMetadataSyncData();
callMetadataSyncData.addFacilitator(
- new CallMetadataSyncData.CallFacilitator("name", "com.google.test"));
+ new CallMetadataSyncData.CallFacilitator("name", "com.google.test",
+ "com.google.test/.InCallService"));
phoneAccountManager.updateFacilitators(0, callMetadataSyncData);
callMetadataSyncData.addFacilitator(
- new CallMetadataSyncData.CallFacilitator("name", "com.google.test2"));
+ new CallMetadataSyncData.CallFacilitator("name", "com.google.test2",
+ "com.google.test2/.InCallService"));
phoneAccountManager.updateFacilitators(0, callMetadataSyncData);
verify(mMockTelecomManager, times(2)).registerPhoneAccount(any());
verify(mMockTelecomManager, times(0)).unregisterPhoneAccount(any());
@@ -223,7 +226,8 @@
new CrossDeviceSyncController.PhoneAccountManager(mMockContext);
final CallMetadataSyncData callMetadataSyncData = new CallMetadataSyncData();
callMetadataSyncData.addFacilitator(
- new CallMetadataSyncData.CallFacilitator("name", "com.google.test"));
+ new CallMetadataSyncData.CallFacilitator("name", "com.google.test",
+ "com.google.test/.InCallService"));
phoneAccountManager.updateFacilitators(0, callMetadataSyncData);
final CallMetadataSyncData callMetadataSyncData2 = new CallMetadataSyncData();
phoneAccountManager.updateFacilitators(0, callMetadataSyncData2);
@@ -236,7 +240,9 @@
final CallMetadataSyncData.Call call = new CallMetadataSyncData.Call();
call.setId("123abc");
call.setDirection(android.companion.Telecom.Call.INCOMING);
- call.setFacilitator(new CallMetadataSyncData.CallFacilitator("name", "com.android.test"));
+ call.setFacilitator(
+ new CallMetadataSyncData.CallFacilitator("name", "com.google.test",
+ "com.google.test/.InCallService"));
final CallMetadataSyncData callMetadataSyncData = new CallMetadataSyncData();
callMetadataSyncData.addCall(call);
final CrossDeviceSyncController.CallManager callManager =
@@ -252,7 +258,9 @@
final CallMetadataSyncData.Call call = new CallMetadataSyncData.Call();
call.setId("123abc");
call.setDirection(android.companion.Telecom.Call.OUTGOING);
- call.setFacilitator(new CallMetadataSyncData.CallFacilitator("name", "com.android.test"));
+ call.setFacilitator(
+ new CallMetadataSyncData.CallFacilitator("name", "com.google.test",
+ "com.google.test/.InCallService"));
call.setCallerId("555-555-5555");
final CallMetadataSyncData callMetadataSyncData = new CallMetadataSyncData();
callMetadataSyncData.addCall(call);
@@ -269,7 +277,9 @@
final CallMetadataSyncData.Call call = new CallMetadataSyncData.Call();
call.setId("123abc");
call.setDirection(android.companion.Telecom.Call.OUTGOING);
- call.setFacilitator(new CallMetadataSyncData.CallFacilitator("name", "com.android.test"));
+ call.setFacilitator(
+ new CallMetadataSyncData.CallFacilitator("name", "com.google.test",
+ "com.google.test/.InCallService"));
final CallMetadataSyncData callMetadataSyncData = new CallMetadataSyncData();
callMetadataSyncData.addCall(call);
final CrossDeviceSyncController.CallManager callManager =
@@ -316,7 +326,8 @@
final CallMetadataSyncData.Call call = new CallMetadataSyncData.Call();
call.setId("123abc::originalId");
call.setDirection(android.companion.Telecom.Call.INCOMING);
- call.setFacilitator(new CallMetadataSyncData.CallFacilitator("name", "com.android.test"));
+ call.setFacilitator(new CallMetadataSyncData.CallFacilitator("name", "com.google.test",
+ "com.google.test/.InCallService"));
final CallMetadataSyncData callMetadataSyncData = new CallMetadataSyncData();
callMetadataSyncData.addCall(call);
final CrossDeviceSyncController.CallManager callManager =
@@ -334,7 +345,8 @@
final CallMetadataSyncData.Call call = new CallMetadataSyncData.Call();
call.setId("123abc::originalId");
call.setDirection(android.companion.Telecom.Call.OUTGOING);
- call.setFacilitator(new CallMetadataSyncData.CallFacilitator("name", "com.android.test"));
+ call.setFacilitator(new CallMetadataSyncData.CallFacilitator("name", "com.google.test",
+ "com.google.test/.InCallService"));
call.setCallerId("555-555-5555");
final CallMetadataSyncData callMetadataSyncData = new CallMetadataSyncData();
callMetadataSyncData.addCall(call);
@@ -352,7 +364,8 @@
final CallMetadataSyncData.Call call = new CallMetadataSyncData.Call();
call.setId("123abc");
call.setDirection(android.companion.Telecom.Call.INCOMING);
- call.setFacilitator(new CallMetadataSyncData.CallFacilitator("name", "com.android.test"));
+ call.setFacilitator(new CallMetadataSyncData.CallFacilitator("name", "com.google.test",
+ "com.google.test/.InCallService"));
final CallMetadataSyncData callMetadataSyncData = new CallMetadataSyncData();
callMetadataSyncData.addCall(call);
final CrossDeviceSyncController.CallManager callManager =
@@ -369,7 +382,8 @@
final CallMetadataSyncData.Call call = new CallMetadataSyncData.Call();
call.setId("123abc");
call.setDirection(android.companion.Telecom.Call.OUTGOING);
- call.setFacilitator(new CallMetadataSyncData.CallFacilitator("name", "com.android.test"));
+ call.setFacilitator(new CallMetadataSyncData.CallFacilitator("name", "com.google.test",
+ "com.google.test/.InCallService"));
call.setCallerId("555-555-5555");
final CallMetadataSyncData callMetadataSyncData = new CallMetadataSyncData();
callMetadataSyncData.addCall(call);
diff --git a/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java
index 379c8b7..4b801bc 100644
--- a/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java
@@ -16,6 +16,7 @@
package com.android.server.companion.virtual;
+import static android.companion.virtual.VirtualDeviceManager.ASSOCIATION_ID_INVALID;
import static android.companion.virtual.VirtualDeviceParams.DEVICE_POLICY_CUSTOM;
import static android.companion.virtual.VirtualDeviceParams.DEVICE_POLICY_DEFAULT;
import static android.companion.virtual.VirtualDeviceParams.POLICY_TYPE_RECENTS;
@@ -1711,6 +1712,22 @@
assertThat(displayIds).containsExactly(DISPLAY_ID_1, DISPLAY_ID_2);
}
+ @Test
+ public void getAssociationIdForDevice_invalidDeviceId_returnsInvalidAssociationId() {
+ assertThat(mLocalService.getAssociationIdForDevice(DEVICE_ID_INVALID))
+ .isEqualTo(ASSOCIATION_ID_INVALID);
+ assertThat(mLocalService.getAssociationIdForDevice(DEVICE_ID_DEFAULT))
+ .isEqualTo(ASSOCIATION_ID_INVALID);
+ assertThat(mLocalService.getAssociationIdForDevice(VIRTUAL_DEVICE_ID_2))
+ .isEqualTo(ASSOCIATION_ID_INVALID);
+ }
+
+ @Test
+ public void getAssociationIdForDevice_returnsCorrectAssociationId() {
+ assertThat(mLocalService.getAssociationIdForDevice(VIRTUAL_DEVICE_ID_1))
+ .isEqualTo(mAssociationInfo.getId());
+ }
+
private VirtualDeviceImpl createVirtualDevice(int virtualDeviceId, int ownerUid) {
VirtualDeviceParams params = new VirtualDeviceParams.Builder()
.setBlockedActivities(getBlockedActivities())
@@ -1727,6 +1744,7 @@
mPendingTrampolineCallback, mActivityListener, mSoundEffectListener,
mRunningAppsChangedCallback, params, new DisplayManagerGlobal(mIDisplayManager));
mVdms.addVirtualDevice(virtualDeviceImpl);
+ assertThat(virtualDeviceImpl.getAssociationId()).isEqualTo(mAssociationInfo.getId());
return virtualDeviceImpl;
}
diff --git a/services/tests/servicestests/src/com/android/server/display/DisplayDeviceConfigTest.java b/services/tests/servicestests/src/com/android/server/display/DisplayDeviceConfigTest.java
index 708421d..8b04eca 100644
--- a/services/tests/servicestests/src/com/android/server/display/DisplayDeviceConfigTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/DisplayDeviceConfigTest.java
@@ -33,8 +33,8 @@
import android.util.SparseArray;
import android.view.SurfaceControl;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
import com.android.internal.R;
import com.android.server.display.config.ThermalStatus;
diff --git a/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java
index 0e775d5..5db9d1f 100644
--- a/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java
@@ -32,6 +32,7 @@
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@@ -60,6 +61,8 @@
import android.content.res.Resources;
import android.graphics.Insets;
import android.graphics.Rect;
+import android.hardware.Sensor;
+import android.hardware.SensorManager;
import android.hardware.display.BrightnessConfiguration;
import android.hardware.display.Curve;
import android.hardware.display.DisplayManager;
@@ -109,8 +112,6 @@
import libcore.junit.util.compat.CoreCompatChangeRule.DisableCompatChanges;
import libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges;
-import com.google.common.collect.ImmutableMap;
-
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -125,6 +126,7 @@
import java.time.Duration;
import java.util.Arrays;
+import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
@@ -136,6 +138,9 @@
public class DisplayManagerServiceTest {
private static final int MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS = 1;
private static final long SHORT_DEFAULT_DISPLAY_TIMEOUT_MILLIS = 10;
+
+ private static final float FLOAT_TOLERANCE = 0.01f;
+
private static final String VIRTUAL_DISPLAY_NAME = "Test Virtual Display";
private static final String PACKAGE_NAME = "com.android.frameworks.servicestests";
private static final long STANDARD_DISPLAY_EVENTS = DisplayManager.EVENT_FLAG_DISPLAY_ADDED
@@ -250,6 +255,10 @@
@Mock IBinder mMockDisplayToken;
@Mock SensorManagerInternal mMockSensorManagerInternal;
+ @Mock SensorManager mSensorManager;
+
+ @Mock DisplayDeviceConfig mMockDisplayDeviceConfig;
+
@Captor ArgumentCaptor<ContentRecordingSession> mContentRecordingSessionCaptor;
@Before
@@ -267,7 +276,7 @@
LocalServices.removeServiceForTest(VirtualDeviceManagerInternal.class);
LocalServices.addService(
VirtualDeviceManagerInternal.class, mMockVirtualDeviceManagerInternal);
-
+ // TODO: b/287945043
mContext = spy(new ContextWrapper(ApplicationProvider.getApplicationContext()));
VirtualDeviceManager vdm = new VirtualDeviceManager(mIVirtualDeviceManager, mContext);
@@ -396,7 +405,7 @@
final int size = displayIds.length;
assertTrue(size > 0);
- Map<Integer, Integer> expectedDisplayTypeToViewPortTypeMapping = ImmutableMap.of(
+ Map<Integer, Integer> expectedDisplayTypeToViewPortTypeMapping = Map.of(
Display.TYPE_INTERNAL, DisplayViewport.VIEWPORT_INTERNAL,
Display.TYPE_EXTERNAL, DisplayViewport.VIEWPORT_EXTERNAL
);
@@ -1934,6 +1943,74 @@
assertEquals(mode, displayManager.getHdrConversionModeInternal());
}
+ @Test
+ public void testReturnsRefreshRateForDisplayAndSensor_proximitySensorSet() {
+ DisplayManagerService displayManager = new DisplayManagerService(mContext, mBasicInjector);
+ DisplayManagerInternal localService = displayManager.new LocalService();
+ DisplayManagerService.BinderService displayManagerBinderService =
+ displayManager.new BinderService();
+ displayManager.overrideSensorManager(mSensorManager);
+
+ FakeDisplayDevice displayDevice = createFakeDisplayDevice(displayManager, new float[]{60f});
+ displayDevice.mDisplayDeviceConfig = mMockDisplayDeviceConfig;
+ int displayId = getDisplayIdForDisplayDevice(displayManager, displayManagerBinderService,
+ displayDevice);
+
+ String testSensorName = "testName";
+ String testSensorType = "testType";
+ Sensor testSensor = TestUtils.createSensor(testSensorType, testSensorName);
+
+ DisplayDeviceConfig.SensorData sensorData = new DisplayDeviceConfig.SensorData();
+ sensorData.type = testSensorType;
+ sensorData.name = testSensorName;
+ sensorData.minRefreshRate = 10f;
+ sensorData.maxRefreshRate = 100f;
+
+ when(mMockDisplayDeviceConfig.getProximitySensor()).thenReturn(sensorData);
+ when(mSensorManager.getSensorList(Sensor.TYPE_ALL)).thenReturn(Collections.singletonList(
+ testSensor));
+
+ SurfaceControl.RefreshRateRange result = localService.getRefreshRateForDisplayAndSensor(
+ displayId, testSensorName, testSensorType);
+
+ assertNotNull(result);
+ assertEquals(result.min, sensorData.minRefreshRate, FLOAT_TOLERANCE);
+ assertEquals(result.max, sensorData.maxRefreshRate, FLOAT_TOLERANCE);
+ }
+
+ @Test
+ public void testReturnsRefreshRateForDisplayAndSensor_proximitySensorNotSet() {
+ DisplayManagerService displayManager = new DisplayManagerService(mContext, mBasicInjector);
+ DisplayManagerInternal localService = displayManager.new LocalService();
+ DisplayManagerService.BinderService displayManagerBinderService =
+ displayManager.new BinderService();
+ displayManager.overrideSensorManager(mSensorManager);
+
+ FakeDisplayDevice displayDevice = createFakeDisplayDevice(displayManager, new float[]{60f});
+ displayDevice.mDisplayDeviceConfig = mMockDisplayDeviceConfig;
+ int displayId = getDisplayIdForDisplayDevice(displayManager, displayManagerBinderService,
+ displayDevice);
+
+ String testSensorName = "testName";
+ String testSensorType = "testType";
+ Sensor testSensor = TestUtils.createSensor(testSensorType, testSensorName);
+
+ DisplayDeviceConfig.SensorData sensorData = new DisplayDeviceConfig.SensorData();
+ sensorData.type = testSensorType;
+ sensorData.name = testSensorName;
+ sensorData.minRefreshRate = 10f;
+ sensorData.maxRefreshRate = 100f;
+
+ when(mMockDisplayDeviceConfig.getProximitySensor()).thenReturn(null);
+ when(mSensorManager.getSensorList(Sensor.TYPE_ALL)).thenReturn(Collections.singletonList(
+ testSensor));
+
+ SurfaceControl.RefreshRateRange result = localService.getRefreshRateForDisplayAndSensor(
+ displayId, testSensorName, testSensorType);
+
+ assertNull(result);
+ }
+
private void testDisplayInfoFrameRateOverrideModeCompat(boolean compatChangeEnabled)
throws Exception {
DisplayManagerService displayManager =
diff --git a/services/tests/servicestests/src/com/android/server/display/TestUtils.java b/services/tests/servicestests/src/com/android/server/display/TestUtils.java
index 90d9bae..8b45145 100644
--- a/services/tests/servicestests/src/com/android/server/display/TestUtils.java
+++ b/services/tests/servicestests/src/com/android/server/display/TestUtils.java
@@ -18,6 +18,7 @@
import android.hardware.Sensor;
import android.hardware.SensorEvent;
+import android.hardware.input.InputSensorInfo;
import android.os.Parcel;
import android.os.SystemClock;
import android.view.DisplayAddress;
@@ -75,6 +76,12 @@
return sensor;
}
+ public static Sensor createSensor(String type, String name) {
+ return new Sensor(new InputSensorInfo(
+ name, "vendor", 0, 0, 0, 1f, 1f, 1, 1, 1, 1,
+ type, "", 0, 0, 0));
+ }
+
/**
* Create a custom {@link DisplayAddress} to ensure we're not relying on any specific
* display-address implementation in our code. Intentionally uses default object (reference)
diff --git a/services/tests/servicestests/src/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategyTest.java b/services/tests/servicestests/src/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategyTest.java
index f68d344..b652576 100644
--- a/services/tests/servicestests/src/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategyTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategyTest.java
@@ -96,32 +96,101 @@
}
@Test
- public void setAutoBrightnessWhenDisabled() {
+ public void testAutoBrightnessState_AutoBrightnessDisabled() {
mAutomaticBrightnessStrategy.setUseAutoBrightness(false);
int targetDisplayState = Display.STATE_ON;
boolean allowAutoBrightnessWhileDozing = false;
- float brightnessState = Float.NaN;
- int brightnessReason = BrightnessReason.REASON_OVERRIDE;
+ int brightnessReason = BrightnessReason.REASON_UNKNOWN;
int policy = DisplayManagerInternal.DisplayPowerRequest.POLICY_BRIGHT;
float lastUserSetBrightness = 0.2f;
boolean userSetBrightnessChanged = true;
mAutomaticBrightnessStrategy.updatePendingAutoBrightnessAdjustments(true);
mAutomaticBrightnessStrategy.setAutoBrightnessState(targetDisplayState,
- allowAutoBrightnessWhileDozing, brightnessState, brightnessReason, policy,
- lastUserSetBrightness, userSetBrightnessChanged);
+ allowAutoBrightnessWhileDozing, brightnessReason, policy, lastUserSetBrightness,
+ userSetBrightnessChanged);
verify(mAutomaticBrightnessController)
.configure(AutomaticBrightnessController.AUTO_BRIGHTNESS_DISABLED,
mBrightnessConfiguration,
lastUserSetBrightness,
userSetBrightnessChanged, 0.5f,
false, policy, true);
+ assertFalse(mAutomaticBrightnessStrategy.isAutoBrightnessEnabled());
+ assertFalse(mAutomaticBrightnessStrategy.isAutoBrightnessDisabledDueToDisplayOff());
}
@Test
- public void setAutoBrightnessWhenEnabledAndDisplayIsDozing() {
+ public void testAutoBrightnessState_DisplayIsOff() {
+ mAutomaticBrightnessStrategy.setUseAutoBrightness(true);
+ int targetDisplayState = Display.STATE_OFF;
+ boolean allowAutoBrightnessWhileDozing = false;
+ int brightnessReason = BrightnessReason.REASON_UNKNOWN;
+ int policy = DisplayManagerInternal.DisplayPowerRequest.POLICY_OFF;
+ float lastUserSetBrightness = 0.2f;
+ boolean userSetBrightnessChanged = true;
+ mAutomaticBrightnessStrategy.updatePendingAutoBrightnessAdjustments(true);
+ mAutomaticBrightnessStrategy.setAutoBrightnessState(targetDisplayState,
+ allowAutoBrightnessWhileDozing, brightnessReason, policy, lastUserSetBrightness,
+ userSetBrightnessChanged);
+ verify(mAutomaticBrightnessController)
+ .configure(AutomaticBrightnessController.AUTO_BRIGHTNESS_OFF_DUE_TO_DISPLAY_STATE,
+ mBrightnessConfiguration,
+ lastUserSetBrightness,
+ userSetBrightnessChanged, 0.5f,
+ false, policy, true);
+ assertFalse(mAutomaticBrightnessStrategy.isAutoBrightnessEnabled());
+ assertTrue(mAutomaticBrightnessStrategy.isAutoBrightnessDisabledDueToDisplayOff());
+ }
+
+ @Test
+ public void testAutoBrightnessState_DisplayIsInDoze_ConfigDoesNotAllow() {
mAutomaticBrightnessStrategy.setUseAutoBrightness(true);
int targetDisplayState = Display.STATE_DOZE;
- float brightnessState = Float.NaN;
+ boolean allowAutoBrightnessWhileDozing = false;
+ int brightnessReason = BrightnessReason.REASON_UNKNOWN;
+ int policy = DisplayManagerInternal.DisplayPowerRequest.POLICY_DOZE;
+ float lastUserSetBrightness = 0.2f;
+ boolean userSetBrightnessChanged = true;
+ mAutomaticBrightnessStrategy.updatePendingAutoBrightnessAdjustments(true);
+ mAutomaticBrightnessStrategy.setAutoBrightnessState(targetDisplayState,
+ allowAutoBrightnessWhileDozing, brightnessReason, policy, lastUserSetBrightness,
+ userSetBrightnessChanged);
+ verify(mAutomaticBrightnessController)
+ .configure(AutomaticBrightnessController.AUTO_BRIGHTNESS_OFF_DUE_TO_DISPLAY_STATE,
+ mBrightnessConfiguration,
+ lastUserSetBrightness,
+ userSetBrightnessChanged, 0.5f,
+ false, policy, true);
+ assertFalse(mAutomaticBrightnessStrategy.isAutoBrightnessEnabled());
+ assertTrue(mAutomaticBrightnessStrategy.isAutoBrightnessDisabledDueToDisplayOff());
+ }
+
+ @Test
+ public void testAutoBrightnessState_BrightnessReasonIsOverride() {
+ mAutomaticBrightnessStrategy.setUseAutoBrightness(true);
+ int targetDisplayState = Display.STATE_ON;
+ boolean allowAutoBrightnessWhileDozing = false;
+ int brightnessReason = BrightnessReason.REASON_OVERRIDE;
+ int policy = DisplayManagerInternal.DisplayPowerRequest.POLICY_BRIGHT;
+ float lastUserSetBrightness = 0.2f;
+ boolean userSetBrightnessChanged = true;
+ mAutomaticBrightnessStrategy.updatePendingAutoBrightnessAdjustments(true);
+ mAutomaticBrightnessStrategy.setAutoBrightnessState(targetDisplayState,
+ allowAutoBrightnessWhileDozing, brightnessReason, policy, lastUserSetBrightness,
+ userSetBrightnessChanged);
+ verify(mAutomaticBrightnessController)
+ .configure(AutomaticBrightnessController.AUTO_BRIGHTNESS_DISABLED,
+ mBrightnessConfiguration,
+ lastUserSetBrightness,
+ userSetBrightnessChanged, 0.5f,
+ false, policy, true);
+ assertFalse(mAutomaticBrightnessStrategy.isAutoBrightnessEnabled());
+ assertFalse(mAutomaticBrightnessStrategy.isAutoBrightnessDisabledDueToDisplayOff());
+ }
+
+ @Test
+ public void testAutoBrightnessState_DisplayIsInDoze_ConfigDoesAllow() {
+ mAutomaticBrightnessStrategy.setUseAutoBrightness(true);
+ int targetDisplayState = Display.STATE_DOZE;
boolean allowAutoBrightnessWhileDozing = true;
int brightnessReason = BrightnessReason.REASON_DOZE;
int policy = DisplayManagerInternal.DisplayPowerRequest.POLICY_DOZE;
@@ -131,23 +200,24 @@
Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ, 0.4f);
mAutomaticBrightnessStrategy.updatePendingAutoBrightnessAdjustments(false);
mAutomaticBrightnessStrategy.setAutoBrightnessState(targetDisplayState,
- allowAutoBrightnessWhileDozing, brightnessState, brightnessReason, policy,
- lastUserSetBrightness, userSetBrightnessChanged);
+ allowAutoBrightnessWhileDozing, brightnessReason, policy, lastUserSetBrightness,
+ userSetBrightnessChanged);
verify(mAutomaticBrightnessController)
.configure(AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED,
mBrightnessConfiguration,
lastUserSetBrightness,
userSetBrightnessChanged, 0.4f,
true, policy, true);
+ assertTrue(mAutomaticBrightnessStrategy.isAutoBrightnessEnabled());
+ assertFalse(mAutomaticBrightnessStrategy.isAutoBrightnessDisabledDueToDisplayOff());
}
@Test
- public void setAutoBrightnessWhenEnabledAndDisplayIsOn() {
+ public void testAutoBrightnessState_DisplayIsOn() {
mAutomaticBrightnessStrategy.setUseAutoBrightness(true);
int targetDisplayState = Display.STATE_ON;
- float brightnessState = Float.NaN;
boolean allowAutoBrightnessWhileDozing = false;
- int brightnessReason = BrightnessReason.REASON_OVERRIDE;
+ int brightnessReason = BrightnessReason.REASON_UNKNOWN;
float lastUserSetBrightness = 0.2f;
boolean userSetBrightnessChanged = true;
int policy = DisplayManagerInternal.DisplayPowerRequest.POLICY_BRIGHT;
@@ -156,14 +226,16 @@
Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ, pendingBrightnessAdjustment);
mAutomaticBrightnessStrategy.updatePendingAutoBrightnessAdjustments(false);
mAutomaticBrightnessStrategy.setAutoBrightnessState(targetDisplayState,
- allowAutoBrightnessWhileDozing, brightnessState, brightnessReason, policy,
- lastUserSetBrightness, userSetBrightnessChanged);
+ allowAutoBrightnessWhileDozing, brightnessReason, policy, lastUserSetBrightness,
+ userSetBrightnessChanged);
verify(mAutomaticBrightnessController)
.configure(AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED,
mBrightnessConfiguration,
lastUserSetBrightness,
userSetBrightnessChanged, pendingBrightnessAdjustment,
true, policy, true);
+ assertTrue(mAutomaticBrightnessStrategy.isAutoBrightnessEnabled());
+ assertFalse(mAutomaticBrightnessStrategy.isAutoBrightnessDisabledDueToDisplayOff());
}
@Test
diff --git a/services/tests/servicestests/src/com/android/server/display/utils/SensorUtilsTest.java b/services/tests/servicestests/src/com/android/server/display/utils/SensorUtilsTest.java
new file mode 100644
index 0000000..4494b0c
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/display/utils/SensorUtilsTest.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.display.utils;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.mockito.Mockito.when;
+
+import android.annotation.Nullable;
+import android.hardware.Sensor;
+import android.hardware.SensorManager;
+import android.hardware.input.InputSensorInfo;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.internal.annotations.Keep;
+import com.android.server.display.DisplayDeviceConfig.SensorData;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.Collections;
+import java.util.List;
+
+import junitparams.JUnitParamsRunner;
+import junitparams.Parameters;
+
+@SmallTest
+@RunWith(JUnitParamsRunner.class)
+public class SensorUtilsTest {
+
+ private static final String TEST_SENSOR_NAME = "test_sensor_name";
+ private static final String TEST_SENSOR_TYPE = "test_sensor_type";
+ private static final Sensor TEST_SENSOR = createSensor();
+ @Mock
+ private SensorManager mSensorManager;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ }
+
+ @Test
+ public void testNoSensorData() {
+ Sensor result = SensorUtils.findSensor(mSensorManager, null, Sensor.TYPE_LIGHT);
+ assertNull(result);
+ }
+
+ @Test
+ public void testNoSensorManager() {
+ Sensor result = SensorUtils.findSensor(null, new SensorData(), Sensor.TYPE_LIGHT);
+ assertNull(result);
+ }
+
+ @Keep
+ private static Object[][] findSensorData() {
+ // sensorName, sensorType, fallbackType, allSensors, defaultSensor, expectedResult
+ return new Object[][]{
+ // no data, no default
+ {null, null, Sensor.TYPE_LIGHT,
+ Collections.singletonList(TEST_SENSOR), null, null},
+ // matching name, matching type, no default
+ {TEST_SENSOR_NAME, TEST_SENSOR_TYPE, Sensor.TYPE_LIGHT,
+ Collections.singletonList(TEST_SENSOR), null, TEST_SENSOR},
+ // matching name, no default
+ {TEST_SENSOR_NAME, null, Sensor.TYPE_LIGHT,
+ Collections.singletonList(TEST_SENSOR), null, TEST_SENSOR},
+ // not matching name, no default
+ {"not_matching_name", null, Sensor.TYPE_LIGHT,
+ Collections.singletonList(TEST_SENSOR), null, null},
+ // matching type, no default
+ {null, TEST_SENSOR_TYPE, Sensor.TYPE_LIGHT,
+ Collections.singletonList(TEST_SENSOR), null, TEST_SENSOR},
+ // not matching type, no default
+ {null, "not_matching_type", Sensor.TYPE_LIGHT,
+ Collections.singletonList(TEST_SENSOR), null, null},
+ // not matching type, matching name, no default
+ {TEST_SENSOR_NAME, "not_matching_type", Sensor.TYPE_LIGHT,
+ Collections.singletonList(TEST_SENSOR), null, null},
+ // not matching name, matching type, no default
+ {"not_matching_name", TEST_SENSOR_TYPE, Sensor.TYPE_LIGHT,
+ Collections.singletonList(TEST_SENSOR), null, null},
+ // not matching type, not matching name, no default
+ {"not_matching_name", "not_matching_type", Sensor.TYPE_LIGHT,
+ Collections.singletonList(TEST_SENSOR), null, null},
+ // not matching type, not matching name, with default
+ {"not_matching_name", "not_matching_type", Sensor.TYPE_LIGHT,
+ Collections.singletonList(TEST_SENSOR), TEST_SENSOR, TEST_SENSOR},
+ // no data, with default
+ {null, null, Sensor.TYPE_LIGHT,
+ Collections.singletonList(TEST_SENSOR), TEST_SENSOR, TEST_SENSOR},
+ // empty data, with default
+ {"", "", Sensor.TYPE_LIGHT,
+ Collections.singletonList(TEST_SENSOR), TEST_SENSOR, TEST_SENSOR},
+ // empty data, with default, no fallback
+ {"", "", SensorUtils.NO_FALLBACK,
+ Collections.singletonList(TEST_SENSOR), TEST_SENSOR, null},
+ };
+ }
+
+ @Test
+ @Parameters(method = "findSensorData")
+ public void testFindSensor(@Nullable String sensorName, @Nullable String sensorType,
+ int fallbackType, List<Sensor> allSensors, @Nullable Sensor defaultSensor,
+ @Nullable Sensor expectedResult) {
+ when(mSensorManager.getSensorList(Sensor.TYPE_ALL)).thenReturn(allSensors);
+ when(mSensorManager.getDefaultSensor(fallbackType)).thenReturn(defaultSensor);
+
+ SensorData sensorData = new SensorData();
+ sensorData.name = sensorName;
+ sensorData.type = sensorType;
+
+ Sensor result = SensorUtils.findSensor(mSensorManager, sensorData, fallbackType);
+
+ assertEquals(expectedResult, result);
+ }
+
+ private static Sensor createSensor() {
+ return new Sensor(new InputSensorInfo(
+ TEST_SENSOR_NAME, "vendor", 0, 0, 0, 1f, 1f, 1, 1, 1, 1,
+ TEST_SENSOR_TYPE, "", 0, 0, 0));
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/PlatformKeyManagerTest.java b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/PlatformKeyManagerTest.java
index c546a74..c09e09c 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/PlatformKeyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/PlatformKeyManagerTest.java
@@ -27,6 +27,7 @@
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import static org.testng.Assert.assertThrows;
import android.app.KeyguardManager;
import android.content.Context;
@@ -54,6 +55,7 @@
import java.io.File;
import java.security.KeyStore;
+import java.security.KeyStoreException;
import java.security.UnrecoverableKeyException;
import java.util.List;
@@ -393,6 +395,18 @@
}
@Test
+ public void getEncryptKey_noScreenlock() throws Exception {
+ when(mKeyguardManager.isDeviceSecure(USER_ID_FIXTURE)).thenReturn(false);
+ doThrow(new KeyStoreException()).when(mKeyStoreProxy).setEntry(
+ anyString(),
+ any(),
+ any());
+
+ assertThrows(InsecureUserException.class,
+ () -> mPlatformKeyManager.getEncryptKey(USER_ID_FIXTURE));
+ }
+
+ @Test
public void getDecryptKey_generatesNewKeyIfOldOneIsInvalid() throws Exception {
doThrow(new UnrecoverableKeyException()).when(mKeyStoreProxy).getKey(
eq(DECRYPTION_KEY_ALIAS_1),
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 b91a6cb..c42928e 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
@@ -344,7 +344,7 @@
// Second start - so not valid.
projection.start(mIMediaProjectionCallback);
- assertThrows(IllegalStateException.class, projection::isValid);
+ assertThrows(SecurityException.class, projection::isValid);
}
// TODO(269273190): Test flag using compat annotations instead.
diff --git a/services/tests/servicestests/src/com/android/server/os/BugreportManagerServiceImplTest.java b/services/tests/servicestests/src/com/android/server/os/BugreportManagerServiceImplTest.java
index 52c6777..24029b1 100644
--- a/services/tests/servicestests/src/com/android/server/os/BugreportManagerServiceImplTest.java
+++ b/services/tests/servicestests/src/com/android/server/os/BugreportManagerServiceImplTest.java
@@ -16,15 +16,18 @@
package com.android.server.os;
+import static com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertThrows;
+import android.app.role.RoleManager;
import android.content.Context;
import android.os.Binder;
import android.os.BugreportManager.BugreportCallback;
import android.os.IBinder;
import android.os.IDumpstateListener;
+import android.os.Process;
import android.os.RemoteException;
import android.util.ArraySet;
import android.util.Pair;
@@ -37,21 +40,23 @@
import org.junit.runner.RunWith;
import java.io.FileDescriptor;
+import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
+import java.util.function.Consumer;
@RunWith(AndroidJUnit4.class)
public class BugreportManagerServiceImplTest {
- Context mContext;
- BugreportManagerServiceImpl mService;
- BugreportManagerServiceImpl.BugreportFileManager mBugreportFileManager;
+ private Context mContext;
+ private BugreportManagerServiceImpl mService;
+ private BugreportManagerServiceImpl.BugreportFileManager mBugreportFileManager;
- int mCallingUid = 1234;
- String mCallingPackage = "test.package";
+ private int mCallingUid = 1234;
+ private String mCallingPackage = "test.package";
- String mBugreportFile = "bugreport-file.zip";
- String mBugreportFile2 = "bugreport-file2.zip";
+ private String mBugreportFile = "bugreport-file.zip";
+ private String mBugreportFile2 = "bugreport-file2.zip";
@Before
public void setUp() {
@@ -109,6 +114,36 @@
BugreportCallback.BUGREPORT_ERROR_NO_BUGREPORT_TO_RETRIEVE);
}
+ @Test
+ public void testCancelBugreportWithoutRole() throws Exception {
+ // Clear out allowlisted packages.
+ mService = new BugreportManagerServiceImpl(
+ new BugreportManagerServiceImpl.Injector(mContext, new ArraySet<>()));
+
+ assertThrows(SecurityException.class, () -> mService.cancelBugreport(
+ Binder.getCallingUid(), mContext.getPackageName()));
+ }
+
+ @Test
+ public void testCancelBugreportWithRole() throws Exception {
+ // Clear out allowlisted packages.
+ mService = new BugreportManagerServiceImpl(
+ new BugreportManagerServiceImpl.Injector(mContext, new ArraySet<>()));
+ RoleManager roleManager = mContext.getSystemService(RoleManager.class);
+ CallbackFuture future = new CallbackFuture();
+ runWithShellPermissionIdentity(() -> roleManager.setBypassingRoleQualification(true));
+ runWithShellPermissionIdentity(() -> roleManager.addRoleHolderAsUser(
+ "android.app.role.SYSTEM_AUTOMOTIVE_PROJECTION",
+ mContext.getPackageName(),
+ /* flags= */ 0,
+ Process.myUserHandle(),
+ mContext.getMainExecutor(),
+ future));
+
+ assertThat(future.get()).isEqualTo(true);
+ mService.cancelBugreport(Binder.getCallingUid(), mContext.getPackageName());
+ }
+
private static class Listener implements IDumpstateListener {
CountDownLatch mLatch;
int mErrorCode;
@@ -149,4 +184,12 @@
return mErrorCode;
}
}
+
+ private static class CallbackFuture extends CompletableFuture<Boolean>
+ implements Consumer<Boolean> {
+ @Override
+ public void accept(Boolean successful) {
+ complete(successful);
+ }
+ }
}
diff --git a/services/tests/voiceinteractiontests/src/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareLoggingLatencyTest.java b/services/tests/voiceinteractiontests/src/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareLoggingLatencyTest.java
index 6a1674b..fc4e6e0 100644
--- a/services/tests/voiceinteractiontests/src/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareLoggingLatencyTest.java
+++ b/services/tests/voiceinteractiontests/src/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareLoggingLatencyTest.java
@@ -41,9 +41,11 @@
import androidx.test.platform.app.InstrumentationRegistry;
import com.android.internal.util.FakeLatencyTracker;
+import com.android.modules.utils.testing.TestableDeviceConfig.TestableDeviceConfigRule;
import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
@@ -54,6 +56,9 @@
@RunWith(JUnit4.class)
public class SoundTriggerMiddlewareLoggingLatencyTest {
+ @Rule
+ public TestableDeviceConfigRule mDeviceConfigRule = new TestableDeviceConfigRule();
+
private FakeLatencyTracker mLatencyTracker;
@Mock
private BatteryStatsInternal mBatteryStatsInternal;
diff --git a/services/tests/wmtests/AndroidManifest.xml b/services/tests/wmtests/AndroidManifest.xml
index 37e5da5..9c79375 100644
--- a/services/tests/wmtests/AndroidManifest.xml
+++ b/services/tests/wmtests/AndroidManifest.xml
@@ -96,6 +96,19 @@
android:theme="@style/WhiteBackgroundTheme"
android:exported="true"/>
+ <activity android:name="com.android.server.wm.TrustedPresentationCallbackTest$TestActivity"
+ android:exported="true"
+ android:showWhenLocked="true"
+ android:turnScreenOn="true" />
+
+ <activity
+ android:name="androidx.test.core.app.InstrumentationActivityInvoker$EmptyActivity"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ </intent-filter>
+ </activity>
+
<service android:name="android.view.cts.surfacevalidator.LocalMediaProjectionService"
android:foregroundServiceType="mediaProjection"
android:enabled="true">
diff --git a/services/tests/wmtests/src/com/android/server/wm/SynchedDeviceConfigTests.java b/services/tests/wmtests/src/com/android/server/wm/SynchedDeviceConfigTests.java
index ecab62f..7d44e11 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SynchedDeviceConfigTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SynchedDeviceConfigTests.java
@@ -16,9 +16,13 @@
package com.android.server.wm;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
+
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
import android.app.ActivityThread;
import android.platform.test.annotations.Presubmit;
@@ -68,8 +72,6 @@
.addDeviceConfigEntry(/* key */ "key2", /* default */ false, /* enabled */ true)
.addDeviceConfigEntry(/* key */ "key3", /* default */ true, /* enabled */ false)
.addDeviceConfigEntry(/* key */ "key4", /* default */ false, /* enabled */ false)
- .addDeviceConfigEntry(/* key */ "key5", /* default */ true, /* enabled */ false)
- .addDeviceConfigEntry(/* key */ "key6", /* default */ false, /* enabled */ false)
.build();
}
@@ -84,8 +86,6 @@
assertFlagValue(/* key */ "key2", /* expected */ false); // enabled
assertFlagValue(/* key */ "key3", /* expected */ false); // disabled
assertFlagValue(/* key */ "key4", /* expected */ false); // disabled
- assertFlagValue(/* key */ "key5", /* expected */ false); // disabled
- assertFlagValue(/* key */ "key6", /* expected */ false); // disabled
}
@Test
@@ -94,18 +94,17 @@
assertFlagEnabled(/* key */ "key2", /* expected */ true);
assertFlagEnabled(/* key */ "key3", /* expected */ false);
assertFlagEnabled(/* key */ "key4", /* expected */ false);
- assertFlagEnabled(/* key */ "key5", /* expected */ false);
- assertFlagEnabled(/* key */ "key6", /* expected */ false);
}
@Test
public void testWhenUpdated_onlyEnabledChanges() {
final CountDownLatch countDownLatch = new CountDownLatch(4);
- final DeviceConfig.OnPropertiesChangedListener countDownLatchListener =
- properties -> countDownLatch.countDown();
- DeviceConfig.addOnPropertiesChangedListener(NAMESPACE_FOR_TEST, mExecutor,
- countDownLatchListener);
-
+ spyOn(mDeviceConfig);
+ doAnswer(invocation -> {
+ invocation.callRealMethod();
+ countDownLatch.countDown();
+ return null;
+ }).when(mDeviceConfig).onPropertiesChanged(any());
try {
// We update all the keys
updateProperty(/* key */ "key1", /* value */ false);
@@ -123,58 +122,9 @@
assertFlagValue(/* key */ "key4", /* expected */ false); // disabled
} catch (InterruptedException e) {
Assert.fail(e.getMessage());
- } finally {
- DeviceConfig.removeOnPropertiesChangedListener(countDownLatchListener);
}
}
- @Test
- public void testWhenEnabled_updatesAreUsed() {
- final CountDownLatch countDownLatchBefore = new CountDownLatch(2);
- final CountDownLatch countDownLatchAfter = new CountDownLatch(2);
- final DeviceConfig.OnPropertiesChangedListener countDownLatchBeforeListener =
- properties -> countDownLatchBefore.countDown();
- final DeviceConfig.OnPropertiesChangedListener countDownLatchAfterListener =
- properties -> countDownLatchAfter.countDown();
- DeviceConfig.addOnPropertiesChangedListener(NAMESPACE_FOR_TEST, mExecutor,
- countDownLatchBeforeListener);
-
- try {
- // We update disabled values
- updateProperty(/* key */ "key3", /* value */ false);
- updateProperty(/* key */ "key4", /* value */ true);
-
- assertThat(countDownLatchBefore.await(
- WAIT_FOR_PROPERTY_CHANGE_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS)).isTrue();
-
- // We check they haven't been updated
- assertFlagValue(/* key */ "key3", /* expected */ false);
- assertFlagValue(/* key */ "key4", /* expected */ false);
-
-
- DeviceConfig.removeOnPropertiesChangedListener(countDownLatchBeforeListener);
- DeviceConfig.addOnPropertiesChangedListener(NAMESPACE_FOR_TEST, mExecutor,
- countDownLatchAfterListener);
-
- // We update enabled flags
- updateProperty(/* key */ "key1", /* value */ false);
- updateProperty(/* key */ "key2", /* value */ true);
-
- assertThat(countDownLatchAfter.await(
- WAIT_FOR_PROPERTY_CHANGE_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS)).isTrue();
-
- // Value have been updated
- assertFlagValue(/* key */ "key1", /* expected */ false);
- assertFlagValue(/* key */ "key2", /* expected */ true);
-
- } catch (InterruptedException e) {
- Assert.fail(e.getMessage());
- } finally {
- DeviceConfig.removeOnPropertiesChangedListener(countDownLatchAfterListener);
- }
- }
-
-
private void assertFlagValue(String key, boolean expectedValue) {
assertEquals(/* message */"Flag " + key + " value is not " + expectedValue, /* expected */
expectedValue, /* actual */ mDeviceConfig.getFlagValue(key));
diff --git a/services/tests/wmtests/src/com/android/server/wm/TrustedPresentationCallbackTest.java b/services/tests/wmtests/src/com/android/server/wm/TrustedPresentationCallbackTest.java
new file mode 100644
index 0000000..df11a44
--- /dev/null
+++ b/services/tests/wmtests/src/com/android/server/wm/TrustedPresentationCallbackTest.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm;
+
+import static android.server.wm.ActivityManagerTestBase.createFullscreenActivityScenarioRule;
+import static android.server.wm.BuildUtils.HW_TIMEOUT_MULTIPLIER;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import android.app.Activity;
+import android.platform.test.annotations.Presubmit;
+import android.util.Log;
+import android.view.SurfaceControl;
+import android.view.SurfaceControl.TrustedPresentationThresholds;
+
+import androidx.test.ext.junit.rules.ActivityScenarioRule;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Consumer;
+
+/**
+ * TODO (b/287076178): Move these tests to
+ * {@link android.view.surfacecontrol.cts.TrustedPresentationCallbackTest} when API is made public
+ */
+@Presubmit
+public class TrustedPresentationCallbackTest {
+ private static final String TAG = "TrustedPresentationCallbackTest";
+ private static final int STABILITY_REQUIREMENT_MS = 500;
+ private static final long WAIT_TIME_MS = HW_TIMEOUT_MULTIPLIER * 2000L;
+
+ private static final float FRACTION_VISIBLE = 0.1f;
+
+ @Rule
+ public ActivityScenarioRule<TestActivity> mActivityRule = createFullscreenActivityScenarioRule(
+ TestActivity.class);
+
+ private TestActivity mActivity;
+
+ @Before
+ public void setup() {
+ mActivityRule.getScenario().onActivity(activity -> mActivity = activity);
+ }
+
+ @Test
+ public void testAddTrustedPresentationListenerOnWindow() throws InterruptedException {
+ boolean[] results = new boolean[1];
+ CountDownLatch receivedResults = new CountDownLatch(1);
+ TrustedPresentationThresholds thresholds = new TrustedPresentationThresholds(
+ 1 /* minAlpha */, FRACTION_VISIBLE, STABILITY_REQUIREMENT_MS);
+ SurfaceControl.Transaction t = new SurfaceControl.Transaction();
+ mActivity.getWindow().getRootSurfaceControl().addTrustedPresentationCallback(t, thresholds,
+ Runnable::run, inTrustedPresentationState -> {
+ Log.d(TAG, "onTrustedPresentationChanged " + inTrustedPresentationState);
+ results[0] = inTrustedPresentationState;
+ receivedResults.countDown();
+ });
+ t.apply();
+
+ assertTrue("Timed out waiting for results",
+ receivedResults.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
+ assertTrue(results[0]);
+ }
+
+ @Test
+ public void testRemoveTrustedPresentationListenerOnWindow() throws InterruptedException {
+ final Object resultsLock = new Object();
+ boolean[] results = new boolean[1];
+ boolean[] receivedResults = new boolean[1];
+ TrustedPresentationThresholds thresholds = new TrustedPresentationThresholds(
+ 1 /* minAlpha */, FRACTION_VISIBLE, STABILITY_REQUIREMENT_MS);
+ Consumer<Boolean> trustedPresentationCallback = inTrustedPresentationState -> {
+ synchronized (resultsLock) {
+ results[0] = inTrustedPresentationState;
+ receivedResults[0] = true;
+ resultsLock.notify();
+ }
+ };
+ SurfaceControl.Transaction t = new SurfaceControl.Transaction();
+ mActivity.getWindow().getRootSurfaceControl().addTrustedPresentationCallback(t, thresholds,
+ Runnable::run, trustedPresentationCallback);
+ t.apply();
+
+ synchronized (resultsLock) {
+ if (!receivedResults[0]) {
+ resultsLock.wait(WAIT_TIME_MS);
+ }
+ // Make sure we received the results and not just timed out
+ assertTrue("Timed out waiting for results", receivedResults[0]);
+ assertTrue(results[0]);
+
+ // reset the state
+ receivedResults[0] = false;
+ }
+
+ mActivity.getWindow().getRootSurfaceControl().removeTrustedPresentationCallback(t,
+ trustedPresentationCallback);
+ t.apply();
+
+ synchronized (resultsLock) {
+ if (!receivedResults[0]) {
+ resultsLock.wait(WAIT_TIME_MS);
+ }
+ // Ensure we waited the full time and never received a notify on the result from the
+ // callback.
+ assertFalse("Should never have received a callback", receivedResults[0]);
+ // results shouldn't have changed.
+ assertTrue(results[0]);
+ }
+ }
+
+ public static class TestActivity extends Activity {
+ }
+}
diff --git a/services/usage/java/com/android/server/usage/BroadcastResponseStatsTracker.java b/services/usage/java/com/android/server/usage/BroadcastResponseStatsTracker.java
index 7d5be8e..c47d459 100644
--- a/services/usage/java/com/android/server/usage/BroadcastResponseStatsTracker.java
+++ b/services/usage/java/com/android/server/usage/BroadcastResponseStatsTracker.java
@@ -28,9 +28,9 @@
import android.app.usage.BroadcastResponseStats;
import android.content.Context;
import android.content.pm.PackageManager;
+import android.os.Process;
import android.os.SystemClock;
import android.os.UserHandle;
-import android.permission.PermissionManager;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.LongArrayQueue;
@@ -94,9 +94,12 @@
private AppStandbyInternal mAppStandby;
private BroadcastResponseStatsLogger mLogger;
private RoleManager mRoleManager;
+ private final Context mContext;
- BroadcastResponseStatsTracker(@NonNull AppStandbyInternal appStandby) {
+ BroadcastResponseStatsTracker(@NonNull AppStandbyInternal appStandby,
+ @NonNull Context context) {
mAppStandby = appStandby;
+ mContext = context;
mLogger = new BroadcastResponseStatsLogger();
}
@@ -305,12 +308,19 @@
boolean doesPackageHoldExemptedPermission(@NonNull String packageName,
@NonNull UserHandle user) {
- final List<String> exemptedPermissions = mAppStandby
- .getBroadcastResponseExemptedPermissions();
+ int uid;
+ try {
+ uid = mContext.getPackageManager().getPackageUidAsUser(
+ packageName, user.getIdentifier());
+ } catch (PackageManager.NameNotFoundException e) {
+ return false;
+ }
+ final List<String> exemptedPermissions =
+ mAppStandby.getBroadcastResponseExemptedPermissions();
for (int i = exemptedPermissions.size() - 1; i >= 0; --i) {
final String permissionName = exemptedPermissions.get(i);
- if (PermissionManager.checkPackageNamePermission(permissionName, packageName,
- user.getIdentifier()) == PackageManager.PERMISSION_GRANTED) {
+ if (mContext.checkPermission(permissionName, Process.INVALID_PID, uid)
+ == PackageManager.PERMISSION_GRANTED) {
return true;
}
}
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index cf236dd..43cebe8 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -300,7 +300,7 @@
mHandler = new H(BackgroundThread.get().getLooper());
mAppStandby = mInjector.getAppStandbyController(getContext());
- mResponseStatsTracker = new BroadcastResponseStatsTracker(mAppStandby);
+ mResponseStatsTracker = new BroadcastResponseStatsTracker(mAppStandby, getContext());
mAppTimeLimit = new AppTimeLimitController(getContext(),
new AppTimeLimitController.TimeLimitCallbackListener() {
diff --git a/services/usb/java/com/android/server/usb/hal/gadget/UsbGadgetAidl.java b/services/usb/java/com/android/server/usb/hal/gadget/UsbGadgetAidl.java
index d47ccc7..b7f7c43 100644
--- a/services/usb/java/com/android/server/usb/hal/gadget/UsbGadgetAidl.java
+++ b/services/usb/java/com/android/server/usb/hal/gadget/UsbGadgetAidl.java
@@ -67,10 +67,6 @@
return GADGET_HAL_V2_0;
}
- @Override
- public void systemReady() {
- }
-
public void serviceDied() {
logAndPrint(Log.ERROR, mPw, "Usb Gadget AIDL hal service died");
synchronized (mGadgetProxyLock) {
diff --git a/services/usb/java/com/android/server/usb/hal/gadget/UsbGadgetHal.java b/services/usb/java/com/android/server/usb/hal/gadget/UsbGadgetHal.java
index 7b52f46..eac796d 100644
--- a/services/usb/java/com/android/server/usb/hal/gadget/UsbGadgetHal.java
+++ b/services/usb/java/com/android/server/usb/hal/gadget/UsbGadgetHal.java
@@ -29,69 +29,6 @@
*/
public interface UsbGadgetHal {
/**
- * Power role: This USB port can act as a source (provide power).
- * @hide
- */
- public static final int HAL_POWER_ROLE_SOURCE = 1;
-
- /**
- * Power role: This USB port can act as a sink (receive power).
- * @hide
- */
- public static final int HAL_POWER_ROLE_SINK = 2;
-
- @IntDef(prefix = { "HAL_POWER_ROLE_" }, value = {
- HAL_POWER_ROLE_SOURCE,
- HAL_POWER_ROLE_SINK
- })
- @Retention(RetentionPolicy.SOURCE)
- @interface HalUsbPowerRole{}
-
- /**
- * Data role: This USB port can act as a host (access data services).
- * @hide
- */
- public static final int HAL_DATA_ROLE_HOST = 1;
-
- /**
- * Data role: This USB port can act as a device (offer data services).
- * @hide
- */
- public static final int HAL_DATA_ROLE_DEVICE = 2;
-
- @IntDef(prefix = { "HAL_DATA_ROLE_" }, value = {
- HAL_DATA_ROLE_HOST,
- HAL_DATA_ROLE_DEVICE
- })
- @Retention(RetentionPolicy.SOURCE)
- @interface HalUsbDataRole{}
-
- /**
- * This USB port can act as a downstream facing port (host).
- *
- * @hide
- */
- public static final int HAL_MODE_DFP = 1;
-
- /**
- * This USB port can act as an upstream facing port (device).
- *
- * @hide
- */
- public static final int HAL_MODE_UFP = 2;
- @IntDef(prefix = { "HAL_MODE_" }, value = {
- HAL_MODE_DFP,
- HAL_MODE_UFP,
- })
- @Retention(RetentionPolicy.SOURCE)
- @interface HalUsbPortMode{}
-
- /**
- * UsbPortManager would call this when the system is done booting.
- */
- public void systemReady();
-
- /**
* This function is used to query the USB functions included in the
* current USB configuration.
*
diff --git a/services/usb/java/com/android/server/usb/hal/gadget/UsbGadgetHidl.java b/services/usb/java/com/android/server/usb/hal/gadget/UsbGadgetHidl.java
index 68067d2..80a70dd 100644
--- a/services/usb/java/com/android/server/usb/hal/gadget/UsbGadgetHidl.java
+++ b/services/usb/java/com/android/server/usb/hal/gadget/UsbGadgetHidl.java
@@ -123,10 +123,6 @@
}
}
- @Override
- public void systemReady() {
- }
-
static boolean isServicePresent(IndentingPrintWriter pw) {
try {
IUsbGadget.getService(true);
diff --git a/services/usb/java/com/android/server/usb/hal/port/UsbPortHal.java b/services/usb/java/com/android/server/usb/hal/port/UsbPortHal.java
index f98c598..45de058 100644
--- a/services/usb/java/com/android/server/usb/hal/port/UsbPortHal.java
+++ b/services/usb/java/com/android/server/usb/hal/port/UsbPortHal.java
@@ -70,17 +70,17 @@
*
* @hide
*/
- public static final int HAL_MODE_DFP = 1;
+ public static final int HAL_MODE_UFP = 1;
/**
* This USB port can act as an upstream facing port (device).
*
* @hide
*/
- public static final int HAL_MODE_UFP = 2;
+ public static final int HAL_MODE_DFP = 2;
@IntDef(prefix = { "HAL_MODE_" }, value = {
- HAL_MODE_DFP,
HAL_MODE_UFP,
+ HAL_MODE_DFP,
})
@Retention(RetentionPolicy.SOURCE)
@interface HalUsbPortMode{}
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index 26590c4..a72f780 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -2097,7 +2097,10 @@
* For a self-managed {@link ConnectionService}, a {@link SecurityException} will be thrown if
* the {@link PhoneAccount} has {@link PhoneAccount#CAPABILITY_SELF_MANAGED} and the calling app
* does not have {@link android.Manifest.permission#MANAGE_OWN_CALLS}.
- *
+ * <p>
+ * <p>
+ * <b>Note</b>: {@link android.app.Notification.CallStyle} notifications should be posted after
+ * the call is added to Telecom in order for the notification to be non-dismissible.
* @param phoneAccount A {@link PhoneAccountHandle} registered with
* {@link #registerPhoneAccount}.
* @param extras A bundle that will be passed through to
@@ -2345,7 +2348,10 @@
* {@link PhoneAccount} with the {@link PhoneAccount#CAPABILITY_PLACE_EMERGENCY_CALLS}
* capability, depending on external factors, such as network conditions and Modem/SIM status.
* </p>
- *
+ * <p>
+ * <p>
+ * <b>Note</b>: {@link android.app.Notification.CallStyle} notifications should be posted after
+ * the call is placed in order for the notification to be non-dismissible.
* @param address The address to make the call to.
* @param extras Bundle of extras to use with the call.
*/
@@ -2679,9 +2685,11 @@
/**
* Add a call to the Android system service Telecom. This allows the system to start tracking an
- * incoming or outgoing call with the specified {@link CallAttributes}. Once the call is ready
- * to be disconnected, use the {@link CallControl#disconnect(DisconnectCause, Executor,
- * OutcomeReceiver)} which is provided by the {@code pendingControl#onResult(CallControl)}.
+ * incoming or outgoing call with the specified {@link CallAttributes}. Once a call is added,
+ * a {@link android.app.Notification.CallStyle} notification should be posted and when the
+ * call is ready to be disconnected, use {@link CallControl#disconnect(DisconnectCause,
+ * Executor, OutcomeReceiver)} which is provided by the
+ * {@code pendingControl#onResult(CallControl)}.
* <p>
* <p>
* <p>
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 27b81d8..d421df8 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -9905,9 +9905,9 @@
sDefaults.putString(KEY_CARRIER_ERI_FILE_NAME_STRING, "eri.xml");
sDefaults.putInt(KEY_DURATION_BLOCKING_DISABLED_AFTER_EMERGENCY_INT, 7200);
sDefaults.putStringArray(KEY_CARRIER_METERED_APN_TYPES_STRINGS,
- new String[]{"default", "mms", "dun", "supl"});
+ new String[]{"default", "mms", "dun", "supl", "enterprise"});
sDefaults.putStringArray(KEY_CARRIER_METERED_ROAMING_APN_TYPES_STRINGS,
- new String[]{"default", "mms", "dun", "supl"});
+ new String[]{"default", "mms", "dun", "supl", "enterprise"});
sDefaults.putIntArray(KEY_ONLY_SINGLE_DC_ALLOWED_INT_ARRAY,
new int[] {TelephonyManager.NETWORK_TYPE_CDMA, TelephonyManager.NETWORK_TYPE_1xRTT,
TelephonyManager.NETWORK_TYPE_EVDO_0, TelephonyManager.NETWORK_TYPE_EVDO_A,
diff --git a/telephony/java/android/telephony/data/DataCallResponse.java b/telephony/java/android/telephony/data/DataCallResponse.java
index b5c1d7d..e69040e 100644
--- a/telephony/java/android/telephony/data/DataCallResponse.java
+++ b/telephony/java/android/telephony/data/DataCallResponse.java
@@ -36,8 +36,10 @@
import java.lang.annotation.RetentionPolicy;
import java.net.InetAddress;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import java.util.Objects;
+import java.util.Set;
/**
* Description of the response of a setup data call connection request.
@@ -172,63 +174,48 @@
@Nullable List<InetAddress> dnsAddresses,
@Nullable List<InetAddress> gatewayAddresses,
@Nullable List<InetAddress> pcscfAddresses, int mtu) {
- mCause = cause;
- mSuggestedRetryTime = suggestedRetryTime;
- mId = id;
- mLinkStatus = linkStatus;
- mProtocolType = protocolType;
- mInterfaceName = (interfaceName == null) ? "" : interfaceName;
- mAddresses = (addresses == null)
- ? new ArrayList<>() : new ArrayList<>(addresses);
- mDnsAddresses = (dnsAddresses == null)
- ? new ArrayList<>() : new ArrayList<>(dnsAddresses);
- mGatewayAddresses = (gatewayAddresses == null)
- ? new ArrayList<>() : new ArrayList<>(gatewayAddresses);
- mPcscfAddresses = (pcscfAddresses == null)
- ? new ArrayList<>() : new ArrayList<>(pcscfAddresses);
- mMtu = mMtuV4 = mMtuV6 = mtu;
- mHandoverFailureMode = HANDOVER_FAILURE_MODE_LEGACY;
- mPduSessionId = PDU_SESSION_ID_NOT_SET;
- mDefaultQos = null;
- mQosBearerSessions = new ArrayList<>();
- mSliceInfo = null;
- mTrafficDescriptors = new ArrayList<>();
+ this(cause, suggestedRetryTime, id,
+ linkStatus, protocolType,
+ interfaceName == null ? "" : interfaceName,
+ addresses == null ? Collections.emptyList() : addresses,
+ dnsAddresses == null ? Collections.emptyList() : dnsAddresses,
+ gatewayAddresses == null ? Collections.emptyList() : gatewayAddresses,
+ pcscfAddresses == null ? Collections.emptyList() : pcscfAddresses,
+ mtu, mtu /* mtuV4 */, mtu /* mtuV6 */,
+ HANDOVER_FAILURE_MODE_LEGACY, PDU_SESSION_ID_NOT_SET,
+ null /* defaultQos */, Collections.emptyList() /* qosBearerSessions */,
+ null /* sliceInfo */,
+ Collections.emptyList() /* trafficDescriptors */);
}
private DataCallResponse(@DataFailureCause int cause, long suggestedRetryTime, int id,
@LinkStatus int linkStatus, @ProtocolType int protocolType,
- @Nullable String interfaceName, @Nullable List<LinkAddress> addresses,
- @Nullable List<InetAddress> dnsAddresses, @Nullable List<InetAddress> gatewayAddresses,
- @Nullable List<InetAddress> pcscfAddresses, int mtu, int mtuV4, int mtuV6,
+ @NonNull String interfaceName, @NonNull List<LinkAddress> addresses,
+ @NonNull List<InetAddress> dnsAddresses, @NonNull List<InetAddress> gatewayAddresses,
+ @NonNull List<InetAddress> pcscfAddresses, int mtu, int mtuV4, int mtuV6,
@HandoverFailureMode int handoverFailureMode, int pduSessionId,
- @Nullable Qos defaultQos, @Nullable List<QosBearerSession> qosBearerSessions,
+ @Nullable Qos defaultQos, @NonNull List<QosBearerSession> qosBearerSessions,
@Nullable NetworkSliceInfo sliceInfo,
- @Nullable List<TrafficDescriptor> trafficDescriptors) {
+ @NonNull List<TrafficDescriptor> trafficDescriptors) {
mCause = cause;
mSuggestedRetryTime = suggestedRetryTime;
mId = id;
mLinkStatus = linkStatus;
mProtocolType = protocolType;
- mInterfaceName = (interfaceName == null) ? "" : interfaceName;
- mAddresses = (addresses == null)
- ? new ArrayList<>() : new ArrayList<>(addresses);
- mDnsAddresses = (dnsAddresses == null)
- ? new ArrayList<>() : new ArrayList<>(dnsAddresses);
- mGatewayAddresses = (gatewayAddresses == null)
- ? new ArrayList<>() : new ArrayList<>(gatewayAddresses);
- mPcscfAddresses = (pcscfAddresses == null)
- ? new ArrayList<>() : new ArrayList<>(pcscfAddresses);
+ mInterfaceName = interfaceName;
+ mAddresses = new ArrayList<>(addresses);
+ mDnsAddresses = new ArrayList<>(dnsAddresses);
+ mGatewayAddresses = new ArrayList<>(gatewayAddresses);
+ mPcscfAddresses = new ArrayList<>(pcscfAddresses);
mMtu = mtu;
mMtuV4 = mtuV4;
mMtuV6 = mtuV6;
mHandoverFailureMode = handoverFailureMode;
mPduSessionId = pduSessionId;
mDefaultQos = defaultQos;
- mQosBearerSessions = (qosBearerSessions == null)
- ? new ArrayList<>() : new ArrayList<>(qosBearerSessions);
+ mQosBearerSessions = new ArrayList<>(qosBearerSessions);
mSliceInfo = sliceInfo;
- mTrafficDescriptors = (trafficDescriptors == null)
- ? new ArrayList<>() : new ArrayList<>(trafficDescriptors);
+ mTrafficDescriptors = new ArrayList<>(trafficDescriptors);
}
/** @hide */
@@ -241,24 +228,39 @@
mProtocolType = source.readInt();
mInterfaceName = source.readString();
mAddresses = new ArrayList<>();
- source.readList(mAddresses, LinkAddress.class.getClassLoader(), android.net.LinkAddress.class);
+ source.readList(mAddresses,
+ LinkAddress.class.getClassLoader(),
+ android.net.LinkAddress.class);
mDnsAddresses = new ArrayList<>();
- source.readList(mDnsAddresses, InetAddress.class.getClassLoader(), java.net.InetAddress.class);
+ source.readList(mDnsAddresses,
+ InetAddress.class.getClassLoader(),
+ java.net.InetAddress.class);
mGatewayAddresses = new ArrayList<>();
- source.readList(mGatewayAddresses, InetAddress.class.getClassLoader(), java.net.InetAddress.class);
+ source.readList(mGatewayAddresses,
+ InetAddress.class.getClassLoader(),
+ java.net.InetAddress.class);
mPcscfAddresses = new ArrayList<>();
- source.readList(mPcscfAddresses, InetAddress.class.getClassLoader(), java.net.InetAddress.class);
+ source.readList(mPcscfAddresses,
+ InetAddress.class.getClassLoader(),
+ java.net.InetAddress.class);
mMtu = source.readInt();
mMtuV4 = source.readInt();
mMtuV6 = source.readInt();
mHandoverFailureMode = source.readInt();
mPduSessionId = source.readInt();
- mDefaultQos = source.readParcelable(Qos.class.getClassLoader(), android.telephony.data.Qos.class);
+ mDefaultQos = source.readParcelable(Qos.class.getClassLoader(),
+ android.telephony.data.Qos.class);
mQosBearerSessions = new ArrayList<>();
- source.readList(mQosBearerSessions, QosBearerSession.class.getClassLoader(), android.telephony.data.QosBearerSession.class);
- mSliceInfo = source.readParcelable(NetworkSliceInfo.class.getClassLoader(), android.telephony.data.NetworkSliceInfo.class);
+ source.readList(mQosBearerSessions,
+ QosBearerSession.class.getClassLoader(),
+ android.telephony.data.QosBearerSession.class);
+ mSliceInfo = source.readParcelable(
+ NetworkSliceInfo.class.getClassLoader(),
+ android.telephony.data.NetworkSliceInfo.class);
mTrafficDescriptors = new ArrayList<>();
- source.readList(mTrafficDescriptors, TrafficDescriptor.class.getClassLoader(), android.telephony.data.TrafficDescriptor.class);
+ source.readList(mTrafficDescriptors,
+ TrafficDescriptor.class.getClassLoader(),
+ android.telephony.data.TrafficDescriptor.class);
}
/**
@@ -322,28 +324,36 @@
* @return A list of addresses of this data connection.
*/
@NonNull
- public List<LinkAddress> getAddresses() { return mAddresses; }
+ public List<LinkAddress> getAddresses() {
+ return Collections.unmodifiableList(mAddresses);
+ }
/**
* @return A list of DNS server addresses, e.g., "192.0.1.3" or
* "192.0.1.11 2001:db8::1". Empty list if no dns server addresses returned.
*/
@NonNull
- public List<InetAddress> getDnsAddresses() { return mDnsAddresses; }
+ public List<InetAddress> getDnsAddresses() {
+ return Collections.unmodifiableList(mDnsAddresses);
+ }
/**
* @return A list of default gateway addresses, e.g., "192.0.1.3" or
* "192.0.1.11 2001:db8::1". Empty list if the addresses represent point to point connections.
*/
@NonNull
- public List<InetAddress> getGatewayAddresses() { return mGatewayAddresses; }
+ public List<InetAddress> getGatewayAddresses() {
+ return Collections.unmodifiableList(mGatewayAddresses);
+ }
/**
* @return A list of Proxy Call State Control Function address via PCO (Protocol Configuration
* Option) for IMS client.
*/
@NonNull
- public List<InetAddress> getPcscfAddresses() { return mPcscfAddresses; }
+ public List<InetAddress> getPcscfAddresses() {
+ return Collections.unmodifiableList(mPcscfAddresses);
+ }
/**
* @return MTU (maximum transmission unit) in bytes received from network. Zero or negative
@@ -404,7 +414,7 @@
*/
@NonNull
public List<QosBearerSession> getQosBearerSessions() {
- return mQosBearerSessions;
+ return Collections.unmodifiableList(mQosBearerSessions);
}
/**
@@ -420,7 +430,7 @@
*/
@NonNull
public List<TrafficDescriptor> getTrafficDescriptors() {
- return mTrafficDescriptors;
+ return Collections.unmodifiableList(mTrafficDescriptors);
}
@NonNull
@@ -461,18 +471,6 @@
DataCallResponse other = (DataCallResponse) o;
- final boolean isQosBearerSessionsSame =
- (mQosBearerSessions == null || other.mQosBearerSessions == null)
- ? mQosBearerSessions == other.mQosBearerSessions
- : (mQosBearerSessions.size() == other.mQosBearerSessions.size()
- && mQosBearerSessions.containsAll(other.mQosBearerSessions));
-
- final boolean isTrafficDescriptorsSame =
- (mTrafficDescriptors == null || other.mTrafficDescriptors == null)
- ? mTrafficDescriptors == other.mTrafficDescriptors
- : (mTrafficDescriptors.size() == other.mTrafficDescriptors.size()
- && mTrafficDescriptors.containsAll(other.mTrafficDescriptors));
-
return mCause == other.mCause
&& mSuggestedRetryTime == other.mSuggestedRetryTime
&& mId == other.mId
@@ -493,42 +491,20 @@
&& mHandoverFailureMode == other.mHandoverFailureMode
&& mPduSessionId == other.mPduSessionId
&& Objects.equals(mDefaultQos, other.mDefaultQos)
- && isQosBearerSessionsSame
+ && mQosBearerSessions.size() == other.mQosBearerSessions.size() // non-null
+ && mQosBearerSessions.containsAll(other.mQosBearerSessions) // non-null
&& Objects.equals(mSliceInfo, other.mSliceInfo)
- && isTrafficDescriptorsSame;
+ && mTrafficDescriptors.size() == other.mTrafficDescriptors.size() // non-null
+ && mTrafficDescriptors.containsAll(other.mTrafficDescriptors); // non-null
}
@Override
public int hashCode() {
- // Generate order-independent hashes for lists
- int addressesHash = mAddresses.stream()
- .map(LinkAddress::hashCode)
- .mapToInt(Integer::intValue)
- .sum();
- int dnsAddressesHash = mDnsAddresses.stream()
- .map(InetAddress::hashCode)
- .mapToInt(Integer::intValue)
- .sum();
- int gatewayAddressesHash = mGatewayAddresses.stream()
- .map(InetAddress::hashCode)
- .mapToInt(Integer::intValue)
- .sum();
- int pcscfAddressesHash = mPcscfAddresses.stream()
- .map(InetAddress::hashCode)
- .mapToInt(Integer::intValue)
- .sum();
- int qosBearerSessionsHash = mQosBearerSessions.stream()
- .map(QosBearerSession::hashCode)
- .mapToInt(Integer::intValue)
- .sum();
- int trafficDescriptorsHash = mTrafficDescriptors.stream()
- .map(TrafficDescriptor::hashCode)
- .mapToInt(Integer::intValue)
- .sum();
return Objects.hash(mCause, mSuggestedRetryTime, mId, mLinkStatus, mProtocolType,
- mInterfaceName, addressesHash, dnsAddressesHash, gatewayAddressesHash,
- pcscfAddressesHash, mMtu, mMtuV4, mMtuV6, mHandoverFailureMode, mPduSessionId,
- mDefaultQos, qosBearerSessionsHash, mSliceInfo, trafficDescriptorsHash);
+ mInterfaceName, Set.copyOf(mAddresses), Set.copyOf(mDnsAddresses),
+ Set.copyOf(mGatewayAddresses), Set.copyOf(mPcscfAddresses), mMtu, mMtuV4, mMtuV6,
+ mHandoverFailureMode, mPduSessionId, mDefaultQos, Set.copyOf(mQosBearerSessions),
+ mSliceInfo, Set.copyOf(mTrafficDescriptors));
}
@Override
@@ -616,15 +592,15 @@
private @ProtocolType int mProtocolType;
- private String mInterfaceName;
+ private String mInterfaceName = "";
- private List<LinkAddress> mAddresses;
+ private List<LinkAddress> mAddresses = Collections.emptyList();
- private List<InetAddress> mDnsAddresses;
+ private List<InetAddress> mDnsAddresses = Collections.emptyList();
- private List<InetAddress> mGatewayAddresses;
+ private List<InetAddress> mGatewayAddresses = Collections.emptyList();
- private List<InetAddress> mPcscfAddresses;
+ private List<InetAddress> mPcscfAddresses = Collections.emptyList();
private int mMtu;
@@ -636,11 +612,11 @@
private int mPduSessionId = PDU_SESSION_ID_NOT_SET;
- private Qos mDefaultQos;
+ private @Nullable Qos mDefaultQos;
private List<QosBearerSession> mQosBearerSessions = new ArrayList<>();
- private NetworkSliceInfo mSliceInfo;
+ private @Nullable NetworkSliceInfo mSliceInfo;
private List<TrafficDescriptor> mTrafficDescriptors = new ArrayList<>();
@@ -726,6 +702,7 @@
* @return The same instance of the builder.
*/
public @NonNull Builder setInterfaceName(@NonNull String interfaceName) {
+ Objects.requireNonNull(interfaceName);
mInterfaceName = interfaceName;
return this;
}
@@ -737,6 +714,7 @@
* @return The same instance of the builder.
*/
public @NonNull Builder setAddresses(@NonNull List<LinkAddress> addresses) {
+ Objects.requireNonNull(addresses);
mAddresses = addresses;
return this;
}
@@ -748,6 +726,7 @@
* @return The same instance of the builder.
*/
public @NonNull Builder setDnsAddresses(@NonNull List<InetAddress> dnsAddresses) {
+ Objects.requireNonNull(dnsAddresses);
mDnsAddresses = dnsAddresses;
return this;
}
@@ -759,6 +738,7 @@
* @return The same instance of the builder.
*/
public @NonNull Builder setGatewayAddresses(@NonNull List<InetAddress> gatewayAddresses) {
+ Objects.requireNonNull(gatewayAddresses);
mGatewayAddresses = gatewayAddresses;
return this;
}
@@ -771,6 +751,7 @@
* @return The same instance of the builder.
*/
public @NonNull Builder setPcscfAddresses(@NonNull List<InetAddress> pcscfAddresses) {
+ Objects.requireNonNull(pcscfAddresses);
mPcscfAddresses = pcscfAddresses;
return this;
}
diff --git a/tests/FlickerTests/Android.bp b/tests/FlickerTests/Android.bp
index a996fa1..8faedeb 100644
--- a/tests/FlickerTests/Android.bp
+++ b/tests/FlickerTests/Android.bp
@@ -53,6 +53,11 @@
}
filegroup {
+ name: "FlickerTestsNotification-src",
+ srcs: ["src/**/notification/*.kt"],
+}
+
+filegroup {
name: "FlickerTestsQuickswitch-src",
srcs: ["src/**/quickswitch/*.kt"],
}
@@ -146,6 +151,18 @@
}
android_test {
+ name: "FlickerTestsNotification",
+ defaults: ["FlickerTestsDefault"],
+ additional_manifests: ["manifests/AndroidManifestNotification.xml"],
+ package_name: "com.android.server.wm.flicker.notification",
+ instrumentation_target_package: "com.android.server.wm.flicker.notification",
+ srcs: [
+ ":FlickerTestsBase-src",
+ ":FlickerTestsNotification-src",
+ ],
+}
+
+android_test {
name: "FlickerTestsQuickswitch",
defaults: ["FlickerTestsDefault"],
additional_manifests: ["manifests/AndroidManifestQuickswitch.xml"],
diff --git a/tests/FlickerTests/manifests/AndroidManifest.xml b/tests/FlickerTests/manifests/AndroidManifest.xml
index de8a3c6..1a34d9e 100644
--- a/tests/FlickerTests/manifests/AndroidManifest.xml
+++ b/tests/FlickerTests/manifests/AndroidManifest.xml
@@ -16,6 +16,7 @@
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
package="com.android.server.wm.flicker">
<uses-sdk android:minSdkVersion="29" android:targetSdkVersion="29"/>
@@ -47,5 +48,11 @@
<application android:requestLegacyExternalStorage="true" android:largeHeap="true">
<uses-library android:name="android.test.runner"/>
<uses-library android:name="androidx.window.extensions" android:required="false"/>
+
+ <!-- (b/197936012) Remove startup provider due to test timeout issue -->
+ <provider
+ android:name="androidx.startup.InitializationProvider"
+ android:authorities="${applicationId}.androidx-startup"
+ tools:node="remove" />
</application>
</manifest>
diff --git a/tests/FlickerTests/manifests/AndroidManifestNotification.xml b/tests/FlickerTests/manifests/AndroidManifestNotification.xml
new file mode 100644
index 0000000..ad33dee
--- /dev/null
+++ b/tests/FlickerTests/manifests/AndroidManifestNotification.xml
@@ -0,0 +1,24 @@
+<!--
+ ~ Copyright (C) 2023 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.server.wm.flicker.close">
+
+ <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="com.android.server.wm.flicker.notification"
+ android:label="WindowManager Flicker Tests">
+ </instrumentation>
+</manifest>
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/BaseTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/BaseTest.kt
index efd9b00..7c9c05d 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/BaseTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/BaseTest.kt
@@ -21,7 +21,7 @@
import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.junit.FlickerBuilderProvider
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTest
import android.util.Log
import androidx.test.platform.app.InstrumentationRegistry
import com.android.launcher3.tapl.LauncherInstrumentation
@@ -37,7 +37,7 @@
abstract class BaseTest
@JvmOverloads
constructor(
- protected val flicker: FlickerTest,
+ protected val flicker: LegacyFlickerTest,
protected val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation(),
protected val tapl: LauncherInstrumentation = LauncherInstrumentation()
) {
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt
index ed9e14f..1fdbe7f 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/CommonAssertions.kt
@@ -23,14 +23,14 @@
import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.common.traces.component.IComponentNameMatcher
import android.tools.common.traces.wm.WindowManagerTrace
-import android.tools.device.flicker.legacy.FlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTest
import android.tools.device.helpers.WindowUtils
/**
* Checks that [ComponentNameMatcher.STATUS_BAR] window is visible and above the app windows in all
* WM trace entries
*/
-fun FlickerTest.statusBarWindowIsAlwaysVisible() {
+fun LegacyFlickerTest.statusBarWindowIsAlwaysVisible() {
assertWm { this.isAboveAppWindowVisible(ComponentNameMatcher.STATUS_BAR) }
}
@@ -38,7 +38,7 @@
* Checks that [ComponentNameMatcher.NAV_BAR] window is visible and above the app windows in all WM
* trace entries
*/
-fun FlickerTest.navBarWindowIsAlwaysVisible() {
+fun LegacyFlickerTest.navBarWindowIsAlwaysVisible() {
assertWm { this.isAboveAppWindowVisible(ComponentNameMatcher.NAV_BAR) }
}
@@ -46,7 +46,7 @@
* Checks that [ComponentNameMatcher.NAV_BAR] window is visible and above the app windows at the
* start and end of the WM trace
*/
-fun FlickerTest.navBarWindowIsVisibleAtStartAndEnd() {
+fun LegacyFlickerTest.navBarWindowIsVisibleAtStartAndEnd() {
this.navBarWindowIsVisibleAtStart()
this.navBarWindowIsVisibleAtEnd()
}
@@ -55,7 +55,7 @@
* Checks that [ComponentNameMatcher.NAV_BAR] window is visible and above the app windows at the
* start of the WM trace
*/
-fun FlickerTest.navBarWindowIsVisibleAtStart() {
+fun LegacyFlickerTest.navBarWindowIsVisibleAtStart() {
assertWmStart { this.isAboveAppWindowVisible(ComponentNameMatcher.NAV_BAR) }
}
@@ -63,7 +63,7 @@
* Checks that [ComponentNameMatcher.NAV_BAR] window is visible and above the app windows at the end
* of the WM trace
*/
-fun FlickerTest.navBarWindowIsVisibleAtEnd() {
+fun LegacyFlickerTest.navBarWindowIsVisibleAtEnd() {
assertWmEnd { this.isAboveAppWindowVisible(ComponentNameMatcher.NAV_BAR) }
}
@@ -71,7 +71,7 @@
* Checks that [ComponentNameMatcher.TASK_BAR] window is visible and above the app windows in all WM
* trace entries
*/
-fun FlickerTest.taskBarWindowIsAlwaysVisible() {
+fun LegacyFlickerTest.taskBarWindowIsAlwaysVisible() {
assertWm { this.isAboveAppWindowVisible(ComponentNameMatcher.TASK_BAR) }
}
@@ -79,7 +79,7 @@
* Checks that [ComponentNameMatcher.TASK_BAR] window is visible and above the app windows in all WM
* trace entries
*/
-fun FlickerTest.taskBarWindowIsVisibleAtEnd() {
+fun LegacyFlickerTest.taskBarWindowIsVisibleAtEnd() {
assertWmEnd { this.isAboveAppWindowVisible(ComponentNameMatcher.TASK_BAR) }
}
@@ -93,43 +93,45 @@
* @param allStates if all states should be checked, othersie, just initial and final
*/
@JvmOverloads
-fun FlickerTest.entireScreenCovered(allStates: Boolean = true) {
+fun LegacyFlickerTest.entireScreenCovered(allStates: Boolean = true) {
if (allStates) {
assertLayers {
this.invoke("entireScreenCovered") { entry ->
- entry.entry.displays.filter { it.isOn }.forEach { display ->
- entry.visibleRegion().coversAtLeast(display.layerStackSpace)
- }
+ entry.entry.displays
+ .filter { it.isOn }
+ .forEach { display ->
+ entry.visibleRegion().coversAtLeast(display.layerStackSpace)
+ }
}
}
} else {
assertLayersStart {
- this.entry.displays.filter { it.isOn }.forEach { display ->
- this.visibleRegion().coversAtLeast(display.layerStackSpace)
- }
+ this.entry.displays
+ .filter { it.isOn }
+ .forEach { display -> this.visibleRegion().coversAtLeast(display.layerStackSpace) }
}
assertLayersEnd {
- this.entry.displays.filter { it.isOn }.forEach { display ->
- this.visibleRegion().coversAtLeast(display.layerStackSpace)
- }
+ this.entry.displays
+ .filter { it.isOn }
+ .forEach { display -> this.visibleRegion().coversAtLeast(display.layerStackSpace) }
}
}
}
/** Checks that [ComponentNameMatcher.NAV_BAR] layer is visible at the start of the SF trace */
-fun FlickerTest.navBarLayerIsVisibleAtStart() {
+fun LegacyFlickerTest.navBarLayerIsVisibleAtStart() {
assertLayersStart { this.isVisible(ComponentNameMatcher.NAV_BAR) }
}
/** Checks that [ComponentNameMatcher.NAV_BAR] layer is visible at the end of the SF trace */
-fun FlickerTest.navBarLayerIsVisibleAtEnd() {
+fun LegacyFlickerTest.navBarLayerIsVisibleAtEnd() {
assertLayersEnd { this.isVisible(ComponentNameMatcher.NAV_BAR) }
}
/**
* Checks that [ComponentNameMatcher.NAV_BAR] layer is visible at the start and end of the SF trace
*/
-fun FlickerTest.navBarLayerIsVisibleAtStartAndEnd() {
+fun LegacyFlickerTest.navBarLayerIsVisibleAtStartAndEnd() {
this.navBarLayerIsVisibleAtStart()
this.navBarLayerIsVisibleAtEnd()
}
@@ -137,18 +139,18 @@
/**
* Checks that [ComponentNameMatcher.TASK_BAR] layer is visible at the start and end of the SF trace
*/
-fun FlickerTest.taskBarLayerIsVisibleAtStartAndEnd() {
+fun LegacyFlickerTest.taskBarLayerIsVisibleAtStartAndEnd() {
this.taskBarLayerIsVisibleAtStart()
this.taskBarLayerIsVisibleAtEnd()
}
/** Checks that [ComponentNameMatcher.TASK_BAR] layer is visible at the start of the SF trace */
-fun FlickerTest.taskBarLayerIsVisibleAtStart() {
+fun LegacyFlickerTest.taskBarLayerIsVisibleAtStart() {
assertLayersStart { this.isVisible(ComponentNameMatcher.TASK_BAR) }
}
/** Checks that [ComponentNameMatcher.TASK_BAR] layer is visible at the end of the SF trace */
-fun FlickerTest.taskBarLayerIsVisibleAtEnd() {
+fun LegacyFlickerTest.taskBarLayerIsVisibleAtEnd() {
assertLayersEnd { this.isVisible(ComponentNameMatcher.TASK_BAR) }
}
@@ -156,7 +158,7 @@
* Checks that [ComponentNameMatcher.STATUS_BAR] layer is visible at the start and end of the SF
* trace
*/
-fun FlickerTest.statusBarLayerIsVisibleAtStartAndEnd() {
+fun LegacyFlickerTest.statusBarLayerIsVisibleAtStartAndEnd() {
assertLayersStart { this.isVisible(ComponentNameMatcher.STATUS_BAR) }
assertLayersEnd { this.isVisible(ComponentNameMatcher.STATUS_BAR) }
}
@@ -165,7 +167,7 @@
* Asserts that the [ComponentNameMatcher.NAV_BAR] layer is at the correct position at the start of
* the SF trace
*/
-fun FlickerTest.navBarLayerPositionAtStart() {
+fun LegacyFlickerTest.navBarLayerPositionAtStart() {
assertLayersStart {
val display =
this.entry.displays.firstOrNull { !it.isVirtual } ?: error("There is no display!")
@@ -180,7 +182,7 @@
* Asserts that the [ComponentNameMatcher.NAV_BAR] layer is at the correct position at the end of
* the SF trace
*/
-fun FlickerTest.navBarLayerPositionAtEnd() {
+fun LegacyFlickerTest.navBarLayerPositionAtEnd() {
assertLayersEnd {
val display =
this.entry.displays.minByOrNull { it.id }
@@ -196,7 +198,7 @@
* Asserts that the [ComponentNameMatcher.NAV_BAR] layer is at the correct position at the start and
* end of the SF trace
*/
-fun FlickerTest.navBarLayerPositionAtStartAndEnd() {
+fun LegacyFlickerTest.navBarLayerPositionAtStartAndEnd() {
navBarLayerPositionAtStart()
navBarLayerPositionAtEnd()
}
@@ -205,7 +207,7 @@
* Asserts that the [ComponentNameMatcher.STATUS_BAR] layer is at the correct position at the start
* of the SF trace
*/
-fun FlickerTest.statusBarLayerPositionAtStart(
+fun LegacyFlickerTest.statusBarLayerPositionAtStart(
wmTrace: WindowManagerTrace? = this.reader.readWmTrace()
) {
// collect navbar position for the equivalent WM state
@@ -221,7 +223,7 @@
* Asserts that the [ComponentNameMatcher.STATUS_BAR] layer is at the correct position at the end of
* the SF trace
*/
-fun FlickerTest.statusBarLayerPositionAtEnd(
+fun LegacyFlickerTest.statusBarLayerPositionAtEnd(
wmTrace: WindowManagerTrace? = this.reader.readWmTrace()
) {
// collect navbar position for the equivalent WM state
@@ -237,7 +239,7 @@
* Asserts that the [ComponentNameMatcher.STATUS_BAR] layer is at the correct position at the start
* and end of the SF trace
*/
-fun FlickerTest.statusBarLayerPositionAtStartAndEnd() {
+fun LegacyFlickerTest.statusBarLayerPositionAtStartAndEnd() {
statusBarLayerPositionAtStart()
statusBarLayerPositionAtEnd()
}
@@ -246,7 +248,9 @@
* Asserts that the visibleRegion of the [ComponentNameMatcher.SNAPSHOT] layer can cover the
* visibleRegion of the given app component exactly
*/
-fun FlickerTest.snapshotStartingWindowLayerCoversExactlyOnApp(component: IComponentNameMatcher) {
+fun LegacyFlickerTest.snapshotStartingWindowLayerCoversExactlyOnApp(
+ component: IComponentNameMatcher
+) {
assertLayers {
invoke("snapshotStartingWindowLayerCoversExactlyOnApp") {
val snapshotLayers =
@@ -307,7 +311,7 @@
* otherwise we won't and the layer must appear immediately.
* ```
*/
-fun FlickerTest.replacesLayer(
+fun LegacyFlickerTest.replacesLayer(
originalLayer: IComponentNameMatcher,
newLayer: IComponentNameMatcher,
ignoreEntriesWithRotationLayer: Boolean = false,
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/ActivityEmbeddingTestBase.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/ActivityEmbeddingTestBase.kt
index 7ef4d93..45cd65d 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/ActivityEmbeddingTestBase.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/ActivityEmbeddingTestBase.kt
@@ -16,12 +16,12 @@
package com.android.server.wm.flicker.activityembedding
-import android.tools.device.flicker.legacy.FlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTest
import com.android.server.wm.flicker.BaseTest
import com.android.server.wm.flicker.helpers.ActivityEmbeddingAppHelper
import org.junit.Before
-abstract class ActivityEmbeddingTestBase(flicker: FlickerTest) : BaseTest(flicker) {
+abstract class ActivityEmbeddingTestBase(flicker: LegacyFlickerTest) : BaseTest(flicker) {
val testApp = ActivityEmbeddingAppHelper(instrumentation)
@Before
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/RTLStartSecondaryWithPlaceholderTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/RTLStartSecondaryWithPlaceholderTest.kt
index 236c44e..4bc17ed 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/RTLStartSecondaryWithPlaceholderTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/RTLStartSecondaryWithPlaceholderTest.kt
@@ -19,8 +19,8 @@
import android.platform.test.annotations.Presubmit
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import androidx.test.filters.RequiresDevice
import com.android.server.wm.flicker.helpers.ActivityEmbeddingAppHelper
import org.junit.FixMethodOrder
@@ -32,10 +32,9 @@
/**
* Test launching a placeholder split over a normal split, both splits are configured in RTL.
*
- * Setup: From A launch a split in RTL - resulting in B|A.
- * Transitions:
- * From A start PlaceholderPrimary, which is configured to launch with PlaceholderSecondary in RTL.
- * Expect split PlaceholderSecondary|PlaceholderPrimary covering split B|A.
+ * Setup: From A launch a split in RTL - resulting in B|A. Transitions: From A start
+ * PlaceholderPrimary, which is configured to launch with PlaceholderSecondary in RTL. Expect split
+ * PlaceholderSecondary|PlaceholderPrimary covering split B|A.
*
* To run this test: `atest FlickerTests:RTLStartSecondaryWithPlaceholderTest`
*/
@@ -43,169 +42,165 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class RTLStartSecondaryWithPlaceholderTest(flicker: FlickerTest) :
- ActivityEmbeddingTestBase(flicker) {
+class RTLStartSecondaryWithPlaceholderTest(flicker: LegacyFlickerTest) :
+ ActivityEmbeddingTestBase(flicker) {
- /** {@inheritDoc} */
- override val transition: FlickerBuilder.() -> Unit = {
- setup {
- tapl.setExpectedRotationCheckEnabled(false)
- testApp.launchViaIntent(wmHelper)
- testApp.launchSecondaryActivityRTL(wmHelper)
+ /** {@inheritDoc} */
+ override val transition: FlickerBuilder.() -> Unit = {
+ setup {
+ tapl.setExpectedRotationCheckEnabled(false)
+ testApp.launchViaIntent(wmHelper)
+ testApp.launchSecondaryActivityRTL(wmHelper)
+ }
+ transitions { testApp.launchPlaceholderSplitRTL(wmHelper) }
+ teardown {
+ tapl.goHome()
+ testApp.exit(wmHelper)
+ }
}
- transitions {
- testApp.launchPlaceholderSplitRTL(wmHelper)
- }
- teardown {
- tapl.goHome()
- testApp.exit(wmHelper)
- }
- }
- /**
- * Main activity and Secondary activity will become invisible because they are covered by
- * PlaceholderPrimary activity and PlaceholderSecondary activity.
- */
- @Presubmit
- @Test
- fun assertWindowVisibilities() {
- flicker.assertWm {
- isAppWindowVisible(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT)
- .then()
- .isAppWindowInvisible(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT)
- }
- flicker.assertWm {
- isAppWindowVisible(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT)
- .then()
- .isAppWindowInvisible(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT)
- }
- flicker.assertWm {
- isAppWindowInvisible(ActivityEmbeddingAppHelper.PLACEHOLDER_PRIMARY_COMPONENT)
- .then()
- .isAppWindowVisible(ActivityEmbeddingAppHelper.PLACEHOLDER_PRIMARY_COMPONENT)
- }
- flicker.assertWm {
- isAppWindowInvisible(ActivityEmbeddingAppHelper.PLACEHOLDER_SECONDARY_COMPONENT)
- .then()
- .isAppWindowVisible(ActivityEmbeddingAppHelper.PLACEHOLDER_SECONDARY_COMPONENT)
- }
- }
-
- /**
- * Main activity and Secondary activity will become invisible because they are covered by
- * PlaceholderPrimary activity and PlaceholderSecondary activity.
- */
- @Presubmit
- @Test
- fun assertLayerVisibilities() {
- flicker.assertLayers {
- this.isVisible(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT)
- .then()
- .isInvisible(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT)
- }
- flicker.assertLayers {
- this.isVisible(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT)
- .then()
- .isInvisible(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT)
- }
- flicker.assertLayers {
- isInvisible(ActivityEmbeddingAppHelper.PLACEHOLDER_PRIMARY_COMPONENT)
- .then()
- .isVisible(ActivityEmbeddingAppHelper.PLACEHOLDER_PRIMARY_COMPONENT)
- }
- flicker.assertLayers {
- isInvisible(ActivityEmbeddingAppHelper.PLACEHOLDER_SECONDARY_COMPONENT)
- .then()
- .isVisible(ActivityEmbeddingAppHelper.PLACEHOLDER_SECONDARY_COMPONENT)
- }
- }
-
- /** Main activity and Secondary activity split is in right-to-left layout direction. */
- @Presubmit
- @Test
- fun assertWMRTLBeforeTransition() {
- flicker.assertWmStart {
- val mainActivityRegion =
- this.visibleRegion(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT)
- val secondaryActivityRegion =
- this.visibleRegion(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT)
- mainActivityRegion.notOverlaps(secondaryActivityRegion.region)
- // secondary activity is on the left, main activity is on the right.
- check { "isRTLBeforeTransition" }
- .that(mainActivityRegion.region.bounds.left)
- .isEqual(secondaryActivityRegion.region.bounds.right)
- }
- }
-
- /** Main activity and Secondary activity split is in right-to-left layout direction. */
- @Presubmit
- @Test
- fun assertLayerRTLBeforeTransition() {
- flicker.assertLayersStart {
- val mainActivityRegion =
- this.visibleRegion(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT)
- val secondaryActivityRegion =
- this.visibleRegion(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT)
- mainActivityRegion.notOverlaps(secondaryActivityRegion.region)
- // secondary activity is on the left, main activity is on the right.
- check { "isRTLBeforeTransition" }
- .that(mainActivityRegion.region.bounds.left)
- .isEqual(secondaryActivityRegion.region.bounds.right)
- }
- }
-
- /**
- * PlaceholderPrimary activity and PlaceholderSecondary activity split are in right-to-left
- * layout direction.
- */
- @Presubmit
- @Test
- fun assertWMRTLAfterTransition() {
- flicker.assertWmEnd {
- val mainActivityRegion =
- this.visibleRegion(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT)
- val secondaryActivityRegion =
- this.visibleRegion(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT)
- mainActivityRegion.notOverlaps(secondaryActivityRegion.region)
- // secondary activity is on the left, main activity is on the right.
- check { "isRTLBeforeTransition" }
- .that(mainActivityRegion.region.bounds.left)
- .isEqual(secondaryActivityRegion.region.bounds.right)
- }
- }
-
- /**
- * PlaceholderPrimary activity and PlaceholderSecondary activity split are in right-to-left
- * layout direction.
- */
- @Presubmit
- @Test
- fun assertLayerRTLAfterTransition() {
- flicker.assertLayersEnd {
- val mainActivityRegion =
- this.visibleRegion(ActivityEmbeddingAppHelper.PLACEHOLDER_PRIMARY_COMPONENT)
- val secondaryActivityRegion =
- this.visibleRegion(ActivityEmbeddingAppHelper.PLACEHOLDER_SECONDARY_COMPONENT)
- mainActivityRegion.notOverlaps(secondaryActivityRegion.region)
- // Placeholder secondary activity is on the left, placeholder primary activity is on the
- // right.
- check { "isRTLAfterTransition" }
- .that(mainActivityRegion.region.bounds.left)
- .isEqual(secondaryActivityRegion.region.bounds.right)
- }
- }
-
- companion object {
/**
- * Creates the test configurations.
- *
- * See [FlickerTestFactory.nonRotationTests] for configuring screen orientation and
- * navigation modes.
+ * Main activity and Secondary activity will become invisible because they are covered by
+ * PlaceholderPrimary activity and PlaceholderSecondary activity.
*/
- @Parameterized.Parameters(name = "{0}")
- @JvmStatic
- fun getParams(): Collection<FlickerTest> {
- return FlickerTestFactory.nonRotationTests()
+ @Presubmit
+ @Test
+ fun assertWindowVisibilities() {
+ flicker.assertWm {
+ isAppWindowVisible(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT)
+ .then()
+ .isAppWindowInvisible(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT)
+ }
+ flicker.assertWm {
+ isAppWindowVisible(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT)
+ .then()
+ .isAppWindowInvisible(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT)
+ }
+ flicker.assertWm {
+ isAppWindowInvisible(ActivityEmbeddingAppHelper.PLACEHOLDER_PRIMARY_COMPONENT)
+ .then()
+ .isAppWindowVisible(ActivityEmbeddingAppHelper.PLACEHOLDER_PRIMARY_COMPONENT)
+ }
+ flicker.assertWm {
+ isAppWindowInvisible(ActivityEmbeddingAppHelper.PLACEHOLDER_SECONDARY_COMPONENT)
+ .then()
+ .isAppWindowVisible(ActivityEmbeddingAppHelper.PLACEHOLDER_SECONDARY_COMPONENT)
+ }
}
- }
+
+ /**
+ * Main activity and Secondary activity will become invisible because they are covered by
+ * PlaceholderPrimary activity and PlaceholderSecondary activity.
+ */
+ @Presubmit
+ @Test
+ fun assertLayerVisibilities() {
+ flicker.assertLayers {
+ this.isVisible(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT)
+ .then()
+ .isInvisible(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT)
+ }
+ flicker.assertLayers {
+ this.isVisible(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT)
+ .then()
+ .isInvisible(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT)
+ }
+ flicker.assertLayers {
+ isInvisible(ActivityEmbeddingAppHelper.PLACEHOLDER_PRIMARY_COMPONENT)
+ .then()
+ .isVisible(ActivityEmbeddingAppHelper.PLACEHOLDER_PRIMARY_COMPONENT)
+ }
+ flicker.assertLayers {
+ isInvisible(ActivityEmbeddingAppHelper.PLACEHOLDER_SECONDARY_COMPONENT)
+ .then()
+ .isVisible(ActivityEmbeddingAppHelper.PLACEHOLDER_SECONDARY_COMPONENT)
+ }
+ }
+
+ /** Main activity and Secondary activity split is in right-to-left layout direction. */
+ @Presubmit
+ @Test
+ fun assertWMRTLBeforeTransition() {
+ flicker.assertWmStart {
+ val mainActivityRegion =
+ this.visibleRegion(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT)
+ val secondaryActivityRegion =
+ this.visibleRegion(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT)
+ mainActivityRegion.notOverlaps(secondaryActivityRegion.region)
+ // secondary activity is on the left, main activity is on the right.
+ check { "isRTLBeforeTransition" }
+ .that(mainActivityRegion.region.bounds.left)
+ .isEqual(secondaryActivityRegion.region.bounds.right)
+ }
+ }
+
+ /** Main activity and Secondary activity split is in right-to-left layout direction. */
+ @Presubmit
+ @Test
+ fun assertLayerRTLBeforeTransition() {
+ flicker.assertLayersStart {
+ val mainActivityRegion =
+ this.visibleRegion(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT)
+ val secondaryActivityRegion =
+ this.visibleRegion(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT)
+ mainActivityRegion.notOverlaps(secondaryActivityRegion.region)
+ // secondary activity is on the left, main activity is on the right.
+ check { "isRTLBeforeTransition" }
+ .that(mainActivityRegion.region.bounds.left)
+ .isEqual(secondaryActivityRegion.region.bounds.right)
+ }
+ }
+
+ /**
+ * PlaceholderPrimary activity and PlaceholderSecondary activity split are in right-to-left
+ * layout direction.
+ */
+ @Presubmit
+ @Test
+ fun assertWMRTLAfterTransition() {
+ flicker.assertWmEnd {
+ val mainActivityRegion =
+ this.visibleRegion(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT)
+ val secondaryActivityRegion =
+ this.visibleRegion(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT)
+ mainActivityRegion.notOverlaps(secondaryActivityRegion.region)
+ // secondary activity is on the left, main activity is on the right.
+ check { "isRTLBeforeTransition" }
+ .that(mainActivityRegion.region.bounds.left)
+ .isEqual(secondaryActivityRegion.region.bounds.right)
+ }
+ }
+
+ /**
+ * PlaceholderPrimary activity and PlaceholderSecondary activity split are in right-to-left
+ * layout direction.
+ */
+ @Presubmit
+ @Test
+ fun assertLayerRTLAfterTransition() {
+ flicker.assertLayersEnd {
+ val mainActivityRegion =
+ this.visibleRegion(ActivityEmbeddingAppHelper.PLACEHOLDER_PRIMARY_COMPONENT)
+ val secondaryActivityRegion =
+ this.visibleRegion(ActivityEmbeddingAppHelper.PLACEHOLDER_SECONDARY_COMPONENT)
+ mainActivityRegion.notOverlaps(secondaryActivityRegion.region)
+ // Placeholder secondary activity is on the left, placeholder primary activity is on the
+ // right.
+ check { "isRTLAfterTransition" }
+ .that(mainActivityRegion.region.bounds.left)
+ .isEqual(secondaryActivityRegion.region.bounds.right)
+ }
+ }
+
+ companion object {
+ /**
+ * Creates the test configurations.
+ *
+ * See [LegacyFlickerTestFactory.nonRotationTests] for configuring screen orientation and
+ * navigation modes.
+ */
+ @Parameterized.Parameters(name = "{0}")
+ @JvmStatic
+ fun getParams() = LegacyFlickerTestFactory.nonRotationTests()
+ }
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/close/CloseSecondaryActivityInSplitTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/close/CloseSecondaryActivityInSplitTest.kt
index c0c738b..7a582f7 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/close/CloseSecondaryActivityInSplitTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/close/CloseSecondaryActivityInSplitTest.kt
@@ -21,8 +21,8 @@
import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import androidx.test.filters.RequiresDevice
import com.android.server.wm.flicker.helpers.ActivityEmbeddingAppHelper
import org.junit.FixMethodOrder
@@ -34,8 +34,8 @@
/**
* Test closing a secondary activity in a split.
*
- * Setup: Launch A|B in split with B being the secondary activity.
- * Transitions: Finish B and expect A to become fullscreen.
+ * Setup: Launch A|B in split with B being the secondary activity. Transitions: Finish B and expect
+ * A to become fullscreen.
*
* To run this test: `atest FlickerTests:CloseSecondaryActivityInSplitTest`
*/
@@ -43,95 +43,93 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class CloseSecondaryActivityInSplitTest(flicker: FlickerTest) :
- ActivityEmbeddingTestBase(flicker) {
+class CloseSecondaryActivityInSplitTest(flicker: LegacyFlickerTest) :
+ ActivityEmbeddingTestBase(flicker) {
- override val transition: FlickerBuilder.() -> Unit = {
- setup {
- tapl.setExpectedRotationCheckEnabled(false)
- // Launches fullscreen A.
- testApp.launchViaIntent(wmHelper)
- // Launches a split A|B and waits for both activities to show.
- testApp.launchSecondaryActivity(wmHelper)
- // Get fullscreen bounds
- startDisplayBounds =
- wmHelper.currentState.layerState.physicalDisplayBounds ?:
- error("Can't get display bounds")
+ override val transition: FlickerBuilder.() -> Unit = {
+ setup {
+ tapl.setExpectedRotationCheckEnabled(false)
+ // Launches fullscreen A.
+ testApp.launchViaIntent(wmHelper)
+ // Launches a split A|B and waits for both activities to show.
+ testApp.launchSecondaryActivity(wmHelper)
+ // Get fullscreen bounds
+ startDisplayBounds =
+ wmHelper.currentState.layerState.physicalDisplayBounds
+ ?: error("Can't get display bounds")
+ }
+ transitions {
+ // Finish secondary activity B.
+ testApp.finishSecondaryActivity(wmHelper)
+ // Expect the main activity A to expand into fullscreen.
+ wmHelper.StateSyncBuilder().withFullScreenApp(testApp).waitForAndVerify()
+ }
+ teardown {
+ tapl.goHome()
+ testApp.exit(wmHelper)
+ }
}
- transitions {
- // Finish secondary activity B.
- testApp.finishSecondaryActivity(wmHelper)
- // Expect the main activity A to expand into fullscreen.
- wmHelper.StateSyncBuilder().withFullScreenApp(testApp).waitForAndVerify()
- }
- teardown {
- tapl.goHome()
- testApp.exit(wmHelper)
- }
- }
- /** Main activity is always visible and becomes fullscreen in the end. */
- @Presubmit
- @Test
- fun mainActivityWindowBecomesFullScreen() {
- flicker.assertWm { isAppWindowVisible(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT) }
- flicker.assertWmEnd {
- this.visibleRegion(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT)
- .coversExactly(startDisplayBounds)
+ /** Main activity is always visible and becomes fullscreen in the end. */
+ @Presubmit
+ @Test
+ fun mainActivityWindowBecomesFullScreen() {
+ flicker.assertWm { isAppWindowVisible(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT) }
+ flicker.assertWmEnd {
+ this.visibleRegion(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT)
+ .coversExactly(startDisplayBounds)
+ }
}
- }
- /** Main activity surface is animated from split to fullscreen. */
- @Presubmit
- @Test
- fun mainActivityLayerIsAlwaysVisible() {
- flicker.assertLayers {
- isVisible(
- ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT.or(
- ComponentNameMatcher.TRANSITION_SNAPSHOT
- )
- )
+ /** Main activity surface is animated from split to fullscreen. */
+ @Presubmit
+ @Test
+ fun mainActivityLayerIsAlwaysVisible() {
+ flicker.assertLayers {
+ isVisible(
+ ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT.or(
+ ComponentNameMatcher.TRANSITION_SNAPSHOT
+ )
+ )
+ }
+ flicker.assertLayersEnd {
+ isVisible(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT)
+ .isInvisible(ComponentNameMatcher.TRANSITION_SNAPSHOT)
+ }
}
- flicker.assertLayersEnd {
- isVisible(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT)
- .isInvisible(ComponentNameMatcher.TRANSITION_SNAPSHOT)
- }
- }
- /** Secondary activity should destroy and become invisible. */
- @Presubmit
- @Test
- fun secondaryActivityWindowFinishes() {
- flicker.assertWm {
- contains(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT)
- .then()
- .notContains(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT)
+ /** Secondary activity should destroy and become invisible. */
+ @Presubmit
+ @Test
+ fun secondaryActivityWindowFinishes() {
+ flicker.assertWm {
+ contains(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT)
+ .then()
+ .notContains(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT)
+ }
}
- }
- @Presubmit
- @Test
- fun secondaryActivityLayerFinishes() {
- flicker.assertLayers {
- isVisible(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT)
- .then()
- .isInvisible(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT)
+ @Presubmit
+ @Test
+ fun secondaryActivityLayerFinishes() {
+ flicker.assertLayers {
+ isVisible(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT)
+ .then()
+ .isInvisible(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT)
+ }
}
- }
- companion object {
- /** {@inheritDoc} */
- private var startDisplayBounds = Rect.EMPTY
- /**
- * Creates the test configurations.
- *
- * See [FlickerTestFactory.nonRotationTests] for configuring screen orientation and
- * navigation modes.
- */
- @Parameterized.Parameters(name = "{0}")
- @JvmStatic
- fun getParams(): Collection<FlickerTest> {
- return FlickerTestFactory.nonRotationTests()
+ companion object {
+ /** {@inheritDoc} */
+ private var startDisplayBounds = Rect.EMPTY
+ /**
+ * Creates the test configurations.
+ *
+ * See [LegacyFlickerTestFactory.nonRotationTests] for configuring screen orientation and
+ * navigation modes.
+ */
+ @Parameterized.Parameters(name = "{0}")
+ @JvmStatic
+ fun getParams() = LegacyFlickerTestFactory.nonRotationTests()
}
- }
- }
\ No newline at end of file
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/open/MainActivityStartsSecondaryWithAlwaysExpandTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/open/MainActivityStartsSecondaryWithAlwaysExpandTest.kt
index 00316ea..48aaebd 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/open/MainActivityStartsSecondaryWithAlwaysExpandTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/open/MainActivityStartsSecondaryWithAlwaysExpandTest.kt
@@ -16,11 +16,13 @@
package com.android.server.wm.flicker.activityembedding
+import android.platform.test.annotations.FlakyTest
import android.platform.test.annotations.Presubmit
+import android.tools.common.datatypes.Rect
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import androidx.test.filters.RequiresDevice
import com.android.server.wm.flicker.helpers.ActivityEmbeddingAppHelper
import org.junit.FixMethodOrder
@@ -28,14 +30,12 @@
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
import org.junit.runners.Parameterized
-import android.tools.common.datatypes.Rect
/**
* Test launching an activity with AlwaysExpand rule.
*
- * Setup: Launch A|B in split with B being the secondary activity.
- * Transitions:
- * A start C with alwaysExpand=true, expect C to launch in fullscreen and cover split A|B.
+ * Setup: Launch A|B in split with B being the secondary activity. Transitions: A start C with
+ * alwaysExpand=true, expect C to launch in fullscreen and cover split A|B.
*
* To run this test: `atest FlickerTests:MainActivityStartsSecondaryWithAlwaysExpandTest`
*/
@@ -43,98 +43,109 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class MainActivityStartsSecondaryWithAlwaysExpandTest(flicker: FlickerTest) :
- ActivityEmbeddingTestBase(flicker) {
+class MainActivityStartsSecondaryWithAlwaysExpandTest(flicker: LegacyFlickerTest) :
+ ActivityEmbeddingTestBase(flicker) {
- /** {@inheritDoc} */
- override val transition: FlickerBuilder.() -> Unit = {
- setup {
- tapl.setExpectedRotationCheckEnabled(false)
- // Launch a split
- testApp.launchViaIntent(wmHelper)
- testApp.launchSecondaryActivity(wmHelper)
- startDisplayBounds =
- wmHelper.currentState.layerState.physicalDisplayBounds ?: error("Display not found")
- }
- transitions {
- // Launch C with alwaysExpand
- testApp.launchAlwaysExpandActivity(wmHelper)
- }
- teardown {
- tapl.goHome()
- testApp.exit(wmHelper)
- }
- }
-
- /** Transition begins with a split. */
- @Presubmit
- @Test
- fun startsWithSplit() {
- flicker.assertWmStart {
- this.isAppWindowVisible(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT)
- }
- flicker.assertWmStart {
- this.isAppWindowVisible(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT)
- }
- }
-
-
- /** Main activity should become invisible after being covered by always expand activity. */
- @Presubmit
- @Test
- fun mainActivityLayerBecomesInvisible() {
- flicker.assertLayers {
- isVisible(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT)
- .then()
- .isInvisible(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT)
- }
- }
-
- /** Secondary activity should become invisible after being covered by always expand activity. */
- @Presubmit
- @Test
- fun secondaryActivityLayerBecomesInvisible() {
- flicker.assertLayers {
- isVisible(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT)
- .then()
- .isInvisible(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT)
- }
- }
-
- /** At the end of transition always expand activity is in fullscreen. */
- @Presubmit
- @Test
- fun endsWithAlwaysExpandActivityCoveringFullScreen() {
- flicker.assertWmEnd {
- this.visibleRegion(ActivityEmbeddingAppHelper.ALWAYS_EXPAND_ACTIVITY_COMPONENT)
- .coversExactly(startDisplayBounds)
- }
- }
-
- /** Always expand activity is on top of the split. */
- @Presubmit
- @Test
- fun endsWithAlwaysExpandActivityOnTop() {
- flicker.assertWmEnd {
- this.isAppWindowOnTop(
- ActivityEmbeddingAppHelper.ALWAYS_EXPAND_ACTIVITY_COMPONENT)
- }
- }
-
- companion object {
/** {@inheritDoc} */
- private var startDisplayBounds = Rect.EMPTY
- /**
- * Creates the test configurations.
- *
- * See [FlickerTestFactory.nonRotationTests] for configuring screen orientation and
- * navigation modes.
- */
- @Parameterized.Parameters(name = "{0}")
- @JvmStatic
- fun getParams(): Collection<FlickerTest> {
- return FlickerTestFactory.nonRotationTests()
+ override val transition: FlickerBuilder.() -> Unit = {
+ setup {
+ tapl.setExpectedRotationCheckEnabled(false)
+ // Launch a split
+ testApp.launchViaIntent(wmHelper)
+ testApp.launchSecondaryActivity(wmHelper)
+ startDisplayBounds =
+ wmHelper.currentState.layerState.physicalDisplayBounds ?: error("Display not found")
+ }
+ transitions {
+ // Launch C with alwaysExpand
+ testApp.launchAlwaysExpandActivity(wmHelper)
+ }
+ teardown {
+ tapl.goHome()
+ testApp.exit(wmHelper)
+ }
}
- }
-}
+ @FlakyTest(bugId = 286952194)
+ @Presubmit
+ @Test
+ override fun navBarWindowIsVisibleAtStartAndEnd() {}
+
+ @FlakyTest(bugId = 286952194)
+ @Presubmit
+ @Test
+ override fun statusBarWindowIsAlwaysVisible() {}
+
+ @FlakyTest(bugId = 286952194)
+ @Presubmit
+ @Test
+ override fun statusBarLayerPositionAtStartAndEnd() {}
+
+ /** Transition begins with a split. */
+ @Presubmit
+ @Test
+ fun startsWithSplit() {
+ flicker.assertWmStart {
+ this.isAppWindowVisible(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT)
+ }
+ flicker.assertWmStart {
+ this.isAppWindowVisible(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT)
+ }
+ }
+
+ /** Main activity should become invisible after being covered by always expand activity. */
+ @Presubmit
+ @Test
+ fun mainActivityLayerBecomesInvisible() {
+ flicker.assertLayers {
+ isVisible(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT)
+ .then()
+ .isInvisible(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT)
+ }
+ }
+
+ /** Secondary activity should become invisible after being covered by always expand activity. */
+ @Presubmit
+ @Test
+ fun secondaryActivityLayerBecomesInvisible() {
+ flicker.assertLayers {
+ isVisible(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT)
+ .then()
+ .isInvisible(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT)
+ }
+ }
+
+ /** At the end of transition always expand activity is in fullscreen. */
+ @Presubmit
+ @Test
+ fun endsWithAlwaysExpandActivityCoveringFullScreen() {
+ flicker.assertWmEnd {
+ this.visibleRegion(ActivityEmbeddingAppHelper.ALWAYS_EXPAND_ACTIVITY_COMPONENT)
+ .coversExactly(startDisplayBounds)
+ }
+ }
+
+ /** Always expand activity is on top of the split. */
+ @FlakyTest(bugId = 286952194)
+ @Presubmit
+ @Test
+ fun endsWithAlwaysExpandActivityOnTop() {
+ flicker.assertWmEnd {
+ this.isAppWindowOnTop(ActivityEmbeddingAppHelper.ALWAYS_EXPAND_ACTIVITY_COMPONENT)
+ }
+ }
+
+ companion object {
+ /** {@inheritDoc} */
+ private var startDisplayBounds = Rect.EMPTY
+ /**
+ * Creates the test configurations.
+ *
+ * See [LegacyFlickerTestFactory.nonRotationTests] for configuring screen orientation and
+ * navigation modes.
+ */
+ @Parameterized.Parameters(name = "{0}")
+ @JvmStatic
+ fun getParams() = LegacyFlickerTestFactory.nonRotationTests()
+ }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/open/OpenActivityEmbeddingPlaceholderSplitTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/open/OpenActivityEmbeddingPlaceholderSplitTest.kt
index ed17059..27a5bd0 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/open/OpenActivityEmbeddingPlaceholderSplitTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/open/OpenActivityEmbeddingPlaceholderSplitTest.kt
@@ -19,8 +19,8 @@
import android.platform.test.annotations.Presubmit
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import androidx.test.filters.RequiresDevice
import com.android.server.wm.flicker.helpers.ActivityEmbeddingAppHelper
import org.junit.FixMethodOrder
@@ -39,7 +39,7 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class OpenActivityEmbeddingPlaceholderSplitTest(flicker: FlickerTest) :
+class OpenActivityEmbeddingPlaceholderSplitTest(flicker: LegacyFlickerTest) :
ActivityEmbeddingTestBase(flicker) {
/** {@inheritDoc} */
@@ -117,13 +117,11 @@
/**
* Creates the test configurations.
*
- * See [FlickerTestFactory.nonRotationTests] for configuring screen orientation and
+ * See [LegacyFlickerTestFactory.nonRotationTests] for configuring screen orientation and
* navigation modes.
*/
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): Collection<FlickerTest> {
- return FlickerTestFactory.nonRotationTests()
- }
+ fun getParams() = LegacyFlickerTestFactory.nonRotationTests()
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/open/OpenActivityEmbeddingSecondaryToSplitTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/open/OpenActivityEmbeddingSecondaryToSplitTest.kt
index 8638288..16dbfce 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/open/OpenActivityEmbeddingSecondaryToSplitTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/open/OpenActivityEmbeddingSecondaryToSplitTest.kt
@@ -20,8 +20,8 @@
import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import androidx.test.filters.RequiresDevice
import com.android.server.wm.flicker.helpers.ActivityEmbeddingAppHelper
import org.junit.FixMethodOrder
@@ -39,7 +39,7 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class OpenActivityEmbeddingSecondaryToSplitTest(flicker: FlickerTest) :
+class OpenActivityEmbeddingSecondaryToSplitTest(flicker: LegacyFlickerTest) :
ActivityEmbeddingTestBase(flicker) {
/** {@inheritDoc} */
@@ -110,13 +110,11 @@
/**
* Creates the test configurations.
*
- * See [FlickerTestFactory.nonRotationTests] for configuring screen orientation and
+ * See [LegacyFlickerTestFactory.nonRotationTests] for configuring screen orientation and
* navigation modes.
*/
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): Collection<FlickerTest> {
- return FlickerTestFactory.nonRotationTests()
- }
+ fun getParams() = LegacyFlickerTestFactory.nonRotationTests()
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/rotation/RotateSplitNoChangeTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/rotation/RotateSplitNoChangeTest.kt
index 39ae8e2..856c9e2 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/rotation/RotateSplitNoChangeTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/rotation/RotateSplitNoChangeTest.kt
@@ -18,13 +18,13 @@
import android.platform.test.annotations.Presubmit
import android.tools.common.traces.component.ComponentNameMatcher
-import com.android.server.wm.flicker.rotation.RotationTransition
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import androidx.test.filters.RequiresDevice
import com.android.server.wm.flicker.helpers.ActivityEmbeddingAppHelper
+import com.android.server.wm.flicker.rotation.RotationTransition
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
@@ -34,8 +34,8 @@
/**
* Tests rotating two activities in an Activity Embedding split.
*
- * Setup: Launch A|B in split with B being the secondary activity.
- * Transitions: Rotate display, and expect A and B to split evenly in new rotation.
+ * Setup: Launch A|B in split with B being the secondary activity. Transitions: Rotate display, and
+ * expect A and B to split evenly in new rotation.
*
* To run this test: `atest FlickerTests:RotateSplitNoChangeTest`
*/
@@ -43,100 +43,104 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class RotateSplitNoChangeTest(flicker: FlickerTest) : RotationTransition(flicker) {
+open class RotateSplitNoChangeTest(flicker: LegacyFlickerTest) : RotationTransition(flicker) {
- override val testApp = ActivityEmbeddingAppHelper(instrumentation)
- override val transition: FlickerBuilder.() -> Unit
- get() = {
- super.transition(this)
- setup {
- testApp.launchViaIntent(wmHelper)
- testApp.launchSecondaryActivity(wmHelper)
- }
- }
+ override val testApp = ActivityEmbeddingAppHelper(instrumentation)
+ override val transition: FlickerBuilder.() -> Unit
+ get() = {
+ super.transition(this)
+ setup {
+ testApp.launchViaIntent(wmHelper)
+ testApp.launchSecondaryActivity(wmHelper)
+ }
+ }
- /**
- * Checks that the [ComponentNameMatcher.ROTATION] layer appears during the transition, doesn't
- * flicker, and disappears before the transition is complete
- */
- @Presubmit
- @Test
- fun rotationLayerAppearsAndVanishes() {
- flicker.assertLayers {
- this.isVisible(testApp)
- .then()
- .isVisible(ComponentNameMatcher.ROTATION)
- .then()
- .isVisible(testApp)
- .isInvisible(ComponentNameMatcher.ROTATION)
- }
- }
-
- /**
- * Overrides inherited assertion because in AE Split, the main and secondary activity are separate
- * layers, each covering up exactly half of the display.
- */
- @Presubmit
- @Test
- override fun appLayerRotates_StartingPos() {
- flicker.assertLayersStart {
- this.entry.displays.map { display ->
- val leftLayerRegion = this.visibleRegion(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT)
- val rightLayerRegion =
- this.visibleRegion(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT)
- // Compare dimensions of two splits, given we're using default split attributes,
- // both activities take up the same visible size on the display.
- check{"height"}.that(leftLayerRegion.region.height).isEqual(rightLayerRegion.region.height)
- check{"width"}.that(leftLayerRegion.region.width).isEqual(rightLayerRegion.region.width)
- leftLayerRegion.notOverlaps(rightLayerRegion.region)
- // Layers of two activities sum to be fullscreen size on display.
- leftLayerRegion.plus(rightLayerRegion.region).coversExactly(display.layerStackSpace)
- }
- }
- }
-
- /**
- * Verifies dimensions of both split activities hold their invariance after transition too.
- */
- @Presubmit
- @Test
- override fun appLayerRotates_EndingPos() {
- flicker.assertLayersEnd {
- this.entry.displays.map { display ->
- val leftLayerRegion = this.visibleRegion(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT)
- val rightLayerRegion =
- this.visibleRegion(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT)
- check{"height"}.that(leftLayerRegion.region.height).isEqual(rightLayerRegion.region.height)
- check{"width"}.that(leftLayerRegion.region.width).isEqual(rightLayerRegion.region.width)
- leftLayerRegion.notOverlaps(rightLayerRegion.region)
- leftLayerRegion.plus(rightLayerRegion.region).coversExactly(display.layerStackSpace)
- }
- }
- }
-
- /** Both activities in split should remain visible during rotation. */
- @Presubmit
- @Test
- fun bothActivitiesAreAlwaysVisible() {
- flicker.assertWm {
- isAppWindowVisible(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT)
- }
- flicker.assertWm {
- isAppWindowVisible(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT)
- }
- }
-
- companion object {
/**
- * Creates the test configurations.
- *
- * See [FlickerTestFactory.nonRotationTests] for configuring screen orientation and
- * navigation modes.
+ * Checks that the [ComponentNameMatcher.ROTATION] layer appears during the transition, doesn't
+ * flicker, and disappears before the transition is complete
*/
- @Parameterized.Parameters(name = "{0}")
- @JvmStatic
- fun getParams(): Collection<FlickerTest> {
- return FlickerTestFactory.rotationTests()
+ @Presubmit
+ @Test
+ fun rotationLayerAppearsAndVanishes() {
+ flicker.assertLayers {
+ this.isVisible(testApp)
+ .then()
+ .isVisible(ComponentNameMatcher.ROTATION)
+ .then()
+ .isVisible(testApp)
+ .isInvisible(ComponentNameMatcher.ROTATION)
+ }
}
- }
-}
\ No newline at end of file
+
+ /**
+ * Overrides inherited assertion because in AE Split, the main and secondary activity are
+ * separate layers, each covering up exactly half of the display.
+ */
+ @Presubmit
+ @Test
+ override fun appLayerRotates_StartingPos() {
+ flicker.assertLayersStart {
+ this.entry.displays.map { display ->
+ val leftLayerRegion =
+ this.visibleRegion(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT)
+ val rightLayerRegion =
+ this.visibleRegion(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT)
+ // Compare dimensions of two splits, given we're using default split attributes,
+ // both activities take up the same visible size on the display.
+ check { "height" }
+ .that(leftLayerRegion.region.height)
+ .isEqual(rightLayerRegion.region.height)
+ check { "width" }
+ .that(leftLayerRegion.region.width)
+ .isEqual(rightLayerRegion.region.width)
+ leftLayerRegion.notOverlaps(rightLayerRegion.region)
+ // Layers of two activities sum to be fullscreen size on display.
+ leftLayerRegion.plus(rightLayerRegion.region).coversExactly(display.layerStackSpace)
+ }
+ }
+ }
+
+ /** Verifies dimensions of both split activities hold their invariance after transition too. */
+ @Presubmit
+ @Test
+ override fun appLayerRotates_EndingPos() {
+ flicker.assertLayersEnd {
+ this.entry.displays.map { display ->
+ val leftLayerRegion =
+ this.visibleRegion(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT)
+ val rightLayerRegion =
+ this.visibleRegion(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT)
+ check { "height" }
+ .that(leftLayerRegion.region.height)
+ .isEqual(rightLayerRegion.region.height)
+ check { "width" }
+ .that(leftLayerRegion.region.width)
+ .isEqual(rightLayerRegion.region.width)
+ leftLayerRegion.notOverlaps(rightLayerRegion.region)
+ leftLayerRegion.plus(rightLayerRegion.region).coversExactly(display.layerStackSpace)
+ }
+ }
+ }
+
+ /** Both activities in split should remain visible during rotation. */
+ @Presubmit
+ @Test
+ fun bothActivitiesAreAlwaysVisible() {
+ flicker.assertWm { isAppWindowVisible(ActivityEmbeddingAppHelper.MAIN_ACTIVITY_COMPONENT) }
+ flicker.assertWm {
+ isAppWindowVisible(ActivityEmbeddingAppHelper.SECONDARY_ACTIVITY_COMPONENT)
+ }
+ }
+
+ companion object {
+ /**
+ * Creates the test configurations.
+ *
+ * See [LegacyFlickerTestFactory.nonRotationTests] for configuring screen orientation and
+ * navigation modes.
+ */
+ @Parameterized.Parameters(name = "{0}")
+ @JvmStatic
+ fun getParams() = LegacyFlickerTestFactory.rotationTests()
+ }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppBackButtonTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppBackButtonTest.kt
index 10b71ff..865d5b4 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppBackButtonTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppBackButtonTest.kt
@@ -20,8 +20,8 @@
import android.tools.device.flicker.annotation.FlickerServiceCompatible
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import androidx.test.filters.RequiresDevice
import org.junit.FixMethodOrder
import org.junit.Test
@@ -76,7 +76,7 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class CloseAppBackButtonTest(flicker: FlickerTest) : CloseAppTransition(flicker) {
+open class CloseAppBackButtonTest(flicker: LegacyFlickerTest) : CloseAppTransition(flicker) {
/** {@inheritDoc} */
override val transition: FlickerBuilder.() -> Unit
get() = {
@@ -96,13 +96,11 @@
/**
* Creates the test configurations.
*
- * See [FlickerTestFactory.nonRotationTests] for configuring screen orientation and
+ * See [LegacyFlickerTestFactory.nonRotationTests] for configuring screen orientation and
* navigation modes.
*/
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): List<FlickerTest> {
- return FlickerTestFactory.nonRotationTests()
- }
+ fun getParams() = LegacyFlickerTestFactory.nonRotationTests()
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppBackButtonTestCfArm.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppBackButtonTestCfArm.kt
index 9fa84019..c108633 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppBackButtonTestCfArm.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppBackButtonTestCfArm.kt
@@ -18,8 +18,8 @@
import android.tools.device.flicker.annotation.FlickerServiceCompatible
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import org.junit.FixMethodOrder
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
@@ -29,18 +29,16 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class CloseAppBackButtonTestCfArm(flicker: FlickerTest) : CloseAppBackButtonTest(flicker) {
+class CloseAppBackButtonTestCfArm(flicker: LegacyFlickerTest) : CloseAppBackButtonTest(flicker) {
companion object {
/**
* Creates the test configurations.
*
- * See [FlickerTestFactory.nonRotationTests] for configuring screen orientation and
+ * See [LegacyFlickerTestFactory.nonRotationTests] for configuring screen orientation and
* navigation modes.
*/
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): List<FlickerTest> {
- return FlickerTestFactory.nonRotationTests()
- }
+ fun getParams() = LegacyFlickerTestFactory.nonRotationTests()
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppHomeButtonTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppHomeButtonTest.kt
index e5bd350..ea9710c6 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppHomeButtonTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppHomeButtonTest.kt
@@ -20,8 +20,8 @@
import android.tools.device.flicker.annotation.FlickerServiceCompatible
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import androidx.test.filters.RequiresDevice
import org.junit.FixMethodOrder
import org.junit.Test
@@ -76,7 +76,7 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class CloseAppHomeButtonTest(flicker: FlickerTest) : CloseAppTransition(flicker) {
+open class CloseAppHomeButtonTest(flicker: LegacyFlickerTest) : CloseAppTransition(flicker) {
/** {@inheritDoc} */
override val transition: FlickerBuilder.() -> Unit
get() = {
@@ -101,8 +101,6 @@
/** Creates the test configurations. */
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): Collection<FlickerTest> {
- return FlickerTestFactory.nonRotationTests()
- }
+ fun getParams() = LegacyFlickerTestFactory.nonRotationTests()
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppHomeButtonTestCfArm.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppHomeButtonTestCfArm.kt
index 136995a..d65555a 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppHomeButtonTestCfArm.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppHomeButtonTestCfArm.kt
@@ -18,8 +18,8 @@
import android.tools.device.flicker.annotation.FlickerServiceCompatible
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import org.junit.FixMethodOrder
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
@@ -29,13 +29,11 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class CloseAppHomeButtonTestCfArm(flicker: FlickerTest) : CloseAppHomeButtonTest(flicker) {
+class CloseAppHomeButtonTestCfArm(flicker: LegacyFlickerTest) : CloseAppHomeButtonTest(flicker) {
companion object {
/** Creates the test configurations. */
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): Collection<FlickerTest> {
- return FlickerTestFactory.nonRotationTests()
- }
+ fun getParams() = LegacyFlickerTestFactory.nonRotationTests()
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppTransition.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppTransition.kt
index 4570fa2..8737edb 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppTransition.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppTransition.kt
@@ -16,11 +16,14 @@
package com.android.server.wm.flicker.close
+import android.platform.test.annotations.FlakyTest
import android.platform.test.annotations.Presubmit
+import android.tools.common.flicker.subject.layers.LayersTraceSubject.Companion.VISIBLE_FOR_MORE_THAN_ONE_ENTRY_IGNORE_LAYERS
+import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.common.traces.component.ComponentNameMatcher.Companion.LAUNCHER
import android.tools.device.apphelpers.StandardAppHelper
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTest
import com.android.server.wm.flicker.BaseTest
import com.android.server.wm.flicker.helpers.SimpleAppHelper
import com.android.server.wm.flicker.helpers.setRotation
@@ -28,7 +31,7 @@
import org.junit.Test
/** Base test class for transitions that close an app back to the launcher screen */
-abstract class CloseAppTransition(flicker: FlickerTest) : BaseTest(flicker) {
+abstract class CloseAppTransition(flicker: LegacyFlickerTest) : BaseTest(flicker) {
protected open val testApp: StandardAppHelper = SimpleAppHelper(instrumentation)
/** {@inheritDoc} */
@@ -71,4 +74,21 @@
ignoreEntriesWithRotationLayer = flicker.scenario.isLandscapeOrSeascapeAtStart
)
}
+
+ /** {@inheritDoc} */
+ @Presubmit
+ @Test
+ override fun visibleLayersShownMoreThanOneConsecutiveEntry() {
+ flicker.assertLayers {
+ this.visibleLayersShownMoreThanOneConsecutiveEntry(
+ VISIBLE_FOR_MORE_THAN_ONE_ENTRY_IGNORE_LAYERS + listOf(ComponentNameMatcher.NAV_BAR)
+ )
+ }
+ }
+
+ @FlakyTest(bugId = 288369951)
+ @Test
+ fun visibleLayersShownMoreThanOneConsecutiveEntryWithNavBar() {
+ flicker.assertLayers { this.visibleLayersShownMoreThanOneConsecutiveEntry() }
+ }
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ActivityEmbeddingAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ActivityEmbeddingAppHelper.kt
index 793c68e..351eb1e 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ActivityEmbeddingAppHelper.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ActivityEmbeddingAppHelper.kt
@@ -75,7 +75,7 @@
.StateSyncBuilder()
.withActivityRemoved(SECONDARY_ACTIVITY_COMPONENT)
.waitForAndVerify()
- }
+ }
/**
* Clicks the button to launch a secondary activity with alwaysExpand enabled, which will launch
@@ -83,21 +83,19 @@
*/
fun launchAlwaysExpandActivity(wmHelper: WindowManagerStateHelper) {
val launchButton =
- uiDevice.wait(
- Until.findObject(
- By.res(getPackage(),
- "launch_always_expand_activity_button")),
- FIND_TIMEOUT
- )
+ uiDevice.wait(
+ Until.findObject(By.res(getPackage(), "launch_always_expand_activity_button")),
+ FIND_TIMEOUT
+ )
require(launchButton != null) {
"Can't find launch always expand activity button on screen."
}
launchButton.click()
wmHelper
- .StateSyncBuilder()
- .withActivityState(ALWAYS_EXPAND_ACTIVITY_COMPONENT, PlatformConsts.STATE_RESUMED)
- .withActivityState(MAIN_ACTIVITY_COMPONENT, PlatformConsts.STATE_PAUSED)
- .waitForAndVerify()
+ .StateSyncBuilder()
+ .withActivityState(ALWAYS_EXPAND_ACTIVITY_COMPONENT, PlatformConsts.STATE_RESUMED)
+ .withActivityState(MAIN_ACTIVITY_COMPONENT, PlatformConsts.STATE_PAUSED)
+ .waitForAndVerify()
}
/**
@@ -106,21 +104,19 @@
*/
fun launchSecondaryActivityRTL(wmHelper: WindowManagerStateHelper) {
val launchButton =
- uiDevice.wait(
- Until.findObject(
- By.res(getPackage(),
- "launch_secondary_activity_rtl_button")),
- FIND_TIMEOUT
- )
+ uiDevice.wait(
+ Until.findObject(By.res(getPackage(), "launch_secondary_activity_rtl_button")),
+ FIND_TIMEOUT
+ )
require(launchButton != null) {
"Can't find launch secondary activity rtl button on screen."
}
launchButton.click()
wmHelper
- .StateSyncBuilder()
- .withActivityState(SECONDARY_ACTIVITY_COMPONENT, PlatformConsts.STATE_RESUMED)
- .withActivityState(MAIN_ACTIVITY_COMPONENT, PlatformConsts.STATE_RESUMED)
- .waitForAndVerify()
+ .StateSyncBuilder()
+ .withActivityState(SECONDARY_ACTIVITY_COMPONENT, PlatformConsts.STATE_RESUMED)
+ .withActivityState(MAIN_ACTIVITY_COMPONENT, PlatformConsts.STATE_RESUMED)
+ .waitForAndVerify()
}
/**
@@ -148,21 +144,17 @@
*/
fun launchPlaceholderSplitRTL(wmHelper: WindowManagerStateHelper) {
val launchButton =
- uiDevice.wait(
- Until.findObject(
- By.res(getPackage(),
- "launch_placeholder_split_rtl_button")),
- FIND_TIMEOUT
- )
- require(launchButton != null) {
- "Can't find launch placeholder split button on screen."
- }
+ uiDevice.wait(
+ Until.findObject(By.res(getPackage(), "launch_placeholder_split_rtl_button")),
+ FIND_TIMEOUT
+ )
+ require(launchButton != null) { "Can't find launch placeholder split button on screen." }
launchButton.click()
wmHelper
- .StateSyncBuilder()
- .withActivityState(PLACEHOLDER_PRIMARY_COMPONENT, PlatformConsts.STATE_RESUMED)
- .withActivityState(PLACEHOLDER_SECONDARY_COMPONENT, PlatformConsts.STATE_RESUMED)
- .waitForAndVerify()
+ .StateSyncBuilder()
+ .withActivityState(PLACEHOLDER_PRIMARY_COMPONENT, PlatformConsts.STATE_RESUMED)
+ .withActivityState(PLACEHOLDER_SECONDARY_COMPONENT, PlatformConsts.STATE_RESUMED)
+ .waitForAndVerify()
}
companion object {
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/FlickerExtensions.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/FlickerExtensions.kt
index 9227e07..5c8cbe4 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/FlickerExtensions.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/FlickerExtensions.kt
@@ -19,7 +19,7 @@
package com.android.server.wm.flicker.helpers
import android.tools.common.Rotation
-import android.tools.device.flicker.legacy.IFlickerTestData
+import android.tools.device.flicker.legacy.FlickerTestData
import android.tools.device.flicker.rules.ChangeDisplayOrientationRule
/**
@@ -27,7 +27,7 @@
*
* @param rotation New device rotation
*/
-fun IFlickerTestData.setRotation(rotation: Rotation) =
+fun FlickerTestData.setRotation(rotation: Rotation) =
ChangeDisplayOrientationRule.setRotation(
rotation,
instrumentation,
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/LetterboxAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/LetterboxAppHelper.kt
index 34581bb..d83b6d3 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/LetterboxAppHelper.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/LetterboxAppHelper.kt
@@ -17,8 +17,8 @@
package com.android.server.wm.flicker.helpers
import android.app.Instrumentation
-import android.tools.common.datatypes.Region
import android.tools.common.datatypes.Rect
+import android.tools.common.datatypes.Region
import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.apphelpers.StandardAppHelper
import android.tools.device.helpers.FIND_TIMEOUT
@@ -81,15 +81,20 @@
displayBounds: Rect,
right: Boolean
) {
- wmHelper.StateSyncBuilder().add("letterboxAppRepositioned") {
- val letterboxAppWindow = getWindowRegion(wmHelper)
- val appRegionBounds = letterboxAppWindow.bounds
- val appWidth = appRegionBounds.width
- return@add if (right) appRegionBounds.left == displayBounds.right - appWidth &&
- appRegionBounds.right == displayBounds.right
- else appRegionBounds.left == displayBounds.left &&
- appRegionBounds.right == displayBounds.left + appWidth
- }.waitForAndVerify()
+ wmHelper
+ .StateSyncBuilder()
+ .add("letterboxAppRepositioned") {
+ val letterboxAppWindow = getWindowRegion(wmHelper)
+ val appRegionBounds = letterboxAppWindow.bounds
+ val appWidth = appRegionBounds.width
+ return@add if (right)
+ appRegionBounds.left == displayBounds.right - appWidth &&
+ appRegionBounds.right == displayBounds.right
+ else
+ appRegionBounds.left == displayBounds.left &&
+ appRegionBounds.right == displayBounds.left + appWidth
+ }
+ .waitForAndVerify()
}
fun waitForAppToMoveVerticallyTo(
@@ -98,15 +103,20 @@
navBarHeight: Int,
bottom: Boolean
) {
- wmHelper.StateSyncBuilder().add("letterboxAppRepositioned") {
- val letterboxAppWindow = getWindowRegion(wmHelper)
- val appRegionBounds = letterboxAppWindow.bounds
- val appHeight = appRegionBounds.height
- return@add if (bottom) appRegionBounds.bottom == displayBounds.bottom &&
- appRegionBounds.top == (displayBounds.bottom - appHeight + navBarHeight)
- else appRegionBounds.top == displayBounds.top &&
- appRegionBounds.bottom == displayBounds.top + appHeight
- }.waitForAndVerify()
+ wmHelper
+ .StateSyncBuilder()
+ .add("letterboxAppRepositioned") {
+ val letterboxAppWindow = getWindowRegion(wmHelper)
+ val appRegionBounds = letterboxAppWindow.bounds
+ val appHeight = appRegionBounds.height
+ return@add if (bottom)
+ appRegionBounds.bottom == displayBounds.bottom &&
+ appRegionBounds.top == (displayBounds.bottom - appHeight + navBarHeight)
+ else
+ appRegionBounds.top == displayBounds.top &&
+ appRegionBounds.bottom == displayBounds.top + appHeight
+ }
+ .waitForAndVerify()
}
private fun getWindowRegion(wmHelper: WindowManagerStateHelper): Region {
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeOnDismissPopupDialogTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeOnDismissPopupDialogTest.kt
index 7e0632d..98446c1 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeOnDismissPopupDialogTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeOnDismissPopupDialogTest.kt
@@ -22,8 +22,8 @@
import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import androidx.test.filters.RequiresDevice
import com.android.server.wm.flicker.BaseTest
import com.android.server.wm.flicker.helpers.ImeEditorPopupDialogAppHelper
@@ -37,7 +37,7 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class CloseImeOnDismissPopupDialogTest(flicker: FlickerTest) : BaseTest(flicker) {
+open class CloseImeOnDismissPopupDialogTest(flicker: LegacyFlickerTest) : BaseTest(flicker) {
private val imeTestApp = ImeEditorPopupDialogAppHelper(instrumentation)
/** {@inheritDoc} */
@@ -101,10 +101,9 @@
companion object {
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): Collection<FlickerTest> {
- return FlickerTestFactory.nonRotationTests(
+ fun getParams() =
+ LegacyFlickerTestFactory.nonRotationTests(
supportedRotations = listOf(Rotation.ROTATION_0)
)
- }
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeOnDismissPopupDialogTestCfArm.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeOnDismissPopupDialogTestCfArm.kt
index c355e27..d87a1da 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeOnDismissPopupDialogTestCfArm.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeOnDismissPopupDialogTestCfArm.kt
@@ -18,8 +18,8 @@
import android.tools.common.Rotation
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import org.junit.FixMethodOrder
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
@@ -28,15 +28,14 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class CloseImeOnDismissPopupDialogTestCfArm(flicker: FlickerTest) :
+class CloseImeOnDismissPopupDialogTestCfArm(flicker: LegacyFlickerTest) :
CloseImeOnDismissPopupDialogTest(flicker) {
companion object {
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): Collection<FlickerTest> {
- return FlickerTestFactory.nonRotationTests(
+ fun getParams() =
+ LegacyFlickerTestFactory.nonRotationTests(
supportedRotations = listOf(Rotation.ROTATION_0)
)
- }
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeOnGoHomeTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeOnGoHomeTest.kt
index 537238b..b995d3df 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeOnGoHomeTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeOnGoHomeTest.kt
@@ -22,8 +22,8 @@
import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import androidx.test.filters.RequiresDevice
import com.android.server.wm.flicker.BaseTest
import com.android.server.wm.flicker.helpers.ImeAppHelper
@@ -41,7 +41,7 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class CloseImeOnGoHomeTest(flicker: FlickerTest) : BaseTest(flicker) {
+open class CloseImeOnGoHomeTest(flicker: LegacyFlickerTest) : BaseTest(flicker) {
private val testApp = ImeAppHelper(instrumentation)
/** {@inheritDoc} */
@@ -115,10 +115,9 @@
companion object {
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): Collection<FlickerTest> {
- return FlickerTestFactory.nonRotationTests(
+ fun getParams() =
+ LegacyFlickerTestFactory.nonRotationTests(
supportedRotations = listOf(Rotation.ROTATION_0)
)
- }
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeOnGoHomeTestCfArm.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeOnGoHomeTestCfArm.kt
index 0fe52df..3b5bfa9 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeOnGoHomeTestCfArm.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeOnGoHomeTestCfArm.kt
@@ -17,7 +17,7 @@
package com.android.server.wm.flicker.ime
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
-import android.tools.device.flicker.legacy.FlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTest
import org.junit.FixMethodOrder
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
@@ -26,4 +26,4 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class CloseImeOnGoHomeTestCfArm(flicker: FlickerTest) : CloseImeOnGoHomeTest(flicker)
+class CloseImeOnGoHomeTestCfArm(flicker: LegacyFlickerTest) : CloseImeOnGoHomeTest(flicker)
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeShownOnAppStartOnGoHomeTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeShownOnAppStartOnGoHomeTest.kt
index cbe03dc..765bb4c 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeShownOnAppStartOnGoHomeTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeShownOnAppStartOnGoHomeTest.kt
@@ -21,8 +21,8 @@
import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import androidx.test.filters.RequiresDevice
import com.android.server.wm.flicker.BaseTest
import com.android.server.wm.flicker.helpers.ImeShownOnAppStartHelper
@@ -49,7 +49,7 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class CloseImeShownOnAppStartOnGoHomeTest(flicker: FlickerTest) : BaseTest(flicker) {
+open class CloseImeShownOnAppStartOnGoHomeTest(flicker: LegacyFlickerTest) : BaseTest(flicker) {
private val testApp = ImeShownOnAppStartHelper(instrumentation, flicker.scenario.startRotation)
/** {@inheritDoc} */
@@ -94,11 +94,10 @@
companion object {
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): Collection<FlickerTest> {
- return FlickerTestFactory.nonRotationTests(
+ fun getParams() =
+ LegacyFlickerTestFactory.nonRotationTests(
// b/190352379 (IME doesn't show on app launch in 90 degrees)
supportedRotations = listOf(Rotation.ROTATION_0)
)
- }
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeShownOnAppStartOnGoHomeTestCfArm.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeShownOnAppStartOnGoHomeTestCfArm.kt
index 5aacb30..58411cc 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeShownOnAppStartOnGoHomeTestCfArm.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeShownOnAppStartOnGoHomeTestCfArm.kt
@@ -17,7 +17,7 @@
package com.android.server.wm.flicker.ime
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
-import android.tools.device.flicker.legacy.FlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTest
import org.junit.FixMethodOrder
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
@@ -26,5 +26,5 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class CloseImeShownOnAppStartOnGoHomeTestCfArm(flicker: FlickerTest) :
+open class CloseImeShownOnAppStartOnGoHomeTestCfArm(flicker: LegacyFlickerTest) :
CloseImeShownOnAppStartOnGoHomeTest(flicker)
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeShownOnAppStartToAppOnPressBackTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeShownOnAppStartToAppOnPressBackTest.kt
index 82c390b..c87217b 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeShownOnAppStartToAppOnPressBackTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeShownOnAppStartToAppOnPressBackTest.kt
@@ -21,8 +21,8 @@
import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import androidx.test.filters.RequiresDevice
import com.android.server.wm.flicker.BaseTest
import com.android.server.wm.flicker.helpers.ImeShownOnAppStartHelper
@@ -49,7 +49,8 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class CloseImeShownOnAppStartToAppOnPressBackTest(flicker: FlickerTest) : BaseTest(flicker) {
+open class CloseImeShownOnAppStartToAppOnPressBackTest(flicker: LegacyFlickerTest) :
+ BaseTest(flicker) {
private val testApp = ImeShownOnAppStartHelper(instrumentation, flicker.scenario.startRotation)
/** {@inheritDoc} */
@@ -88,11 +89,10 @@
companion object {
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): Collection<FlickerTest> {
- return FlickerTestFactory.nonRotationTests(
+ fun getParams() =
+ LegacyFlickerTestFactory.nonRotationTests(
// b/190352379 (IME doesn't show on app launch in 90 degrees)
supportedRotations = listOf(Rotation.ROTATION_0)
)
- }
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeShownOnAppStartToAppOnPressBackTestCfArm.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeShownOnAppStartToAppOnPressBackTestCfArm.kt
index eb81aed..41b06c0 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeShownOnAppStartToAppOnPressBackTestCfArm.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeShownOnAppStartToAppOnPressBackTestCfArm.kt
@@ -17,7 +17,7 @@
package com.android.server.wm.flicker.ime
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
-import android.tools.device.flicker.legacy.FlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTest
import org.junit.FixMethodOrder
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
@@ -26,5 +26,5 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class CloseImeShownOnAppStartToAppOnPressBackTestCfArm(flicker: FlickerTest) :
+class CloseImeShownOnAppStartToAppOnPressBackTestCfArm(flicker: LegacyFlickerTest) :
CloseImeShownOnAppStartToAppOnPressBackTest(flicker)
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeToAppOnPressBackTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeToAppOnPressBackTest.kt
index 8d80759..c74870b 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeToAppOnPressBackTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeToAppOnPressBackTest.kt
@@ -21,8 +21,8 @@
import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import androidx.test.filters.RequiresDevice
import com.android.server.wm.flicker.BaseTest
import com.android.server.wm.flicker.helpers.ImeAppHelper
@@ -42,7 +42,7 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class CloseImeToAppOnPressBackTest(flicker: FlickerTest) : BaseTest(flicker) {
+open class CloseImeToAppOnPressBackTest(flicker: LegacyFlickerTest) : BaseTest(flicker) {
private val testApp = ImeAppHelper(instrumentation)
/** {@inheritDoc} */
@@ -115,8 +115,6 @@
companion object {
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): Collection<FlickerTest> {
- return FlickerTestFactory.nonRotationTests()
- }
+ fun getParams() = LegacyFlickerTestFactory.nonRotationTests()
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeToAppOnPressBackTestCfArm.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeToAppOnPressBackTestCfArm.kt
index db1440b..104af22 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeToAppOnPressBackTestCfArm.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeToAppOnPressBackTestCfArm.kt
@@ -17,7 +17,7 @@
package com.android.server.wm.flicker.ime
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
-import android.tools.device.flicker.legacy.FlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTest
import org.junit.FixMethodOrder
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
@@ -26,5 +26,5 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class CloseImeToAppOnPressBackTestCfArm(flicker: FlickerTest) :
+class CloseImeToAppOnPressBackTestCfArm(flicker: LegacyFlickerTest) :
CloseImeToAppOnPressBackTest(flicker)
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeToHomeOnFinishActivityTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeToHomeOnFinishActivityTest.kt
index 1526295..21fd590 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeToHomeOnFinishActivityTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeToHomeOnFinishActivityTest.kt
@@ -22,8 +22,8 @@
import android.tools.common.Rotation
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import androidx.test.filters.RequiresDevice
import com.android.server.wm.flicker.BaseTest
import com.android.server.wm.flicker.helpers.ImeAppHelper
@@ -44,7 +44,7 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class CloseImeToHomeOnFinishActivityTest(flicker: FlickerTest) : BaseTest(flicker) {
+open class CloseImeToHomeOnFinishActivityTest(flicker: LegacyFlickerTest) : BaseTest(flicker) {
private val simpleApp = SimpleAppHelper(instrumentation)
private val testApp = ImeAppHelper(instrumentation)
@@ -90,10 +90,9 @@
companion object {
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): Collection<FlickerTest> {
- return FlickerTestFactory.nonRotationTests(
+ fun getParams() =
+ LegacyFlickerTestFactory.nonRotationTests(
supportedRotations = listOf(Rotation.ROTATION_0)
)
- }
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeToHomeOnFinishActivityTestCfArm.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeToHomeOnFinishActivityTestCfArm.kt
index 405ab6b..0e18385 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeToHomeOnFinishActivityTestCfArm.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeToHomeOnFinishActivityTestCfArm.kt
@@ -17,7 +17,7 @@
package com.android.server.wm.flicker.ime
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
-import android.tools.device.flicker.legacy.FlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTest
import org.junit.FixMethodOrder
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
@@ -26,5 +26,5 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class CloseImeToHomeOnFinishActivityTestCfArm(flicker: FlickerTest) :
+open class CloseImeToHomeOnFinishActivityTestCfArm(flicker: LegacyFlickerTest) :
CloseImeToHomeOnFinishActivityTest(flicker)
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CommonAssertions.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CommonAssertions.kt
index 8e33719..777231e 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CommonAssertions.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CommonAssertions.kt
@@ -19,21 +19,21 @@
package com.android.server.wm.flicker.ime
import android.tools.common.traces.component.ComponentNameMatcher
-import android.tools.device.flicker.legacy.FlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTest
-fun FlickerTest.imeLayerBecomesVisible() {
+fun LegacyFlickerTest.imeLayerBecomesVisible() {
assertLayers {
this.isInvisible(ComponentNameMatcher.IME).then().isVisible(ComponentNameMatcher.IME)
}
}
-fun FlickerTest.imeLayerBecomesInvisible() {
+fun LegacyFlickerTest.imeLayerBecomesInvisible() {
assertLayers {
this.isVisible(ComponentNameMatcher.IME).then().isInvisible(ComponentNameMatcher.IME)
}
}
-fun FlickerTest.imeWindowIsAlwaysVisible(rotatesScreen: Boolean = false) {
+fun LegacyFlickerTest.imeWindowIsAlwaysVisible(rotatesScreen: Boolean = false) {
if (rotatesScreen) {
assertWm {
this.isNonAppWindowVisible(ComponentNameMatcher.IME)
@@ -47,7 +47,7 @@
}
}
-fun FlickerTest.imeWindowBecomesVisible() {
+fun LegacyFlickerTest.imeWindowBecomesVisible() {
assertWm {
this.isNonAppWindowInvisible(ComponentNameMatcher.IME)
.then()
@@ -55,7 +55,7 @@
}
}
-fun FlickerTest.imeWindowBecomesInvisible() {
+fun LegacyFlickerTest.imeWindowBecomesInvisible() {
assertWm {
this.isNonAppWindowVisible(ComponentNameMatcher.IME)
.then()
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowToFixedPortraitAppTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowToFixedPortraitAppTest.kt
index 19bbf0c..976ac82 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowToFixedPortraitAppTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowToFixedPortraitAppTest.kt
@@ -22,8 +22,8 @@
import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import android.tools.device.helpers.WindowUtils
import androidx.test.filters.RequiresDevice
import com.android.server.wm.flicker.BaseTest
@@ -42,7 +42,7 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class OpenImeWindowToFixedPortraitAppTest(flicker: FlickerTest) : BaseTest(flicker) {
+class OpenImeWindowToFixedPortraitAppTest(flicker: LegacyFlickerTest) : BaseTest(flicker) {
private val testApp = ImeShownOnAppStartHelper(instrumentation, flicker.scenario.startRotation)
/** {@inheritDoc} */
@@ -99,19 +99,18 @@
/**
* Creates the test configurations.
*
- * See [FlickerTestFactory.nonRotationTests] for configuring screen orientation and
+ * See [LegacyFlickerTestFactory.nonRotationTests] for configuring screen orientation and
* navigation modes.
*/
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): Collection<FlickerTest> {
- return FlickerTestFactory.nonRotationTests(
+ fun getParams() =
+ LegacyFlickerTestFactory.nonRotationTests(
supportedRotations =
listOf(
Rotation.ROTATION_90,
),
supportedNavigationModes = listOf(NavBar.MODE_3BUTTON, NavBar.MODE_GESTURAL)
)
- }
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppCfArmTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppCfArmTest.kt
index 03f21f9..db80001 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppCfArmTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppCfArmTest.kt
@@ -17,7 +17,7 @@
package com.android.server.wm.flicker.ime
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
-import android.tools.device.flicker.legacy.FlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTest
import org.junit.FixMethodOrder
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
@@ -26,5 +26,5 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class ShowImeOnAppStartWhenLaunchingAppCfArmTest(flicker: FlickerTest) :
+class ShowImeOnAppStartWhenLaunchingAppCfArmTest(flicker: LegacyFlickerTest) :
ShowImeOnAppStartWhenLaunchingAppTest(flicker)
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppFromFixedOrientationTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppFromFixedOrientationTest.kt
index 496165a..44bd8c8 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppFromFixedOrientationTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppFromFixedOrientationTest.kt
@@ -16,17 +16,17 @@
package com.android.server.wm.flicker.ime
+import android.platform.test.annotations.Postsubmit
import android.platform.test.annotations.Presubmit
import android.tools.common.Rotation
-import android.platform.test.annotations.Postsubmit
import android.tools.common.Timestamp
-import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.common.flicker.subject.exceptions.ExceptionMessageBuilder
import android.tools.common.flicker.subject.exceptions.InvalidPropertyException
+import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import androidx.test.filters.RequiresDevice
import com.android.server.wm.flicker.BaseTest
import com.android.server.wm.flicker.helpers.ImeShownOnAppStartHelper
@@ -47,7 +47,7 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class ShowImeOnAppStartWhenLaunchingAppFromFixedOrientationTest(flicker: FlickerTest) :
+open class ShowImeOnAppStartWhenLaunchingAppFromFixedOrientationTest(flicker: LegacyFlickerTest) :
BaseTest(flicker) {
private val imeTestApp =
ImeShownOnAppStartHelper(instrumentation, flicker.scenario.startRotation)
@@ -93,33 +93,35 @@
layerTraceEntries.zipWithNext { prev, next ->
val prevSnapshotLayerVisible =
- ComponentNameMatcher.SNAPSHOT.layerMatchesAnyOf(prev.visibleLayers)
+ ComponentNameMatcher.SNAPSHOT.layerMatchesAnyOf(prev.visibleLayers)
val nextSnapshotLayerVisible =
- ComponentNameMatcher.SNAPSHOT.layerMatchesAnyOf(next.visibleLayers)
+ ComponentNameMatcher.SNAPSHOT.layerMatchesAnyOf(next.visibleLayers)
- if (imeSnapshotRemovedTimestamp == null &&
- (prevSnapshotLayerVisible && !nextSnapshotLayerVisible)) {
+ if (
+ imeSnapshotRemovedTimestamp == null &&
+ (prevSnapshotLayerVisible && !nextSnapshotLayerVisible)
+ ) {
imeSnapshotRemovedTimestamp = next.timestamp
}
}
// if so, make an assertion
imeSnapshotRemovedTimestamp?.let { timestamp ->
- val stateAfterSnapshot = layerTrace?.getEntryAt(timestamp)
- ?: error("State not found for $timestamp")
+ val stateAfterSnapshot =
+ layerTrace?.getEntryAt(timestamp) ?: error("State not found for $timestamp")
- val imeLayers = ComponentNameMatcher.IME
- .filterLayers(stateAfterSnapshot.visibleLayers.toList())
+ val imeLayers =
+ ComponentNameMatcher.IME.filterLayers(stateAfterSnapshot.visibleLayers.toList())
require(imeLayers.isNotEmpty()) { "IME layer not found" }
if (imeLayers.any { it.color.a != 1.0f }) {
- val errorMsgBuilder = ExceptionMessageBuilder()
+ val errorMsgBuilder =
+ ExceptionMessageBuilder()
.setTimestamp(timestamp)
.forInvalidProperty("IME layer alpha")
.setExpected("is 1.0")
.setActual("not 1.0")
- .addExtraDescription("Filter",
- ComponentNameMatcher.IME.toLayerIdentifier())
+ .addExtraDescription("Filter", ComponentNameMatcher.IME.toLayerIdentifier())
throw InvalidPropertyException(errorMsgBuilder)
}
}
@@ -129,15 +131,14 @@
/**
* Creates the test configurations.
*
- * See [FlickerTestFactory.nonRotationTests] for configuring screen orientation and
+ * See [LegacyFlickerTestFactory.nonRotationTests] for configuring screen orientation and
* navigation modes.
*/
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): Collection<FlickerTest> {
- return FlickerTestFactory.nonRotationTests(
+ fun getParams() =
+ LegacyFlickerTestFactory.nonRotationTests(
supportedRotations = listOf(Rotation.ROTATION_90)
)
- }
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppFromFixedOrientationTestCfArm.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppFromFixedOrientationTestCfArm.kt
index 3aca2a0..6d9ea22 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppFromFixedOrientationTestCfArm.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppFromFixedOrientationTestCfArm.kt
@@ -17,7 +17,7 @@
package com.android.server.wm.flicker.ime
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
-import android.tools.device.flicker.legacy.FlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTest
import org.junit.FixMethodOrder
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
@@ -26,5 +26,5 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class ShowImeOnAppStartWhenLaunchingAppFromFixedOrientationTestCfArm(flicker: FlickerTest) :
+class ShowImeOnAppStartWhenLaunchingAppFromFixedOrientationTestCfArm(flicker: LegacyFlickerTest) :
ShowImeOnAppStartWhenLaunchingAppFromFixedOrientationTest(flicker)
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppFromOverviewTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppFromOverviewTest.kt
index f64ad53..ae05e37 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppFromOverviewTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppFromOverviewTest.kt
@@ -21,8 +21,8 @@
import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import android.tools.device.helpers.reopenAppFromOverview
import androidx.test.filters.RequiresDevice
import com.android.server.wm.flicker.BaseTest
@@ -41,7 +41,7 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class ShowImeOnAppStartWhenLaunchingAppFromOverviewTest(flicker: FlickerTest) :
+open class ShowImeOnAppStartWhenLaunchingAppFromOverviewTest(flicker: LegacyFlickerTest) :
BaseTest(flicker) {
private val testApp = ImeShownOnAppStartHelper(instrumentation, flicker.scenario.startRotation)
@@ -140,10 +140,9 @@
companion object {
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): Collection<FlickerTest> {
- return FlickerTestFactory.nonRotationTests(
+ fun getParams() =
+ LegacyFlickerTestFactory.nonRotationTests(
supportedRotations = listOf(Rotation.ROTATION_0)
)
- }
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppFromOverviewTestCfArm.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppFromOverviewTestCfArm.kt
index e1aa418..92b3968 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppFromOverviewTestCfArm.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppFromOverviewTestCfArm.kt
@@ -18,8 +18,8 @@
import android.tools.common.Rotation
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import org.junit.FixMethodOrder
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
@@ -28,16 +28,15 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class ShowImeOnAppStartWhenLaunchingAppFromOverviewTestCfArm(flicker: FlickerTest) :
+class ShowImeOnAppStartWhenLaunchingAppFromOverviewTestCfArm(flicker: LegacyFlickerTest) :
ShowImeOnAppStartWhenLaunchingAppFromOverviewTest(flicker) {
companion object {
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): Collection<FlickerTest> {
- return FlickerTestFactory.nonRotationTests(
+ fun getParams() =
+ LegacyFlickerTestFactory.nonRotationTests(
supportedRotations = listOf(Rotation.ROTATION_0)
)
- }
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppFromQuickSwitchTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppFromQuickSwitchTest.kt
index 11bc7b9..c991651 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppFromQuickSwitchTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppFromQuickSwitchTest.kt
@@ -22,8 +22,8 @@
import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import androidx.test.filters.RequiresDevice
import com.android.server.wm.flicker.BaseTest
import com.android.server.wm.flicker.helpers.ImeShownOnAppStartHelper
@@ -44,7 +44,7 @@
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@Presubmit
-open class ShowImeOnAppStartWhenLaunchingAppFromQuickSwitchTest(flicker: FlickerTest) :
+open class ShowImeOnAppStartWhenLaunchingAppFromQuickSwitchTest(flicker: LegacyFlickerTest) :
BaseTest(flicker) {
private val testApp = SimpleAppHelper(instrumentation)
private val imeTestApp =
@@ -121,12 +121,11 @@
companion object {
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): Collection<FlickerTest> {
- return FlickerTestFactory.nonRotationTests(
+ fun getParams() =
+ LegacyFlickerTestFactory.nonRotationTests(
supportedNavigationModes = listOf(NavBar.MODE_GESTURAL),
supportedRotations = listOf(Rotation.ROTATION_0)
)
- }
private const val TAG_IME_VISIBLE = "imeVisible"
private const val TAG_IME_INVISIBLE = "imeInVisible"
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppFromQuickSwitchTestCfArm.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppFromQuickSwitchTestCfArm.kt
index 0f57467..09bfacc 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppFromQuickSwitchTestCfArm.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppFromQuickSwitchTestCfArm.kt
@@ -18,7 +18,7 @@
import android.platform.test.annotations.Presubmit
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
-import android.tools.device.flicker.legacy.FlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTest
import org.junit.FixMethodOrder
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
@@ -28,5 +28,5 @@
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@Presubmit
-open class ShowImeOnAppStartWhenLaunchingAppFromQuickSwitchTestCfArm(flicker: FlickerTest) :
+open class ShowImeOnAppStartWhenLaunchingAppFromQuickSwitchTestCfArm(flicker: LegacyFlickerTest) :
ShowImeOnAppStartWhenLaunchingAppFromQuickSwitchTest(flicker)
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppTest.kt
index 46967db..9763521 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppTest.kt
@@ -21,8 +21,8 @@
import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import androidx.test.filters.RequiresDevice
import com.android.server.wm.flicker.BaseTest
import com.android.server.wm.flicker.helpers.ImeShownOnAppStartHelper
@@ -79,7 +79,7 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class ShowImeOnAppStartWhenLaunchingAppTest(flicker: FlickerTest) : BaseTest(flicker) {
+open class ShowImeOnAppStartWhenLaunchingAppTest(flicker: LegacyFlickerTest) : BaseTest(flicker) {
private val testApp = ImeShownOnAppStartHelper(instrumentation, flicker.scenario.startRotation)
private val initializeApp = ImeStateInitializeHelper(instrumentation)
@@ -123,15 +123,14 @@
/**
* Creates the test configurations.
*
- * See [FlickerTestFactory.nonRotationTests] for configuring screen orientation and
+ * See [LegacyFlickerTestFactory.nonRotationTests] for configuring screen orientation and
* navigation modes.
*/
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): Collection<FlickerTest> {
- return FlickerTestFactory.nonRotationTests(
+ fun getParams() =
+ LegacyFlickerTestFactory.nonRotationTests(
supportedRotations = listOf(Rotation.ROTATION_0)
)
- }
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeWhenFocusingOnInputFieldTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeWhenFocusingOnInputFieldTest.kt
index 827110d..7bd5825 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeWhenFocusingOnInputFieldTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeWhenFocusingOnInputFieldTest.kt
@@ -21,8 +21,8 @@
import android.tools.common.Rotation
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import androidx.test.filters.RequiresDevice
import com.android.server.wm.flicker.BaseTest
import com.android.server.wm.flicker.helpers.ImeAppHelper
@@ -37,7 +37,7 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class ShowImeWhenFocusingOnInputFieldTest(flicker: FlickerTest) : BaseTest(flicker) {
+open class ShowImeWhenFocusingOnInputFieldTest(flicker: LegacyFlickerTest) : BaseTest(flicker) {
private val testApp = ImeAppHelper(instrumentation)
/** {@inheritDoc} */
@@ -79,10 +79,9 @@
companion object {
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): Collection<FlickerTest> {
- return FlickerTestFactory.nonRotationTests(
+ fun getParams() =
+ LegacyFlickerTestFactory.nonRotationTests(
supportedRotations = listOf(Rotation.ROTATION_0)
)
- }
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeWhenFocusingOnInputFieldTestCfArm.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeWhenFocusingOnInputFieldTestCfArm.kt
index f5b2294..f8c8149 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeWhenFocusingOnInputFieldTestCfArm.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeWhenFocusingOnInputFieldTestCfArm.kt
@@ -17,7 +17,7 @@
package com.android.server.wm.flicker.ime
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
-import android.tools.device.flicker.legacy.FlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTest
import org.junit.FixMethodOrder
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
@@ -26,5 +26,5 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class ShowImeWhenFocusingOnInputFieldTestCfArm(flicker: FlickerTest) :
+class ShowImeWhenFocusingOnInputFieldTestCfArm(flicker: LegacyFlickerTest) :
ShowImeWhenFocusingOnInputFieldTest(flicker)
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeWhileDismissingThemedPopupDialogTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeWhileDismissingThemedPopupDialogTest.kt
index 277b9155..0b168ba 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeWhileDismissingThemedPopupDialogTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeWhileDismissingThemedPopupDialogTest.kt
@@ -21,8 +21,8 @@
import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import android.view.WindowInsets.Type.ime
import android.view.WindowInsets.Type.navigationBars
import android.view.WindowInsets.Type.statusBars
@@ -45,7 +45,8 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class ShowImeWhileDismissingThemedPopupDialogTest(flicker: FlickerTest) : BaseTest(flicker) {
+open class ShowImeWhileDismissingThemedPopupDialogTest(flicker: LegacyFlickerTest) :
+ BaseTest(flicker) {
private val testApp = ImeShownOnAppStartHelper(instrumentation, flicker.scenario.startRotation)
/** {@inheritDoc} */
@@ -84,15 +85,14 @@
/**
* Creates the test configurations.
*
- * See [FlickerTestFactory.nonRotationTests] for configuring screen orientation and
+ * See [LegacyFlickerTestFactory.nonRotationTests] for configuring screen orientation and
* navigation modes.
*/
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): Collection<FlickerTest> {
- return FlickerTestFactory.nonRotationTests(
+ fun getParams() =
+ LegacyFlickerTestFactory.nonRotationTests(
supportedRotations = listOf(Rotation.ROTATION_0)
)
- }
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeWhileDismissingThemedPopupDialogTestCfArm.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeWhileDismissingThemedPopupDialogTestCfArm.kt
index 8891d26..ad41b81 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeWhileDismissingThemedPopupDialogTestCfArm.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeWhileDismissingThemedPopupDialogTestCfArm.kt
@@ -18,8 +18,8 @@
import android.tools.common.Rotation
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import org.junit.FixMethodOrder
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
@@ -28,21 +28,20 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class ShowImeWhileDismissingThemedPopupDialogTestCfArm(flicker: FlickerTest) :
+class ShowImeWhileDismissingThemedPopupDialogTestCfArm(flicker: LegacyFlickerTest) :
ShowImeWhileDismissingThemedPopupDialogTest(flicker) {
companion object {
/**
* Creates the test configurations.
*
- * See [FlickerTestFactory.nonRotationTests] for configuring screen orientation and
+ * See [LegacyFlickerTestFactory.nonRotationTests] for configuring screen orientation and
* navigation modes.
*/
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): Collection<FlickerTest> {
- return FlickerTestFactory.nonRotationTests(
+ fun getParams() =
+ LegacyFlickerTestFactory.nonRotationTests(
supportedRotations = listOf(Rotation.ROTATION_0)
)
- }
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeWhileEnteringOverviewTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeWhileEnteringOverviewTest.kt
index 9275d6a..7722c93 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeWhileEnteringOverviewTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeWhileEnteringOverviewTest.kt
@@ -21,8 +21,8 @@
import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import android.tools.device.traces.parsers.WindowManagerStateHelper
import androidx.test.filters.RequiresDevice
import com.android.server.wm.flicker.BaseTest
@@ -45,7 +45,7 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class ShowImeWhileEnteringOverviewTest(flicker: FlickerTest) : BaseTest(flicker) {
+open class ShowImeWhileEnteringOverviewTest(flicker: LegacyFlickerTest) : BaseTest(flicker) {
private val imeTestApp =
ImeShownOnAppStartHelper(instrumentation, flicker.scenario.startRotation)
@@ -205,13 +205,11 @@
/**
* Creates the test configurations.
*
- * See [FlickerTestFactory.nonRotationTests] for configuring screen orientation and
+ * See [LegacyFlickerTestFactory.nonRotationTests] for configuring screen orientation and
* navigation modes.
*/
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): Collection<FlickerTest> {
- return FlickerTestFactory.nonRotationTests()
- }
+ fun getParams() = LegacyFlickerTestFactory.nonRotationTests()
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeWhileEnteringOverviewTestCfArm.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeWhileEnteringOverviewTestCfArm.kt
index fc39713..90fbbf9 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeWhileEnteringOverviewTestCfArm.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ShowImeWhileEnteringOverviewTestCfArm.kt
@@ -17,7 +17,7 @@
package com.android.server.wm.flicker.ime
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
-import android.tools.device.flicker.legacy.FlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTest
import org.junit.FixMethodOrder
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
@@ -26,5 +26,5 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class ShowImeWhileEnteringOverviewTestCfArm(flicker: FlickerTest) :
+class ShowImeWhileEnteringOverviewTestCfArm(flicker: LegacyFlickerTest) :
ShowImeWhileEnteringOverviewTest(flicker)
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/ActivityTransitionTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/ActivityTransitionTest.kt
index a87fae8..3461907 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/ActivityTransitionTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/ActivityTransitionTest.kt
@@ -20,8 +20,8 @@
import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import android.tools.device.traces.parsers.toFlickerComponent
import androidx.test.filters.RequiresDevice
import com.android.server.wm.flicker.BaseTest
@@ -57,7 +57,7 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class ActivityTransitionTest(flicker: FlickerTest) : BaseTest(flicker) {
+open class ActivityTransitionTest(flicker: LegacyFlickerTest) : BaseTest(flicker) {
private val testApp: TwoActivitiesAppHelper = TwoActivitiesAppHelper(instrumentation)
/** {@inheritDoc} */
@@ -119,13 +119,11 @@
/**
* Creates the test configurations.
*
- * See [FlickerTestFactory.nonRotationTests] for configuring screen orientation and
+ * See [LegacyFlickerTestFactory.nonRotationTests] for configuring screen orientation and
* navigation modes.
*/
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): Collection<FlickerTest> {
- return FlickerTestFactory.nonRotationTests()
- }
+ fun getParams() = LegacyFlickerTestFactory.nonRotationTests()
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/ActivityTransitionTestCfArm.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/ActivityTransitionTestCfArm.kt
index 85344a1..6bbf40e 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/ActivityTransitionTestCfArm.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/ActivityTransitionTestCfArm.kt
@@ -17,8 +17,8 @@
package com.android.server.wm.flicker.launch
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import org.junit.FixMethodOrder
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
@@ -27,18 +27,16 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class ActivityTransitionTestCfArm(flicker: FlickerTest) : ActivityTransitionTest(flicker) {
+class ActivityTransitionTestCfArm(flicker: LegacyFlickerTest) : ActivityTransitionTest(flicker) {
companion object {
/**
* Creates the test configurations.
*
- * See [FlickerTestFactory.nonRotationTests] for configuring screen orientation and
+ * See [LegacyFlickerTestFactory.nonRotationTests] for configuring screen orientation and
* navigation modes.
*/
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): Collection<FlickerTest> {
- return FlickerTestFactory.nonRotationTests()
- }
+ fun getParams() = LegacyFlickerTestFactory.nonRotationTests()
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromIconColdTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromIconColdTest.kt
index 5752065..ae1f78a 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromIconColdTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromIconColdTest.kt
@@ -20,8 +20,8 @@
import android.tools.common.Rotation
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import android.tools.device.flicker.rules.RemoveAllTasksButHomeRule
import androidx.test.filters.RequiresDevice
import org.junit.FixMethodOrder
@@ -55,7 +55,8 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class OpenAppFromIconColdTest(flicker: FlickerTest) : OpenAppFromLauncherTransition(flicker) {
+open class OpenAppFromIconColdTest(flicker: LegacyFlickerTest) :
+ OpenAppFromLauncherTransition(flicker) {
/** {@inheritDoc} */
override val transition: FlickerBuilder.() -> Unit
get() = {
@@ -207,13 +208,11 @@
/**
* Creates the test configurations.
*
- * See [FlickerTestFactory.nonRotationTests] for configuring screen orientation and
+ * See [LegacyFlickerTestFactory.nonRotationTests] for configuring screen orientation and
* navigation modes.
*/
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): Collection<FlickerTest> {
- return FlickerTestFactory.nonRotationTests()
- }
+ fun getParams() = LegacyFlickerTestFactory.nonRotationTests()
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromIconColdTestCfArm.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromIconColdTestCfArm.kt
index d453c1a..2563bfb 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromIconColdTestCfArm.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromIconColdTestCfArm.kt
@@ -19,8 +19,8 @@
import android.platform.test.annotations.FlakyTest
import android.tools.device.flicker.annotation.FlickerServiceCompatible
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
@@ -32,7 +32,7 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class OpenAppFromIconColdTestCfArm(flicker: FlickerTest) : OpenAppFromIconColdTest(flicker) {
+class OpenAppFromIconColdTestCfArm(flicker: LegacyFlickerTest) : OpenAppFromIconColdTest(flicker) {
@Test
@FlakyTest
override fun visibleLayersShownMoreThanOneConsecutiveEntry() {
@@ -43,13 +43,11 @@
/**
* Creates the test configurations.
*
- * See [FlickerTestFactory.nonRotationTests] for configuring screen orientation and
+ * See [LegacyFlickerTestFactory.nonRotationTests] for configuring screen orientation and
* navigation modes.
*/
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): Collection<FlickerTest> {
- return FlickerTestFactory.nonRotationTests()
- }
+ fun getParams() = LegacyFlickerTestFactory.nonRotationTests()
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromIntentColdAfterCameraTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromIntentColdAfterCameraTest.kt
index e747315..c95c548 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromIntentColdAfterCameraTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromIntentColdAfterCameraTest.kt
@@ -19,8 +19,8 @@
import android.tools.device.apphelpers.CameraAppHelper
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import androidx.test.filters.RequiresDevice
import org.junit.FixMethodOrder
import org.junit.runner.RunWith
@@ -38,7 +38,7 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class OpenAppFromIntentColdAfterCameraTest(flicker: FlickerTest) :
+open class OpenAppFromIntentColdAfterCameraTest(flicker: LegacyFlickerTest) :
OpenAppFromLauncherTransition(flicker) {
private val cameraApp = CameraAppHelper(instrumentation)
/** {@inheritDoc} */
@@ -62,13 +62,11 @@
/**
* Creates the test configurations.
*
- * See [FlickerTestFactory.nonRotationTests] for configuring screen orientation and
+ * See [LegacyFlickerTestFactory.nonRotationTests] for configuring screen orientation and
* navigation modes.
*/
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): Collection<FlickerTest> {
- return FlickerTestFactory.nonRotationTests()
- }
+ fun getParams() = LegacyFlickerTestFactory.nonRotationTests()
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromIntentColdAfterCameraTestCfArm.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromIntentColdAfterCameraTestCfArm.kt
index 177ad7d..117cff2 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromIntentColdAfterCameraTestCfArm.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromIntentColdAfterCameraTestCfArm.kt
@@ -17,8 +17,8 @@
package com.android.server.wm.flicker.launch
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import org.junit.FixMethodOrder
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
@@ -27,19 +27,17 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class OpenAppFromIntentColdAfterCameraTestCfArm(flicker: FlickerTest) :
+class OpenAppFromIntentColdAfterCameraTestCfArm(flicker: LegacyFlickerTest) :
OpenAppFromIntentColdAfterCameraTest(flicker) {
companion object {
/**
* Creates the test configurations.
*
- * See [FlickerTestFactory.nonRotationTests] for configuring screen orientation and
+ * See [LegacyFlickerTestFactory.nonRotationTests] for configuring screen orientation and
* navigation modes.
*/
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): Collection<FlickerTest> {
- return FlickerTestFactory.nonRotationTests()
- }
+ fun getParams() = LegacyFlickerTestFactory.nonRotationTests()
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromIntentColdTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromIntentColdTest.kt
index f45f728..33302fa 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromIntentColdTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromIntentColdTest.kt
@@ -21,8 +21,8 @@
import android.tools.device.flicker.annotation.FlickerServiceCompatible
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import android.tools.device.flicker.rules.RemoveAllTasksButHomeRule.Companion.removeAllTasksButHome
import androidx.test.filters.RequiresDevice
import com.android.server.wm.flicker.helpers.setRotation
@@ -58,7 +58,7 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class OpenAppFromIntentColdTest(flicker: FlickerTest) :
+open class OpenAppFromIntentColdTest(flicker: LegacyFlickerTest) :
OpenAppFromLauncherTransition(flicker) {
/** {@inheritDoc} */
override val transition: FlickerBuilder.() -> Unit
@@ -83,13 +83,11 @@
/**
* Creates the test configurations.
*
- * See [FlickerTestFactory.nonRotationTests] for configuring screen orientation and
+ * See [LegacyFlickerTestFactory.nonRotationTests] for configuring screen orientation and
* navigation modes.
*/
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): Collection<FlickerTest> {
- return FlickerTestFactory.nonRotationTests()
- }
+ fun getParams() = LegacyFlickerTestFactory.nonRotationTests()
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromIntentColdTestCfArm.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromIntentColdTestCfArm.kt
index 0d695f3..45fb453 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromIntentColdTestCfArm.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromIntentColdTestCfArm.kt
@@ -19,8 +19,8 @@
import android.platform.test.annotations.FlakyTest
import android.tools.device.flicker.annotation.FlickerServiceCompatible
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
@@ -31,7 +31,8 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class OpenAppFromIntentColdTestCfArm(flicker: FlickerTest) : OpenAppFromIntentColdTest(flicker) {
+class OpenAppFromIntentColdTestCfArm(flicker: LegacyFlickerTest) :
+ OpenAppFromIntentColdTest(flicker) {
@FlakyTest(bugId = 273696733)
@Test
override fun appLayerReplacesLauncher() = super.appLayerReplacesLauncher()
@@ -40,13 +41,11 @@
/**
* Creates the test configurations.
*
- * See [FlickerTestFactory.nonRotationTests] for configuring screen orientation and
+ * See [LegacyFlickerTestFactory.nonRotationTests] for configuring screen orientation and
* navigation modes.
*/
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): Collection<FlickerTest> {
- return FlickerTestFactory.nonRotationTests()
- }
+ fun getParams() = LegacyFlickerTestFactory.nonRotationTests()
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromIntentWarmTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromIntentWarmTest.kt
index a42bff5..12ee7d0 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromIntentWarmTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromIntentWarmTest.kt
@@ -21,8 +21,8 @@
import android.tools.device.flicker.annotation.FlickerServiceCompatible
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import androidx.test.filters.RequiresDevice
import com.android.server.wm.flicker.helpers.setRotation
import org.junit.FixMethodOrder
@@ -58,7 +58,7 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class OpenAppFromIntentWarmTest(flicker: FlickerTest) :
+open class OpenAppFromIntentWarmTest(flicker: LegacyFlickerTest) :
OpenAppFromLauncherTransition(flicker) {
/** Defines the transition used to run the test */
override val transition: FlickerBuilder.() -> Unit
@@ -94,13 +94,11 @@
/**
* Creates the test configurations.
*
- * See [FlickerTestFactory.nonRotationTests] for configuring screen orientation and
+ * See [LegacyFlickerTestFactory.nonRotationTests] for configuring screen orientation and
* navigation modes.
*/
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): Collection<FlickerTest> {
- return FlickerTestFactory.nonRotationTests()
- }
+ fun getParams() = LegacyFlickerTestFactory.nonRotationTests()
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromIntentWarmTestCfArm.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromIntentWarmTestCfArm.kt
index b6ffcb3..1371fd7 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromIntentWarmTestCfArm.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromIntentWarmTestCfArm.kt
@@ -18,8 +18,8 @@
import android.tools.device.flicker.annotation.FlickerServiceCompatible
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import org.junit.FixMethodOrder
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
@@ -29,18 +29,17 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class OpenAppFromIntentWarmTestCfArm(flicker: FlickerTest) : OpenAppFromIntentWarmTest(flicker) {
+class OpenAppFromIntentWarmTestCfArm(flicker: LegacyFlickerTest) :
+ OpenAppFromIntentWarmTest(flicker) {
companion object {
/**
* Creates the test configurations.
*
- * See [FlickerTestFactory.nonRotationTests] for configuring screen orientation and
+ * See [LegacyFlickerTestFactory.nonRotationTests] for configuring screen orientation and
* navigation modes.
*/
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): Collection<FlickerTest> {
- return FlickerTestFactory.nonRotationTests()
- }
+ fun getParams() = LegacyFlickerTestFactory.nonRotationTests()
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLauncherTransition.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLauncherTransition.kt
index 3d5a8e3..62fb570 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLauncherTransition.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLauncherTransition.kt
@@ -18,12 +18,13 @@
import android.platform.test.annotations.Presubmit
import android.tools.common.traces.component.ComponentNameMatcher
-import android.tools.device.flicker.legacy.FlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTest
import com.android.server.wm.flicker.replacesLayer
import org.junit.Test
/** Base class for app launch tests */
-abstract class OpenAppFromLauncherTransition(flicker: FlickerTest) : OpenAppTransition(flicker) {
+abstract class OpenAppFromLauncherTransition(flicker: LegacyFlickerTest) :
+ OpenAppTransition(flicker) {
/** Checks that the focus changes from the [ComponentNameMatcher.LAUNCHER] to [testApp] */
@Presubmit
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockscreenTransition.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockscreenTransition.kt
index 30c3ec2..687bc19 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockscreenTransition.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockscreenTransition.kt
@@ -20,7 +20,7 @@
import android.platform.test.annotations.Presubmit
import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTest
import com.android.server.wm.flicker.navBarLayerPositionAtEnd
import com.android.server.wm.flicker.statusBarLayerPositionAtEnd
import org.junit.Assume
@@ -28,7 +28,8 @@
import org.junit.Test
/** Base class for app launch tests from lock screen */
-abstract class OpenAppFromLockscreenTransition(flicker: FlickerTest) : OpenAppTransition(flicker) {
+abstract class OpenAppFromLockscreenTransition(flicker: LegacyFlickerTest) :
+ OpenAppTransition(flicker) {
/** Defines the transition used to run the test */
override val transition: FlickerBuilder.() -> Unit = {
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockscreenViaIntentTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockscreenViaIntentTest.kt
index 924d03f..46eb257 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockscreenViaIntentTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockscreenViaIntentTest.kt
@@ -23,8 +23,8 @@
import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.annotation.FlickerServiceCompatible
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import androidx.test.filters.RequiresDevice
import com.android.server.wm.flicker.helpers.NonResizeableAppHelper
import org.junit.Assume
@@ -63,7 +63,7 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class OpenAppFromLockscreenViaIntentTest(flicker: FlickerTest) :
+open class OpenAppFromLockscreenViaIntentTest(flicker: LegacyFlickerTest) :
OpenAppFromLockscreenTransition(flicker) {
override val testApp = NonResizeableAppHelper(instrumentation)
@@ -210,16 +210,15 @@
/**
* Creates the test configurations.
*
- * See [FlickerTestFactory.nonRotationTests] for configuring screen orientation and
+ * See [LegacyFlickerTestFactory.nonRotationTests] for configuring screen orientation and
* navigation modes.
*/
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): Collection<FlickerTest> {
- return FlickerTestFactory.nonRotationTests(
+ fun getParams() =
+ LegacyFlickerTestFactory.nonRotationTests(
supportedNavigationModes = listOf(NavBar.MODE_GESTURAL),
supportedRotations = listOf(Rotation.ROTATION_0)
)
- }
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTest.kt
index 8e1b059..1497e50 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTest.kt
@@ -22,8 +22,8 @@
import android.tools.device.flicker.annotation.FlickerServiceCompatible
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import androidx.test.filters.RequiresDevice
import com.android.server.wm.flicker.helpers.setRotation
import org.junit.FixMethodOrder
@@ -60,7 +60,8 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class OpenAppFromOverviewTest(flicker: FlickerTest) : OpenAppFromLauncherTransition(flicker) {
+open class OpenAppFromOverviewTest(flicker: LegacyFlickerTest) :
+ OpenAppFromLauncherTransition(flicker) {
/** Defines the transition used to run the test */
override val transition: FlickerBuilder.() -> Unit
@@ -106,13 +107,11 @@
/**
* Creates the test configurations.
*
- * See [FlickerTestFactory.nonRotationTests] for configuring screen orientation and
+ * See [LegacyFlickerTestFactory.nonRotationTests] for configuring screen orientation and
* navigation modes.
*/
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): Collection<FlickerTest> {
- return FlickerTestFactory.nonRotationTests()
- }
+ fun getParams() = LegacyFlickerTestFactory.nonRotationTests()
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTestCfArm.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTestCfArm.kt
index ff24190..9b6c136 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTestCfArm.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTestCfArm.kt
@@ -18,8 +18,8 @@
import android.tools.device.flicker.annotation.FlickerServiceCompatible
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import org.junit.FixMethodOrder
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
@@ -30,18 +30,17 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class OpenAppFromOverviewTestCfArm(flicker: FlickerTest) : OpenAppFromOverviewTest(flicker) {
+open class OpenAppFromOverviewTestCfArm(flicker: LegacyFlickerTest) :
+ OpenAppFromOverviewTest(flicker) {
companion object {
/**
* Creates the test configurations.
*
- * See [FlickerTestFactory.nonRotationTests] for configuring screen orientation and
+ * See [LegacyFlickerTestFactory.nonRotationTests] for configuring screen orientation and
* navigation modes.
*/
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): Collection<FlickerTest> {
- return FlickerTestFactory.nonRotationTests()
- }
+ fun getParams() = LegacyFlickerTestFactory.nonRotationTests()
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppTransition.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppTransition.kt
index 87a14c6..bb11be5 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppTransition.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppTransition.kt
@@ -20,7 +20,7 @@
import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.apphelpers.StandardAppHelper
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTest
import android.tools.device.helpers.wakeUpAndGoToHomeScreen
import com.android.server.wm.flicker.BaseTest
import com.android.server.wm.flicker.helpers.SimpleAppHelper
@@ -28,7 +28,7 @@
import org.junit.Test
/** Base class for app launch tests */
-abstract class OpenAppTransition(flicker: FlickerTest) : BaseTest(flicker) {
+abstract class OpenAppTransition(flicker: LegacyFlickerTest) : BaseTest(flicker) {
protected open val testApp: StandardAppHelper = SimpleAppHelper(instrumentation)
/** {@inheritDoc} */
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenCameraFromHomeOnDoubleClickPowerButtonTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenCameraFromHomeOnDoubleClickPowerButtonTest.kt
index 6ee8ae6..4a1bd7e 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenCameraFromHomeOnDoubleClickPowerButtonTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenCameraFromHomeOnDoubleClickPowerButtonTest.kt
@@ -22,8 +22,8 @@
import android.tools.device.apphelpers.StandardAppHelper
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import android.tools.device.flicker.rules.RemoveAllTasksButHomeRule
import android.view.KeyEvent
import androidx.test.filters.RequiresDevice
@@ -60,7 +60,7 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class OpenCameraFromHomeOnDoubleClickPowerButtonTest(flicker: FlickerTest) :
+class OpenCameraFromHomeOnDoubleClickPowerButtonTest(flicker: LegacyFlickerTest) :
OpenAppFromLauncherTransition(flicker) {
private val cameraApp = CameraAppHelper(instrumentation)
override val testApp: StandardAppHelper
@@ -155,13 +155,11 @@
/**
* Creates the test configurations.
*
- * See [FlickerTestFactory.nonRotationTests] for configuring screen orientation and
+ * See [LegacyFlickerTestFactory.nonRotationTests] for configuring screen orientation and
* navigation modes.
*/
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): Collection<FlickerTest> {
- return FlickerTestFactory.nonRotationTests()
- }
+ fun getParams() = LegacyFlickerTestFactory.nonRotationTests()
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OverrideTaskTransitionTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OverrideTaskTransitionTest.kt
index b48611e..98e3646 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OverrideTaskTransitionTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OverrideTaskTransitionTest.kt
@@ -25,8 +25,8 @@
import android.tools.device.flicker.junit.FlickerBuilderProvider
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import android.tools.device.flicker.rules.RemoveAllTasksButHomeRule
import android.tools.device.helpers.wakeUpAndGoToHomeScreen
import androidx.test.filters.RequiresDevice
@@ -54,7 +54,7 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class OverrideTaskTransitionTest(val flicker: FlickerTest) {
+class OverrideTaskTransitionTest(val flicker: LegacyFlickerTest) {
private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
private val testApp = SimpleAppHelper(instrumentation)
@@ -121,8 +121,6 @@
companion object {
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): Collection<FlickerTest> {
- return FlickerTestFactory.nonRotationTests()
- }
+ fun getParams() = LegacyFlickerTestFactory.nonRotationTests()
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/TaskTransitionTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/TaskTransitionTest.kt
index d0fd732..39c8ca0 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/TaskTransitionTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/TaskTransitionTest.kt
@@ -28,8 +28,8 @@
import android.tools.common.traces.component.IComponentMatcher
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import android.tools.device.helpers.WindowUtils
import android.tools.device.traces.parsers.toFlickerComponent
import androidx.test.filters.RequiresDevice
@@ -58,7 +58,7 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class TaskTransitionTest(flicker: FlickerTest) : BaseTest(flicker) {
+class TaskTransitionTest(flicker: LegacyFlickerTest) : BaseTest(flicker) {
private val launchNewTaskApp = NewTasksAppHelper(instrumentation)
private val simpleApp = SimpleAppHelper(instrumentation)
private val wallpaper by lazy { getWallpaperPackage(instrumentation) }
@@ -214,8 +214,6 @@
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): Collection<FlickerTest> {
- return FlickerTestFactory.nonRotationTests()
- }
+ fun getParams() = LegacyFlickerTestFactory.nonRotationTests()
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockscreenNotificationColdTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/notification/OpenAppFromLockscreenNotificationColdTest.kt
similarity index 89%
rename from tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockscreenNotificationColdTest.kt
rename to tests/FlickerTests/src/com/android/server/wm/flicker/notification/OpenAppFromLockscreenNotificationColdTest.kt
index fd42726..6f5daeb 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockscreenNotificationColdTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/notification/OpenAppFromLockscreenNotificationColdTest.kt
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 The Android Open Source Project
+ * Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,15 +14,15 @@
* limitations under the License.
*/
-package com.android.server.wm.flicker.launch
+package com.android.server.wm.flicker.notification
import android.platform.test.annotations.Postsubmit
import android.platform.test.rule.SettingOverrideRule
import android.provider.Settings
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import androidx.test.filters.RequiresDevice
import org.junit.ClassRule
import org.junit.FixMethodOrder
@@ -44,7 +44,7 @@
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@Postsubmit
-open class OpenAppFromLockscreenNotificationColdTest(flicker: FlickerTest) :
+open class OpenAppFromLockscreenNotificationColdTest(flicker: LegacyFlickerTest) :
OpenAppFromNotificationColdTest(flicker) {
override val openingNotificationsFromLockScreen = true
@@ -111,14 +111,12 @@
/**
* Creates the test configurations.
*
- * See [FlickerTestFactory.nonRotationTests] for configuring screen orientation and
+ * See [LegacyFlickerTestFactory.nonRotationTests] for configuring screen orientation and
* navigation modes.
*/
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): Collection<FlickerTest> {
- return FlickerTestFactory.nonRotationTests()
- }
+ fun getParams() = LegacyFlickerTestFactory.nonRotationTests()
/**
* Ensures that posted notifications will be visible on the lockscreen and not suppressed
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockscreenNotificationWarmTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/notification/OpenAppFromLockscreenNotificationWarmTest.kt
similarity index 91%
rename from tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockscreenNotificationWarmTest.kt
rename to tests/FlickerTests/src/com/android/server/wm/flicker/notification/OpenAppFromLockscreenNotificationWarmTest.kt
index fd051d5..483caa7 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockscreenNotificationWarmTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/notification/OpenAppFromLockscreenNotificationWarmTest.kt
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 The Android Open Source Project
+ * Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.server.wm.flicker.launch
+package com.android.server.wm.flicker.notification
import android.platform.test.annotations.FlakyTest
import android.platform.test.annotations.Presubmit
@@ -23,8 +23,8 @@
import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import androidx.test.filters.RequiresDevice
import com.android.server.wm.flicker.statusBarLayerPositionAtEnd
import org.junit.ClassRule
@@ -46,7 +46,7 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class OpenAppFromLockscreenNotificationWarmTest(flicker: FlickerTest) :
+class OpenAppFromLockscreenNotificationWarmTest(flicker: LegacyFlickerTest) :
OpenAppFromNotificationWarmTest(flicker) {
override val openingNotificationsFromLockScreen = true
@@ -143,14 +143,12 @@
/**
* Creates the test configurations.
*
- * See [FlickerTestFactory.nonRotationTests] for configuring screen orientation and
+ * See [LegacyFlickerTestFactory.nonRotationTests] for configuring screen orientation and
* navigation modes.
*/
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): Collection<FlickerTest> {
- return FlickerTestFactory.nonRotationTests()
- }
+ fun getParams() = LegacyFlickerTestFactory.nonRotationTests()
/**
* Ensures that posted notifications will be visible on the lockscreen and not suppressed
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockscreenNotificationWithOverlayAppTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/notification/OpenAppFromLockscreenNotificationWithOverlayAppTest.kt
similarity index 90%
rename from tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockscreenNotificationWithOverlayAppTest.kt
rename to tests/FlickerTests/src/com/android/server/wm/flicker/notification/OpenAppFromLockscreenNotificationWithOverlayAppTest.kt
index 37afa8d..c336399 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockscreenNotificationWithOverlayAppTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/notification/OpenAppFromLockscreenNotificationWithOverlayAppTest.kt
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 The Android Open Source Project
+ * Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.server.wm.flicker.launch
+package com.android.server.wm.flicker.notification
import android.platform.test.annotations.FlakyTest
import android.platform.test.annotations.Postsubmit
@@ -22,8 +22,8 @@
import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import android.tools.device.helpers.wakeUpAndGoToHomeScreen
import androidx.test.filters.RequiresDevice
import com.android.server.wm.flicker.helpers.ShowWhenLockedAppHelper
@@ -46,7 +46,7 @@
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@Postsubmit
-class OpenAppFromLockscreenNotificationWithOverlayAppTest(flicker: FlickerTest) :
+class OpenAppFromLockscreenNotificationWithOverlayAppTest(flicker: LegacyFlickerTest) :
OpenAppFromLockscreenNotificationColdTest(flicker) {
private val showWhenLockedApp = ShowWhenLockedAppHelper(instrumentation)
@@ -126,13 +126,11 @@
/**
* Creates the test configurations.
*
- * See [FlickerTestFactory.nonRotationTests] for configuring screen orientation and
+ * See [LegacyFlickerTestFactory.nonRotationTests] for configuring screen orientation and
* navigation modes.
*/
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): Collection<FlickerTest> {
- return FlickerTestFactory.nonRotationTests()
- }
+ fun getParams() = LegacyFlickerTestFactory.nonRotationTests()
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationColdTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/notification/OpenAppFromNotificationColdTest.kt
similarity index 88%
rename from tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationColdTest.kt
rename to tests/FlickerTests/src/com/android/server/wm/flicker/notification/OpenAppFromNotificationColdTest.kt
index d873ec5..50dec3b 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationColdTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/notification/OpenAppFromNotificationColdTest.kt
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 The Android Open Source Project
+ * Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,15 +14,15 @@
* limitations under the License.
*/
-package com.android.server.wm.flicker.launch
+package com.android.server.wm.flicker.notification
import android.platform.test.annotations.Postsubmit
import android.platform.test.annotations.Presubmit
import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import androidx.test.filters.RequiresDevice
import com.android.server.wm.flicker.statusBarLayerPositionAtEnd
import org.junit.FixMethodOrder
@@ -42,7 +42,7 @@
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@Postsubmit
-open class OpenAppFromNotificationColdTest(flicker: FlickerTest) :
+open class OpenAppFromNotificationColdTest(flicker: LegacyFlickerTest) :
OpenAppFromNotificationWarmTest(flicker) {
/** {@inheritDoc} */
override val transition: FlickerBuilder.() -> Unit
@@ -99,13 +99,11 @@
/**
* Creates the test configurations.
*
- * See [FlickerTestFactory.nonRotationTests] for configuring screen orientation and
+ * See [LegacyFlickerTestFactory.nonRotationTests] for configuring screen orientation and
* navigation modes.
*/
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): Collection<FlickerTest> {
- return FlickerTestFactory.nonRotationTests()
- }
+ fun getParams() = LegacyFlickerTestFactory.nonRotationTests()
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationColdTestCfArm.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/notification/OpenAppFromNotificationColdTestCfArm.kt
similarity index 74%
rename from tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationColdTestCfArm.kt
rename to tests/FlickerTests/src/com/android/server/wm/flicker/notification/OpenAppFromNotificationColdTestCfArm.kt
index fb2a48c..a147171 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationColdTestCfArm.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/notification/OpenAppFromNotificationColdTestCfArm.kt
@@ -14,12 +14,12 @@
* limitations under the License.
*/
-package com.android.server.wm.flicker.launch
+package com.android.server.wm.flicker.notification
import android.platform.test.annotations.Postsubmit
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import org.junit.FixMethodOrder
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
@@ -29,19 +29,17 @@
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@Postsubmit
-class OpenAppFromNotificationColdTestCfArm(flicker: FlickerTest) :
+class OpenAppFromNotificationColdTestCfArm(flicker: LegacyFlickerTest) :
OpenAppFromNotificationColdTest(flicker) {
companion object {
/**
* Creates the test configurations.
*
- * See [FlickerTestFactory.nonRotationTests] for configuring screen orientation and
+ * See [LegacyFlickerTestFactory.nonRotationTests] for configuring screen orientation and
* navigation modes.
*/
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): Collection<FlickerTest> {
- return FlickerTestFactory.nonRotationTests()
- }
+ fun getParams() = LegacyFlickerTestFactory.nonRotationTests()
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationWarmTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/notification/OpenAppFromNotificationWarmTest.kt
similarity index 92%
rename from tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationWarmTest.kt
rename to tests/FlickerTests/src/com/android/server/wm/flicker/notification/OpenAppFromNotificationWarmTest.kt
index 99668ec..19a070b 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationWarmTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/notification/OpenAppFromNotificationWarmTest.kt
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 The Android Open Source Project
+ * Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,15 +14,15 @@
* limitations under the License.
*/
-package com.android.server.wm.flicker.launch
+package com.android.server.wm.flicker.notification
import android.platform.test.annotations.Postsubmit
import android.platform.test.annotations.Presubmit
import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import android.tools.device.helpers.wakeUpAndGoToHomeScreen
import android.view.WindowInsets
import android.view.WindowManager
@@ -53,7 +53,8 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class OpenAppFromNotificationWarmTest(flicker: FlickerTest) : OpenAppTransition(flicker) {
+open class OpenAppFromNotificationWarmTest(flicker: LegacyFlickerTest) :
+ OpenAppTransition(flicker) {
override val testApp: NotificationAppHelper = NotificationAppHelper(instrumentation)
open val openingNotificationsFromLockScreen = false
@@ -193,13 +194,11 @@
/**
* Creates the test configurations.
*
- * See [FlickerTestFactory.nonRotationTests] for configuring screen orientation and
+ * See [LegacyFlickerTestFactory.nonRotationTests] for configuring screen orientation and
* navigation modes.
*/
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): Collection<FlickerTest> {
- return FlickerTestFactory.nonRotationTests()
- }
+ fun getParams() = LegacyFlickerTestFactory.nonRotationTests()
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationWarmTestCfArm.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/notification/OpenAppFromNotificationWarmTestCfArm.kt
similarity index 73%
rename from tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationWarmTestCfArm.kt
rename to tests/FlickerTests/src/com/android/server/wm/flicker/notification/OpenAppFromNotificationWarmTestCfArm.kt
index 2a2597e..98356d7 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationWarmTestCfArm.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/notification/OpenAppFromNotificationWarmTestCfArm.kt
@@ -14,11 +14,11 @@
* limitations under the License.
*/
-package com.android.server.wm.flicker.launch
+package com.android.server.wm.flicker.notification
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import org.junit.FixMethodOrder
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
@@ -27,19 +27,17 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class OpenAppFromNotificationWarmTestCfArm(flicker: FlickerTest) :
+class OpenAppFromNotificationWarmTestCfArm(flicker: LegacyFlickerTest) :
OpenAppFromNotificationWarmTest(flicker) {
companion object {
/**
* Creates the test configurations.
*
- * See [FlickerTestFactory.nonRotationTests] for configuring screen orientation and
+ * See [LegacyFlickerTestFactory.nonRotationTests] for configuring screen orientation and
* navigation modes.
*/
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): Collection<FlickerTest> {
- return FlickerTestFactory.nonRotationTests()
- }
+ fun getParams() = LegacyFlickerTestFactory.nonRotationTests()
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/notification/OpenAppTransition.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/notification/OpenAppTransition.kt
new file mode 100644
index 0000000..684b4b7
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/notification/OpenAppTransition.kt
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2021 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.notification
+
+import android.platform.test.annotations.Presubmit
+import android.tools.common.traces.component.ComponentNameMatcher
+import android.tools.device.apphelpers.StandardAppHelper
+import android.tools.device.flicker.legacy.FlickerBuilder
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.helpers.wakeUpAndGoToHomeScreen
+import com.android.server.wm.flicker.BaseTest
+import com.android.server.wm.flicker.helpers.SimpleAppHelper
+import com.android.server.wm.flicker.helpers.setRotation
+import org.junit.Test
+
+/** Base class for app launch tests */
+abstract class OpenAppTransition(flicker: LegacyFlickerTest) : BaseTest(flicker) {
+ protected open val testApp: StandardAppHelper = SimpleAppHelper(instrumentation)
+
+ /** {@inheritDoc} */
+ override val transition: FlickerBuilder.() -> Unit = {
+ setup {
+ tapl.setExpectedRotation(flicker.scenario.startRotation.value)
+ device.wakeUpAndGoToHomeScreen()
+ this.setRotation(flicker.scenario.startRotation)
+ }
+ teardown { testApp.exit(wmHelper) }
+ }
+
+ /**
+ * Checks that the [testApp] layer doesn't exist or is invisible at the start of the transition,
+ * but is created and/or becomes visible during the transition.
+ */
+ @Presubmit
+ @Test
+ open fun appLayerBecomesVisible() {
+ appLayerBecomesVisible_coldStart()
+ }
+
+ protected fun appLayerBecomesVisible_coldStart() {
+ flicker.assertLayers {
+ this.notContains(testApp)
+ .then()
+ .isInvisible(testApp, isOptional = true)
+ .then()
+ .isVisible(ComponentNameMatcher.SNAPSHOT, isOptional = true)
+ .then()
+ .isVisible(ComponentNameMatcher.SPLASH_SCREEN, isOptional = true)
+ .then()
+ .isVisible(testApp)
+ }
+ }
+
+ protected fun appLayerBecomesVisible_warmStart() {
+ flicker.assertLayers {
+ this.isInvisible(testApp)
+ .then()
+ .isVisible(ComponentNameMatcher.SNAPSHOT, isOptional = true)
+ .then()
+ .isVisible(ComponentNameMatcher.SPLASH_SCREEN, isOptional = true)
+ .then()
+ .isVisible(testApp)
+ }
+ }
+
+ /**
+ * Checks that the [testApp] window doesn't exist at the start of the transition, that it is
+ * created (invisible - optional) and becomes visible during the transition
+ *
+ * The `isAppWindowInvisible` step is optional because we log once per frame, upon logging, the
+ * window may be visible or not depending on what was processed until that moment.
+ */
+ @Presubmit @Test open fun appWindowBecomesVisible() = appWindowBecomesVisible_coldStart()
+
+ protected fun appWindowBecomesVisible_coldStart() {
+ flicker.assertWm {
+ this.notContains(testApp)
+ .then()
+ .isAppWindowInvisible(testApp, isOptional = true)
+ .then()
+ .isAppWindowVisible(testApp)
+ }
+ }
+
+ protected fun appWindowBecomesVisible_warmStart() {
+ flicker.assertWm {
+ this.isAppWindowInvisible(testApp)
+ .then()
+ .isAppWindowVisible(ComponentNameMatcher.SNAPSHOT, isOptional = true)
+ .then()
+ .isAppWindowVisible(ComponentNameMatcher.SPLASH_SCREEN, isOptional = true)
+ .then()
+ .isAppWindowVisible(testApp)
+ }
+ }
+
+ /**
+ * Checks that [testApp] window is not on top at the start of the transition, and then becomes
+ * the top visible window until the end of the transition.
+ */
+ @Presubmit
+ @Test
+ open fun appWindowBecomesTopWindow() {
+ flicker.assertWm {
+ this.isAppWindowNotOnTop(testApp)
+ .then()
+ .isAppWindowOnTop(
+ testApp.or(ComponentNameMatcher.SNAPSHOT).or(ComponentNameMatcher.SPLASH_SCREEN)
+ )
+ }
+ }
+
+ /**
+ * Checks that [testApp] window is not on top at the start of the transition, and then becomes
+ * the top visible window until the end of the transition.
+ */
+ @Presubmit
+ @Test
+ open fun appWindowIsTopWindowAtEnd() {
+ flicker.assertWmEnd { this.isAppWindowOnTop(testApp) }
+ }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsBackTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsBackTest.kt
index a8b80ad..7883910 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsBackTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsBackTest.kt
@@ -23,8 +23,8 @@
import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import androidx.test.filters.RequiresDevice
import com.android.server.wm.flicker.BaseTest
import com.android.server.wm.flicker.helpers.NonResizeableAppHelper
@@ -52,7 +52,7 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class QuickSwitchBetweenTwoAppsBackTest(flicker: FlickerTest) : BaseTest(flicker) {
+open class QuickSwitchBetweenTwoAppsBackTest(flicker: LegacyFlickerTest) : BaseTest(flicker) {
private val testApp1 = SimpleAppHelper(instrumentation)
private val testApp2 = NonResizeableAppHelper(instrumentation)
@@ -243,10 +243,9 @@
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): Collection<FlickerTest> {
- return FlickerTestFactory.nonRotationTests(
+ fun getParams() =
+ LegacyFlickerTestFactory.nonRotationTests(
supportedNavigationModes = listOf(NavBar.MODE_GESTURAL)
)
- }
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsBackTestCfArm.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsBackTestCfArm.kt
index f970a79..f68cd5c 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsBackTestCfArm.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsBackTestCfArm.kt
@@ -18,8 +18,8 @@
import android.tools.common.NavBar
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import org.junit.FixMethodOrder
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
@@ -28,15 +28,14 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class QuickSwitchBetweenTwoAppsBackTestCfArm(flicker: FlickerTest) :
+class QuickSwitchBetweenTwoAppsBackTestCfArm(flicker: LegacyFlickerTest) :
QuickSwitchBetweenTwoAppsBackTest(flicker) {
companion object {
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): Collection<FlickerTest> {
- return FlickerTestFactory.nonRotationTests(
+ fun getParams() =
+ LegacyFlickerTestFactory.nonRotationTests(
supportedNavigationModes = listOf(NavBar.MODE_GESTURAL)
)
- }
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTest.kt
index 96cd8ff..1c4c7cd 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTest.kt
@@ -23,8 +23,8 @@
import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import androidx.test.filters.RequiresDevice
import com.android.server.wm.flicker.BaseTest
import com.android.server.wm.flicker.helpers.NonResizeableAppHelper
@@ -53,7 +53,7 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class QuickSwitchBetweenTwoAppsForwardTest(flicker: FlickerTest) : BaseTest(flicker) {
+open class QuickSwitchBetweenTwoAppsForwardTest(flicker: LegacyFlickerTest) : BaseTest(flicker) {
private val testApp1 = SimpleAppHelper(instrumentation)
private val testApp2 = NonResizeableAppHelper(instrumentation)
@@ -261,10 +261,9 @@
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): Collection<FlickerTest> {
- return FlickerTestFactory.nonRotationTests(
+ fun getParams() =
+ LegacyFlickerTestFactory.nonRotationTests(
supportedNavigationModes = listOf(NavBar.MODE_GESTURAL)
)
- }
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTestCfArm.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTestCfArm.kt
index 9f48cda..3de58ac 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTestCfArm.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTestCfArm.kt
@@ -18,8 +18,8 @@
import android.tools.common.NavBar
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import org.junit.FixMethodOrder
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
@@ -28,15 +28,14 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class QuickSwitchBetweenTwoAppsForwardTestCfArm(flicker: FlickerTest) :
+class QuickSwitchBetweenTwoAppsForwardTestCfArm(flicker: LegacyFlickerTest) :
QuickSwitchBetweenTwoAppsForwardTest(flicker) {
companion object {
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): Collection<FlickerTest> {
- return FlickerTestFactory.nonRotationTests(
+ fun getParams() =
+ LegacyFlickerTestFactory.nonRotationTests(
supportedNavigationModes = listOf(NavBar.MODE_GESTURAL)
)
- }
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchFromLauncherTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchFromLauncherTest.kt
index 7e935f0..6417456 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchFromLauncherTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchFromLauncherTest.kt
@@ -24,8 +24,8 @@
import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import androidx.test.filters.RequiresDevice
import com.android.server.wm.flicker.BaseTest
import com.android.server.wm.flicker.helpers.SimpleAppHelper
@@ -52,7 +52,7 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class QuickSwitchFromLauncherTest(flicker: FlickerTest) : BaseTest(flicker) {
+open class QuickSwitchFromLauncherTest(flicker: LegacyFlickerTest) : BaseTest(flicker) {
private val testApp = SimpleAppHelper(instrumentation)
/** {@inheritDoc} */
@@ -272,12 +272,11 @@
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): Collection<FlickerTest> {
- return FlickerTestFactory.nonRotationTests(
+ fun getParams() =
+ LegacyFlickerTestFactory.nonRotationTests(
supportedNavigationModes = listOf(NavBar.MODE_GESTURAL),
// TODO: Test with 90 rotation
supportedRotations = listOf(Rotation.ROTATION_0)
)
- }
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchFromLauncherTestCfArm.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchFromLauncherTestCfArm.kt
index af671df..84fc754 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchFromLauncherTestCfArm.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchFromLauncherTestCfArm.kt
@@ -19,8 +19,8 @@
import android.tools.common.NavBar
import android.tools.common.Rotation
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import org.junit.FixMethodOrder
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
@@ -29,17 +29,16 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class QuickSwitchFromLauncherTestCfArm(flicker: FlickerTest) :
+open class QuickSwitchFromLauncherTestCfArm(flicker: LegacyFlickerTest) :
QuickSwitchFromLauncherTest(flicker) {
companion object {
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): Collection<FlickerTest> {
- return FlickerTestFactory.nonRotationTests(
+ fun getParams() =
+ LegacyFlickerTestFactory.nonRotationTests(
supportedNavigationModes = listOf(NavBar.MODE_GESTURAL),
// TODO: Test with 90 rotation
supportedRotations = listOf(Rotation.ROTATION_0)
)
- }
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt
index ef75c61..842ece3 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt
@@ -21,8 +21,8 @@
import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import androidx.test.filters.RequiresDevice
import com.android.server.wm.flicker.helpers.SimpleAppHelper
import org.junit.FixMethodOrder
@@ -34,7 +34,7 @@
/**
* Test opening an app and cycling through app rotations
*
- * Currently runs:
+ * Currently, runs:
* ```
* 0 -> 90 degrees
* 90 -> 0 degrees
@@ -85,7 +85,7 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class ChangeAppRotationTest(flicker: FlickerTest) : RotationTransition(flicker) {
+open class ChangeAppRotationTest(flicker: LegacyFlickerTest) : RotationTransition(flicker) {
override val testApp = SimpleAppHelper(instrumentation)
override val transition: FlickerBuilder.() -> Unit
get() = {
@@ -140,13 +140,11 @@
/**
* Creates the test configurations.
*
- * See [FlickerTestFactory.rotationTests] for configuring screen orientation and navigation
- * modes.
+ * See [LegacyFlickerTestFactory.rotationTests] for configuring screen orientation and
+ * navigation modes.
*/
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): Collection<FlickerTest> {
- return FlickerTestFactory.rotationTests()
- }
+ fun getParams() = LegacyFlickerTestFactory.rotationTests()
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTestCfArm.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTestCfArm.kt
index 0e6b20f..1ab5c5a 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTestCfArm.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTestCfArm.kt
@@ -17,8 +17,8 @@
package com.android.server.wm.flicker.rotation
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import org.junit.FixMethodOrder
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
@@ -27,18 +27,16 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class ChangeAppRotationTestCfArm(flicker: FlickerTest) : ChangeAppRotationTest(flicker) {
+class ChangeAppRotationTestCfArm(flicker: LegacyFlickerTest) : ChangeAppRotationTest(flicker) {
companion object {
/**
* Creates the test configurations.
*
- * See [FlickerTestFactory.rotationTests] for configuring screen orientation and navigation
- * modes.
+ * See [LegacyFlickerTestFactory.rotationTests] for configuring screen orientation and
+ * navigation modes.
*/
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): Collection<FlickerTest> {
- return FlickerTestFactory.rotationTests()
- }
+ fun getParams() = LegacyFlickerTestFactory.rotationTests()
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/RotationTransition.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/RotationTransition.kt
index fe9da33..b0ca4d2 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/RotationTransition.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/RotationTransition.kt
@@ -20,13 +20,13 @@
import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.apphelpers.StandardAppHelper
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTest
import com.android.server.wm.flicker.BaseTest
import com.android.server.wm.flicker.helpers.setRotation
import org.junit.Test
/** Base class for app rotation tests */
-abstract class RotationTransition(flicker: FlickerTest) : BaseTest(flicker) {
+abstract class RotationTransition(flicker: LegacyFlickerTest) : BaseTest(flicker) {
protected abstract val testApp: StandardAppHelper
/** {@inheritDoc} */
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt
index f654bdd4..b6ad3cc7 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt
@@ -19,11 +19,12 @@
import android.platform.test.annotations.PlatinumTest
import android.platform.test.annotations.Presubmit
import android.tools.common.ScenarioBuilder
+import android.tools.common.ScenarioImpl
import android.tools.common.traces.component.ComponentNameMatcher
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import android.view.WindowManager
import androidx.test.filters.RequiresDevice
import com.android.server.wm.flicker.helpers.SeamlessRotationAppHelper
@@ -91,7 +92,7 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class SeamlessAppRotationTest(flicker: FlickerTest) : RotationTransition(flicker) {
+open class SeamlessAppRotationTest(flicker: LegacyFlickerTest) : RotationTransition(flicker) {
override val testApp = SeamlessRotationAppHelper(instrumentation)
/** {@inheritDoc} */
@@ -236,43 +237,50 @@
}
companion object {
- private val FlickerTest.starveUiThread
+ private val LegacyFlickerTest.starveUiThread
get() =
- getConfigValue<Boolean>(ActivityOptions.SeamlessRotation.EXTRA_STARVE_UI_THREAD)
+ scenario.getConfigValue<Boolean>(
+ ActivityOptions.SeamlessRotation.EXTRA_STARVE_UI_THREAD
+ )
?: false
@JvmStatic
protected fun createConfig(
- sourceConfig: FlickerTest,
+ sourceConfig: LegacyFlickerTest,
starveUiThread: Boolean
- ): FlickerTest {
- val originalScenario = sourceConfig.initialize("createConfig")
+ ): LegacyFlickerTest {
+ val originalScenario = sourceConfig.initialize("createConfig") as ScenarioImpl
val nameExt = if (starveUiThread) "_BUSY_UI_THREAD" else ""
val newConfig =
ScenarioBuilder()
- .fromScenario(originalScenario)
+ .forClass(originalScenario.testClass)
+ .withStartRotation(originalScenario.startRotation)
+ .withEndRotation(originalScenario.endRotation)
+ .withNavBarMode(originalScenario.navBarMode)
+ .withExtraConfigs(originalScenario.extraConfig)
+ .withDescriptionOverride(originalScenario.description)
.withExtraConfig(
ActivityOptions.SeamlessRotation.EXTRA_STARVE_UI_THREAD,
starveUiThread
)
.withDescriptionOverride("${originalScenario.description}$nameExt")
- return FlickerTest(newConfig)
+ return LegacyFlickerTest(newConfig)
}
/**
* Creates the test configurations for seamless rotation based on the default rotation tests
- * from [FlickerTestFactory.rotationTests], but adding a flag (
+ * from [LegacyFlickerTestFactory.rotationTests], but adding a flag (
* [ActivityOptions.SeamlessRotation.EXTRA_STARVE_UI_THREAD]) to indicate if the app should
* starve the UI thread of not
*/
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): Collection<FlickerTest> {
- return FlickerTestFactory.rotationTests().flatMap { sourceConfig ->
- val defaultRun = createConfig(sourceConfig, starveUiThread = false)
- val busyUiRun = createConfig(sourceConfig, starveUiThread = true)
+ fun getParams() =
+ LegacyFlickerTestFactory.rotationTests().flatMap { sourceCfg ->
+ val legacyCfg = sourceCfg as LegacyFlickerTest
+ val defaultRun = createConfig(legacyCfg, starveUiThread = false)
+ val busyUiRun = createConfig(legacyCfg, starveUiThread = true)
listOf(defaultRun, busyUiRun)
}
- }
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTestCfArm.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTestCfArm.kt
index b236d87..592be05 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTestCfArm.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTestCfArm.kt
@@ -17,8 +17,8 @@
package com.android.server.wm.flicker.rotation
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
-import android.tools.device.flicker.legacy.FlickerTest
-import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import com.android.server.wm.flicker.testapp.ActivityOptions
import org.junit.FixMethodOrder
import org.junit.runner.RunWith
@@ -29,22 +29,23 @@
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-open class SeamlessAppRotationTestCfArm(flicker: FlickerTest) : SeamlessAppRotationTest(flicker) {
+open class SeamlessAppRotationTestCfArm(flicker: LegacyFlickerTest) :
+ SeamlessAppRotationTest(flicker) {
companion object {
/**
* Creates the test configurations for seamless rotation based on the default rotation tests
- * from [FlickerTestFactory.rotationTests], but adding a flag (
+ * from [LegacyFlickerTestFactory.rotationTests], but adding a flag (
* [ActivityOptions.SeamlessRotation.EXTRA_STARVE_UI_THREAD]) to indicate if the app should
* starve the UI thread of not
*/
@Parameterized.Parameters(name = "{0}")
@JvmStatic
- fun getParams(): Collection<FlickerTest> {
- return FlickerTestFactory.rotationTests().flatMap { sourceConfig ->
- val defaultRun = createConfig(sourceConfig, starveUiThread = false)
- val busyUiRun = createConfig(sourceConfig, starveUiThread = true)
+ fun getParams() =
+ LegacyFlickerTestFactory.rotationTests().flatMap { sourceCfg ->
+ val legacyCfg = sourceCfg as LegacyFlickerTest
+ val defaultRun = createConfig(legacyCfg, starveUiThread = false)
+ val busyUiRun = createConfig(legacyCfg, starveUiThread = true)
listOf(defaultRun, busyUiRun)
}
- }
}
}
diff --git a/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ActivityOptions.java b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ActivityOptions.java
index 0f5c003..5210618 100644
--- a/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ActivityOptions.java
+++ b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ActivityOptions.java
@@ -186,6 +186,8 @@
public static final String LABEL = "SplitScreenPrimaryActivity";
public static final ComponentName COMPONENT = new ComponentName(FLICKER_APP_PACKAGE,
FLICKER_APP_PACKAGE + ".SplitScreenActivity");
+
+ public static final String EXTRA_LAUNCH_ADJACENT = "launch_adjacent";
}
public static class Secondary {
diff --git a/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/SplitScreenActivity.java b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/SplitScreenActivity.java
index 70196ae..8a27252 100644
--- a/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/SplitScreenActivity.java
+++ b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/SplitScreenActivity.java
@@ -16,9 +16,14 @@
package com.android.server.wm.flicker.testapp;
+import static com.android.server.wm.flicker.testapp.ActivityOptions.SplitScreen.Primary.EXTRA_LAUNCH_ADJACENT;
+
import android.app.Activity;
+import android.content.Intent;
import android.os.Bundle;
+import androidx.annotation.Nullable;
+
public class SplitScreenActivity extends Activity {
@Override
@@ -26,4 +31,17 @@
super.onCreate(icicle);
setContentView(R.layout.activity_splitscreen);
}
+
+ @Override
+ protected void onPostCreate(@Nullable Bundle savedInstanceState) {
+ super.onPostCreate(savedInstanceState);
+ final boolean startSecondaryActivity = getIntent().hasExtra(EXTRA_LAUNCH_ADJACENT);
+ if (startSecondaryActivity) {
+ final Intent intent = new Intent(this, SplitScreenSecondaryActivity.class);
+ intent.addCategory(Intent.CATEGORY_LAUNCHER);
+ intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT | Intent.FLAG_ACTIVITY_NEW_TASK
+ | Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
+ startActivity(intent);
+ }
+ }
}
diff --git a/tests/HwAccelerationTest/AndroidManifest.xml b/tests/HwAccelerationTest/AndroidManifest.xml
index 80c7a21..db3a992 100644
--- a/tests/HwAccelerationTest/AndroidManifest.xml
+++ b/tests/HwAccelerationTest/AndroidManifest.xml
@@ -789,6 +789,15 @@
</intent-filter>
</activity>
+ <activity android:name="BackdropBlurActivity"
+ android:label="RenderEffect/BackdropBlur"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="com.android.test.hwui.TEST"/>
+ </intent-filter>
+ </activity>
+
<activity android:name="BlurActivity"
android:label="RenderEffect/Blur"
android:exported="true">
diff --git a/tests/HwAccelerationTest/res/drawable/robot_repeated.xml b/tests/HwAccelerationTest/res/drawable/robot_repeated.xml
new file mode 100644
index 0000000..bbb15b7
--- /dev/null
+++ b/tests/HwAccelerationTest/res/drawable/robot_repeated.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2022 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+ android:src="@drawable/robot"
+ android:tileMode="repeat" android:gravity="fill" />
\ No newline at end of file
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/BackdropBlurActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/BackdropBlurActivity.java
new file mode 100644
index 0000000..8086b29
--- /dev/null
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/BackdropBlurActivity.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.test.hwui;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.ColorMatrix;
+import android.graphics.ColorMatrixColorFilter;
+import android.graphics.Outline;
+import android.graphics.RenderEffect;
+import android.graphics.Shader;
+import android.os.Bundle;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewOutlineProvider;
+import android.view.animation.DecelerateInterpolator;
+import android.widget.FrameLayout;
+import android.widget.ScrollView;
+
+@SuppressWarnings({"UnusedDeclaration"})
+public class BackdropBlurActivity extends Activity {
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ final ScrollView scrollView = new ScrollView(this);
+ final FrameLayout innerFrame = new FrameLayout(this);
+ final View backgroundView = new View(this);
+ backgroundView.setBackgroundResource(R.drawable.robot_repeated);
+ innerFrame.addView(backgroundView, ViewGroup.LayoutParams.MATCH_PARENT, 10000);
+ scrollView.addView(innerFrame,
+ ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
+
+ final FrameLayout contentView = new FrameLayout(this);
+ contentView.addView(scrollView,
+ ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
+ contentView.addView(new BackdropBlurView(this), 300, 300);
+ setContentView(contentView);
+ }
+
+ private static class BackdropBlurView extends View {
+ private final float mBlurRadius = 60f;
+ private final float mSaturation = 1.8f;
+
+ private float mDownOffsetX;
+ private float mDownOffsetY;
+
+ BackdropBlurView(Context c) {
+ super(c);
+
+ // init RenderEffect.
+ final RenderEffect blurEffect = RenderEffect.createBlurEffect(
+ mBlurRadius, mBlurRadius,
+ null, Shader.TileMode.MIRROR // TileMode.MIRROR is better for blur.
+ );
+
+ final ColorMatrix colorMatrix = new ColorMatrix();
+ colorMatrix.setSaturation(mSaturation);
+ final RenderEffect effect = RenderEffect.createColorFilterEffect(
+ new ColorMatrixColorFilter(colorMatrix), blurEffect
+ );
+ setBackdropRenderEffect(effect);
+
+ // clip to a round outline.
+ setOutlineProvider(new ViewOutlineProvider() {
+ @Override
+ public void getOutline(View v, Outline outline) {
+ outline.setOval(0, 0, v.getWidth(), v.getHeight());
+ }
+ });
+ setClipToOutline(true);
+
+ animate().setInterpolator(new DecelerateInterpolator(2.0f));
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ super.onDraw(canvas);
+
+ canvas.drawColor(0x99F0F0F0);
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent event) {
+ switch (event.getActionMasked()) {
+ case MotionEvent.ACTION_DOWN:
+ mDownOffsetX = event.getRawX() - getTranslationX();
+ mDownOffsetY = event.getRawY() - getTranslationY();
+ animate().scaleX(1.5f).scaleY(1.5f).start();
+ break;
+ case MotionEvent.ACTION_UP:
+ case MotionEvent.ACTION_CANCEL:
+ animate().scaleX(1f).scaleY(1f).start();
+ break;
+ case MotionEvent.ACTION_MOVE:
+ setTranslationX(event.getRawX() - mDownOffsetX);
+ setTranslationY(event.getRawY() - mDownOffsetY);
+ break;
+ }
+ return true;
+ }
+ }
+}
diff --git a/tools/aapt2/format/binary/TableFlattener.cpp b/tools/aapt2/format/binary/TableFlattener.cpp
index a1953c6..f056110 100644
--- a/tools/aapt2/format/binary/TableFlattener.cpp
+++ b/tools/aapt2/format/binary/TableFlattener.cpp
@@ -144,10 +144,9 @@
// 2) the entries will be accessed on platforms U+, and
// 3) all entry keys can be encoded in 16 bits
bool UseCompactEntries(const ConfigDescription& config, std::vector<FlatEntry>* entries) const {
- return compact_entries_ &&
- (context_->GetMinSdkVersion() > SDK_TIRAMISU || config.sdkVersion > SDK_TIRAMISU) &&
- std::none_of(entries->cbegin(), entries->cend(),
- [](const auto& e) { return e.entry_key >= std::numeric_limits<uint16_t>::max(); });
+ return compact_entries_ && context_->GetMinSdkVersion() > SDK_TIRAMISU &&
+ std::none_of(entries->cbegin(), entries->cend(),
+ [](const auto& e) { return e.entry_key >= std::numeric_limits<uint16_t>::max(); });
}
std::unique_ptr<ResEntryWriter> GetResEntryWriter(bool dedup, bool compact, BigBuffer* buffer) {