Merge "Disallow enter PiP when starting a split task" into main
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
index e857175..c4ffa34 100644
--- a/PREUPLOAD.cfg
+++ b/PREUPLOAD.cfg
@@ -30,7 +30,7 @@
ktlint_hook = ${REPO_ROOT}/prebuilts/ktlint/ktlint.py --no-verify-format -f ${PREUPLOAD_FILES}
# This flag check hook runs only for "packages/SystemUI" subdirectory. If you want to include this check for other subdirectories, please modify flag_check.py.
-flag_hook = ${REPO_ROOT}/frameworks/base/packages/SystemUI/flag_check.py --msg=${PREUPLOAD_COMMIT_MESSAGE} --files=${PREUPLOAD_FILES} --project=${REPO_PATH}
+flag_hook = ${REPO_ROOT}/frameworks/base/packages/SystemUI/flag_check.py --msg=${PREUPLOAD_COMMIT_MESSAGE} --files=${PREUPLOAD_FILES} --project=${REPO_PROJECT}
[Tool Paths]
ktfmt = ${REPO_ROOT}/prebuilts/build-tools/common/framework/ktfmt.jar
diff --git a/core/api/current.txt b/core/api/current.txt
index c0bc6d9..a819b6e 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -9801,6 +9801,7 @@
method @NonNull public java.util.List<android.companion.AssociationInfo> getMyAssociations();
method @Deprecated public boolean hasNotificationAccess(android.content.ComponentName);
method @FlaggedApi("android.companion.perm_sync_user_consent") public boolean isPermissionTransferUserConsented(int);
+ method @FlaggedApi("android.companion.unpair_associated_device") @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean removeBond(int);
method public void requestNotificationAccess(android.content.ComponentName);
method @FlaggedApi("android.companion.association_tag") public void setAssociationTag(int, @NonNull String);
method @RequiresPermission(android.Manifest.permission.REQUEST_OBSERVE_COMPANION_DEVICE_PRESENCE) public void startObservingDevicePresence(@NonNull String) throws android.companion.DeviceNotAssociatedException;
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 76c1ed6..b384326 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -7500,7 +7500,7 @@
+ data.instrumentationName + ": " + e.toString(), e);
}
try {
- timestampApplicationOnCreateNs = SystemClock.elapsedRealtimeNanos();
+ timestampApplicationOnCreateNs = SystemClock.uptimeNanos();
mInstrumentation.callApplicationOnCreate(app);
} catch (Exception e) {
timestampApplicationOnCreateNs = 0;
diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
index 15b13dc..ffb920b 100644
--- a/core/java/android/app/IActivityManager.aidl
+++ b/core/java/android/app/IActivityManager.aidl
@@ -757,6 +757,15 @@
void addStartInfoTimestamp(int key, long timestampNs, int userId);
/**
+ * Reports view related timestamps to be added to the calling apps most
+ * recent {@link ApplicationStartInfo}.
+ *
+ * @param renderThreadDrawStartTimeNs Clock monotonic time in nanoseconds of RenderThread draw start
+ * @param framePresentedTimeNs Clock monotonic time in nanoseconds of frame presented
+ */
+ oneway void reportStartInfoViewTimestamps(long renderThreadDrawStartTimeNs, long framePresentedTimeNs);
+
+ /**
* Return a list of {@link ApplicationExitInfo} records.
*
* <p class="note"> Note: System stores these historical information in a ring buffer, older
diff --git a/core/java/android/companion/CompanionDeviceManager.java b/core/java/android/companion/CompanionDeviceManager.java
index 8fe5ae0..b4ad1c8 100644
--- a/core/java/android/companion/CompanionDeviceManager.java
+++ b/core/java/android/companion/CompanionDeviceManager.java
@@ -1149,6 +1149,32 @@
}
}
+ /**
+ * Remove bonding between this device and an associated companion device.
+ *
+ * <p>This is an asynchronous call, it will return immediately. Register for {@link
+ * BluetoothDevice#ACTION_BOND_STATE_CHANGED} intents to be notified when the bond removal
+ * process completes, and its result.
+ *
+ * @param associationId an already-associated companion device to remove bond from
+ * @return false on immediate error, true if bond removal process will begin
+ */
+ @FlaggedApi(Flags.FLAG_UNPAIR_ASSOCIATED_DEVICE)
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
+ public boolean removeBond(int associationId) {
+ if (mService == null) {
+ Log.w(TAG, "CompanionDeviceManager service is not available.");
+ return false;
+ }
+
+ try {
+ return mService.removeBond(associationId, mContext.getOpPackageName(),
+ mContext.getUserId());
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
// TODO(b/315163162) Add @Deprecated keyword after 24Q2 cut.
/**
* Register to receive callbacks whenever the associated device comes in and out of range.
diff --git a/core/java/android/companion/ICompanionDeviceManager.aidl b/core/java/android/companion/ICompanionDeviceManager.aidl
index 1b00f90e..de3ddec 100644
--- a/core/java/android/companion/ICompanionDeviceManager.aidl
+++ b/core/java/android/companion/ICompanionDeviceManager.aidl
@@ -141,4 +141,7 @@
byte[] getBackupPayload(int userId);
void applyRestoredPayload(in byte[] payload, int userId);
+
+ @EnforcePermission("BLUETOOTH_CONNECT")
+ boolean removeBond(int associationId, in String packageName, int userId);
}
diff --git a/core/java/android/companion/flags.aconfig b/core/java/android/companion/flags.aconfig
index 36d0e08..fd4ba83 100644
--- a/core/java/android/companion/flags.aconfig
+++ b/core/java/android/companion/flags.aconfig
@@ -46,4 +46,11 @@
namespace: "companion"
description: "Enable ongoing perm sync"
bug: "338469649"
+}
+
+flag {
+ name: "unpair_associated_device"
+ namespace: "companion"
+ description: "Unpair with an associated bluetooth device"
+ bug: "322237619"
}
\ No newline at end of file
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index bad73fc..4fcf6b6 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -7188,9 +7188,10 @@
* as the package remains in the foreground, or has any active manifest components (e.g. when
* another app is accessing a content provider in the package).
* <p>
- * If you want to revoke the permissions right away, you could call {@code System.exit()}, but
- * this could affect other apps that are accessing your app at the moment. For example, apps
- * accessing a content provider in your app will all crash.
+ * If you want to revoke the permissions right away, you could call {@code System.exit()} in
+ * {@code Handler.postDelayed} with a delay to allow completion of async IPC, But
+ * {@code System.exit()} could affect other apps that are accessing your app at the moment.
+ * For example, apps accessing a content provider in your app will all crash.
* <p>
* Note that the settings UI shows a permission group as granted as long as at least one
* permission in the group is granted. If you want the user to observe the revocation in the
diff --git a/core/java/android/content/pm/LauncherApps.java b/core/java/android/content/pm/LauncherApps.java
index 6168b68..93cc71b 100644
--- a/core/java/android/content/pm/LauncherApps.java
+++ b/core/java/android/content/pm/LauncherApps.java
@@ -695,13 +695,13 @@
* <p>If the caller is running on a managed profile, it'll return only the current profile.
* Otherwise it'll return the same list as {@link UserManager#getUserProfiles()} would.
*
- * <p>To get hidden profile {@link UserManager.USER_TYPE_PROFILE_PRIVATE},
+ * <p>To get hidden profile {@link UserManager#USER_TYPE_PROFILE_PRIVATE},
* caller should have either:</p>
* <ul>
- * <li>the privileged {@link android.Manifest.permission.ACCESS_HIDDEN_PROFILES_FULL}
+ * <li>the privileged {@code android.Manifest.permission#ACCESS_HIDDEN_PROFILES_FULL}
* permission</li>
- * <li>the normal {@link android.Manifest.permission.ACCESS_HIDDEN_PROFILES} permission and the
- * {@link android.app.role.RoleManager.ROLE_HOME} role. </li>
+ * <li>the normal {@link android.Manifest.permission#ACCESS_HIDDEN_PROFILES} permission and the
+ * {@link android.app.role.RoleManager#ROLE_HOME} role. </li>
* </ul>
*/
@SuppressLint("RequiresPermission")
@@ -764,13 +764,13 @@
* list.</li>
* </ul>
*
- * <p>If the user in question is a hidden profile {@link UserManager.USER_TYPE_PROFILE_PRIVATE},
+ * <p>If the user in question is a hidden profile {@link UserManager#USER_TYPE_PROFILE_PRIVATE},
* caller should have either:</p>
* <ul>
- * <li>the privileged {@link android.Manifest.permission.ACCESS_HIDDEN_PROFILES_FULL}
+ * <li>the privileged {@code android.Manifest.permission#ACCESS_HIDDEN_PROFILES_FULL}
* permission</li>
- * <li>the normal {@link android.Manifest.permission.ACCESS_HIDDEN_PROFILES} permission and the
- * {@link android.app.role.RoleManager.ROLE_HOME} role. </li>
+ * <li>the normal {@link android.Manifest.permission#ACCESS_HIDDEN_PROFILES} permission and the
+ * {@link android.app.role.RoleManager#ROLE_HOME} role. </li>
* </ul>
*
* @param packageName The specific package to query. If null, it checks all installed packages
@@ -820,13 +820,13 @@
* Returns information related to a user which is useful for displaying UI elements
* to distinguish it from other users (eg, badges).
*
- * <p>If the user in question is a hidden profile {@link UserManager.USER_TYPE_PROFILE_PRIVATE},
+ * <p>If the user in question is a hidden profile {@link UserManager#USER_TYPE_PROFILE_PRIVATE},
* caller should have either:</p>
* <ul>
- * <li>the privileged {@link android.Manifest.permission.ACCESS_HIDDEN_PROFILES_FULL}
+ * <li>the privileged {@code android.Manifest.permission#ACCESS_HIDDEN_PROFILES_FULL}
* permission</li>
- * <li>the normal {@link android.Manifest.permission.ACCESS_HIDDEN_PROFILES} permission and the
- * {@link android.app.role.RoleManager.ROLE_HOME} role. </li>
+ * <li>the normal {@link android.Manifest.permission#ACCESS_HIDDEN_PROFILES} permission and the
+ * {@link android.app.role.RoleManager#ROLE_HOME} role. </li>
* </ul>
*
* @param userHandle user handle of the user for which LauncherUserInfo is requested.
@@ -873,13 +873,13 @@
* </ul>
* </p>
*
- * <p>If the user in question is a hidden profile {@link UserManager.USER_TYPE_PROFILE_PRIVATE},
+ * <p>If the user in question is a hidden profile {@link UserManager#USER_TYPE_PROFILE_PRIVATE},
* caller should have either:</p>
* <ul>
- * <li>the privileged {@link android.Manifest.permission.ACCESS_HIDDEN_PROFILES_FULL}
+ * <li>the privileged {@code android.Manifest.permission#ACCESS_HIDDEN_PROFILES_FULL}
* permission</li>
- * <li>the normal {@link android.Manifest.permission.ACCESS_HIDDEN_PROFILES} permission and the
- * {@link android.app.role.RoleManager.ROLE_HOME} role. </li>
+ * <li>the normal {@link android.Manifest.permission#ACCESS_HIDDEN_PROFILES} permission and the
+ * {@link android.app.role.RoleManager#ROLE_HOME} role. </li>
* </ul>
*
* @param packageName the package for which intent sender to launch App Market Activity is
@@ -913,13 +913,13 @@
* <p>An empty list denotes that all system packages should be treated as pre-installed for that
* user at creation.
*
- * <p>If the user in question is a hidden profile {@link UserManager.USER_TYPE_PROFILE_PRIVATE},
+ * <p>If the user in question is a hidden profile {@link UserManager#USER_TYPE_PROFILE_PRIVATE},
* caller should have either:</p>
* <ul>
- * <li>the privileged {@link android.Manifest.permission.ACCESS_HIDDEN_PROFILES_FULL}
+ * <li>the privileged {@code android.Manifest.permission#ACCESS_HIDDEN_PROFILES_FULL}
* permission</li>
- * <li>the normal {@link android.Manifest.permission.ACCESS_HIDDEN_PROFILES} permission and the
- * {@link android.app.role.RoleManager.ROLE_HOME} role. </li>
+ * <li>the normal {@link android.Manifest.permission#ACCESS_HIDDEN_PROFILES} permission and the
+ * {@link android.app.role.RoleManager#ROLE_HOME} role. </li>
* </ul>
*
* @param userHandle the user for which installed system packages are required.
@@ -945,7 +945,7 @@
/**
* Returns {@link IntentSender} which can be used to start the Private Space Settings Activity.
*
- * <p> Caller should have {@link android.app.role.RoleManager.ROLE_HOME} and either of the
+ * <p> Caller should have {@link android.app.role.RoleManager#ROLE_HOME} and either of the
* permissions required.</p>
*
* @return {@link IntentSender} object which launches the Private Space Settings Activity, if
@@ -968,13 +968,13 @@
* Returns the activity info for a given intent and user handle, if it resolves. Otherwise it
* returns null.
*
- * <p>If the user in question is a hidden profile {@link UserManager.USER_TYPE_PROFILE_PRIVATE},
+ * <p>If the user in question is a hidden profile {@link UserManager#USER_TYPE_PROFILE_PRIVATE},
* caller should have either:</p>
* <ul>
- * <li>the privileged {@link android.Manifest.permission.ACCESS_HIDDEN_PROFILES_FULL}
+ * <li>the privileged {@code android.Manifest.permission#ACCESS_HIDDEN_PROFILES_FULL}
* permission</li>
- * <li>the normal {@link android.Manifest.permission.ACCESS_HIDDEN_PROFILES} permission and the
- * {@link android.app.role.RoleManager.ROLE_HOME} role. </li>
+ * <li>the normal {@link android.Manifest.permission#ACCESS_HIDDEN_PROFILES} permission and the
+ * {@link android.app.role.RoleManager#ROLE_HOME} role. </li>
* </ul>
*
* @param intent The intent to find a match for.
@@ -1033,13 +1033,13 @@
/**
* Starts a Main activity in the specified profile.
*
- * <p>If the user in question is a hidden profile {@link UserManager.USER_TYPE_PROFILE_PRIVATE},
+ * <p>If the user in question is a hidden profile {@link UserManager#USER_TYPE_PROFILE_PRIVATE},
* caller should have either:</p>
* <ul>
- * <li>the privileged {@link android.Manifest.permission.ACCESS_HIDDEN_PROFILES_FULL}
+ * <li>the privileged {@code android.Manifest.permission#ACCESS_HIDDEN_PROFILES_FULL}
* permission</li>
- * <li>the normal {@link android.Manifest.permission.ACCESS_HIDDEN_PROFILES} permission and the
- * {@link android.app.role.RoleManager.ROLE_HOME} role. </li>
+ * <li>the normal {@link android.Manifest.permission#ACCESS_HIDDEN_PROFILES} permission and the
+ * {@link android.app.role.RoleManager#ROLE_HOME} role. </li>
* </ul>
*
* @param component The ComponentName of the activity to launch
@@ -1087,13 +1087,13 @@
* Starts the settings activity to show the application details for a
* package in the specified profile.
*
- * <p>If the user in question is a hidden profile {@link UserManager.USER_TYPE_PROFILE_PRIVATE},
+ * <p>If the user in question is a hidden profile {@link UserManager#USER_TYPE_PROFILE_PRIVATE},
* caller should have either:</p>
* <ul>
- * <li>the privileged {@link android.Manifest.permission.ACCESS_HIDDEN_PROFILES_FULL}
+ * <li>the privileged {@code android.Manifest.permission#ACCESS_HIDDEN_PROFILES_FULL}
* permission</li>
- * <li>the normal {@link android.Manifest.permission.ACCESS_HIDDEN_PROFILES} permission and the
- * {@link android.app.role.RoleManager.ROLE_HOME} role. </li>
+ * <li>the normal {@link android.Manifest.permission#ACCESS_HIDDEN_PROFILES} permission and the
+ * {@link android.app.role.RoleManager#ROLE_HOME} role. </li>
* </ul>
*
* @param component The ComponentName of the package to launch settings for.
@@ -1215,13 +1215,13 @@
/**
* Checks if the package is installed and enabled for a profile.
*
- * <p>If the user in question is a hidden profile {@link UserManager.USER_TYPE_PROFILE_PRIVATE},
+ * <p>If the user in question is a hidden profile {@link UserManager#USER_TYPE_PROFILE_PRIVATE},
* caller should have either:</p>
* <ul>
- * <li>the privileged {@link android.Manifest.permission.ACCESS_HIDDEN_PROFILES_FULL}
+ * <li>the privileged {@code android.Manifest.permission#ACCESS_HIDDEN_PROFILES_FULL}
* permission</li>
- * <li>the normal {@link android.Manifest.permission.ACCESS_HIDDEN_PROFILES} permission and the
- * {@link android.app.role.RoleManager.ROLE_HOME} role. </li>
+ * <li>the normal {@link android.Manifest.permission#ACCESS_HIDDEN_PROFILES} permission and the
+ * {@link android.app.role.RoleManager#ROLE_HOME} role. </li>
* </ul>
*
* @param packageName The package to check.
@@ -1249,13 +1249,13 @@
* <p>The contents of this {@link Bundle} are supposed to be a contract between the suspending
* app and the launcher.
*
- * <p>If the user in question is a hidden profile {@link UserManager.USER_TYPE_PROFILE_PRIVATE},
+ * <p>If the user in question is a hidden profile {@link UserManager#USER_TYPE_PROFILE_PRIVATE},
* caller should have either:</p>
* <ul>
- * <li>the privileged {@link android.Manifest.permission.ACCESS_HIDDEN_PROFILES_FULL}
+ * <li>the privileged {@code android.Manifest.permission#ACCESS_HIDDEN_PROFILES_FULL}
* permission</li>
- * <li>the normal {@link android.Manifest.permission.ACCESS_HIDDEN_PROFILES} permission and the
- * {@link android.app.role.RoleManager.ROLE_HOME} role. </li>
+ * <li>the normal {@link android.Manifest.permission#ACCESS_HIDDEN_PROFILES} permission and the
+ * {@link android.app.role.RoleManager#ROLE_HOME} role. </li>
* </ul>
*
* <p>Note: This just returns whatever extras were provided to the system, <em>which might
@@ -1286,13 +1286,13 @@
* could be done because the package was marked as distracting to the user via
* {@code PackageManager.setDistractingPackageRestrictions(String[], int)}.
*
- * <p>If the user in question is a hidden profile {@link UserManager.USER_TYPE_PROFILE_PRIVATE},
+ * <p>If the user in question is a hidden profile {@link UserManager#USER_TYPE_PROFILE_PRIVATE},
* caller should have either:</p>
* <ul>
- * <li>the privileged {@link android.Manifest.permission.ACCESS_HIDDEN_PROFILES_FULL}
+ * <li>the privileged {@code android.Manifest.permission#ACCESS_HIDDEN_PROFILES_FULL}
* permission</li>
- * <li>the normal {@link android.Manifest.permission.ACCESS_HIDDEN_PROFILES} permission and the
- * {@link android.app.role.RoleManager.ROLE_HOME} role. </li>
+ * <li>the normal {@link android.Manifest.permission#ACCESS_HIDDEN_PROFILES} permission and the
+ * {@link android.app.role.RoleManager#ROLE_HOME} role. </li>
* </ul>
*
* @param packageName The package for which to check.
@@ -1316,13 +1316,13 @@
/**
* Returns {@link ApplicationInfo} about an application installed for a specific user profile.
*
- * <p>If the user in question is a hidden profile {@link UserManager.USER_TYPE_PROFILE_PRIVATE},
+ * <p>If the user in question is a hidden profile {@link UserManager#USER_TYPE_PROFILE_PRIVATE},
* caller should have either:</p>
* <ul>
- * <li>the privileged {@link android.Manifest.permission.ACCESS_HIDDEN_PROFILES_FULL}
+ * <li>the privileged {@code android.Manifest.permission#ACCESS_HIDDEN_PROFILES_FULL}
* permission</li>
- * <li>the normal {@link android.Manifest.permission.ACCESS_HIDDEN_PROFILES} permission and the
- * {@link android.app.role.RoleManager.ROLE_HOME} role. </li>
+ * <li>the normal {@link android.Manifest.permission#ACCESS_HIDDEN_PROFILES} permission and the
+ * {@link android.app.role.RoleManager#ROLE_HOME} role. </li>
* </ul>
*
* @param packageName The package name of the application
@@ -1385,13 +1385,13 @@
* <p>The activity may still not be exported, in which case {@link #startMainActivity} will
* throw a {@link SecurityException} unless the caller has the same UID as the target app's.
*
- * <p>If the user in question is a hidden profile {@link UserManager.USER_TYPE_PROFILE_PRIVATE},
+ * <p>If the user in question is a hidden profile {@link UserManager#USER_TYPE_PROFILE_PRIVATE},
* caller should have either:</p>
* <ul>
- * <li>the privileged {@link android.Manifest.permission.ACCESS_HIDDEN_PROFILES_FULL}
+ * <li>the privileged {@code android.Manifest.permission#ACCESS_HIDDEN_PROFILES_FULL}
* permission</li>
- * <li>the normal {@link android.Manifest.permission.ACCESS_HIDDEN_PROFILES} permission and the
- * {@link android.app.role.RoleManager.ROLE_HOME} role. </li>
+ * <li>the normal {@link android.Manifest.permission#ACCESS_HIDDEN_PROFILES} permission and the
+ * {@link android.app.role.RoleManager#ROLE_HOME} role. </li>
* </ul>
*
* @param component The activity to check.
@@ -1960,13 +1960,13 @@
/**
* Registers a callback for changes to packages in this user and managed profiles.
*
- * <p>To receive callbacks for hidden profile {@link UserManager.USER_TYPE_PROFILE_PRIVATE},
+ * <p>To receive callbacks for hidden profile {@link UserManager#USER_TYPE_PROFILE_PRIVATE},
* caller should have either:</p>
* <ul>
- * <li>the privileged {@link android.Manifest.permission.ACCESS_HIDDEN_PROFILES_FULL}
+ * <li>the privileged {@code android.Manifest.permission#ACCESS_HIDDEN_PROFILES_FULL}
* permission</li>
- * <li>the normal {@link android.Manifest.permission.ACCESS_HIDDEN_PROFILES} permission and the
- * {@link android.app.role.RoleManager.ROLE_HOME} role. </li>
+ * <li>the normal {@link android.Manifest.permission#ACCESS_HIDDEN_PROFILES} permission and the
+ * {@link android.app.role.RoleManager#ROLE_HOME} role. </li>
* </ul>
*
* @param callback The callback to register.
@@ -1981,13 +1981,13 @@
/**
* Registers a callback for changes to packages in this user and managed profiles.
*
- * <p>To receive callbacks for hidden profile {@link UserManager.USER_TYPE_PROFILE_PRIVATE},
+ * <p>To receive callbacks for hidden profile {@link UserManager#USER_TYPE_PROFILE_PRIVATE},
* caller should have either:</p>
* <ul>
- * <li>the privileged {@link android.Manifest.permission.ACCESS_HIDDEN_PROFILES_FULL}
+ * <li>the privileged {@code android.Manifest.permission#ACCESS_HIDDEN_PROFILES_FULL}
* permission</li>
- * <li>the normal {@link android.Manifest.permission.ACCESS_HIDDEN_PROFILES} permission and the
- * {@link android.app.role.RoleManager.ROLE_HOME} role. </li>
+ * <li>the normal {@link android.Manifest.permission#ACCESS_HIDDEN_PROFILES} permission and the
+ * {@link android.app.role.RoleManager#ROLE_HOME} role. </li>
* </ul>
*
* @param callback The callback to register.
@@ -2446,13 +2446,13 @@
* package name in the app's manifest, have the android.permission.QUERY_ALL_PACKAGES, or be
* the session owner to retrieve these details.
*
- * <p>To receive callbacks for hidden profile {@link UserManager.USER_TYPE_PROFILE_PRIVATE},
+ * <p>To receive callbacks for hidden profile {@link UserManager#USER_TYPE_PROFILE_PRIVATE},
* caller should have either:</p>
* <ul>
- * <li>the privileged {@link android.Manifest.permission.ACCESS_HIDDEN_PROFILES}
+ * <li>the privileged {@code android.Manifest.permission#ACCESS_HIDDEN_PROFILES_FULL}
* permission</li>
- * <li>the normal {@link android.Manifest.permission.ACCESS_HIDDEN_PROFILES} permission and the
- * {@link android.app.role.RoleManager.ROLE_HOME} role. </li>
+ * <li>the normal {@link android.Manifest.permission#ACCESS_HIDDEN_PROFILES} permission and the
+ * {@link android.app.role.RoleManager#ROLE_HOME} role. </li>
* </ul>
*
* @see PackageInstaller#getAllSessions()
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index 3cc87ea..6fffb82 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -1472,9 +1472,9 @@
new Key<Integer>("android.flash.info.strengthDefaultLevel", int.class);
/**
- * <p>Maximum flash brightness level for manual flash control in SINGLE mode.</p>
+ * <p>Maximum flash brightness level for manual flash control in <code>SINGLE</code> mode.</p>
* <p>Maximum flash brightness level in camera capture mode and
- * {@link CaptureRequest#FLASH_MODE android.flash.mode} set to SINGLE.
+ * {@link CaptureRequest#FLASH_MODE android.flash.mode} set to <code>SINGLE</code>.
* Value will be > 1 if the manual flash strength control feature is supported,
* otherwise the value will be equal to 1.
* Note that this level is just a number of supported levels (the granularity of control).
@@ -1490,7 +1490,7 @@
new Key<Integer>("android.flash.singleStrengthMaxLevel", int.class);
/**
- * <p>Default flash brightness level for manual flash control in SINGLE mode.</p>
+ * <p>Default flash brightness level for manual flash control in <code>SINGLE</code> mode.</p>
* <p>If flash unit is available this will be greater than or equal to 1 and less
* or equal to {@link CameraCharacteristics#FLASH_SINGLE_STRENGTH_MAX_LEVEL android.flash.singleStrengthMaxLevel}.
* Note for devices that do not support the manual flash strength control
@@ -1506,9 +1506,9 @@
new Key<Integer>("android.flash.singleStrengthDefaultLevel", int.class);
/**
- * <p>Maximum flash brightness level for manual flash control in TORCH mode</p>
+ * <p>Maximum flash brightness level for manual flash control in <code>TORCH</code> mode</p>
* <p>Maximum flash brightness level in camera capture mode and
- * {@link CaptureRequest#FLASH_MODE android.flash.mode} set to TORCH.
+ * {@link CaptureRequest#FLASH_MODE android.flash.mode} set to <code>TORCH</code>.
* Value will be > 1 if the manual flash strength control feature is supported,
* otherwise the value will be equal to 1.</p>
* <p>Note that this level is just a number of supported levels(the granularity of control).
@@ -1530,7 +1530,7 @@
new Key<Integer>("android.flash.torchStrengthMaxLevel", int.class);
/**
- * <p>Default flash brightness level for manual flash control in TORCH mode</p>
+ * <p>Default flash brightness level for manual flash control in <code>TORCH</code> mode</p>
* <p>If flash unit is available this will be greater than or equal to 1 and less
* or equal to {@link CameraCharacteristics#FLASH_TORCH_STRENGTH_MAX_LEVEL android.flash.torchStrengthMaxLevel}.
* Note for the devices that do not support the manual flash strength control feature,
@@ -4152,10 +4152,16 @@
/**
* <p>Whether the RAW images output from this camera device are subject to
* lens shading correction.</p>
- * <p>If TRUE, all images produced by the camera device in the RAW image formats will
- * have lens shading correction already applied to it. If FALSE, the images will
- * not be adjusted for lens shading correction.
- * See {@link CameraCharacteristics#REQUEST_MAX_NUM_OUTPUT_RAW android.request.maxNumOutputRaw} for a list of RAW image formats.</p>
+ * <p>If <code>true</code>, all images produced by the camera device in the <code>RAW</code> image formats will have
+ * at least some lens shading correction already applied to it. If <code>false</code>, the images will
+ * not be adjusted for lens shading correction. See {@link CameraCharacteristics#REQUEST_MAX_NUM_OUTPUT_RAW android.request.maxNumOutputRaw} for a
+ * list of RAW image formats.</p>
+ * <p>When <code>true</code>, the <code>lensShadingCorrectionMap</code> key may still have values greater than 1.0,
+ * and those will need to be applied to any captured RAW frames for them to match the shading
+ * correction of processed buffers such as <code>YUV</code> or <code>JPEG</code> images. This may occur, for
+ * example, when some basic fixed lens shading correction is applied by hardware to RAW data,
+ * and additional correction is done dynamically in the camera processing pipeline after
+ * demosaicing.</p>
* <p>This key will be <code>null</code> for all devices do not report this information.
* Devices with RAW capability will always report this information in this key.</p>
* <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java
index 938636f..6968f27 100644
--- a/core/java/android/hardware/camera2/CaptureRequest.java
+++ b/core/java/android/hardware/camera2/CaptureRequest.java
@@ -2683,27 +2683,27 @@
/**
* <p>Flash strength level to be used when manual flash control is active.</p>
* <p>Flash strength level to use in capture mode i.e. when the applications control
- * flash with either SINGLE or TORCH mode.</p>
+ * flash with either <code>SINGLE</code> or <code>TORCH</code> mode.</p>
* <p>Use {@link CameraCharacteristics#FLASH_SINGLE_STRENGTH_MAX_LEVEL android.flash.singleStrengthMaxLevel} and
* {@link CameraCharacteristics#FLASH_TORCH_STRENGTH_MAX_LEVEL android.flash.torchStrengthMaxLevel} to check whether the device supports
* flash strength control or not.
- * If the values of android.flash.info.singleStrengthMaxLevel and
+ * If the values of {@link CameraCharacteristics#FLASH_SINGLE_STRENGTH_MAX_LEVEL android.flash.singleStrengthMaxLevel} and
* {@link CameraCharacteristics#FLASH_TORCH_STRENGTH_MAX_LEVEL android.flash.torchStrengthMaxLevel} are greater than 1,
* then the device supports manual flash strength control.</p>
- * <p>If the {@link CaptureRequest#FLASH_MODE android.flash.mode} <code>==</code> TORCH the value must be >= 1
+ * <p>If the {@link CaptureRequest#FLASH_MODE android.flash.mode} <code>==</code> <code>TORCH</code> the value must be >= 1
* and <= {@link CameraCharacteristics#FLASH_TORCH_STRENGTH_MAX_LEVEL android.flash.torchStrengthMaxLevel}.
* If the application doesn't set the key and
* {@link CameraCharacteristics#FLASH_TORCH_STRENGTH_MAX_LEVEL android.flash.torchStrengthMaxLevel} > 1,
* then the flash will be fired at the default level set by HAL in
* {@link CameraCharacteristics#FLASH_TORCH_STRENGTH_DEFAULT_LEVEL android.flash.torchStrengthDefaultLevel}.
- * If the {@link CaptureRequest#FLASH_MODE android.flash.mode} <code>==</code> SINGLE, then the value must be >= 1
+ * If the {@link CaptureRequest#FLASH_MODE android.flash.mode} <code>==</code> <code>SINGLE</code>, then the value must be >= 1
* and <= {@link CameraCharacteristics#FLASH_SINGLE_STRENGTH_MAX_LEVEL android.flash.singleStrengthMaxLevel}.
* If the application does not set this key and
* {@link CameraCharacteristics#FLASH_SINGLE_STRENGTH_MAX_LEVEL android.flash.singleStrengthMaxLevel} > 1,
* then the flash will be fired at the default level set by HAL
* in {@link CameraCharacteristics#FLASH_SINGLE_STRENGTH_DEFAULT_LEVEL android.flash.singleStrengthDefaultLevel}.
- * If {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode} is set to any of ON_AUTO_FLASH, ON_ALWAYS_FLASH,
- * ON_AUTO_FLASH_REDEYE, ON_EXTERNAL_FLASH values, then the strengthLevel will be ignored.</p>
+ * If {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode} is set to any of <code>ON_AUTO_FLASH</code>, <code>ON_ALWAYS_FLASH</code>,
+ * <code>ON_AUTO_FLASH_REDEYE</code>, <code>ON_EXTERNAL_FLASH</code> values, then the strengthLevel will be ignored.</p>
* <p><b>Range of valid values:</b><br>
* <code>[1-{@link CameraCharacteristics#FLASH_TORCH_STRENGTH_MAX_LEVEL android.flash.torchStrengthMaxLevel}]</code> when the {@link CaptureRequest#FLASH_MODE android.flash.mode} is
* set to TORCH;
diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java
index 4406a41..ef83f9a 100644
--- a/core/java/android/hardware/camera2/CaptureResult.java
+++ b/core/java/android/hardware/camera2/CaptureResult.java
@@ -2976,27 +2976,27 @@
/**
* <p>Flash strength level to be used when manual flash control is active.</p>
* <p>Flash strength level to use in capture mode i.e. when the applications control
- * flash with either SINGLE or TORCH mode.</p>
+ * flash with either <code>SINGLE</code> or <code>TORCH</code> mode.</p>
* <p>Use {@link CameraCharacteristics#FLASH_SINGLE_STRENGTH_MAX_LEVEL android.flash.singleStrengthMaxLevel} and
* {@link CameraCharacteristics#FLASH_TORCH_STRENGTH_MAX_LEVEL android.flash.torchStrengthMaxLevel} to check whether the device supports
* flash strength control or not.
- * If the values of android.flash.info.singleStrengthMaxLevel and
+ * If the values of {@link CameraCharacteristics#FLASH_SINGLE_STRENGTH_MAX_LEVEL android.flash.singleStrengthMaxLevel} and
* {@link CameraCharacteristics#FLASH_TORCH_STRENGTH_MAX_LEVEL android.flash.torchStrengthMaxLevel} are greater than 1,
* then the device supports manual flash strength control.</p>
- * <p>If the {@link CaptureRequest#FLASH_MODE android.flash.mode} <code>==</code> TORCH the value must be >= 1
+ * <p>If the {@link CaptureRequest#FLASH_MODE android.flash.mode} <code>==</code> <code>TORCH</code> the value must be >= 1
* and <= {@link CameraCharacteristics#FLASH_TORCH_STRENGTH_MAX_LEVEL android.flash.torchStrengthMaxLevel}.
* If the application doesn't set the key and
* {@link CameraCharacteristics#FLASH_TORCH_STRENGTH_MAX_LEVEL android.flash.torchStrengthMaxLevel} > 1,
* then the flash will be fired at the default level set by HAL in
* {@link CameraCharacteristics#FLASH_TORCH_STRENGTH_DEFAULT_LEVEL android.flash.torchStrengthDefaultLevel}.
- * If the {@link CaptureRequest#FLASH_MODE android.flash.mode} <code>==</code> SINGLE, then the value must be >= 1
+ * If the {@link CaptureRequest#FLASH_MODE android.flash.mode} <code>==</code> <code>SINGLE</code>, then the value must be >= 1
* and <= {@link CameraCharacteristics#FLASH_SINGLE_STRENGTH_MAX_LEVEL android.flash.singleStrengthMaxLevel}.
* If the application does not set this key and
* {@link CameraCharacteristics#FLASH_SINGLE_STRENGTH_MAX_LEVEL android.flash.singleStrengthMaxLevel} > 1,
* then the flash will be fired at the default level set by HAL
* in {@link CameraCharacteristics#FLASH_SINGLE_STRENGTH_DEFAULT_LEVEL android.flash.singleStrengthDefaultLevel}.
- * If {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode} is set to any of ON_AUTO_FLASH, ON_ALWAYS_FLASH,
- * ON_AUTO_FLASH_REDEYE, ON_EXTERNAL_FLASH values, then the strengthLevel will be ignored.</p>
+ * If {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode} is set to any of <code>ON_AUTO_FLASH</code>, <code>ON_ALWAYS_FLASH</code>,
+ * <code>ON_AUTO_FLASH_REDEYE</code>, <code>ON_EXTERNAL_FLASH</code> values, then the strengthLevel will be ignored.</p>
* <p><b>Range of valid values:</b><br>
* <code>[1-{@link CameraCharacteristics#FLASH_TORCH_STRENGTH_MAX_LEVEL android.flash.torchStrengthMaxLevel}]</code> when the {@link CaptureRequest#FLASH_MODE android.flash.mode} is
* set to TORCH;
@@ -4846,6 +4846,9 @@
* correction map that needs to be applied to get shading
* corrected images that match the camera device's output for
* non-RAW formats.</p>
+ * <p>Therefore, whatever the value of lensShadingApplied is, the lens
+ * shading map should always be applied to RAW images if the goal is to
+ * match the shading appearance of processed (non-RAW) images.</p>
* <p>For a complete shading correction map, the least shaded
* section of the image will have a gain factor of 1; all
* other sections will have gains above 1.</p>
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index 278e863..4d69437 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -720,6 +720,7 @@
final ViewTreeObserver.OnComputeInternalInsetsListener mInsetsComputer = info -> {
onComputeInsets(mTmpInsets);
+ mNavigationBarController.updateInsets(mTmpInsets);
if (!mViewsCreated) {
// The IME views are not ready, keep visible insets untouched.
mTmpInsets.visibleTopInsets = 0;
diff --git a/core/java/android/inputmethodservice/NavigationBarController.java b/core/java/android/inputmethodservice/NavigationBarController.java
index 9c55b0e..de67e06 100644
--- a/core/java/android/inputmethodservice/NavigationBarController.java
+++ b/core/java/android/inputmethodservice/NavigationBarController.java
@@ -58,6 +58,10 @@
final class NavigationBarController {
private interface Callback {
+
+ default void updateInsets(@NonNull InputMethodService.Insets originalInsets) {
+ }
+
default void updateTouchableInsets(@NonNull InputMethodService.Insets originalInsets,
@NonNull ViewTreeObserver.InternalInsetsInfo dest) {
}
@@ -96,6 +100,15 @@
? new Impl(inputMethodService) : Callback.NOOP;
}
+ /**
+ * Update the given insets to be at least as big as the IME navigation bar, when visible.
+ *
+ * @param originalInsets the insets to check and modify to include the IME navigation bar.
+ */
+ void updateInsets(@NonNull InputMethodService.Insets originalInsets) {
+ mImpl.updateInsets(originalInsets);
+ }
+
void updateTouchableInsets(@NonNull InputMethodService.Insets originalInsets,
@NonNull ViewTreeObserver.InternalInsetsInfo dest) {
mImpl.updateTouchableInsets(originalInsets, dest);
@@ -270,6 +283,24 @@
}
@Override
+ public void updateInsets(@NonNull InputMethodService.Insets originalInsets) {
+ if (!mImeDrawsImeNavBar || mNavigationBarFrame == null
+ || mNavigationBarFrame.getVisibility() != View.VISIBLE
+ || mService.isFullscreenMode()) {
+ return;
+ }
+
+ final int[] loc = new int[2];
+ mNavigationBarFrame.getLocationInWindow(loc);
+ if (originalInsets.contentTopInsets > loc[1]) {
+ originalInsets.contentTopInsets = loc[1];
+ }
+ if (originalInsets.visibleTopInsets > loc[1]) {
+ originalInsets.visibleTopInsets = loc[1];
+ }
+ }
+
+ @Override
public void updateTouchableInsets(@NonNull InputMethodService.Insets originalInsets,
@NonNull ViewTreeObserver.InternalInsetsInfo dest) {
if (!mImeDrawsImeNavBar || mNavigationBarFrame == null) {
diff --git a/core/java/android/os/BatteryConsumer.java b/core/java/android/os/BatteryConsumer.java
index b417534..7bdd53d 100644
--- a/core/java/android/os/BatteryConsumer.java
+++ b/core/java/android/os/BatteryConsumer.java
@@ -197,6 +197,9 @@
POWER_COMPONENT_MOBILE_RADIO,
POWER_COMPONENT_WIFI,
POWER_COMPONENT_BLUETOOTH,
+ POWER_COMPONENT_AUDIO,
+ POWER_COMPONENT_VIDEO,
+ POWER_COMPONENT_FLASHLIGHT,
};
static final int COLUMN_INDEX_BATTERY_CONSUMER_TYPE = 0;
diff --git a/core/java/android/telephony/DropBoxManagerLoggerBackend.java b/core/java/android/telephony/DropBoxManagerLoggerBackend.java
new file mode 100644
index 0000000..25a3b9f
--- /dev/null
+++ b/core/java/android/telephony/DropBoxManagerLoggerBackend.java
@@ -0,0 +1,261 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.os.DropBoxManager;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.util.Log;
+
+import com.android.internal.R;
+import com.android.internal.annotations.GuardedBy;
+
+import java.time.Instant;
+import java.time.ZoneId;
+import java.time.format.DateTimeFormatter;
+import java.util.Optional;
+
+/**
+ * A persistent logger backend that stores logs in Android DropBoxManager
+ *
+ * @hide
+ */
+public class DropBoxManagerLoggerBackend implements PersistentLoggerBackend {
+
+ private static final String TAG = "DropBoxManagerLoggerBackend";
+ // Separate tag reference to be explicitly used for dropboxmanager instead of logcat logging
+ private static final String DROPBOX_TAG = "DropBoxManagerLoggerBackend";
+ private static final DateTimeFormatter LOG_TIMESTAMP_FORMATTER =
+ DateTimeFormatter.ofPattern("MM-dd HH:mm:ss.SSS");
+ private static final ZoneId LOCAL_ZONE_ID = ZoneId.systemDefault();
+ private static final int BUFFER_SIZE_BYTES = 500 * 1024; // 500 KB
+ private static final int MIN_BUFFER_BYTES_FOR_FLUSH = 5 * 1024; // 5 KB
+
+ private static DropBoxManagerLoggerBackend sInstance;
+
+ private final DropBoxManager mDropBoxManager;
+ private final Object mBufferLock = new Object();
+ @GuardedBy("mBufferLock")
+ private final StringBuilder mLogBuffer = new StringBuilder();
+ private long mBufferStartTime = -1L;
+ private final HandlerThread mHandlerThread = new HandlerThread(DROPBOX_TAG);
+ private final Handler mHandler;
+ // Flag for determining if logging is enabled as a general feature
+ private final boolean mDropBoxManagerLoggingEnabled;
+ // Flag for controlling if logging is enabled at runtime
+ private boolean mIsLoggingEnabled = false;
+
+ /**
+ * Returns a singleton instance of {@code DropBoxManagerLoggerBackend} that will log to
+ * DropBoxManager if the config_dropboxmanager_persistent_logging_enabled resource config is
+ * enabled.
+ * @param context Android context
+ */
+ @Nullable
+ public static synchronized DropBoxManagerLoggerBackend getInstance(@NonNull Context context) {
+ if (sInstance == null) {
+ sInstance = new DropBoxManagerLoggerBackend(context);
+ }
+ return sInstance;
+ }
+
+ private DropBoxManagerLoggerBackend(@NonNull Context context) {
+ mDropBoxManager = context.getSystemService(DropBoxManager.class);
+ mHandlerThread.start();
+ mHandler = new Handler(mHandlerThread.getLooper());
+ mDropBoxManagerLoggingEnabled = persistentLoggingEnabled(context);
+ }
+
+ private boolean persistentLoggingEnabled(@NonNull Context context) {
+ try {
+ return context.getResources().getBoolean(
+ R.bool.config_dropboxmanager_persistent_logging_enabled);
+ } catch (RuntimeException e) {
+ Log.w(TAG, "Persistent logging config not found");
+ return false;
+ }
+ }
+
+ /**
+ * Enable or disable logging to DropBoxManager
+ * @param isLoggingEnabled Whether logging should be enabled
+ */
+ public void setLoggingEnabled(boolean isLoggingEnabled) {
+ Log.i(DROPBOX_TAG, "toggle logging: " + isLoggingEnabled);
+ mIsLoggingEnabled = isLoggingEnabled;
+ }
+
+ /**
+ * Persist a DEBUG log message.
+ * @param tag Used to identify the source of a log message.
+ * @param msg The message you would like logged.
+ */
+ public void debug(@NonNull String tag, @NonNull String msg) {
+ if (!mDropBoxManagerLoggingEnabled) {
+ return;
+ }
+ bufferLog("D", tag, msg, Optional.empty());
+ }
+
+ /**
+ * Persist a INFO log message.
+ * @param tag Used to identify the source of a log message.
+ * @param msg The message you would like logged.
+ */
+ public void info(@NonNull String tag, @NonNull String msg) {
+ if (!mDropBoxManagerLoggingEnabled) {
+ return;
+ }
+ bufferLog("I", tag, msg, Optional.empty());
+ }
+
+ /**
+ * Persist a WARN log message.
+ * @param tag Used to identify the source of a log message.
+ * @param msg The message you would like logged.
+ */
+ public void warn(@NonNull String tag, @NonNull String msg) {
+ if (!mDropBoxManagerLoggingEnabled) {
+ return;
+ }
+ bufferLog("W", tag, msg, Optional.empty());
+ }
+
+ /**
+ * Persist a WARN log message.
+ * @param tag Used to identify the source of a log message.
+ * @param msg The message you would like logged.
+ * @param t An exception to log.
+ */
+ public void warn(@NonNull String tag, @NonNull String msg, @NonNull Throwable t) {
+ if (!mDropBoxManagerLoggingEnabled) {
+ return;
+ }
+ bufferLog("W", tag, msg, Optional.of(t));
+ }
+
+ /**
+ * Persist a ERROR log message.
+ * @param tag Used to identify the source of a log message.
+ * @param msg The message you would like logged.
+ */
+ public void error(@NonNull String tag, @NonNull String msg) {
+ if (!mDropBoxManagerLoggingEnabled) {
+ return;
+ }
+ bufferLog("E", tag, msg, Optional.empty());
+ }
+
+ /**
+ * Persist a ERROR log message.
+ * @param tag Used to identify the source of a log message.
+ * @param msg The message you would like logged.
+ * @param t An exception to log.
+ */
+ public void error(@NonNull String tag, @NonNull String msg, @NonNull Throwable t) {
+ if (!mDropBoxManagerLoggingEnabled) {
+ return;
+ }
+ bufferLog("E", tag, msg, Optional.of(t));
+ }
+
+ private synchronized void bufferLog(
+ @NonNull String level,
+ @NonNull String tag,
+ @NonNull String msg,
+ Optional<Throwable> t) {
+ if (!mIsLoggingEnabled) {
+ return;
+ }
+
+ if (mBufferStartTime == -1L) {
+ mBufferStartTime = System.currentTimeMillis();
+ }
+
+ synchronized (mBufferLock) {
+ mLogBuffer
+ .append(formatLog(level, tag, msg, t))
+ .append("\n");
+
+ if (mLogBuffer.length() >= BUFFER_SIZE_BYTES) {
+ flushAsync();
+ }
+ }
+ }
+
+ private String formatLog(
+ @NonNull String level,
+ @NonNull String tag,
+ @NonNull String msg,
+ Optional<Throwable> t) {
+ // Expected format = "$Timestamp $Level $Tag: $Message"
+ return formatTimestamp(System.currentTimeMillis()) + " " + level + " " + tag + ": "
+ + t.map(throwable -> msg + ": " + Log.getStackTraceString(throwable)).orElse(msg);
+ }
+
+ private String formatTimestamp(long currentTimeMillis) {
+ return Instant.ofEpochMilli(currentTimeMillis)
+ .atZone(LOCAL_ZONE_ID)
+ .format(LOG_TIMESTAMP_FORMATTER);
+ }
+
+ /**
+ * Flushes all buffered logs into DropBoxManager as a single log record with a tag of
+ * {@link #DROPBOX_TAG} asynchronously. Should be invoked sparingly as DropBoxManager has
+ * device-level limitations on the number files that can be stored.
+ */
+ public void flushAsync() {
+ if (!mDropBoxManagerLoggingEnabled) {
+ return;
+ }
+
+ mHandler.post(this::flush);
+ };
+
+ /**
+ * Flushes all buffered logs into DropBoxManager as a single log record with a tag of
+ * {@link #DROPBOX_TAG}. Should be invoked sparingly as DropBoxManager has device-level
+ * limitations on the number files that can be stored.
+ */
+ public void flush() {
+ if (!mDropBoxManagerLoggingEnabled) {
+ return;
+ }
+
+ synchronized (mBufferLock) {
+ if (mLogBuffer.length() < MIN_BUFFER_BYTES_FOR_FLUSH) {
+ return;
+ }
+
+ Log.d(DROPBOX_TAG, "Flushing logs from "
+ + formatTimestamp(mBufferStartTime) + " to "
+ + formatTimestamp(System.currentTimeMillis()));
+
+ try {
+ mDropBoxManager.addText(DROPBOX_TAG, mLogBuffer.toString());
+ } catch (Exception e) {
+ Log.w(DROPBOX_TAG, "Failed to flush logs of length "
+ + mLogBuffer.length() + " to DropBoxManager", e);
+ }
+ mLogBuffer.setLength(0);
+ }
+ mBufferStartTime = -1L;
+ }
+}
diff --git a/core/java/android/telephony/PersistentLogger.java b/core/java/android/telephony/PersistentLogger.java
new file mode 100644
index 0000000..8b12a1c
--- /dev/null
+++ b/core/java/android/telephony/PersistentLogger.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony;
+
+import android.annotation.NonNull;
+
+/**
+ * A persistent logging client. Intended for persisting critical debug logs in situations where
+ * standard Android logcat logs may not be retained long enough.
+ *
+ * @hide
+ */
+public class PersistentLogger {
+ private final PersistentLoggerBackend mPersistentLoggerBackend;
+
+ public PersistentLogger(@NonNull PersistentLoggerBackend persistentLoggerBackend) {
+ mPersistentLoggerBackend = persistentLoggerBackend;
+ }
+
+ /**
+ * Persist a DEBUG log message.
+ * @param tag Used to identify the source of a log message.
+ * @param msg The message you would like logged.
+ */
+ public void debug(@NonNull String tag, @NonNull String msg) {
+ mPersistentLoggerBackend.debug(tag, msg);
+ }
+
+ /**
+ * Persist a INFO log message.
+ * @param tag Used to identify the source of a log message.
+ * @param msg The message you would like logged.
+ */
+ public void info(@NonNull String tag, @NonNull String msg) {
+ mPersistentLoggerBackend.info(tag, msg);
+ }
+
+ /**
+ * Persist a WARN log message.
+ * @param tag Used to identify the source of a log message.
+ * @param msg The message you would like logged.
+ */
+ public void warn(@NonNull String tag, @NonNull String msg) {
+ mPersistentLoggerBackend.warn(tag, msg);
+ }
+
+ /**
+ * Persist a WARN log message.
+ * @param tag Used to identify the source of a log message.
+ * @param msg The message you would like logged.
+ * @param t An exception to log.
+ */
+ public void warn(@NonNull String tag, @NonNull String msg, @NonNull Throwable t) {
+ mPersistentLoggerBackend.warn(tag, msg, t);
+ }
+
+ /**
+ * Persist a ERROR log message.
+ * @param tag Used to identify the source of a log message.
+ * @param msg The message you would like logged.
+ */
+ public void error(@NonNull String tag, @NonNull String msg) {
+ mPersistentLoggerBackend.error(tag, msg);
+ }
+
+ /**
+ * Persist a ERROR log message.
+ * @param tag Used to identify the source of a log message.
+ * @param msg The message you would like logged.
+ * @param t An exception to log.
+ */
+ public void error(@NonNull String tag, @NonNull String msg, @NonNull Throwable t) {
+ mPersistentLoggerBackend.error(tag, msg, t);
+ }
+}
diff --git a/core/java/android/telephony/PersistentLoggerBackend.java b/core/java/android/telephony/PersistentLoggerBackend.java
new file mode 100644
index 0000000..e3e72e1
--- /dev/null
+++ b/core/java/android/telephony/PersistentLoggerBackend.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony;
+
+import android.annotation.NonNull;
+
+/**
+ * Interface for logging backends to provide persistent log storage.
+ *
+ * @hide
+ */
+public interface PersistentLoggerBackend {
+
+ /**
+ * Persist a DEBUG log message.
+ * @param tag Used to identify the source of a log message.
+ * @param msg The message you would like logged.
+ */
+ void debug(@NonNull String tag, @NonNull String msg);
+
+ /**
+ * Persist a INFO log message.
+ * @param tag Used to identify the source of a log message.
+ * @param msg The message you would like logged.
+ */
+ void info(@NonNull String tag, @NonNull String msg);
+
+ /**
+ * Persist a WARN log message.
+ * @param tag Used to identify the source of a log message.
+ * @param msg The message you would like logged.
+ */
+ void warn(@NonNull String tag, @NonNull String msg);
+
+ /**
+ * Persist a WARN log message.
+ * @param tag Used to identify the source of a log message.
+ * @param msg The message you would like logged.
+ * @param t An exception to log.
+ */
+ void warn(@NonNull String tag, @NonNull String msg, @NonNull Throwable t);
+
+ /**
+ * Persist a ERROR log message.
+ * @param tag Used to identify the source of a log message.
+ * @param msg The message you would like logged.
+ */
+ void error(@NonNull String tag, @NonNull String msg);
+
+ /**
+ * Persist a ERROR log message.
+ * @param tag Used to identify the source of a log message.
+ * @param msg The message you would like logged.
+ * @param t An exception to log.
+ */
+ void error(@NonNull String tag, @NonNull String msg, @NonNull Throwable t);
+}
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index beb1a5d..54ee375 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -177,6 +177,7 @@
import android.graphics.RenderNode;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
+import android.hardware.SyncFence;
import android.hardware.display.DisplayManager;
import android.hardware.display.DisplayManager.DisplayListener;
import android.hardware.display.DisplayManagerGlobal;
@@ -218,6 +219,7 @@
import android.view.InputDevice.InputSourceClass;
import android.view.Surface.OutOfResourcesException;
import android.view.SurfaceControl.Transaction;
+import android.view.SurfaceControl.TransactionStats;
import android.view.View.AttachInfo;
import android.view.View.FocusDirection;
import android.view.View.MeasureSpec;
@@ -292,6 +294,7 @@
import java.util.Queue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
+import java.util.function.Consumer;
import java.util.function.Predicate;
/**
* The top of a view hierarchy, implementing the needed protocol between View
@@ -1188,6 +1191,13 @@
private String mFpsTraceName;
private String mLargestViewTraceName;
+ private final boolean mAppStartInfoTimestampsFlagValue;
+ @GuardedBy("this")
+ private boolean mAppStartTimestampsSent = false;
+ private boolean mAppStartTrackingStarted = false;
+ private long mRenderThreadDrawStartTimeNs = -1;
+ private long mFirstFramePresentedTimeNs = -1;
+
private static boolean sToolkitSetFrameRateReadOnlyFlagValue;
private static boolean sToolkitFrameRateFunctionEnablingReadOnlyFlagValue;
private static boolean sToolkitMetricsForFrameRateDecisionFlagValue;
@@ -1304,6 +1314,8 @@
} else {
mSensitiveContentProtectionService = null;
}
+
+ mAppStartInfoTimestampsFlagValue = android.app.Flags.appStartInfoTimestamps();
}
public static void addFirstDrawHandler(Runnable callback) {
@@ -2576,6 +2588,12 @@
notifySurfaceDestroyed();
}
destroySurface();
+
+ // Reset so they can be sent again for warm starts.
+ mAppStartTimestampsSent = false;
+ mAppStartTrackingStarted = false;
+ mRenderThreadDrawStartTimeNs = -1;
+ mFirstFramePresentedTimeNs = -1;
}
}
}
@@ -4374,6 +4392,30 @@
reportDrawFinished(t, seqId);
}
});
+
+ // Only trigger once per {@link ViewRootImpl} instance, so don't add listener if
+ // {link mTransactionCompletedTimeNs} has already been set.
+ if (mAppStartInfoTimestampsFlagValue && !mAppStartTrackingStarted) {
+ mAppStartTrackingStarted = true;
+ Transaction transaction = new Transaction();
+ transaction.addTransactionCompletedListener(mExecutor,
+ new Consumer<TransactionStats>() {
+ @Override
+ public void accept(TransactionStats transactionStats) {
+ SyncFence presentFence = transactionStats.getPresentFence();
+ if (presentFence.awaitForever()) {
+ if (mFirstFramePresentedTimeNs == -1) {
+ // Only trigger once per {@link ViewRootImpl} instance.
+ mFirstFramePresentedTimeNs = presentFence.getSignalTime();
+ maybeSendAppStartTimes();
+ }
+ }
+ presentFence.close();
+ }
+ });
+ applyTransactionOnDraw(transaction);
+ }
+
if (DEBUG_BLAST) {
Log.d(mTag, "Setup new sync=" + mWmsRequestSyncGroup.getName());
}
@@ -4381,6 +4423,45 @@
mWmsRequestSyncGroup.add(this, null /* runnable */);
}
+ private void maybeSendAppStartTimes() {
+ synchronized (this) {
+ if (mAppStartTimestampsSent) {
+ // Don't send timestamps more than once.
+ return;
+ }
+
+ // If we already have {@link mRenderThreadDrawStartTimeNs} then pass it through, if not
+ // post to main thread and check if we have it there.
+ if (mRenderThreadDrawStartTimeNs != -1) {
+ sendAppStartTimesLocked();
+ } else {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ synchronized (ViewRootImpl.this) {
+ if (mRenderThreadDrawStartTimeNs == -1) {
+ return;
+ }
+ sendAppStartTimesLocked();
+ }
+ }
+ });
+ }
+ }
+ }
+
+ @GuardedBy("this")
+ private void sendAppStartTimesLocked() {
+ try {
+ ActivityManager.getService().reportStartInfoViewTimestamps(
+ mRenderThreadDrawStartTimeNs, mFirstFramePresentedTimeNs);
+ mAppStartTimestampsSent = true;
+ } catch (RemoteException e) {
+ // Ignore, timestamps may be lost.
+ if (DBG) Log.d(TAG, "Exception attempting to report start timestamps.", e);
+ }
+ }
+
/**
* Helper used to notify the service to block projection when a sensitive
* view (the view displays sensitive content) is attached to the window.
@@ -5567,7 +5648,13 @@
registerCallbackForPendingTransactions();
}
+ long timeNs = SystemClock.uptimeNanos();
mAttachInfo.mThreadedRenderer.draw(mView, mAttachInfo, this);
+
+ // Only trigger once per {@link ViewRootImpl} instance.
+ if (mAppStartInfoTimestampsFlagValue && mRenderThreadDrawStartTimeNs == -1) {
+ mRenderThreadDrawStartTimeNs = timeNs;
+ }
} else {
// If we get here with a disabled & requested hardware renderer, something went
// wrong (an invalidate posted right before we destroyed the hardware surface
@@ -7417,8 +7504,6 @@
final KeyEvent event = (KeyEvent)q.mEvent;
if (mView.dispatchKeyEventPreIme(event)) {
return FINISH_HANDLED;
- } else if (q.forPreImeOnly()) {
- return FINISH_NOT_HANDLED;
}
return FORWARD;
}
@@ -9915,7 +10000,6 @@
public static final int FLAG_RESYNTHESIZED = 1 << 4;
public static final int FLAG_UNHANDLED = 1 << 5;
public static final int FLAG_MODIFIED_FOR_COMPATIBILITY = 1 << 6;
- public static final int FLAG_PRE_IME_ONLY = 1 << 7;
public QueuedInputEvent mNext;
@@ -9923,13 +10007,6 @@
public InputEventReceiver mReceiver;
public int mFlags;
- public boolean forPreImeOnly() {
- if ((mFlags & FLAG_PRE_IME_ONLY) != 0) {
- return true;
- }
- return false;
- }
-
public boolean shouldSkipIme() {
if ((mFlags & FLAG_DELIVER_POST_IME) != 0) {
return true;
@@ -9956,7 +10033,6 @@
hasPrevious = flagToString("FINISHED_HANDLED", FLAG_FINISHED_HANDLED, hasPrevious, sb);
hasPrevious = flagToString("RESYNTHESIZED", FLAG_RESYNTHESIZED, hasPrevious, sb);
hasPrevious = flagToString("UNHANDLED", FLAG_UNHANDLED, hasPrevious, sb);
- hasPrevious = flagToString("FLAG_PRE_IME_ONLY", FLAG_PRE_IME_ONLY, hasPrevious, sb);
if (!hasPrevious) {
sb.append("0");
}
@@ -10013,7 +10089,7 @@
}
@UnsupportedAppUsage
- QueuedInputEvent enqueueInputEvent(InputEvent event,
+ void enqueueInputEvent(InputEvent event,
InputEventReceiver receiver, int flags, boolean processImmediately) {
QueuedInputEvent q = obtainQueuedInputEvent(event, receiver, flags);
@@ -10052,7 +10128,6 @@
} else {
scheduleProcessInputEvents();
}
- return q;
}
private void scheduleProcessInputEvents() {
@@ -12374,45 +12449,29 @@
+ "IWindow:%s Session:%s",
mOnBackInvokedDispatcher, mBasePackageName, mWindow, mWindowSession));
}
- mOnBackInvokedDispatcher.attachToWindow(mWindowSession, mWindow, this,
+ mOnBackInvokedDispatcher.attachToWindow(mWindowSession, mWindow,
mImeBackAnimationController);
}
- /**
- * Sends {@link KeyEvent#ACTION_DOWN ACTION_DOWN} and {@link KeyEvent#ACTION_UP ACTION_UP}
- * back key events
- *
- * @param preImeOnly whether the back events should be sent to the pre-ime stage only
- * @return whether the event was handled (i.e. onKeyPreIme consumed it if preImeOnly=true)
- */
- public boolean injectBackKeyEvents(boolean preImeOnly) {
- boolean consumed;
- try {
- processingBackKey(true);
- sendBackKeyEvent(KeyEvent.ACTION_DOWN, preImeOnly);
- consumed = sendBackKeyEvent(KeyEvent.ACTION_UP, preImeOnly);
- } finally {
- processingBackKey(false);
- }
- return consumed;
- }
-
- private boolean sendBackKeyEvent(int action, boolean preImeOnly) {
+ private void sendBackKeyEvent(int action) {
long when = SystemClock.uptimeMillis();
final KeyEvent ev = new KeyEvent(when, when, action,
KeyEvent.KEYCODE_BACK, 0 /* repeat */, 0 /* metaState */,
KeyCharacterMap.VIRTUAL_KEYBOARD, 0 /* scancode */,
KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY,
InputDevice.SOURCE_KEYBOARD);
- int flags = preImeOnly ? QueuedInputEvent.FLAG_PRE_IME_ONLY : 0;
- QueuedInputEvent q = enqueueInputEvent(ev, null /* receiver */, flags,
- true /* processImmediately */);
- return (q.mFlags & QueuedInputEvent.FLAG_FINISHED_HANDLED) != 0;
+ enqueueInputEvent(ev, null /* receiver */, 0 /* flags */, true /* processImmediately */);
}
private void registerCompatOnBackInvokedCallback() {
mCompatOnBackInvokedCallback = () -> {
- injectBackKeyEvents(/* preImeOnly */ false);
+ try {
+ processingBackKey(true);
+ sendBackKeyEvent(KeyEvent.ACTION_DOWN);
+ sendBackKeyEvent(KeyEvent.ACTION_UP);
+ } finally {
+ processingBackKey(false);
+ }
};
if (mOnBackInvokedDispatcher.hasImeOnBackInvokedDispatcher()) {
Log.d(TAG, "Skip registering CompatOnBackInvokedCallback on IME dispatcher");
diff --git a/core/java/android/view/autofill/AutofillFeatureFlags.java b/core/java/android/view/autofill/AutofillFeatureFlags.java
index 46b41ae..950dfee 100644
--- a/core/java/android/view/autofill/AutofillFeatureFlags.java
+++ b/core/java/android/view/autofill/AutofillFeatureFlags.java
@@ -548,7 +548,7 @@
return DeviceConfig.getBoolean(
DeviceConfig.NAMESPACE_AUTOFILL,
DEVICE_CONFIG_FILL_FIELDS_FROM_CURRENT_SESSION_ONLY,
- false);
+ true);
}
/**
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index 4099e88..15f9cff8 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -1424,6 +1424,10 @@
context.unbindService(this);
}
+ if (items == null) {
+ items = new RemoteCollectionItems.Builder().build();
+ }
+
result.complete(items);
}
diff --git a/core/java/android/window/WindowOnBackInvokedDispatcher.java b/core/java/android/window/WindowOnBackInvokedDispatcher.java
index 4c993c2..b7f6f36 100644
--- a/core/java/android/window/WindowOnBackInvokedDispatcher.java
+++ b/core/java/android/window/WindowOnBackInvokedDispatcher.java
@@ -37,7 +37,6 @@
import android.view.IWindowSession;
import android.view.ImeBackAnimationController;
import android.view.MotionEvent;
-import android.view.ViewRootImpl;
import androidx.annotation.VisibleForTesting;
@@ -50,7 +49,6 @@
import java.util.HashMap;
import java.util.Objects;
import java.util.TreeMap;
-import java.util.function.BooleanSupplier;
import java.util.function.Supplier;
/**
@@ -70,7 +68,6 @@
public class WindowOnBackInvokedDispatcher implements OnBackInvokedDispatcher {
private IWindowSession mWindowSession;
private IWindow mWindow;
- private ViewRootImpl mViewRoot;
@VisibleForTesting
public final BackTouchTracker mTouchTracker = new BackTouchTracker();
@VisibleForTesting
@@ -137,12 +134,10 @@
* is attached a window.
*/
public void attachToWindow(@NonNull IWindowSession windowSession, @NonNull IWindow window,
- @Nullable ViewRootImpl viewRoot,
@Nullable ImeBackAnimationController imeBackAnimationController) {
synchronized (mLock) {
mWindowSession = windowSession;
mWindow = window;
- mViewRoot = viewRoot;
mImeBackAnimationController = imeBackAnimationController;
if (!mAllCallbacks.isEmpty()) {
setTopOnBackInvokedCallback(getTopCallback());
@@ -156,7 +151,6 @@
clear();
mWindow = null;
mWindowSession = null;
- mViewRoot = null;
mImeBackAnimationController = null;
}
}
@@ -182,6 +176,8 @@
return;
}
if (callback instanceof ImeOnBackInvokedDispatcher.ImeOnBackInvokedCallback) {
+ // Fall back to compat back key injection if legacy back behaviour should be used.
+ if (!isOnBackInvokedCallbackEnabled()) return;
if (callback instanceof ImeOnBackInvokedDispatcher.DefaultImeOnBackAnimationCallback
&& mImeBackAnimationController != null) {
// register ImeBackAnimationController instead to play predictive back animation
@@ -304,14 +300,6 @@
}
}
- private boolean callOnKeyPreIme() {
- if (mViewRoot != null && !isOnBackInvokedCallbackEnabled(mViewRoot.mContext)) {
- return mViewRoot.injectBackKeyEvents(/*preImeOnly*/ true);
- } else {
- return false;
- }
- }
-
private void setTopOnBackInvokedCallback(@Nullable OnBackInvokedCallback callback) {
if (mWindowSession == null || mWindow == null) {
return;
@@ -320,8 +308,8 @@
OnBackInvokedCallbackInfo callbackInfo = null;
if (callback != null) {
int priority = mAllCallbacks.get(callback);
- final IOnBackInvokedCallback iCallback = new OnBackInvokedCallbackWrapper(callback,
- mTouchTracker, mProgressAnimator, mHandler, this::callOnKeyPreIme);
+ final IOnBackInvokedCallback iCallback = new OnBackInvokedCallbackWrapper(
+ callback, mTouchTracker, mProgressAnimator, mHandler);
callbackInfo = new OnBackInvokedCallbackInfo(
iCallback,
priority,
@@ -411,20 +399,16 @@
private final BackTouchTracker mTouchTracker;
@NonNull
private final Handler mHandler;
- @NonNull
- private final BooleanSupplier mOnKeyPreIme;
OnBackInvokedCallbackWrapper(
@NonNull OnBackInvokedCallback callback,
@NonNull BackTouchTracker touchTracker,
@NonNull BackProgressAnimator progressAnimator,
- @NonNull Handler handler,
- @NonNull BooleanSupplier onKeyPreIme) {
+ @NonNull Handler handler) {
mCallback = new WeakReference<>(callback);
mTouchTracker = touchTracker;
mProgressAnimator = progressAnimator;
mHandler = handler;
- mOnKeyPreIme = onKeyPreIme;
}
@Override
@@ -467,7 +451,6 @@
public void onBackInvoked() throws RemoteException {
mHandler.post(() -> {
mTouchTracker.reset();
- if (consumedByOnKeyPreIme()) return;
boolean isInProgress = mProgressAnimator.isBackAnimationInProgress();
final OnBackInvokedCallback callback = mCallback.get();
if (callback == null) {
@@ -489,30 +472,6 @@
});
}
- private boolean consumedByOnKeyPreIme() {
- final OnBackInvokedCallback callback = mCallback.get();
- if (callback instanceof ImeBackAnimationController
- || callback instanceof ImeOnBackInvokedDispatcher.ImeOnBackInvokedCallback) {
- // call onKeyPreIme API if the current callback is an IME callback and the app has
- // not set enableOnBackInvokedCallback="false"
- try {
- boolean consumed = mOnKeyPreIme.getAsBoolean();
- if (consumed) {
- // back event intercepted by app in onKeyPreIme -> cancel the IME animation.
- final OnBackAnimationCallback animationCallback =
- getBackAnimationCallback();
- if (animationCallback != null) {
- mProgressAnimator.onBackCancelled(animationCallback::onBackCancelled);
- }
- return true;
- }
- } catch (Exception e) {
- Log.d(TAG, "Failed to call onKeyPreIme", e);
- }
- }
- return false;
- }
-
@Override
public void setTriggerBack(boolean triggerBack) throws RemoteException {
mTouchTracker.setTriggerBack(triggerBack);
diff --git a/core/java/android/window/flags/lse_desktop_experience.aconfig b/core/java/android/window/flags/lse_desktop_experience.aconfig
index daf2fe3..b91f2d6 100644
--- a/core/java/android/window/flags/lse_desktop_experience.aconfig
+++ b/core/java/android/window/flags/lse_desktop_experience.aconfig
@@ -106,3 +106,10 @@
description: "Whether to apply Camera Compat treatment to fixed-orientation apps in desktop windowing mode"
bug: "314952133"
}
+
+flag {
+ name: "enable_task_stack_observer_in_shell"
+ namespace: "lse_desktop_experience"
+ description: "Introduces a new observer in shell to track the task stack."
+ bug: "341932484"
+}
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index 98d6ec6..920981e 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -923,7 +923,7 @@
mSystemWindowInsets = insets.getSystemWindowInsets();
mResolverDrawerLayout.setPadding(mSystemWindowInsets.left, mSystemWindowInsets.top,
- mSystemWindowInsets.right, mSystemWindowInsets.bottom);
+ mSystemWindowInsets.right, 0);
resetButtonBar();
@@ -952,7 +952,7 @@
if (mSystemWindowInsets != null) {
mResolverDrawerLayout.setPadding(mSystemWindowInsets.left, mSystemWindowInsets.top,
- mSystemWindowInsets.right, mSystemWindowInsets.bottom);
+ mSystemWindowInsets.right, 0);
}
}
diff --git a/core/java/com/android/internal/os/BatteryStatsHistory.java b/core/java/com/android/internal/os/BatteryStatsHistory.java
index 244165f..5c270e0 100644
--- a/core/java/com/android/internal/os/BatteryStatsHistory.java
+++ b/core/java/com/android/internal/os/BatteryStatsHistory.java
@@ -1514,6 +1514,36 @@
}
/**
+ * Records an event when some state2 flag changes to true.
+ */
+ public void recordState2StartEvent(long elapsedRealtimeMs, long uptimeMs, int stateFlags,
+ int uid, String name) {
+ synchronized (this) {
+ mHistoryCur.states2 |= stateFlags;
+ mHistoryCur.eventCode = EVENT_STATE_CHANGE | EVENT_FLAG_START;
+ mHistoryCur.eventTag = mHistoryCur.localEventTag;
+ mHistoryCur.eventTag.uid = uid;
+ mHistoryCur.eventTag.string = name;
+ writeHistoryItem(elapsedRealtimeMs, uptimeMs);
+ }
+ }
+
+ /**
+ * Records an event when some state2 flag changes to false.
+ */
+ public void recordState2StopEvent(long elapsedRealtimeMs, long uptimeMs, int stateFlags,
+ int uid, String name) {
+ synchronized (this) {
+ mHistoryCur.states2 &= ~stateFlags;
+ mHistoryCur.eventCode = EVENT_STATE_CHANGE | EVENT_FLAG_FINISH;
+ mHistoryCur.eventTag = mHistoryCur.localEventTag;
+ mHistoryCur.eventTag.uid = uid;
+ mHistoryCur.eventTag.string = name;
+ writeHistoryItem(elapsedRealtimeMs, uptimeMs);
+ }
+ }
+
+ /**
* Records an event when some state2 flag changes to false.
*/
public void recordState2StopEvent(long elapsedRealtimeMs, long uptimeMs, int stateFlags) {
diff --git a/core/res/res/drawable/floating_popup_background_dark.xml b/core/res/res/drawable/floating_popup_background.xml
similarity index 84%
rename from core/res/res/drawable/floating_popup_background_dark.xml
rename to core/res/res/drawable/floating_popup_background.xml
index c4b4448..99acedf 100644
--- a/core/res/res/drawable/floating_popup_background_dark.xml
+++ b/core/res/res/drawable/floating_popup_background.xml
@@ -16,8 +16,9 @@
*/
-->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
android:shape="rectangle">
- <solid android:color="@color/background_floating_material_dark" />
+ <solid android:color="?androidprv:attr/materialColorSurfaceContainerHighest"/>
<corners android:radius="?android:attr/dialogCornerRadius" />
</shape>
diff --git a/core/res/res/drawable/floating_popup_background_light.xml b/core/res/res/drawable/floating_popup_background_light.xml
deleted file mode 100644
index 767140d..0000000
--- a/core/res/res/drawable/floating_popup_background_light.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/* Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/background_floating_material_light" />
- <corners android:radius="?android:attr/dialogCornerRadius" />
-</shape>
-
diff --git a/core/res/res/layout/floating_popup_container.xml b/core/res/res/layout/floating_popup_container.xml
index 776a35d..96f0909 100644
--- a/core/res/res/layout/floating_popup_container.xml
+++ b/core/res/res/layout/floating_popup_container.xml
@@ -24,4 +24,4 @@
android:elevation="@android:dimen/text_edit_floating_toolbar_elevation"
android:focusable="true"
android:focusableInTouchMode="true"
- android:background="?attr/floatingToolbarPopupBackgroundDrawable"/>
+ android:background="@drawable/floating_popup_background"/>
diff --git a/core/res/res/layout/floating_popup_menu_button.xml b/core/res/res/layout/floating_popup_menu_button.xml
index e4c2a34..0b3861c 100644
--- a/core/res/res/layout/floating_popup_menu_button.xml
+++ b/core/res/res/layout/floating_popup_menu_button.xml
@@ -16,6 +16,7 @@
*/
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
@@ -53,7 +54,7 @@
android:ellipsize="end"
android:fontFamily="@*android:string/config_bodyFontFamily"
android:textSize="@dimen/floating_toolbar_text_size"
- android:textColor="?attr/floatingToolbarForegroundColor"
+ android:textColor="?androidprv:attr/materialColorOnSurface"
android:background="@null"
android:focusable="false"
android:focusableInTouchMode="false"
diff --git a/core/res/res/layout/floating_popup_overflow_button.xml b/core/res/res/layout/floating_popup_overflow_button.xml
index 12e2000..a51836b 100644
--- a/core/res/res/layout/floating_popup_overflow_button.xml
+++ b/core/res/res/layout/floating_popup_overflow_button.xml
@@ -16,6 +16,7 @@
*/
-->
<ImageButton xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
android:id="@+id/overflow"
android:layout_width="@dimen/floating_toolbar_menu_image_button_width"
android:layout_height="@dimen/floating_toolbar_height"
@@ -25,4 +26,4 @@
android:paddingBottom="@dimen/floating_toolbar_menu_image_button_vertical_padding"
android:scaleType="centerInside"
android:background="?attr/actionBarItemBackground"
- android:tint="?attr/floatingToolbarForegroundColor" />
+ android:tint="?androidprv:attr/materialColorOnSurface" />
diff --git a/core/res/res/layout/text_edit_suggestion_container_material.xml b/core/res/res/layout/text_edit_suggestion_container_material.xml
index 34e7bc8..d6e1e9d 100644
--- a/core/res/res/layout/text_edit_suggestion_container_material.xml
+++ b/core/res/res/layout/text_edit_suggestion_container_material.xml
@@ -23,7 +23,7 @@
android:id="@+id/suggestionWindowContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:background="?android:attr/floatingToolbarPopupBackgroundDrawable"
+ android:background="@drawable/floating_popup_background"
android:elevation="@android:dimen/text_edit_floating_toolbar_elevation"
android:layout_margin="@android:dimen/text_edit_floating_toolbar_margin"
android:orientation="vertical"
diff --git a/core/res/res/values/arrays.xml b/core/res/res/values/arrays.xml
index 575573c..df5cbb1 100644
--- a/core/res/res/values/arrays.xml
+++ b/core/res/res/values/arrays.xml
@@ -37,8 +37,7 @@
<item>@drawable/fastscroll_label_right_material</item>
<item>@drawable/fastscroll_thumb_material</item>
<item>@drawable/fastscroll_track_material</item>
- <item>@drawable/floating_popup_background_dark</item>
- <item>@drawable/floating_popup_background_light</item>
+ <item>@drawable/floating_popup_background</item>
<item>@drawable/ic_ab_back_material</item>
<item>@drawable/ic_ab_back_material_dark</item>
<item>@drawable/ic_ab_back_material_light</item>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index c74bc9b..9846b71 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -606,11 +606,9 @@
<!-- ============ -->
<eat-comment />
<attr name="floatingToolbarCloseDrawable" format="reference" />
- <attr name="floatingToolbarForegroundColor" format="reference|color" />
<attr name="floatingToolbarItemBackgroundBorderlessDrawable" format="reference" />
<attr name="floatingToolbarItemBackgroundDrawable" format="reference" />
<attr name="floatingToolbarOpenDrawable" format="reference" />
- <attr name="floatingToolbarPopupBackgroundDrawable" format="reference" />
<attr name="floatingToolbarDividerColor" format="reference" />
<!-- ============ -->
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index c6d4f3a..4dfe000 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -4840,7 +4840,7 @@
See android.credentials.CredentialManager
-->
<string name="config_defaultCredentialManagerHybridService" translatable="false"></string>
-
+
<!-- The component name, flattened to a string, for the system's credential manager
autofill service. This service allows interceding autofill requests and routing
them to credential manager.
@@ -6503,6 +6503,9 @@
<string-array name="config_sharedLibrariesLoadedAfterApp" translatable="false">
</string-array>
+ <!-- the number of the max cached processes in the system. -->
+ <integer name="config_customizedMaxCachedProcesses">32</integer>
+
<!-- Whether this device should support taking app snapshots on closure -->
<bool name="config_disableTaskSnapshots">false</bool>
diff --git a/core/res/res/values/config_telephony.xml b/core/res/res/values/config_telephony.xml
index dcda5d8..fba95a5 100644
--- a/core/res/res/values/config_telephony.xml
+++ b/core/res/res/values/config_telephony.xml
@@ -409,4 +409,10 @@
<bool name="config_force_phone_globals_creation">false</bool>
<java-symbol type="bool" name="config_force_phone_globals_creation" />
+ <!-- Boolean indicating whether to enable persistent logging via DropBoxManager.
+ Used in persisting SOS/emergency related log messages.
+ -->
+ <bool name="config_dropboxmanager_persistent_logging_enabled">false</bool>
+ <java-symbol type="bool" name="config_dropboxmanager_persistent_logging_enabled" />
+
</resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 4442b5e..cc74d02 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -5067,6 +5067,8 @@
code and resources provided by applications. -->
<java-symbol type="array" name="config_sharedLibrariesLoadedAfterApp" />
+ <java-symbol type="integer" name="config_customizedMaxCachedProcesses" />
+
<java-symbol type="color" name="overview_background"/>
<java-symbol type="bool" name="config_disableTaskSnapshots" />
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index bdbf96b..c3d304d 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -391,11 +391,9 @@
<!-- Floating toolbar styles -->
<item name="floatingToolbarCloseDrawable">@drawable/ic_ab_back_material_dark</item>
- <item name="floatingToolbarForegroundColor">@color/foreground_material_dark</item>
<item name="floatingToolbarItemBackgroundBorderlessDrawable">@drawable/item_background_borderless_material_dark</item>
<item name="floatingToolbarItemBackgroundDrawable">@drawable/item_background_material_dark</item>
<item name="floatingToolbarOpenDrawable">@drawable/ic_menu_moreoverflow_material_dark</item>
- <item name="floatingToolbarPopupBackgroundDrawable">@drawable/floating_popup_background_dark</item>
<item name="floatingToolbarDividerColor">@color/floating_popup_divider_dark</item>
<!-- SearchView attributes -->
@@ -579,11 +577,9 @@
<!-- Floating toolbar styles -->
<item name="floatingToolbarCloseDrawable">@drawable/ic_ab_back_material_light</item>
- <item name="floatingToolbarForegroundColor">@color/foreground_material_light</item>
<item name="floatingToolbarItemBackgroundBorderlessDrawable">@drawable/item_background_borderless_material_light</item>
<item name="floatingToolbarItemBackgroundDrawable">@drawable/item_background_material_light</item>
<item name="floatingToolbarOpenDrawable">@drawable/ic_menu_moreoverflow_material_light</item>
- <item name="floatingToolbarPopupBackgroundDrawable">@drawable/floating_popup_background_light</item>
<item name="floatingToolbarDividerColor">@color/floating_popup_divider_light</item>
<!-- Tooltip popup colors -->
diff --git a/core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java b/core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java
index d4482f2..b0190a5 100644
--- a/core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java
+++ b/core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java
@@ -112,7 +112,7 @@
doReturn(mApplicationInfo).when(mContext).getApplicationInfo();
mDispatcher = new WindowOnBackInvokedDispatcher(mContext, Looper.getMainLooper());
- mDispatcher.attachToWindow(mWindowSession, mWindow, null, mImeBackAnimationController);
+ mDispatcher.attachToWindow(mWindowSession, mWindow, mImeBackAnimationController);
}
private void waitForIdle() {
@@ -455,26 +455,25 @@
@Test
public void registerImeCallbacks_onBackInvokedCallbackEnabled() throws RemoteException {
- verifyImeCallackRegistrations();
- }
-
- @Test
- public void registerImeCallbacks_onBackInvokedCallbackDisabled() throws RemoteException {
- doReturn(false).when(mApplicationInfo).isOnBackInvokedCallbackEnabled();
- verifyImeCallackRegistrations();
- }
-
- private void verifyImeCallackRegistrations() throws RemoteException {
- // verify default callback is replaced with ImeBackAnimationController
- mDispatcher.registerOnBackInvokedCallbackUnchecked(mDefaultImeCallback, PRIORITY_DEFAULT);
+ mDispatcher.registerOnBackInvokedCallback(PRIORITY_DEFAULT, mDefaultImeCallback);
assertCallbacksSize(/* default */ 1, /* overlay */ 0);
assertSetCallbackInfo();
assertTopCallback(mImeBackAnimationController);
- // verify regular ime callback is successfully registered
- mDispatcher.registerOnBackInvokedCallbackUnchecked(mImeCallback, PRIORITY_DEFAULT);
+ mDispatcher.registerOnBackInvokedCallback(PRIORITY_DEFAULT, mImeCallback);
assertCallbacksSize(/* default */ 2, /* overlay */ 0);
assertSetCallbackInfo();
assertTopCallback(mImeCallback);
}
+
+ @Test
+ public void registerImeCallbacks_legacyBack() throws RemoteException {
+ doReturn(false).when(mApplicationInfo).isOnBackInvokedCallbackEnabled();
+
+ mDispatcher.registerOnBackInvokedCallback(PRIORITY_DEFAULT, mDefaultImeCallback);
+ assertNoSetCallbackInfo();
+
+ mDispatcher.registerOnBackInvokedCallback(PRIORITY_DEFAULT, mImeCallback);
+ assertNoSetCallbackInfo();
+ }
}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/DividerPresenter.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/DividerPresenter.java
index d92d24d..94c281f 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/DividerPresenter.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/DividerPresenter.java
@@ -685,46 +685,53 @@
? taskBounds.width() - mProperties.mDividerWidthPx
: taskBounds.height() - mProperties.mDividerWidthPx;
- if (isDraggingToFullscreenAllowed(mProperties.mDividerAttributes)) {
- final float displayDensity = getDisplayDensity();
- return dividerPositionWithDraggingToFullscreenAllowed(
- dividerPosition,
- minPosition,
- maxPosition,
- fullyExpandedPosition,
- velocity,
- displayDensity);
- }
- return Math.clamp(dividerPosition, minPosition, maxPosition);
+ final float displayDensity = getDisplayDensity();
+ final boolean isDraggingToFullscreenAllowed =
+ isDraggingToFullscreenAllowed(mProperties.mDividerAttributes);
+ return dividerPositionWithPositionOptions(
+ dividerPosition,
+ minPosition,
+ maxPosition,
+ fullyExpandedPosition,
+ velocity,
+ displayDensity,
+ isDraggingToFullscreenAllowed);
}
/**
- * Returns the divider position given a set of position options. A snap algorithm is used to
- * adjust the ending position to either fully expand one container or move the divider back to
- * the specified min/max ratio depending on the dragging velocity.
+ * Returns the divider position given a set of position options. A snap algorithm can adjust
+ * the ending position to either fully expand one container or move the divider back to
+ * the specified min/max ratio depending on the dragging velocity and if dragging to fullscreen
+ * is allowed.
*/
@VisibleForTesting
- static int dividerPositionWithDraggingToFullscreenAllowed(int dividerPosition, int minPosition,
- int maxPosition, int fullyExpandedPosition, float velocity, float displayDensity) {
- final float minDismissVelocityPxPerSecond =
- MIN_DISMISS_VELOCITY_DP_PER_SECOND * displayDensity;
+ static int dividerPositionWithPositionOptions(int dividerPosition, int minPosition,
+ int maxPosition, int fullyExpandedPosition, float velocity, float displayDensity,
+ boolean isDraggingToFullscreenAllowed) {
+ if (isDraggingToFullscreenAllowed) {
+ final float minDismissVelocityPxPerSecond =
+ MIN_DISMISS_VELOCITY_DP_PER_SECOND * displayDensity;
+ if (dividerPosition < minPosition && velocity < -minDismissVelocityPxPerSecond) {
+ return 0;
+ }
+ if (dividerPosition > maxPosition && velocity > minDismissVelocityPxPerSecond) {
+ return fullyExpandedPosition;
+ }
+ }
final float minFlingVelocityPxPerSecond =
MIN_FLING_VELOCITY_DP_PER_SECOND * displayDensity;
- if (dividerPosition < minPosition && velocity < -minDismissVelocityPxPerSecond) {
- return 0;
+ if (Math.abs(velocity) >= minFlingVelocityPxPerSecond) {
+ return dividerPositionForFling(
+ dividerPosition, minPosition, maxPosition, velocity);
}
- if (dividerPosition > maxPosition && velocity > minDismissVelocityPxPerSecond) {
- return fullyExpandedPosition;
+ if (dividerPosition >= minPosition && dividerPosition <= maxPosition) {
+ return dividerPosition;
}
- if (Math.abs(velocity) < minFlingVelocityPxPerSecond) {
- if (dividerPosition >= minPosition && dividerPosition <= maxPosition) {
- return dividerPosition;
- }
- final int[] snapPositions = {0, minPosition, maxPosition, fullyExpandedPosition};
- return snap(dividerPosition, snapPositions);
- }
- return dividerPositionForFling(
- dividerPosition, minPosition, maxPosition, velocity);
+ return snap(
+ dividerPosition,
+ isDraggingToFullscreenAllowed
+ ? new int[] {0, minPosition, maxPosition, fullyExpandedPosition}
+ : new int[] {minPosition, maxPosition});
}
/**
diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/DividerPresenterTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/DividerPresenterTest.java
index af3c4da..4f51815 100644
--- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/DividerPresenterTest.java
+++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/DividerPresenterTest.java
@@ -660,108 +660,241 @@
// Divider position is less than minPosition and the velocity is enough to be dismissed
assertEquals(
0, // Closed position
- DividerPresenter.dividerPositionWithDraggingToFullscreenAllowed(
+ DividerPresenter.dividerPositionWithPositionOptions(
10 /* dividerPosition */,
30 /* minPosition */,
900 /* maxPosition */,
1200 /* fullyExpandedPosition */,
-dismissVelocity,
- displayDensity));
+ displayDensity,
+ true /* isDraggingToFullscreenAllowed */));
// Divider position is greater than maxPosition and the velocity is enough to be dismissed
assertEquals(
1200, // Fully expanded position
- DividerPresenter.dividerPositionWithDraggingToFullscreenAllowed(
+ DividerPresenter.dividerPositionWithPositionOptions(
1000 /* dividerPosition */,
30 /* minPosition */,
900 /* maxPosition */,
1200 /* fullyExpandedPosition */,
dismissVelocity,
- displayDensity));
+ displayDensity,
+ true /* isDraggingToFullscreenAllowed */));
// Divider position is returned when the velocity is not fast enough for fling and is in
// between minPosition and maxPosition
assertEquals(
500, // dividerPosition is not snapped
- DividerPresenter.dividerPositionWithDraggingToFullscreenAllowed(
+ DividerPresenter.dividerPositionWithPositionOptions(
500 /* dividerPosition */,
30 /* minPosition */,
900 /* maxPosition */,
1200 /* fullyExpandedPosition */,
nonFlingVelocity,
- displayDensity));
+ displayDensity,
+ true /* isDraggingToFullscreenAllowed */));
// Divider position is snapped when the velocity is not fast enough for fling and larger
// than maxPosition
assertEquals(
900, // Closest position is maxPosition
- DividerPresenter.dividerPositionWithDraggingToFullscreenAllowed(
+ DividerPresenter.dividerPositionWithPositionOptions(
950 /* dividerPosition */,
30 /* minPosition */,
900 /* maxPosition */,
1200 /* fullyExpandedPosition */,
nonFlingVelocity,
- displayDensity));
+ displayDensity,
+ true /* isDraggingToFullscreenAllowed */));
// Divider position is snapped when the velocity is not fast enough for fling and smaller
// than minPosition
assertEquals(
30, // Closest position is minPosition
- DividerPresenter.dividerPositionWithDraggingToFullscreenAllowed(
+ DividerPresenter.dividerPositionWithPositionOptions(
20 /* dividerPosition */,
30 /* minPosition */,
900 /* maxPosition */,
1200 /* fullyExpandedPosition */,
nonFlingVelocity,
- displayDensity));
+ displayDensity,
+ true /* isDraggingToFullscreenAllowed */));
// Divider position is in the closed to maxPosition bounds and the velocity is enough for
// backward fling
assertEquals(
2000, // maxPosition
- DividerPresenter.dividerPositionWithDraggingToFullscreenAllowed(
+ DividerPresenter.dividerPositionWithPositionOptions(
2200 /* dividerPosition */,
1000 /* minPosition */,
2000 /* maxPosition */,
2500 /* fullyExpandedPosition */,
-flingVelocity,
- displayDensity));
+ displayDensity,
+ true /* isDraggingToFullscreenAllowed */));
// Divider position is not in the closed to maxPosition bounds and the velocity is enough
// for backward fling
assertEquals(
1000, // minPosition
- DividerPresenter.dividerPositionWithDraggingToFullscreenAllowed(
+ DividerPresenter.dividerPositionWithPositionOptions(
1200 /* dividerPosition */,
1000 /* minPosition */,
2000 /* maxPosition */,
2500 /* fullyExpandedPosition */,
-flingVelocity,
- displayDensity));
+ displayDensity,
+ true /* isDraggingToFullscreenAllowed */));
// Divider position is in the closed to minPosition bounds and the velocity is enough for
// forward fling
assertEquals(
1000, // minPosition
- DividerPresenter.dividerPositionWithDraggingToFullscreenAllowed(
+ DividerPresenter.dividerPositionWithPositionOptions(
500 /* dividerPosition */,
1000 /* minPosition */,
2000 /* maxPosition */,
2500 /* fullyExpandedPosition */,
flingVelocity,
- displayDensity));
+ displayDensity,
+ true /* isDraggingToFullscreenAllowed */));
// Divider position is not in the closed to minPosition bounds and the velocity is enough
// for forward fling
assertEquals(
2000, // maxPosition
- DividerPresenter.dividerPositionWithDraggingToFullscreenAllowed(
+ DividerPresenter.dividerPositionWithPositionOptions(
1200 /* dividerPosition */,
1000 /* minPosition */,
2000 /* maxPosition */,
2500 /* fullyExpandedPosition */,
flingVelocity,
- displayDensity));
+ displayDensity,
+ true /* isDraggingToFullscreenAllowed */));
+ }
+
+ @Test
+ public void testDividerPositionWithDraggingToFullscreenNotAllowed() {
+ final float displayDensity = 600F;
+ final float nonFlingVelocity = MIN_FLING_VELOCITY_DP_PER_SECOND * displayDensity - 10f;
+ final float flingVelocity = MIN_FLING_VELOCITY_DP_PER_SECOND * displayDensity + 10f;
+
+ // Divider position is returned when the velocity is not fast enough for fling and is in
+ // between minPosition and maxPosition
+ assertEquals(
+ 500, // dividerPosition is not snapped
+ DividerPresenter.dividerPositionWithPositionOptions(
+ 500 /* dividerPosition */,
+ 30 /* minPosition */,
+ 900 /* maxPosition */,
+ 1200 /* fullyExpandedPosition */,
+ nonFlingVelocity,
+ displayDensity,
+ false /* isDraggingToFullscreenAllowed */));
+
+ // Divider position is snapped when the velocity is not fast enough for fling and larger
+ // than maxPosition
+ assertEquals(
+ 900, // Closest position is maxPosition
+ DividerPresenter.dividerPositionWithPositionOptions(
+ 950 /* dividerPosition */,
+ 30 /* minPosition */,
+ 900 /* maxPosition */,
+ 1200 /* fullyExpandedPosition */,
+ nonFlingVelocity,
+ displayDensity,
+ false /* isDraggingToFullscreenAllowed */));
+
+ // Divider position is snapped when the velocity is not fast enough for fling and smaller
+ // than minPosition
+ assertEquals(
+ 30, // Closest position is minPosition
+ DividerPresenter.dividerPositionWithPositionOptions(
+ 20 /* dividerPosition */,
+ 30 /* minPosition */,
+ 900 /* maxPosition */,
+ 1200 /* fullyExpandedPosition */,
+ nonFlingVelocity,
+ displayDensity,
+ false /* isDraggingToFullscreenAllowed */));
+
+ // Divider position is snapped when the velocity is not fast enough for fling and at the
+ // closed position
+ assertEquals(
+ 30, // Closest position is minPosition
+ DividerPresenter.dividerPositionWithPositionOptions(
+ 0 /* dividerPosition */,
+ 30 /* minPosition */,
+ 900 /* maxPosition */,
+ 1200 /* fullyExpandedPosition */,
+ nonFlingVelocity,
+ displayDensity,
+ false /* isDraggingToFullscreenAllowed */));
+
+ // Divider position is snapped when the velocity is not fast enough for fling and at the
+ // fully expanded position
+ assertEquals(
+ 900, // Closest position is maxPosition
+ DividerPresenter.dividerPositionWithPositionOptions(
+ 1200 /* dividerPosition */,
+ 30 /* minPosition */,
+ 900 /* maxPosition */,
+ 1200 /* fullyExpandedPosition */,
+ nonFlingVelocity,
+ displayDensity,
+ false /* isDraggingToFullscreenAllowed */));
+
+ // Divider position is in the closed to maxPosition bounds and the velocity is enough for
+ // backward fling
+ assertEquals(
+ 2000, // maxPosition
+ DividerPresenter.dividerPositionWithPositionOptions(
+ 2200 /* dividerPosition */,
+ 1000 /* minPosition */,
+ 2000 /* maxPosition */,
+ 2500 /* fullyExpandedPosition */,
+ -flingVelocity,
+ displayDensity,
+ false /* isDraggingToFullscreenAllowed */));
+
+ // Divider position is not in the closed to maxPosition bounds and the velocity is enough
+ // for backward fling
+ assertEquals(
+ 1000, // minPosition
+ DividerPresenter.dividerPositionWithPositionOptions(
+ 1200 /* dividerPosition */,
+ 1000 /* minPosition */,
+ 2000 /* maxPosition */,
+ 2500 /* fullyExpandedPosition */,
+ -flingVelocity,
+ displayDensity,
+ false /* isDraggingToFullscreenAllowed */));
+
+ // Divider position is in the closed to minPosition bounds and the velocity is enough for
+ // forward fling
+ assertEquals(
+ 1000, // minPosition
+ DividerPresenter.dividerPositionWithPositionOptions(
+ 500 /* dividerPosition */,
+ 1000 /* minPosition */,
+ 2000 /* maxPosition */,
+ 2500 /* fullyExpandedPosition */,
+ flingVelocity,
+ displayDensity,
+ false /* isDraggingToFullscreenAllowed */));
+
+ // Divider position is not in the closed to minPosition bounds and the velocity is enough
+ // for forward fling
+ assertEquals(
+ 2000, // maxPosition
+ DividerPresenter.dividerPositionWithPositionOptions(
+ 1200 /* dividerPosition */,
+ 1000 /* minPosition */,
+ 2000 /* maxPosition */,
+ 2500 /* fullyExpandedPosition */,
+ flingVelocity,
+ displayDensity,
+ false /* isDraggingToFullscreenAllowed */));
}
private TaskFragmentContainer createMockTaskFragmentContainer(
diff --git a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubbleStackViewTest.kt b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubbleStackViewTest.kt
index 0efdbdc..327e205 100644
--- a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubbleStackViewTest.kt
+++ b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubbleStackViewTest.kt
@@ -456,5 +456,7 @@
override fun isStackExpanded(): Boolean = false
override fun isShowingAsBubbleBar(): Boolean = false
+
+ override fun hideCurrentInputMethod() {}
}
}
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 4a1da4d..6449073 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
@@ -592,11 +592,12 @@
* Hides the current input method, wherever it may be focused, via InputMethodManagerInternal.
*/
void hideCurrentInputMethod() {
+ mBubblePositioner.setImeVisible(false /* visible */, 0 /* height */);
int displayId = mWindowManager.getDefaultDisplay().getDisplayId();
try {
mBarService.hideCurrentInputMethodForBubbles(displayId);
} catch (RemoteException e) {
- e.printStackTrace();
+ Log.e(TAG, "Failed to hide IME", e);
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedViewManager.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedViewManager.kt
index b0d3cc4..3d9bf03 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedViewManager.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedViewManager.kt
@@ -29,6 +29,7 @@
fun setAppBubbleTaskId(key: String, taskId: Int)
fun isStackExpanded(): Boolean
fun isShowingAsBubbleBar(): Boolean
+ fun hideCurrentInputMethod()
companion object {
/**
@@ -73,6 +74,10 @@
override fun isStackExpanded(): Boolean = controller.isStackExpanded
override fun isShowingAsBubbleBar(): Boolean = controller.isShowingAsBubbleBar
+
+ override fun hideCurrentInputMethod() {
+ controller.hideCurrentInputMethod()
+ }
}
}
}
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 fac9bf6..ed904e2 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
@@ -2324,7 +2324,6 @@
* not.
*/
void hideCurrentInputMethod() {
- mPositioner.setImeVisible(false, 0);
mManager.hideCurrentInputMethod();
}
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 271fb9a..a7da07d 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
@@ -82,6 +82,7 @@
private static final int INVALID_TASK_ID = -1;
private BubbleExpandedViewManager mManager;
+ private BubblePositioner mPositioner;
private boolean mIsOverflow;
private BubbleTaskViewHelper mBubbleTaskViewHelper;
private BubbleBarMenuViewController mMenuViewController;
@@ -160,6 +161,7 @@
boolean isOverflow,
@Nullable BubbleTaskView bubbleTaskView) {
mManager = expandedViewManager;
+ mPositioner = positioner;
mIsOverflow = isOverflow;
if (mIsOverflow) {
@@ -290,15 +292,27 @@
}
/**
- * Hides the current modal menu view or collapses the bubble stack.
- * Called from {@link BubbleBarLayerView}
+ * Hides the current modal menu if it is visible
+ * @return {@code true} if menu was visible and is hidden
*/
- public void hideMenuOrCollapse() {
+ public boolean hideMenuIfVisible() {
if (mMenuViewController.isMenuVisible()) {
- mMenuViewController.hideMenu(/* animated = */ true);
- } else {
- mManager.collapseStack();
+ mMenuViewController.hideMenu(true /* animated */);
+ return true;
}
+ return false;
+ }
+
+ /**
+ * Hides the IME if it is visible
+ * @return {@code true} if IME was visible
+ */
+ public boolean hideImeIfVisible() {
+ if (mPositioner.isImeVisible()) {
+ mManager.hideCurrentInputMethod();
+ return true;
+ }
+ return false;
}
/** Updates the bubble shown in the expanded 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 123cc7e..badc409 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
@@ -132,7 +132,7 @@
}
});
- setOnClickListener(view -> hideMenuOrCollapse());
+ setOnClickListener(view -> hideModalOrCollapse());
}
@Override
@@ -217,7 +217,7 @@
@Override
public void onBackPressed() {
- hideMenuOrCollapse();
+ hideModalOrCollapse();
}
});
@@ -344,15 +344,23 @@
addView(mDismissView);
}
- /** Hides the current modal education/menu view, expanded view or collapses the bubble stack */
- private void hideMenuOrCollapse() {
+ /** Hides the current modal education/menu view, IME or collapses the expanded view */
+ private void hideModalOrCollapse() {
if (mEducationViewController.isEducationVisible()) {
mEducationViewController.hideEducation(/* animated = */ true);
- } else if (isExpanded() && mExpandedView != null) {
- mExpandedView.hideMenuOrCollapse();
- } else {
- mBubbleController.collapseStack();
+ return;
}
+ if (isExpanded() && mExpandedView != null) {
+ boolean menuHidden = mExpandedView.hideMenuIfVisible();
+ if (menuHidden) {
+ return;
+ }
+ boolean imeHidden = mExpandedView.hideImeIfVisible();
+ if (imeHidden) {
+ return;
+ }
+ }
+ mBubbleController.collapseStack();
}
/** Updates the expanded view size and position. */
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 e1657f9..04dd0ef 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
@@ -603,6 +603,8 @@
// the end of the enter animation and reschedule exitPip to run after enter-PiP
// has finished its transition and allowed the client to draw in PiP mode.
mPipTransitionController.end(() -> {
+ // TODO(341627042): force set to entered state to avoid potential stack overflow.
+ mPipTransitionState.setTransitionState(PipTransitionState.ENTERED_PIP);
exitPip(animationDurationMs, requestEnterSplit);
});
return;
diff --git a/libs/hwui/jni/Graphics.cpp b/libs/hwui/jni/Graphics.cpp
index 07e97f8..a88139d 100644
--- a/libs/hwui/jni/Graphics.cpp
+++ b/libs/hwui/jni/Graphics.cpp
@@ -583,6 +583,16 @@
transferParams.a, transferParams.b, transferParams.c, transferParams.d,
transferParams.e, transferParams.f, transferParams.g);
+ // Some transfer functions that are considered valid by Skia are not
+ // accepted by android.graphics.
+ if (hasException(env)) {
+ // Callers (e.g. Bitmap#getColorSpace) are not expected to throw an
+ // Exception, so clear it and return null, which is a documented
+ // possibility.
+ env->ExceptionClear();
+ return nullptr;
+ }
+
jfloatArray xyzArray = env->NewFloatArray(9);
jfloat xyz[9] = {
xyzMatrix.vals[0][0],
diff --git a/media/java/android/media/IMediaRouterService.aidl b/media/java/android/media/IMediaRouterService.aidl
index efbf8da..eeb4853 100644
--- a/media/java/android/media/IMediaRouterService.aidl
+++ b/media/java/android/media/IMediaRouterService.aidl
@@ -52,6 +52,7 @@
// Methods for MediaRouter2
List<MediaRoute2Info> getSystemRoutes(String callerPackageName, boolean isProxyRouter);
RoutingSessionInfo getSystemSessionInfo();
+ boolean showMediaOutputSwitcherWithRouter2(String packageName);
void registerRouter2(IMediaRouter2 router, String packageName);
void unregisterRouter2(IMediaRouter2 router);
@@ -97,5 +98,5 @@
void setSessionVolumeWithManager(IMediaRouter2Manager manager, int requestId,
String sessionId, int volume);
void releaseSessionWithManager(IMediaRouter2Manager manager, int requestId, String sessionId);
- boolean showMediaOutputSwitcher(String packageName);
+ boolean showMediaOutputSwitcherWithProxyRouter(IMediaRouter2Manager manager);
}
diff --git a/media/java/android/media/MediaRouter2.java b/media/java/android/media/MediaRouter2.java
index 5672cd5..0667bfd 100644
--- a/media/java/android/media/MediaRouter2.java
+++ b/media/java/android/media/MediaRouter2.java
@@ -2666,8 +2666,11 @@
@Override
public boolean showSystemOutputSwitcher() {
- throw new UnsupportedOperationException(
- "Cannot show system output switcher from a privileged router.");
+ try {
+ return mMediaRouterService.showMediaOutputSwitcherWithProxyRouter(mClient);
+ } catch (RemoteException ex) {
+ throw ex.rethrowFromSystemServer();
+ }
}
/** Gets the list of all discovered routes. */
@@ -3539,7 +3542,7 @@
public boolean showSystemOutputSwitcher() {
synchronized (mLock) {
try {
- return mMediaRouterService.showMediaOutputSwitcher(mImpl.getPackageName());
+ return mMediaRouterService.showMediaOutputSwitcherWithRouter2(mPackageName);
} catch (RemoteException ex) {
ex.rethrowFromSystemServer();
}
diff --git a/native/android/performance_hint.cpp b/native/android/performance_hint.cpp
index 02d72ad..44fa677 100644
--- a/native/android/performance_hint.cpp
+++ b/native/android/performance_hint.cpp
@@ -51,6 +51,9 @@
constexpr int64_t SEND_HINT_TIMEOUT = std::chrono::nanoseconds(100ms).count();
struct AWorkDuration : public hal::WorkDuration {};
+// Shared lock for the whole PerformanceHintManager and sessions
+static std::mutex sHintMutex = std::mutex{};
+
struct APerformanceHintManager {
public:
static APerformanceHintManager* getInstance();
@@ -192,6 +195,7 @@
}
auto out = new APerformanceHintSession(mHintManager, std::move(session), mPreferredRateNanos,
initialTargetWorkDurationNanos, sessionConfig);
+ std::scoped_lock lock(sHintMutex);
out->traceThreads(tids);
out->traceTargetDuration(initialTargetWorkDurationNanos);
out->tracePowerEfficient(false);
@@ -219,6 +223,7 @@
if (sessionConfig->id > INT32_MAX) {
ALOGE("Session ID too large, must fit 32-bit integer");
}
+ std::scoped_lock lock(sHintMutex);
constexpr int numEnums =
ndk::enum_range<hal::SessionHint>().end() - ndk::enum_range<hal::SessionHint>().begin();
mLastHintSentTimestamp = std::vector<int64_t>(numEnums, 0);
@@ -244,6 +249,7 @@
ret.getMessage());
return EPIPE;
}
+ std::scoped_lock lock(sHintMutex);
mTargetDurationNanos = targetDurationNanos;
/**
* Most of the workload is target_duration dependent, so now clear the cached samples
@@ -267,6 +273,7 @@
}
int APerformanceHintSession::sendHint(SessionHint hint) {
+ std::scoped_lock lock(sHintMutex);
if (hint < 0 || hint >= static_cast<int32_t>(mLastHintSentTimestamp.size())) {
ALOGE("%s: invalid session hint %d", __FUNCTION__, hint);
return EINVAL;
@@ -305,6 +312,7 @@
return EPIPE;
}
+ std::scoped_lock lock(sHintMutex);
traceThreads(tids);
return 0;
@@ -343,6 +351,7 @@
ret.getMessage());
return EPIPE;
}
+ std::scoped_lock lock(sHintMutex);
tracePowerEfficient(enabled);
return OK;
}
@@ -355,6 +364,7 @@
int64_t actualTotalDurationNanos = workDuration->durationNanos;
int64_t now = uptimeNanos();
workDuration->timeStampNanos = now;
+ std::scoped_lock lock(sHintMutex);
traceActualDuration(workDuration->durationNanos);
mActualWorkDurations.push_back(std::move(*workDuration));
diff --git a/packages/SettingsLib/res/values/arrays.xml b/packages/SettingsLib/res/values/arrays.xml
index 38ad560..5a4d3ce 100644
--- a/packages/SettingsLib/res/values/arrays.xml
+++ b/packages/SettingsLib/res/values/arrays.xml
@@ -494,6 +494,26 @@
<item>show_deuteranomaly</item>
</string-array>
+ <!-- Titles for app process limit preference. [CHAR LIMIT=35] -->
+ <string-array name="app_process_limit_entries">
+ <item>Standard limit</item>
+ <item>No background processes</item>
+ <item>At most 1 process</item>
+ <item>At most 2 processes</item>
+ <item>At most 3 processes</item>
+ <item>At most 4 processes</item>
+ </string-array>
+
+ <!-- Values for app process limit preference. -->
+ <string-array name="app_process_limit_values" translatable="false" >
+ <item>-1</item>
+ <item>0</item>
+ <item>1</item>
+ <item>2</item>
+ <item>3</item>
+ <item>4</item>
+ </string-array>
+
<!-- USB configuration names for Developer Settings.
This can be overridden by devices with additional USB configurations. -->
<string-array name="usb_configuration_titles">
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index 927aa69..363045e 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -975,6 +975,9 @@
<string name="immediately_destroy_activities_summary">Destroy every activity as soon as
the user leaves it</string>
+ <!-- UI debug setting: limit number of running background processes [CHAR LIMIT=25] -->
+ <string name="app_process_limit_title">Background process limit</string>
+
<!-- UI debug setting: show all ANRs? [CHAR LIMIT=25] -->
<string name="show_all_anrs">Show background ANRs</string>
<!-- UI debug setting: show all ANRs summary [CHAR LIMIT=100] -->
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/DeviceIconUtil.java b/packages/SettingsLib/src/com/android/settingslib/media/DeviceIconUtil.java
index 3de4933..f3ff0fe 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/DeviceIconUtil.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/DeviceIconUtil.java
@@ -16,135 +16,124 @@
package com.android.settingslib.media;
+import static android.media.AudioDeviceInfo.AudioDeviceType;
+import static android.media.AudioDeviceInfo.TYPE_BUILTIN_SPEAKER;
+import static android.media.AudioDeviceInfo.TYPE_DOCK;
+import static android.media.AudioDeviceInfo.TYPE_HDMI;
+import static android.media.AudioDeviceInfo.TYPE_HDMI_ARC;
+import static android.media.AudioDeviceInfo.TYPE_HDMI_EARC;
+import static android.media.AudioDeviceInfo.TYPE_USB_ACCESSORY;
+import static android.media.AudioDeviceInfo.TYPE_USB_DEVICE;
+import static android.media.AudioDeviceInfo.TYPE_USB_HEADSET;
+import static android.media.AudioDeviceInfo.TYPE_WIRED_HEADPHONES;
+import static android.media.AudioDeviceInfo.TYPE_WIRED_HEADSET;
+
import android.annotation.DrawableRes;
+import android.annotation.SuppressLint;
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
-import android.media.AudioDeviceInfo;
import android.media.MediaRoute2Info;
+import android.util.SparseIntArray;
+import androidx.annotation.NonNull;
+
+import com.android.internal.annotations.VisibleForTesting;
import com.android.settingslib.R;
import com.android.settingslib.media.flags.Flags;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.Objects;
/** A util class to get the appropriate icon for different device types. */
public class DeviceIconUtil {
- // A default icon to use if the type is not present in the map.
- @DrawableRes private static final int DEFAULT_ICON = R.drawable.ic_smartphone;
- @DrawableRes private static final int DEFAULT_ICON_TV = R.drawable.ic_media_speaker_device;
-
- // A map from a @AudioDeviceInfo.AudioDeviceType to full device information.
- private final Map<Integer, Device> mAudioDeviceTypeToIconMap = new HashMap<>();
- // A map from a @MediaRoute2Info.Type to full device information.
- private final Map<Integer, Device> mMediaRouteTypeToIconMap = new HashMap<>();
+ private static final SparseIntArray AUDIO_DEVICE_TO_MEDIA_ROUTE_TYPE = new SparseIntArray();
private final boolean mIsTv;
-
- public DeviceIconUtil(Context context) {
- this(context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_LEANBACK));
+ private final Context mContext;
+ public DeviceIconUtil(@NonNull Context context) {
+ mContext = Objects.requireNonNull(context);
+ mIsTv =
+ mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_LEANBACK)
+ && Flags.enableTvMediaOutputDialog();
}
- public DeviceIconUtil(boolean isTv) {
- mIsTv = isTv && Flags.enableTvMediaOutputDialog();
- List<Device> deviceList = Arrays.asList(
- new Device(
- AudioDeviceInfo.TYPE_USB_DEVICE,
- MediaRoute2Info.TYPE_USB_DEVICE,
- R.drawable.ic_headphone),
- new Device(
- AudioDeviceInfo.TYPE_USB_HEADSET,
- MediaRoute2Info.TYPE_USB_HEADSET,
- R.drawable.ic_headphone),
- new Device(
- AudioDeviceInfo.TYPE_USB_ACCESSORY,
- MediaRoute2Info.TYPE_USB_ACCESSORY,
- mIsTv ? R.drawable.ic_usb : R.drawable.ic_headphone),
- new Device(
- AudioDeviceInfo.TYPE_DOCK,
- MediaRoute2Info.TYPE_DOCK,
- R.drawable.ic_dock_device),
- new Device(
- AudioDeviceInfo.TYPE_HDMI,
- MediaRoute2Info.TYPE_HDMI,
- mIsTv ? R.drawable.ic_tv : R.drawable.ic_external_display),
- new Device(
- AudioDeviceInfo.TYPE_HDMI_ARC,
- MediaRoute2Info.TYPE_HDMI_ARC,
- mIsTv ? R.drawable.ic_hdmi : R.drawable.ic_external_display),
- new Device(
- AudioDeviceInfo.TYPE_HDMI_EARC,
- MediaRoute2Info.TYPE_HDMI_EARC,
- mIsTv ? R.drawable.ic_hdmi : R.drawable.ic_external_display),
- new Device(
- AudioDeviceInfo.TYPE_WIRED_HEADSET,
- MediaRoute2Info.TYPE_WIRED_HEADSET,
- mIsTv ? R.drawable.ic_wired_device : R.drawable.ic_headphone),
- new Device(
- AudioDeviceInfo.TYPE_WIRED_HEADPHONES,
- MediaRoute2Info.TYPE_WIRED_HEADPHONES,
- mIsTv ? R.drawable.ic_wired_device : R.drawable.ic_headphone),
- new Device(
- AudioDeviceInfo.TYPE_BUILTIN_SPEAKER,
- MediaRoute2Info.TYPE_BUILTIN_SPEAKER,
- mIsTv ? R.drawable.ic_tv : R.drawable.ic_smartphone));
- for (int i = 0; i < deviceList.size(); i++) {
- Device device = deviceList.get(i);
- mAudioDeviceTypeToIconMap.put(device.mAudioDeviceType, device);
- mMediaRouteTypeToIconMap.put(device.mMediaRouteType, device);
- }
- }
-
- private int getDefaultIcon() {
- return mIsTv ? DEFAULT_ICON_TV : DEFAULT_ICON;
+ @VisibleForTesting
+ /* package */ DeviceIconUtil(boolean isTv) {
+ mContext = null;
+ mIsTv = isTv;
}
/** Returns a drawable for an icon representing the given audioDeviceType. */
- public Drawable getIconFromAudioDeviceType(
- @AudioDeviceInfo.AudioDeviceType int audioDeviceType, Context context) {
- return context.getDrawable(getIconResIdFromAudioDeviceType(audioDeviceType));
+ public Drawable getIconFromAudioDeviceType(@AudioDeviceType int audioDeviceType) {
+ return mContext.getDrawable(getIconResIdFromAudioDeviceType(audioDeviceType));
}
/** Returns a drawable res ID for an icon representing the given audioDeviceType. */
@DrawableRes
- public int getIconResIdFromAudioDeviceType(
- @AudioDeviceInfo.AudioDeviceType int audioDeviceType) {
- if (mAudioDeviceTypeToIconMap.containsKey(audioDeviceType)) {
- return mAudioDeviceTypeToIconMap.get(audioDeviceType).mIconDrawableRes;
- }
- return getDefaultIcon();
+ public int getIconResIdFromAudioDeviceType(@AudioDeviceType int audioDeviceType) {
+ int mediaRouteType =
+ AUDIO_DEVICE_TO_MEDIA_ROUTE_TYPE.get(audioDeviceType, /* defaultValue */ -1);
+ return getIconResIdFromMediaRouteType(mediaRouteType);
}
/** Returns a drawable res ID for an icon representing the given mediaRouteType. */
@DrawableRes
- public int getIconResIdFromMediaRouteType(
- @MediaRoute2Info.Type int mediaRouteType) {
- if (mMediaRouteTypeToIconMap.containsKey(mediaRouteType)) {
- return mMediaRouteTypeToIconMap.get(mediaRouteType).mIconDrawableRes;
- }
- return getDefaultIcon();
+ public int getIconResIdFromMediaRouteType(@MediaRoute2Info.Type int type) {
+ return mIsTv ? getIconResourceIdForTv(type) : getIconResourceIdForPhone(type);
}
- private static class Device {
- @AudioDeviceInfo.AudioDeviceType
- private final int mAudioDeviceType;
+ @SuppressLint("SwitchIntDef")
+ @DrawableRes
+ private static int getIconResourceIdForPhone(@MediaRoute2Info.Type int type) {
+ return switch (type) {
+ case MediaRoute2Info.TYPE_USB_DEVICE,
+ MediaRoute2Info.TYPE_USB_HEADSET,
+ MediaRoute2Info.TYPE_USB_ACCESSORY,
+ MediaRoute2Info.TYPE_WIRED_HEADSET,
+ MediaRoute2Info.TYPE_WIRED_HEADPHONES ->
+ R.drawable.ic_headphone;
+ case MediaRoute2Info.TYPE_DOCK -> R.drawable.ic_dock_device;
+ case MediaRoute2Info.TYPE_HDMI,
+ MediaRoute2Info.TYPE_HDMI_ARC,
+ MediaRoute2Info.TYPE_HDMI_EARC ->
+ R.drawable.ic_external_display;
+ default -> R.drawable.ic_smartphone; // Includes TYPE_BUILTIN_SPEAKER.
+ };
+ }
- @MediaRoute2Info.Type
- private final int mMediaRouteType;
+ @SuppressLint("SwitchIntDef")
+ @DrawableRes
+ private static int getIconResourceIdForTv(@MediaRoute2Info.Type int type) {
+ return switch (type) {
+ case MediaRoute2Info.TYPE_USB_DEVICE, MediaRoute2Info.TYPE_USB_HEADSET ->
+ R.drawable.ic_headphone;
+ case MediaRoute2Info.TYPE_USB_ACCESSORY -> R.drawable.ic_usb;
+ case MediaRoute2Info.TYPE_DOCK -> R.drawable.ic_dock_device;
+ case MediaRoute2Info.TYPE_HDMI, MediaRoute2Info.TYPE_BUILTIN_SPEAKER ->
+ R.drawable.ic_tv;
+ case MediaRoute2Info.TYPE_HDMI_ARC, MediaRoute2Info.TYPE_HDMI_EARC ->
+ R.drawable.ic_hdmi;
+ case MediaRoute2Info.TYPE_WIRED_HEADSET, MediaRoute2Info.TYPE_WIRED_HEADPHONES ->
+ R.drawable.ic_wired_device;
+ default -> R.drawable.ic_media_speaker_device;
+ };
+ }
- @DrawableRes
- private final int mIconDrawableRes;
-
- Device(@AudioDeviceInfo.AudioDeviceType int audioDeviceType,
- @MediaRoute2Info.Type int mediaRouteType,
- @DrawableRes int iconDrawableRes) {
- mAudioDeviceType = audioDeviceType;
- mMediaRouteType = mediaRouteType;
- mIconDrawableRes = iconDrawableRes;
- }
+ static {
+ AUDIO_DEVICE_TO_MEDIA_ROUTE_TYPE.put(TYPE_USB_DEVICE, MediaRoute2Info.TYPE_USB_DEVICE);
+ AUDIO_DEVICE_TO_MEDIA_ROUTE_TYPE.put(TYPE_USB_HEADSET, MediaRoute2Info.TYPE_USB_HEADSET);
+ AUDIO_DEVICE_TO_MEDIA_ROUTE_TYPE.put(
+ TYPE_USB_ACCESSORY, MediaRoute2Info.TYPE_USB_ACCESSORY);
+ AUDIO_DEVICE_TO_MEDIA_ROUTE_TYPE.put(TYPE_DOCK, MediaRoute2Info.TYPE_DOCK);
+ AUDIO_DEVICE_TO_MEDIA_ROUTE_TYPE.put(TYPE_HDMI, MediaRoute2Info.TYPE_HDMI);
+ AUDIO_DEVICE_TO_MEDIA_ROUTE_TYPE.put(TYPE_HDMI_ARC, MediaRoute2Info.TYPE_HDMI_ARC);
+ AUDIO_DEVICE_TO_MEDIA_ROUTE_TYPE.put(TYPE_HDMI_EARC, MediaRoute2Info.TYPE_HDMI_EARC);
+ AUDIO_DEVICE_TO_MEDIA_ROUTE_TYPE.put(
+ TYPE_WIRED_HEADSET, MediaRoute2Info.TYPE_WIRED_HEADSET);
+ AUDIO_DEVICE_TO_MEDIA_ROUTE_TYPE.put(
+ TYPE_WIRED_HEADPHONES, MediaRoute2Info.TYPE_WIRED_HEADPHONES);
+ AUDIO_DEVICE_TO_MEDIA_ROUTE_TYPE.put(
+ TYPE_BUILTIN_SPEAKER, MediaRoute2Info.TYPE_BUILTIN_SPEAKER);
}
}
diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp
index c2c334b..1e79bb7 100644
--- a/packages/SystemUI/Android.bp
+++ b/packages/SystemUI/Android.bp
@@ -78,10 +78,50 @@
visibility: ["//visibility:private"],
}
+// Tests where robolectric conversion caused errors in SystemUITests at runtime
+filegroup {
+ name: "SystemUI-tests-broken-robofiles-sysui-run",
+ srcs: [
+ "tests/src/**/systemui/broadcast/BroadcastDispatcherTest.kt",
+ "tests/src/**/systemui/broadcast/ActionReceiverTest.kt",
+ "tests/src/**/systemui/doze/DozeMachineTest.java",
+ "tests/src/**/systemui/globalactions/GlobalActionsDialogLiteTest.java",
+ "tests/src/**/systemui/globalactions/GlobalActionsImeTest.java",
+ "tests/src/**/systemui/keyguard/data/repository/KeyguardTransitionRepositoryTest.kt",
+ "tests/src/**/systemui/media/controls/domain/pipeline/LegacyMediaDataManagerImplTest.kt",
+ "tests/src/**/systemui/media/controls/domain/pipeline/MediaDataProcessorTest.kt",
+ "tests/src/**/systemui/media/dialog/MediaOutputAdapterTest.java",
+ "tests/src/**/systemui/media/dialog/MediaOutputBaseDialogTest.java",
+ "tests/src/**/systemui/media/dialog/MediaOutputBroadcastDialogTest.java",
+ "tests/src/**/systemui/media/dialog/MediaOutputDialogTest.java",
+ "tests/src/**/systemui/mediaprojection/permission/MediaProjectionPermissionDialogDelegateTest.kt",
+ ],
+}
+
// Tests where robolectric failed at runtime. (go/multivalent-tests)
filegroup {
name: "SystemUI-tests-broken-robofiles-run",
srcs: [
+ "tests/src/**/systemui/accessibility/AccessibilityButtonModeObserverTest.java",
+ "tests/src/**/systemui/accessibility/AccessibilityButtonTargetsObserverTest.java",
+ "tests/src/**/systemui/accessibility/FullscreenMagnificationControllerTest.java",
+ "tests/src/**/systemui/accessibility/WindowMagnificationAnimationControllerTest.java",
+ "tests/src/**/systemui/animation/FontInterpolatorTest.kt",
+ "tests/src/**/systemui/animation/TextAnimatorTest.kt",
+ "tests/src/**/systemui/animation/TextInterpolatorTest.kt",
+ "tests/src/**/systemui/animation/ActivityTransitionAnimatorTest.kt",
+ "tests/src/**/systemui/animation/AnimatorTestRuleOrderTest.kt",
+ "tests/src/**/systemui/animation/DialogTransitionAnimatorTest.kt",
+ "tests/src/**/systemui/broadcast/ActionReceiverTest.kt",
+ "tests/src/**/systemui/broadcast/BroadcastDispatcherTest.kt",
+ "tests/src/**/systemui/compose/ComposeInitializerTest.kt",
+ "tests/src/**/systemui/controls/ui/ControlsActivityTest.kt",
+ "tests/src/**/systemui/controls/management/ControlsEditingActivityTest.kt",
+ "tests/src/**/systemui/controls/management/ControlsRequestDialogTest.kt",
+ "tests/src/**/systemui/controls/ui/DetailDialogTest.kt",
+ "tests/src/**/systemui/doze/DozeMachineTest.kt",
+ "tests/src/**/systemui/fontscaling/FontScalingDialogDelegateTest.kt",
+ "tests/src/**/systemui/keyguard/CustomizationProviderTest.kt",
"tests/src/**/systemui/globalactions/GlobalActionsColumnLayoutTest.java",
"tests/src/**/systemui/globalactions/GlobalActionsDialogLiteTest.java",
"tests/src/**/systemui/globalactions/GlobalActionsImeTest.java",
@@ -176,9 +216,7 @@
],
}
-// We are running robolectric tests in the tests directory as well as
-// multivalent tests. If you add a test, and it doesn't run in robolectric,
-// it should be added to this exclusion list. go/multivalent-tests
+// Tests where robolectric failed at compile time. (go/multivalent-tests)
filegroup {
name: "SystemUI-tests-broken-robofiles-compile",
srcs: [
@@ -811,6 +849,7 @@
exclude_srcs: [
":SystemUI-tests-broken-robofiles-compile",
":SystemUI-tests-broken-robofiles-run",
+ ":SystemUI-tests-broken-robofiles-sysui-run",
],
static_libs: [
"RoboTestLibraries",
diff --git a/packages/SystemUI/aconfig/communal.aconfig b/packages/SystemUI/aconfig/communal.aconfig
index 2e9af7e..afcd8a9 100644
--- a/packages/SystemUI/aconfig/communal.aconfig
+++ b/packages/SystemUI/aconfig/communal.aconfig
@@ -7,3 +7,13 @@
description: "Enables the communal hub experience"
bug: "304584416"
}
+
+flag {
+ name: "enable_widget_picker_size_filter"
+ namespace: "communal"
+ description: "Enables passing a size filter to the widget picker"
+ bug: "345482907"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
diff --git a/packages/SystemUI/aconfig/systemui.aconfig b/packages/SystemUI/aconfig/systemui.aconfig
index 4311e79..29b57c9 100644
--- a/packages/SystemUI/aconfig/systemui.aconfig
+++ b/packages/SystemUI/aconfig/systemui.aconfig
@@ -1039,6 +1039,16 @@
}
flag {
+ name: "glanceable_hub_animate_timer_activity_starts"
+ namespace: "systemui"
+ description: "Properly animates activity starts from live timers on the glanceable hub"
+ bug: "345741071"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
+
+flag {
name: "new_touchpad_gestures_tutorial"
namespace: "systemui"
description: "Enables new interactive tutorial for learning touchpad gestures"
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContainer.kt b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContainer.kt
index c329384..a1f8f1b 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContainer.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContainer.kt
@@ -1,6 +1,6 @@
package com.android.systemui.communal.ui.compose
-import androidx.compose.animation.core.LinearEasing
+import androidx.compose.animation.core.CubicBezierEasing
import androidx.compose.animation.core.RepeatMode
import androidx.compose.animation.core.animateFloat
import androidx.compose.animation.core.infiniteRepeatable
@@ -20,20 +20,18 @@
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
-import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import androidx.compose.ui.composed
import androidx.compose.ui.draw.alpha
+import androidx.compose.ui.draw.drawBehind
import androidx.compose.ui.geometry.Offset
+import androidx.compose.ui.graphics.BlendMode
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.layout.onGloballyPositioned
+import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.res.dimensionResource
-import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.android.compose.animation.scene.CommunalSwipeDetector
@@ -217,6 +215,7 @@
CommunalBackgroundType.DEFAULT -> DefaultBackground(colors = colors)
CommunalBackgroundType.STATIC_GRADIENT -> StaticLinearGradient()
CommunalBackgroundType.ANIMATED -> AnimatedLinearGradient()
+ CommunalBackgroundType.NONE -> BackgroundTopScrim()
}
}
with(content) { Content(modifier = modifier) }
@@ -252,7 +251,8 @@
val colors = LocalAndroidColorScheme.current
Box(
Modifier.matchParentSize()
- .animatedGradientBackground(colors = listOf(colors.primary, colors.primaryContainer))
+ .background(colors.primary)
+ .animatedRadialGradientBackground(colors.primary, colors.primaryContainer)
)
BackgroundTopScrim()
}
@@ -265,29 +265,76 @@
Box(Modifier.matchParentSize().alpha(0.34f).background(scrimOnTopColor))
}
-/** Modifier which sets the background of a composable to an animated gradient */
+/** The duration to use for the gradient background animation. */
+private const val ANIMATION_DURATION_MS = 10_000
+
+/** The offset to use in order to place the center of each gradient offscreen. */
+private val ANIMATION_OFFSCREEN_OFFSET = 128.dp
+
+/** Modifier which creates two radial gradients that animate up and down. */
@Composable
-private fun Modifier.animatedGradientBackground(colors: List<Color>): Modifier = composed {
- var size by remember { mutableStateOf(IntSize.Zero) }
- val transition = rememberInfiniteTransition(label = "scrim background")
- val startOffsetX by
- transition.animateFloat(
- initialValue = -size.width.toFloat(),
- targetValue = size.width.toFloat(),
+fun Modifier.animatedRadialGradientBackground(toColor: Color, fromColor: Color): Modifier {
+ val density = LocalDensity.current
+ val infiniteTransition = rememberInfiniteTransition(label = "radial gradient transition")
+ val centerFraction by
+ infiniteTransition.animateFloat(
+ initialValue = 0f,
+ targetValue = 1f,
animationSpec =
infiniteRepeatable(
- animation = tween(durationMillis = 5_000, easing = LinearEasing),
- repeatMode = RepeatMode.Reverse,
+ animation =
+ tween(
+ durationMillis = ANIMATION_DURATION_MS,
+ easing = CubicBezierEasing(0.33f, 0f, 0.67f, 1f),
+ ),
+ repeatMode = RepeatMode.Reverse
),
- label = "scrim start offset"
+ label = "radial gradient center fraction"
)
- background(
+
+ // Offset to place the center of the gradients offscreen. This is applied to both the
+ // x and y coordinates.
+ val offsetPx = remember(density) { with(density) { ANIMATION_OFFSCREEN_OFFSET.toPx() } }
+
+ return drawBehind {
+ val gradientRadius = (size.width / 2) + offsetPx
+ val totalHeight = size.height + 2 * offsetPx
+
+ val leftCenter =
+ Offset(
+ x = -offsetPx,
+ y = totalHeight * centerFraction - offsetPx,
+ )
+ val rightCenter =
+ Offset(
+ x = offsetPx + size.width,
+ y = totalHeight * (1f - centerFraction) - offsetPx,
+ )
+
+ // Right gradient
+ drawCircle(
brush =
- Brush.linearGradient(
- colors = colors,
- start = Offset(startOffsetX, 0f),
- end = Offset(startOffsetX + size.width.toFloat(), size.height.toFloat()),
- )
+ Brush.radialGradient(
+ colors = listOf(fromColor, toColor),
+ center = rightCenter,
+ radius = gradientRadius
+ ),
+ center = rightCenter,
+ radius = gradientRadius,
+ blendMode = BlendMode.SrcAtop,
)
- .onGloballyPositioned { size = it.size }
+
+ // Left gradient
+ drawCircle(
+ brush =
+ Brush.radialGradient(
+ colors = listOf(fromColor, toColor),
+ center = leftCenter,
+ radius = gradientRadius
+ ),
+ center = leftCenter,
+ radius = gradientRadius,
+ blendMode = BlendMode.SrcAtop,
+ )
+ }
}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContent.kt b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContent.kt
index 77665155..60b6f62 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContent.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContent.kt
@@ -24,6 +24,7 @@
import com.android.compose.animation.scene.SceneScope
import com.android.compose.theme.LocalAndroidColorScheme
import com.android.systemui.communal.ui.viewmodel.CommunalViewModel
+import com.android.systemui.communal.widgets.WidgetInteractionHandler
import com.android.systemui.keyguard.ui.composable.blueprint.BlueprintAlignmentLines
import com.android.systemui.keyguard.ui.composable.section.LockSection
import com.android.systemui.statusbar.phone.SystemUIDialogFactory
@@ -34,6 +35,7 @@
@Inject
constructor(
private val viewModel: CommunalViewModel,
+ private val interactionHandler: WidgetInteractionHandler,
private val dialogFactory: SystemUIDialogFactory,
private val lockSection: LockSection,
) {
@@ -45,6 +47,7 @@
content = {
CommunalHub(
viewModel = viewModel,
+ interactionHandler = interactionHandler,
dialogFactory = dialogFactory,
modifier = Modifier.element(Communal.Elements.Grid)
)
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt
index 1f7f07b..eccb072 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt
@@ -16,13 +16,13 @@
package com.android.systemui.communal.ui.compose
-import android.appwidget.AppWidgetHostView
import android.graphics.drawable.Icon
import android.os.Bundle
import android.util.SizeF
import android.view.View.IMPORTANT_FOR_ACCESSIBILITY_AUTO
import android.view.View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS
import android.widget.FrameLayout
+import android.widget.RemoteViews
import androidx.annotation.VisibleForTesting
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.AnimatedVisibilityScope
@@ -132,6 +132,7 @@
import com.android.compose.theme.LocalAndroidColorScheme
import com.android.compose.ui.graphics.painter.rememberDrawablePainter
import com.android.internal.R.dimen.system_app_widget_background_radius
+import com.android.systemui.Flags.glanceableHubAnimateTimerActivityStarts
import com.android.systemui.communal.domain.model.CommunalContentModel
import com.android.systemui.communal.shared.model.CommunalContentSize
import com.android.systemui.communal.shared.model.CommunalScenes
@@ -144,6 +145,7 @@
import com.android.systemui.communal.ui.viewmodel.CommunalEditModeViewModel
import com.android.systemui.communal.ui.viewmodel.CommunalViewModel
import com.android.systemui.communal.ui.viewmodel.PopupType
+import com.android.systemui.communal.widgets.SmartspaceAppWidgetHostView
import com.android.systemui.communal.widgets.WidgetConfigurator
import com.android.systemui.res.R
import com.android.systemui.statusbar.phone.SystemUIDialogFactory
@@ -154,6 +156,7 @@
fun CommunalHub(
modifier: Modifier = Modifier,
viewModel: BaseCommunalViewModel,
+ interactionHandler: RemoteViews.InteractionHandler? = null,
dialogFactory: SystemUIDialogFactory? = null,
widgetConfigurator: WidgetConfigurator? = null,
onOpenWidgetPicker: (() -> Unit)? = null,
@@ -262,6 +265,7 @@
contentListState = contentListState,
selectedKey = selectedKey,
widgetConfigurator = widgetConfigurator,
+ interactionHandler = interactionHandler,
)
}
}
@@ -391,6 +395,7 @@
setGridCoordinates: (coordinates: LayoutCoordinates) -> Unit,
updateDragPositionForRemove: (offset: Offset) -> Boolean,
widgetConfigurator: WidgetConfigurator?,
+ interactionHandler: RemoteViews.InteractionHandler?,
) {
var gridModifier =
Modifier.align(Alignment.TopStart).onGloballyPositioned { setGridCoordinates(it) }
@@ -468,7 +473,8 @@
selected = selected && !isDragging,
widgetConfigurator = widgetConfigurator,
index = index,
- contentListState = contentListState
+ contentListState = contentListState,
+ interactionHandler = interactionHandler,
)
}
} else {
@@ -479,7 +485,8 @@
size = size,
selected = false,
index = index,
- contentListState = contentListState
+ contentListState = contentListState,
+ interactionHandler = interactionHandler,
)
}
}
@@ -759,6 +766,7 @@
widgetConfigurator: WidgetConfigurator? = null,
index: Int,
contentListState: ContentListState,
+ interactionHandler: RemoteViews.InteractionHandler?,
) {
when (model) {
is CommunalContentModel.WidgetContent.Widget ->
@@ -778,7 +786,7 @@
is CommunalContentModel.WidgetContent.PendingWidget ->
PendingWidgetPlaceholder(model, modifier)
is CommunalContentModel.CtaTileInViewMode -> CtaTileInViewModeContent(viewModel, modifier)
- is CommunalContentModel.Smartspace -> SmartspaceContent(model, modifier)
+ is CommunalContentModel.Smartspace -> SmartspaceContent(interactionHandler, model, modifier)
is CommunalContentModel.Tutorial -> TutorialContent(modifier)
is CommunalContentModel.Umo -> Umo(viewModel, modifier)
}
@@ -1091,13 +1099,19 @@
@Composable
private fun SmartspaceContent(
+ interactionHandler: RemoteViews.InteractionHandler?,
model: CommunalContentModel.Smartspace,
modifier: Modifier = Modifier,
) {
AndroidView(
modifier = modifier,
factory = { context ->
- AppWidgetHostView(context).apply { updateAppWidget(model.remoteViews) }
+ SmartspaceAppWidgetHostView(context).apply {
+ if (glanceableHubAnimateTimerActivityStarts()) {
+ interactionHandler?.let { setInteractionHandler(it) }
+ }
+ updateAppWidget(model.remoteViews)
+ }
},
// For reusing composition in lazy lists.
onReset = {},
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalScene.kt
index 9e905ac..94018bb 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalScene.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalScene.kt
@@ -24,6 +24,7 @@
import com.android.compose.animation.scene.UserAction
import com.android.compose.animation.scene.UserActionResult
import com.android.systemui.communal.ui.viewmodel.CommunalViewModel
+import com.android.systemui.communal.widgets.WidgetInteractionHandler
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.scene.ui.composable.ComposableScene
@@ -40,6 +41,7 @@
constructor(
private val viewModel: CommunalViewModel,
private val dialogFactory: SystemUIDialogFactory,
+ private val interactionHandler: WidgetInteractionHandler,
) : ComposableScene {
override val key = Scenes.Communal
@@ -53,6 +55,6 @@
@Composable
override fun SceneScope.Content(modifier: Modifier) {
- CommunalHub(modifier, viewModel, dialogFactory)
+ CommunalHub(modifier, viewModel, interactionHandler, dialogFactory)
}
}
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/AnimateToScene.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/AnimateToScene.kt
index 48a348b..c2dd803 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/AnimateToScene.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/AnimateToScene.kt
@@ -109,8 +109,7 @@
layoutState.transitions.interruptionHandler.onInterruption(
transitionState,
target,
- )
- ?: DefaultInterruptionHandler.onInterruption(transitionState, target)
+ ) ?: DefaultInterruptionHandler.onInterruption(transitionState, target)
val animateFrom = interruptionResult.animateFrom
if (
@@ -159,6 +158,7 @@
val transition =
if (reversed) {
OneOffTransition(
+ key = transitionKey,
fromScene = targetScene,
toScene = fromScene,
currentScene = targetScene,
@@ -167,6 +167,7 @@
)
} else {
OneOffTransition(
+ key = transitionKey,
fromScene = fromScene,
toScene = targetScene,
currentScene = targetScene,
@@ -178,7 +179,7 @@
// Change the current layout state to start this new transition. This will compute the
// TransformationSpec associated to this transition, which we need to initialize the Animatable
// that will actually animate it.
- layoutState.startTransition(transition, transitionKey, chain)
+ layoutState.startTransition(transition, chain)
// The transition now contains the transformation spec that we should use to instantiate the
// Animatable.
@@ -207,6 +208,7 @@
}
private class OneOffTransition(
+ override val key: TransitionKey?,
fromScene: SceneKey,
toScene: SceneKey,
override val currentScene: SceneKey,
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/DraggableHandler.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/DraggableHandler.kt
index e9633c2..60d78fe 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/DraggableHandler.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/DraggableHandler.kt
@@ -257,7 +257,7 @@
fun updateTransition(newTransition: SwipeTransition, force: Boolean = false) {
if (isDrivingTransition || force) {
- layoutState.startTransition(newTransition, newTransition.key)
+ layoutState.startTransition(newTransition)
}
swipeTransition = newTransition
@@ -555,7 +555,7 @@
val layoutImpl: SceneTransitionLayoutImpl,
val layoutState: BaseSceneTransitionLayoutState,
val coroutineScope: CoroutineScope,
- val key: TransitionKey?,
+ override val key: TransitionKey?,
val _fromScene: Scene,
val _toScene: Scene,
val userActionDistanceScope: UserActionDistanceScope,
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Element.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Element.kt
index edf8943..980982a 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Element.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Element.kt
@@ -280,7 +280,7 @@
constraints: Constraints,
): MeasureResult {
val transitions = currentTransitions
- val transition = elementTransition(element, transitions)
+ val transition = elementTransition(layoutImpl, element, transitions)
// If this element is not supposed to be laid out now, either because it is not part of any
// ongoing transition or the other scene of its transition is overscrolling, then lay out
@@ -318,13 +318,10 @@
val targetOffsetInScene = lookaheadScopeCoordinates.localLookaheadPositionOf(coords)
// No need to place the element in this scene if we don't want to draw it anyways.
- if (!shouldPlaceElement(layoutImpl, scene, element, transition)) {
+ if (!shouldPlaceElement(layoutImpl, scene.key, element, transition)) {
sceneState.lastOffset = Offset.Unspecified
sceneState.lastScale = Scale.Unspecified
sceneState.lastAlpha = Element.AlphaUnspecified
-
- sceneState.clearValuesBeforeInterruption()
- sceneState.clearInterruptionDeltas()
return
}
@@ -353,7 +350,17 @@
getValueBeforeInterruption = { sceneState.offsetBeforeInterruption },
setValueBeforeInterruption = { sceneState.offsetBeforeInterruption = it },
getInterruptionDelta = { sceneState.offsetInterruptionDelta },
- setInterruptionDelta = { sceneState.offsetInterruptionDelta = it },
+ setInterruptionDelta = { delta ->
+ setPlacementInterruptionDelta(
+ element = element,
+ sceneState = sceneState,
+ transition = transition,
+ delta = delta,
+ setter = { sceneState, delta ->
+ sceneState.offsetInterruptionDelta = delta
+ },
+ )
+ },
diff = { a, b -> a - b },
add = { a, b, bProgress -> a + b * bProgress },
)
@@ -363,7 +370,7 @@
val offset = (interruptedOffset - currentOffset).round()
if (
isElementOpaque(scene, element, transition) &&
- interruptedAlpha(layoutImpl, transition, sceneState, alpha = 1f) == 1f
+ interruptedAlpha(layoutImpl, element, transition, sceneState, alpha = 1f) == 1f
) {
sceneState.lastAlpha = 1f
@@ -374,13 +381,17 @@
} else {
placeable.placeWithLayer(offset) {
// This layer might still run on its own (outside of the placement phase) even
- // if this element is not placed anymore, so we need to double check again here
- // before calling [elementAlpha] (which will update [SceneState.lastAlpha]). We
- // also need to recompute the current transition to make sure that we are using
- // the current transition and not a reference to an old one. See b/343138966 for
- // details.
- val transition = elementTransition(element, currentTransitions)
- if (!shouldPlaceElement(layoutImpl, scene, element, transition)) {
+ // if this element is not placed or composed anymore, so we need to double check
+ // again here before calling [elementAlpha] (which will update
+ // [SceneState.lastAlpha]). We also need to recompute the current transition to
+ // make sure that we are using the current transition and not a reference to an
+ // old one. See b/343138966 for details.
+ if (_element == null) {
+ return@placeWithLayer
+ }
+
+ val transition = elementTransition(layoutImpl, element, currentTransitions)
+ if (!shouldPlaceElement(layoutImpl, scene.key, element, transition)) {
return@placeWithLayer
}
@@ -394,7 +405,7 @@
override fun ContentDrawScope.draw() {
element.wasDrawnInAnyScene = true
- val transition = elementTransition(element, currentTransitions)
+ val transition = elementTransition(layoutImpl, element, currentTransitions)
val drawScale = getDrawScale(layoutImpl, scene, element, transition, sceneState)
if (drawScale == Scale.Default) {
drawContent()
@@ -435,6 +446,7 @@
* its scenes contains the element.
*/
private fun elementTransition(
+ layoutImpl: SceneTransitionLayoutImpl,
element: Element,
transitions: List<TransitionState.Transition>,
): TransitionState.Transition? {
@@ -448,7 +460,7 @@
if (transition != previousTransition && transition != null && previousTransition != null) {
// The previous transition was interrupted by another transition.
- prepareInterruption(element, transition, previousTransition)
+ prepareInterruption(layoutImpl, element, transition, previousTransition)
} else if (transition == null && previousTransition != null) {
// The transition was just finished.
element.sceneStates.values.forEach {
@@ -461,18 +473,43 @@
}
private fun prepareInterruption(
+ layoutImpl: SceneTransitionLayoutImpl,
element: Element,
transition: TransitionState.Transition,
previousTransition: TransitionState.Transition,
) {
val sceneStates = element.sceneStates
- sceneStates[previousTransition.fromScene]?.selfUpdateValuesBeforeInterruption()
- sceneStates[previousTransition.toScene]?.selfUpdateValuesBeforeInterruption()
- sceneStates[transition.fromScene]?.selfUpdateValuesBeforeInterruption()
- sceneStates[transition.toScene]?.selfUpdateValuesBeforeInterruption()
+ fun updatedSceneState(key: SceneKey): Element.SceneState? {
+ return sceneStates[key]?.also { it.selfUpdateValuesBeforeInterruption() }
+ }
+
+ val previousFromState = updatedSceneState(previousTransition.fromScene)
+ val previousToState = updatedSceneState(previousTransition.toScene)
+ val fromState = updatedSceneState(transition.fromScene)
+ val toState = updatedSceneState(transition.toScene)
reconcileStates(element, previousTransition)
reconcileStates(element, transition)
+
+ // Remove the interruption values to all scenes but the scene(s) where the element will be
+ // placed, to make sure that interruption deltas are computed only right after this interruption
+ // is prepared.
+ fun maybeCleanPlacementValuesBeforeInterruption(sceneState: Element.SceneState) {
+ if (!shouldPlaceElement(layoutImpl, sceneState.scene, element, transition)) {
+ sceneState.offsetBeforeInterruption = Offset.Unspecified
+ sceneState.alphaBeforeInterruption = Element.AlphaUnspecified
+ sceneState.scaleBeforeInterruption = Scale.Unspecified
+
+ sceneState.offsetInterruptionDelta = Offset.Zero
+ sceneState.alphaInterruptionDelta = 0f
+ sceneState.scaleInterruptionDelta = Scale.Zero
+ }
+ }
+
+ previousFromState?.let { maybeCleanPlacementValuesBeforeInterruption(it) }
+ previousToState?.let { maybeCleanPlacementValuesBeforeInterruption(it) }
+ fromState?.let { maybeCleanPlacementValuesBeforeInterruption(it) }
+ toState?.let { maybeCleanPlacementValuesBeforeInterruption(it) }
}
/**
@@ -579,9 +616,38 @@
}
}
+/**
+ * Set the interruption delta of a *placement/drawing*-related value (offset, alpha, scale). This
+ * ensures that the delta is also set on the other scene in the transition for shared elements, so
+ * that there is no jump cut if the scene where the element is placed has changed.
+ */
+private inline fun <T> setPlacementInterruptionDelta(
+ element: Element,
+ sceneState: Element.SceneState,
+ transition: TransitionState.Transition?,
+ delta: T,
+ setter: (Element.SceneState, T) -> Unit,
+) {
+ // Set the interruption delta on the current scene.
+ setter(sceneState, delta)
+
+ if (transition == null) {
+ return
+ }
+
+ // If the element is shared, also set the delta on the other scene so that it is used by that
+ // scene if we start overscrolling it and change the scene where the element is placed.
+ val otherScene =
+ if (sceneState.scene == transition.fromScene) transition.toScene else transition.fromScene
+ val otherSceneState = element.sceneStates[otherScene] ?: return
+ if (isSharedElementEnabled(element.key, transition)) {
+ setter(otherSceneState, delta)
+ }
+}
+
private fun shouldPlaceElement(
layoutImpl: SceneTransitionLayoutImpl,
- scene: Scene,
+ scene: SceneKey,
element: Element,
transition: TransitionState.Transition?,
): Boolean {
@@ -592,7 +658,7 @@
// Don't place the element in this scene if this scene is not part of the current element
// transition.
- if (scene.key != transition.fromScene && scene.key != transition.toScene) {
+ if (scene != transition.fromScene && scene != transition.toScene) {
return false
}
@@ -610,7 +676,7 @@
return shouldPlaceOrComposeSharedElement(
layoutImpl,
- scene.key,
+ scene,
element.key,
transition,
)
@@ -740,13 +806,14 @@
element.sceneStates.forEach { it.value.alphaBeforeInterruption = 0f }
}
- val interruptedAlpha = interruptedAlpha(layoutImpl, transition, sceneState, alpha)
+ val interruptedAlpha = interruptedAlpha(layoutImpl, element, transition, sceneState, alpha)
sceneState.lastAlpha = interruptedAlpha
return interruptedAlpha
}
private fun interruptedAlpha(
layoutImpl: SceneTransitionLayoutImpl,
+ element: Element,
transition: TransitionState.Transition?,
sceneState: Element.SceneState,
alpha: Float,
@@ -760,7 +827,15 @@
getValueBeforeInterruption = { sceneState.alphaBeforeInterruption },
setValueBeforeInterruption = { sceneState.alphaBeforeInterruption = it },
getInterruptionDelta = { sceneState.alphaInterruptionDelta },
- setInterruptionDelta = { sceneState.alphaInterruptionDelta = it },
+ setInterruptionDelta = { delta ->
+ setPlacementInterruptionDelta(
+ element = element,
+ sceneState = sceneState,
+ transition = transition,
+ delta = delta,
+ setter = { sceneState, delta -> sceneState.alphaInterruptionDelta = delta },
+ )
+ },
diff = { a, b -> a - b },
add = { a, b, bProgress -> a + b * bProgress },
)
@@ -867,7 +942,15 @@
getValueBeforeInterruption = { sceneState.scaleBeforeInterruption },
setValueBeforeInterruption = { sceneState.scaleBeforeInterruption = it },
getInterruptionDelta = { sceneState.scaleInterruptionDelta },
- setInterruptionDelta = { sceneState.scaleInterruptionDelta = it },
+ setInterruptionDelta = { delta ->
+ setPlacementInterruptionDelta(
+ element = element,
+ sceneState = sceneState,
+ transition = transition,
+ delta = delta,
+ setter = { sceneState, delta -> sceneState.scaleInterruptionDelta = delta },
+ )
+ },
diff = { a, b ->
Scale(
scaleX = a.scaleX - b.scaleX,
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutState.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutState.kt
index 44affd9..6a178c8 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutState.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutState.kt
@@ -226,6 +226,12 @@
val toScene: SceneKey,
) : TransitionState {
/**
+ * The key of this transition. This should usually be null, but it can be specified to use a
+ * specific set of transformations associated to this transition.
+ */
+ open val key: TransitionKey? = null
+
+ /**
* The progress of the transition. This is usually in the `[0; 1]` range, but it can also be
* less than `0` or greater than `1` when using transitions with a spring AnimationSpec or
* when flinging quickly during a swipe gesture.
@@ -455,11 +461,7 @@
*
* Important: you *must* call [finishTransition] once the transition is finished.
*/
- internal fun startTransition(
- transition: TransitionState.Transition,
- transitionKey: TransitionKey? = null,
- chain: Boolean = true,
- ) {
+ internal fun startTransition(transition: TransitionState.Transition, chain: Boolean = true) {
checkThread()
// Compute the [TransformationSpec] when the transition starts.
@@ -469,7 +471,9 @@
// Update the transition specs.
transition.transformationSpec =
- transitions.transitionSpec(fromScene, toScene, key = transitionKey).transformationSpec()
+ transitions
+ .transitionSpec(fromScene, toScene, key = transition.key)
+ .transformationSpec()
if (orientation != null) {
transition.updateOverscrollSpecs(
fromSpec = transitions.overscrollSpec(fromScene, orientation),
@@ -568,9 +572,10 @@
originalTransition = transitionState,
fromScene = targetCurrentScene,
toScene = matchingLink.targetTo,
+ key = matchingLink.targetTransitionKey,
)
- stateLink.target.startTransition(linkedTransition, matchingLink.targetTransitionKey)
+ stateLink.target.startTransition(linkedTransition)
activeTransitionLinks[stateLink] = linkedTransition
}
}
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transition/link/LinkedTransition.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transition/link/LinkedTransition.kt
index 79f126d..ed98885 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transition/link/LinkedTransition.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/transition/link/LinkedTransition.kt
@@ -17,6 +17,7 @@
package com.android.compose.animation.scene.transition.link
import com.android.compose.animation.scene.SceneKey
+import com.android.compose.animation.scene.TransitionKey
import com.android.compose.animation.scene.TransitionState
import kotlinx.coroutines.Job
@@ -25,6 +26,7 @@
private val originalTransition: TransitionState.Transition,
fromScene: SceneKey,
toScene: SceneKey,
+ override val key: TransitionKey? = null,
) : TransitionState.Transition(fromScene, toScene) {
override val currentScene: SceneKey
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/ElementTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/ElementTest.kt
index 47c9b9c..41cacb4 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/ElementTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/ElementTest.kt
@@ -47,7 +47,6 @@
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.layout.approachLayout
import androidx.compose.ui.platform.LocalViewConfiguration
-import androidx.compose.ui.platform.testTag
import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.assertIsNotDisplayed
import androidx.compose.ui.test.assertPositionInRootIsEqualTo
@@ -639,10 +638,7 @@
// Change the current transition.
rule.runOnUiThread {
- state.startTransition(
- transition(from = SceneA, to = SceneB, progress = { 0.5f }),
- transitionKey = null,
- )
+ state.startTransition(transition(from = SceneA, to = SceneB, progress = { 0.5f }))
}
// The size of Foo should still be 20dp given that the new state was not composed yet.
@@ -1171,7 +1167,7 @@
val offsetInAToB = lerp(offsetInA, offsetInB, aToBProgress)
val sizeInAToB = lerp(sizeInA, sizeInB, aToBProgress)
val valueInAToB = lerp(valueInA, valueInB, aToBProgress)
- rule.runOnUiThread { state.startTransition(aToB, transitionKey = null) }
+ rule.runOnUiThread { state.startTransition(aToB) }
rule
.onNode(isElement(TestElements.Foo, SceneB))
.assertSizeIsEqualTo(sizeInAToB)
@@ -1191,7 +1187,7 @@
progress = { bToCProgress },
interruptionProgress = { interruptionProgress },
)
- rule.runOnUiThread { state.startTransition(bToC, transitionKey = null) }
+ rule.runOnUiThread { state.startTransition(bToC) }
// The interruption deltas, which will be multiplied by the interruption progress then added
// to the current transition offset and size.
@@ -1333,9 +1329,9 @@
interruptionProgress = { bToCInterruptionProgress },
onFinish = neverFinish(),
)
- rule.runOnUiThread { state.startTransition(aToB, transitionKey = null) }
+ rule.runOnUiThread { state.startTransition(aToB) }
rule.waitForIdle()
- rule.runOnUiThread { state.startTransition(bToC, transitionKey = null) }
+ rule.runOnUiThread { state.startTransition(bToC) }
// Foo is placed in both B and C given that the shared transition is disabled. In B, its
// offset is impacted by the interruption but in C it is not.
@@ -1371,7 +1367,7 @@
progress = { 0.7f },
interruptionProgress = { 1f },
)
- rule.runOnUiThread { state.startTransition(bToA, transitionKey = null) }
+ rule.runOnUiThread { state.startTransition(bToA) }
// Foo should have the position it had in B right before the interruption.
rule
@@ -1395,8 +1391,7 @@
to = SceneB,
progress = { -1f },
orientation = Orientation.Horizontal
- ),
- transitionKey = null,
+ )
)
}
}
@@ -1513,8 +1508,7 @@
to = SceneB,
progress = { 0.6f },
interruptionProgress = { interruptionProgress },
- ),
- transitionKey = null
+ )
)
}
rule.waitForIdle()
@@ -1632,4 +1626,97 @@
rule.onNode(hasText(fooInA)).assertIsDisplayed()
rule.onNode(hasText(fooInB)).assertDoesNotExist()
}
+
+ @Test
+ fun interruptionThenOverscroll() = runTest {
+ val state =
+ rule.runOnUiThread {
+ MutableSceneTransitionLayoutStateImpl(
+ SceneA,
+ transitions {
+ overscroll(SceneB, Orientation.Vertical) {
+ translate(TestElements.Foo, y = 15.dp)
+ }
+ }
+ )
+ }
+
+ @Composable
+ fun SceneScope.SceneWithFoo(offset: DpOffset, modifier: Modifier = Modifier) {
+ Box(modifier.fillMaxSize()) {
+ Box(Modifier.offset(offset.x, offset.y).element(TestElements.Foo).size(100.dp))
+ }
+ }
+
+ rule.setContent {
+ SceneTransitionLayout(state, Modifier.size(200.dp)) {
+ scene(SceneA) { SceneWithFoo(offset = DpOffset.Zero) }
+ scene(SceneB) { SceneWithFoo(offset = DpOffset(x = 40.dp, y = 0.dp)) }
+ scene(SceneC) { SceneWithFoo(offset = DpOffset(x = 40.dp, y = 40.dp)) }
+ }
+ }
+
+ // Start A => B at 75%.
+ rule.runOnUiThread {
+ state.startTransition(
+ transition(
+ from = SceneA,
+ to = SceneB,
+ progress = { 0.75f },
+ onFinish = neverFinish(),
+ )
+ )
+ }
+
+ // Foo should be at offset (30dp, 0dp) and placed in scene B.
+ rule.onNode(isElement(TestElements.Foo, SceneA)).assertIsNotDisplayed()
+ rule.onNode(isElement(TestElements.Foo, SceneB)).assertPositionInRootIsEqualTo(30.dp, 0.dp)
+ rule.onNode(isElement(TestElements.Foo, SceneC)).assertIsNotDisplayed()
+
+ // Interrupt A => B with B => C at 0%.
+ var progress by mutableStateOf(0f)
+ var interruptionProgress by mutableStateOf(1f)
+ rule.runOnUiThread {
+ state.startTransition(
+ transition(
+ from = SceneB,
+ to = SceneC,
+ progress = { progress },
+ interruptionProgress = { interruptionProgress },
+ orientation = Orientation.Vertical,
+ onFinish = neverFinish(),
+ )
+ )
+ }
+
+ // Because interruption progress is at 100M, Foo should still be at offset (30dp, 0dp) but
+ // placed in scene C.
+ rule.onNode(isElement(TestElements.Foo, SceneA)).assertIsNotDisplayed()
+ rule.onNode(isElement(TestElements.Foo, SceneB)).assertIsNotDisplayed()
+ rule.onNode(isElement(TestElements.Foo, SceneC)).assertPositionInRootIsEqualTo(30.dp, 0.dp)
+
+ // Overscroll B => C on scene B at -100%. Because overscrolling on B => C translates Foo
+ // vertically by -15dp and that interruptionProgress is still 100%, we should now be at
+ // (30dp, -15dp)
+ progress = -1f
+ rule.onNode(isElement(TestElements.Foo, SceneA)).assertIsNotDisplayed()
+ rule
+ .onNode(isElement(TestElements.Foo, SceneB))
+ .assertPositionInRootIsEqualTo(30.dp, -15.dp)
+ rule.onNode(isElement(TestElements.Foo, SceneC)).assertIsNotDisplayed()
+
+ // Finish the interruption, we should now be at (40dp, -15dp), still on scene B.
+ interruptionProgress = 0f
+ rule.onNode(isElement(TestElements.Foo, SceneA)).assertIsNotDisplayed()
+ rule
+ .onNode(isElement(TestElements.Foo, SceneB))
+ .assertPositionInRootIsEqualTo(40.dp, -15.dp)
+ rule.onNode(isElement(TestElements.Foo, SceneC)).assertIsNotDisplayed()
+
+ // Finish the transition, we should be at the final position (40dp, 40dp) on scene C.
+ progress = 1f
+ rule.onNode(isElement(TestElements.Foo, SceneA)).assertIsNotDisplayed()
+ rule.onNode(isElement(TestElements.Foo, SceneB)).assertIsNotDisplayed()
+ rule.onNode(isElement(TestElements.Foo, SceneC)).assertPositionInRootIsEqualTo(40.dp, 40.dp)
+ }
}
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/InterruptionHandlerTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/InterruptionHandlerTest.kt
index 85d4165..09d1a82 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/InterruptionHandlerTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/InterruptionHandlerTest.kt
@@ -40,7 +40,7 @@
val state =
MutableSceneTransitionLayoutState(
SceneA,
- transitions { /* default interruption handler */},
+ transitions { /* default interruption handler */ },
)
state.setTargetScene(SceneB, coroutineScope = this)
@@ -160,7 +160,7 @@
progressVelocity = { progressVelocity },
onFinish = { launch {} },
)
- state.startTransition(aToB, transitionKey = null)
+ state.startTransition(aToB)
// Animate back to A. The previous transition is reversed, i.e. it has the same (from, to)
// pair, and its velocity is used when animating the progress back to 0.
@@ -186,7 +186,7 @@
progressVelocity = { progressVelocity },
onFinish = { launch {} },
)
- state.startTransition(aToB, transitionKey = null)
+ state.startTransition(aToB)
// Animate to B. The previous transition is reversed, i.e. it has the same (from, to) pair,
// and its velocity is used when animating the progress to 1.
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/ObservableTransitionStateTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/ObservableTransitionStateTest.kt
index 2a75e13..5543135 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/ObservableTransitionStateTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/ObservableTransitionStateTest.kt
@@ -135,7 +135,7 @@
var transitionCurrentScene by mutableStateOf(SceneA)
val transition =
transition(from = SceneA, to = SceneB, current = { transitionCurrentScene })
- state.startTransition(transition, transitionKey = null)
+ state.startTransition(transition)
assertThat(currentScene.value).isEqualTo(SceneA)
// Change the transition current scene.
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneTransitionLayoutStateTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneTransitionLayoutStateTest.kt
index d2c8bd6..de6f1cc 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneTransitionLayoutStateTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneTransitionLayoutStateTest.kt
@@ -57,7 +57,7 @@
@Test
fun isTransitioningTo_transition() {
val state = MutableSceneTransitionLayoutStateImpl(SceneA, SceneTransitions.Empty)
- state.startTransition(transition(from = SceneA, to = SceneB), transitionKey = null)
+ state.startTransition(transition(from = SceneA, to = SceneB))
assertThat(state.isTransitioning()).isTrue()
assertThat(state.isTransitioning(from = SceneA)).isTrue()
@@ -175,7 +175,7 @@
val childTransition = transition(SceneA, SceneB)
- childState.startTransition(childTransition, null)
+ childState.startTransition(childTransition)
assertThat(childState.isTransitioning(SceneA, SceneB)).isTrue()
assertThat(parentState.isTransitioning(SceneC, SceneD)).isTrue()
@@ -211,7 +211,7 @@
val childTransition = transition(SceneA, SceneB)
- childState.startTransition(childTransition, null)
+ childState.startTransition(childTransition)
assertThat(childState.isTransitioning(SceneA, SceneB)).isTrue()
assertThat(parentState.isTransitioning(SceneC, SceneD)).isTrue()
assertThat(parentParentState.isTransitioning(SceneB, SceneC)).isTrue()
@@ -229,7 +229,7 @@
var progress = 0f
val childTransition = transition(SceneA, SceneB, progress = { progress })
- childState.startTransition(childTransition, null)
+ childState.startTransition(childTransition)
assertThat(parentState.currentTransition?.progress).isEqualTo(0f)
progress = .5f
@@ -242,7 +242,7 @@
val childTransition = transition(SceneB, SceneA)
- childState.startTransition(childTransition, null)
+ childState.startTransition(childTransition)
assertThat(childState.isTransitioning(SceneB, SceneA)).isTrue()
assertThat(parentState.transitionState).isEqualTo(TransitionState.Idle(SceneC))
@@ -256,7 +256,7 @@
val (parentState, childState) = setupLinkedStates()
val childTransition = transition(SceneA, SceneB)
- childState.startTransition(childTransition, null)
+ childState.startTransition(childTransition)
childState.finishTransition(childTransition, SceneA)
assertThat(childState.transitionState).isEqualTo(TransitionState.Idle(SceneA))
@@ -268,7 +268,7 @@
val (parentState, childState) = setupLinkedStates()
val childTransition = transition(SceneA, SceneB)
- childState.startTransition(childTransition, null)
+ childState.startTransition(childTransition)
childState.finishTransition(childTransition, SceneD)
assertThat(childState.transitionState).isEqualTo(TransitionState.Idle(SceneD))
@@ -283,16 +283,16 @@
transition(
SceneA,
SceneB,
- onFinish = { launch { /* Do nothing. */} },
+ onFinish = { launch { /* Do nothing. */ } },
)
val parentTransition =
transition(
SceneC,
SceneA,
- onFinish = { launch { /* Do nothing. */} },
+ onFinish = { launch { /* Do nothing. */ } },
)
- childState.startTransition(childTransition, null)
- parentState.startTransition(parentTransition, null)
+ childState.startTransition(childTransition)
+ parentState.startTransition(parentTransition)
childState.finishTransition(childTransition, SceneB)
assertThat(childState.transitionState).isEqualTo(TransitionState.Idle(SceneB))
@@ -341,10 +341,7 @@
@Test
fun snapToIdleIfClose_snapToStart() = runMonotonicClockTest {
val state = MutableSceneTransitionLayoutStateImpl(SceneA, SceneTransitions.Empty)
- state.startTransition(
- transition(from = SceneA, to = SceneB, progress = { 0.2f }),
- transitionKey = null
- )
+ state.startTransition(transition(from = SceneA, to = SceneB, progress = { 0.2f }))
assertThat(state.isTransitioning()).isTrue()
// Ignore the request if the progress is not close to 0 or 1, using the threshold.
@@ -360,10 +357,7 @@
@Test
fun snapToIdleIfClose_snapToEnd() = runMonotonicClockTest {
val state = MutableSceneTransitionLayoutStateImpl(SceneA, SceneTransitions.Empty)
- state.startTransition(
- transition(from = SceneA, to = SceneB, progress = { 0.8f }),
- transitionKey = null
- )
+ state.startTransition(transition(from = SceneA, to = SceneB, progress = { 0.8f }))
assertThat(state.isTransitioning()).isTrue()
// Ignore the request if the progress is not close to 0 or 1, using the threshold.
@@ -385,13 +379,13 @@
from = SceneA,
to = SceneB,
progress = { 0.5f },
- onFinish = { launch { /* do nothing */} },
+ onFinish = { launch { /* do nothing */ } },
)
- state.startTransition(aToB, transitionKey = null)
+ state.startTransition(aToB)
assertThat(state.currentTransitions).containsExactly(aToB).inOrder()
val bToC = transition(from = SceneB, to = SceneC, progress = { 0.8f })
- state.startTransition(bToC, transitionKey = null)
+ state.startTransition(bToC)
assertThat(state.currentTransitions).containsExactly(aToB, bToC).inOrder()
// Ignore the request if the progress is not close to 0 or 1, using the threshold.
@@ -409,7 +403,7 @@
val (parentState, childState) = setupLinkedStates(SceneC, SceneA, null, null, null, SceneD)
val childTransition = transition(SceneA, SceneB)
- childState.startTransition(childTransition, null)
+ childState.startTransition(childTransition)
assertThat(childState.isTransitioning(SceneA, SceneB)).isTrue()
assertThat(parentState.isTransitioning(SceneC, SceneD)).isTrue()
@@ -425,7 +419,7 @@
val childTransition = transition(SceneA, SceneB)
- childState.startTransition(childTransition, null)
+ childState.startTransition(childTransition)
assertThat(childState.isTransitioning(SceneA, SceneB)).isTrue()
assertThat(parentState.isTransitioning(SceneC, SceneD)).isTrue()
@@ -440,7 +434,7 @@
setupLinkedStates(SceneC, SceneA, SceneB, null, SceneC, SceneD)
val childTransition = transition(SceneA, SceneB)
- childState.startTransition(childTransition, null)
+ childState.startTransition(childTransition)
assertThat(childState.isTransitioning(SceneA, SceneB)).isTrue()
assertThat(parentState.isTransitioning(SceneC, SceneD)).isFalse()
}
@@ -460,8 +454,7 @@
to = SceneB,
progress = progress,
orientation = Orientation.Vertical,
- ),
- transitionKey = null
+ )
)
assertThat(state.isTransitioning()).isTrue()
return state
@@ -583,19 +576,19 @@
assertThat(state.currentTransitions).isEmpty()
// A => B.
- state.startTransition(aToB, transitionKey = null)
+ state.startTransition(aToB)
assertThat(finishingTransitions).isEmpty()
assertThat(state.finishedTransitions).isEmpty()
assertThat(state.currentTransitions).containsExactly(aToB).inOrder()
// B => C. This should automatically call finish() on aToB.
- state.startTransition(bToC, transitionKey = null)
+ state.startTransition(bToC)
assertThat(finishingTransitions).containsExactly(aToB)
assertThat(state.finishedTransitions).isEmpty()
assertThat(state.currentTransitions).containsExactly(aToB, bToC).inOrder()
// C => A. This should automatically call finish() on bToC.
- state.startTransition(cToA, transitionKey = null)
+ state.startTransition(cToA)
assertThat(finishingTransitions).containsExactly(aToB, bToC)
assertThat(state.finishedTransitions).isEmpty()
assertThat(state.currentTransitions).containsExactly(aToB, bToC, cToA).inOrder()
@@ -617,8 +610,8 @@
val state = MutableSceneTransitionLayoutStateImpl(SceneA, EmptyTestTransitions)
fun startTransition() {
- val transition = transition(SceneA, SceneB, onFinish = { launch { /* do nothing */} })
- state.startTransition(transition, transitionKey = null)
+ val transition = transition(SceneA, SceneB, onFinish = { launch { /* do nothing */ } })
+ state.startTransition(transition)
}
var hasLoggedWtf = false
diff --git a/packages/SystemUI/flag_check.py b/packages/SystemUI/flag_check.py
index 95a25c5..d78ef5a 100755
--- a/packages/SystemUI/flag_check.py
+++ b/packages/SystemUI/flag_check.py
@@ -52,7 +52,7 @@
nargs='?',
default='',
help=
- 'REPO_PATH in repo upload to determine whether the check should run for this project.')
+ 'REPO_PROJECT in repo upload to determine whether the check should run for this project.')
# Parse the arguments
args = parser.parse_args()
@@ -112,16 +112,16 @@
sys.exit(0)
-def should_run_path(path, files):
+def should_run_path(project, files):
"""Returns a boolean if this check should run with these paths.
If you want to check for a particular subdirectory under the path,
add a check here, call should_run_files and check for a specific sub dir path in should_run_files.
"""
- if not path:
+ if not project:
return False
- if path == 'frameworks/base':
+ if project == 'platform/frameworks/base':
return should_run_files(files)
- # Default case, run for all other paths which calls this script.
+ # Default case, run for all other projects which calls this script.
return True
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerWithCoroutinesTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerWithCoroutinesTest.kt
index ab55125..29a6e56 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerWithCoroutinesTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerWithCoroutinesTest.kt
@@ -235,6 +235,7 @@
job.cancel()
}
+
@Test
fun fadeFromDialogSuggestedAlpha() =
testScope.runTest {
@@ -511,9 +512,10 @@
testScope.runTest {
// GIVEN view is attached
mController.onViewAttached()
+ val job = mController.listenForLockscreenAodTransitions(this)
+ runCurrent()
Mockito.reset(mView)
- val job = mController.listenForLockscreenAodTransitions(this)
// WHEN aod to lockscreen transition is cancelled
transitionRepository.sendTransitionStep(
TransitionStep(
@@ -537,7 +539,7 @@
// THEN doze amount is updated to zero
verify(mView)
- .onDozeAmountChanged(eq(0f), eq(0f), eq(UdfpsKeyguardViewLegacy.ANIMATION_NONE))
+ .onDozeAmountChanged(eq(0f), eq(0f), eq(ANIMATION_BETWEEN_AOD_AND_LOCKSCREEN))
job.cancel()
}
@@ -546,9 +548,10 @@
testScope.runTest {
// GIVEN view is attached
mController.onViewAttached()
+ val job = mController.listenForLockscreenAodTransitions(this)
+ runCurrent()
Mockito.reset(mView)
- val job = mController.listenForLockscreenAodTransitions(this)
// WHEN lockscreen to aod transition is cancelled
transitionRepository.sendTransitionStep(
TransitionStep(
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalDreamStartableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalDreamStartableTest.kt
index bfed33c..fe683e07 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalDreamStartableTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalDreamStartableTest.kt
@@ -22,7 +22,6 @@
import androidx.test.filters.SmallTest
import com.android.systemui.Flags
import com.android.systemui.SysuiTestCase
-import com.android.systemui.communal.domain.interactor.communalInteractor
import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
import com.android.systemui.keyguard.data.repository.keyguardRepository
@@ -66,7 +65,6 @@
powerInteractor = kosmos.powerInteractor,
keyguardInteractor = kosmos.keyguardInteractor,
keyguardTransitionInteractor = kosmos.keyguardTransitionInteractor,
- communalInteractor = kosmos.communalInteractor,
dreamManager = dreamManager,
bgScope = kosmos.applicationCoroutineScope,
)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalSceneInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalSceneInteractorTest.kt
index aad2e60..a0e7781 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalSceneInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalSceneInteractorTest.kt
@@ -20,6 +20,7 @@
import androidx.test.filters.SmallTest
import com.android.compose.animation.scene.ObservableTransitionState
import com.android.systemui.SysuiTestCase
+import com.android.systemui.animation.ActivityTransitionAnimator
import com.android.systemui.communal.data.repository.communalSceneRepository
import com.android.systemui.communal.domain.model.CommunalTransitionProgressModel
import com.android.systemui.communal.shared.model.CommunalScenes
@@ -27,8 +28,10 @@
import com.android.systemui.kosmos.testScope
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.test.advanceTimeBy
import kotlinx.coroutines.test.runTest
import org.junit.Test
import org.junit.runner.RunWith
@@ -63,6 +66,21 @@
assertThat(currentScene).isEqualTo(CommunalScenes.Communal)
}
+ @OptIn(ExperimentalCoroutinesApi::class)
+ @Test
+ fun snapToSceneWithDelay() =
+ testScope.runTest {
+ val currentScene by collectLastValue(underTest.currentScene)
+ assertThat(currentScene).isEqualTo(CommunalScenes.Blank)
+ underTest.snapToScene(
+ CommunalScenes.Communal,
+ ActivityTransitionAnimator.TIMINGS.totalDuration
+ )
+ assertThat(currentScene).isEqualTo(CommunalScenes.Blank)
+ advanceTimeBy(ActivityTransitionAnimator.TIMINGS.totalDuration)
+ assertThat(currentScene).isEqualTo(CommunalScenes.Communal)
+ }
+
@Test
fun transitionProgress_fullProgress() =
testScope.runTest {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/WidgetInteractionHandlerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/WidgetInteractionHandlerTest.kt
index 420b11c..df7b291 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/WidgetInteractionHandlerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/WidgetInteractionHandlerTest.kt
@@ -27,23 +27,19 @@
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.plugins.ActivityStarter
-import com.android.systemui.util.mockito.eq
-import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import org.mockito.ArgumentMatchers.refEq
-import org.mockito.Mock
-import org.mockito.Mockito.isNull
-import org.mockito.Mockito.notNull
-import org.mockito.Mockito.verify
-import org.mockito.MockitoAnnotations
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.isNull
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.notNull
+import org.mockito.kotlin.refEq
+import org.mockito.kotlin.verify
@SmallTest
@RunWith(AndroidJUnit4::class)
class WidgetInteractionHandlerTest : SysuiTestCase() {
- @Mock private lateinit var activityStarter: ActivityStarter
-
- private lateinit var underTest: WidgetInteractionHandler
+ private val activityStarter = mock<ActivityStarter>()
private val testIntent =
PendingIntent.getActivity(
@@ -54,10 +50,8 @@
)
private val testResponse = RemoteResponse.fromPendingIntent(testIntent)
- @Before
- fun setUp() {
- MockitoAnnotations.initMocks(this)
- underTest = WidgetInteractionHandler(activityStarter)
+ private val underTest: WidgetInteractionHandler by lazy {
+ WidgetInteractionHandler(activityStarter)
}
@Test
@@ -81,6 +75,26 @@
}
@Test
+ fun launchAnimatorIsUsedForSmartspaceView() {
+ val parent = FrameLayout(context)
+ val view = SmartspaceAppWidgetHostView(context)
+ parent.addView(view)
+ val (fillInIntent, activityOptions) = testResponse.getLaunchOptions(view)
+
+ underTest.onInteraction(view, testIntent, testResponse)
+
+ verify(activityStarter)
+ .startPendingIntentMaybeDismissingKeyguard(
+ eq(testIntent),
+ eq(false),
+ isNull(),
+ notNull(),
+ refEq(fillInIntent),
+ refEq(activityOptions.toBundle()),
+ )
+ }
+
+ @Test
fun launchAnimatorIsNotUsedForRegularView() {
val parent = FrameLayout(context)
val view = View(context)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorTest.kt
index 5756bca..0f061de 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorTest.kt
@@ -125,68 +125,6 @@
}
@Test
- fun dozeAmountTransitionTest_AodToFromLockscreen() =
- testScope.runTest {
- val dozeAmountSteps by collectValues(underTest.dozeAmountTransition)
-
- val steps = mutableListOf<TransitionStep>()
-
- steps.add(TransitionStep(AOD, LOCKSCREEN, 0f, STARTED))
- steps.add(TransitionStep(AOD, LOCKSCREEN, 0.5f, RUNNING))
- steps.add(TransitionStep(AOD, LOCKSCREEN, 1f, FINISHED))
- steps.add(TransitionStep(LOCKSCREEN, AOD, 0f, STARTED))
- steps.add(TransitionStep(LOCKSCREEN, AOD, 0.8f, RUNNING))
- steps.add(TransitionStep(LOCKSCREEN, AOD, 0.9f, RUNNING))
- steps.add(TransitionStep(LOCKSCREEN, AOD, 1f, FINISHED))
-
- steps.forEach {
- repository.sendTransitionStep(it)
- runCurrent()
- }
-
- assertThat(dozeAmountSteps.subList(0, 3))
- .isEqualTo(
- listOf(
- steps[0].copy(value = 1f - steps[0].value),
- steps[1].copy(value = 1f - steps[1].value),
- steps[2].copy(value = 1f - steps[2].value),
- )
- )
- assertThat(dozeAmountSteps.subList(3, 7)).isEqualTo(steps.subList(3, 7))
- }
-
- @Test
- fun dozeAmountTransitionTest_AodToFromGone() =
- testScope.runTest {
- val dozeAmountSteps by collectValues(underTest.dozeAmountTransition)
-
- val steps = mutableListOf<TransitionStep>()
-
- steps.add(TransitionStep(AOD, GONE, 0f, STARTED))
- steps.add(TransitionStep(AOD, GONE, 0.3f, RUNNING))
- steps.add(TransitionStep(AOD, GONE, 1f, FINISHED))
- steps.add(TransitionStep(GONE, AOD, 0f, STARTED))
- steps.add(TransitionStep(GONE, AOD, 0.1f, RUNNING))
- steps.add(TransitionStep(GONE, AOD, 0.3f, RUNNING))
- steps.add(TransitionStep(GONE, AOD, 1f, FINISHED))
-
- steps.forEach {
- repository.sendTransitionStep(it)
- runCurrent()
- }
-
- assertThat(dozeAmountSteps.subList(0, 3))
- .isEqualTo(
- listOf(
- steps[0].copy(value = 1f - steps[0].value),
- steps[1].copy(value = 1f - steps[1].value),
- steps[2].copy(value = 1f - steps[2].value),
- )
- )
- assertThat(dozeAmountSteps.subList(3, 7)).isEqualTo(steps.subList(3, 7))
- }
-
- @Test
fun finishedKeyguardStateTests() =
testScope.runTest {
val finishedSteps by collectValues(underTest.finishedKeyguardState)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelTest.kt
index 49df345..194f362 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelTest.kt
@@ -39,7 +39,9 @@
import com.android.systemui.keyguard.shared.model.TransitionState
import com.android.systemui.keyguard.shared.model.TransitionStep
import com.android.systemui.kosmos.testScope
+import com.android.systemui.scene.data.repository.Idle
import com.android.systemui.scene.data.repository.sceneContainerRepository
+import com.android.systemui.scene.data.repository.setSceneTransition
import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.shade.shadeTestUtil
@@ -290,6 +292,7 @@
testScope,
)
+ kosmos.setSceneTransition(Idle(Scenes.Gone))
// Make sure the value hasn't changed since we're GONE
keyguardRepository.topClippingBounds.value = 5
assertThat(topClippingBounds).isEqualTo(1000)
@@ -518,11 +521,14 @@
to = KeyguardState.GONE,
testScope = testScope,
)
+ kosmos.setSceneTransition(Idle(Scenes.Gone))
assertThat(alpha).isEqualTo(0f)
- // Try pulling down shade and ensure the value doesn't change
- shadeTestUtil.setQsExpansion(0.5f)
- assertThat(alpha).isEqualTo(0f)
+ if (!SceneContainerFlag.isEnabled) {
+ // Try pulling down shade and ensure the value doesn't change
+ shadeTestUtil.setQsExpansion(0.5f)
+ assertThat(alpha).isEqualTo(0f)
+ }
}
@Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeSceneViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeSceneViewModelTest.kt
index 9d8ec95..6b1794e2 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeSceneViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeSceneViewModelTest.kt
@@ -30,7 +30,9 @@
import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFingerprintAuthRepository
import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus
import com.android.systemui.kosmos.testScope
+import com.android.systemui.scene.domain.interactor.homeSceneFamilyResolver
import com.android.systemui.scene.domain.interactor.sceneInteractor
+import com.android.systemui.scene.shared.model.SceneFamilies
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.shade.ui.viewmodel.notificationsShadeSceneViewModel
import com.android.systemui.testKosmos
@@ -62,7 +64,9 @@
val destinationScenes by collectLastValue(underTest.destinationScenes)
lockDevice()
- assertThat(destinationScenes?.get(Swipe.Up)?.toScene).isEqualTo(Scenes.Lockscreen)
+ assertThat(destinationScenes?.get(Swipe.Up)?.toScene).isEqualTo(SceneFamilies.Home)
+ assertThat(kosmos.homeSceneFamilyResolver.resolvedScene.value)
+ .isEqualTo(Scenes.Lockscreen)
}
@Test
@@ -72,7 +76,8 @@
lockDevice()
unlockDevice()
- assertThat(destinationScenes?.get(Swipe.Up)?.toScene).isEqualTo(Scenes.Gone)
+ assertThat(destinationScenes?.get(Swipe.Up)?.toScene).isEqualTo(SceneFamilies.Home)
+ assertThat(sceneInteractor.currentScene.value).isEqualTo(Scenes.Gone)
}
@Test
@@ -85,7 +90,9 @@
)
sceneInteractor.changeScene(Scenes.Lockscreen, "reason")
- assertThat(destinationScenes?.get(Swipe.Up)?.toScene).isEqualTo(Scenes.Lockscreen)
+ assertThat(destinationScenes?.get(Swipe.Up)?.toScene).isEqualTo(SceneFamilies.Home)
+ assertThat(kosmos.homeSceneFamilyResolver.resolvedScene.value)
+ .isEqualTo(Scenes.Lockscreen)
}
@Test
@@ -96,10 +103,12 @@
kosmos.fakeAuthenticationRepository.setAuthenticationMethod(
AuthenticationMethodModel.None
)
+ sceneInteractor // force the lazy; this will kick off StateFlows
runCurrent()
sceneInteractor.changeScene(Scenes.Gone, "reason")
- assertThat(destinationScenes?.get(Swipe.Up)?.toScene).isEqualTo(Scenes.Gone)
+ assertThat(destinationScenes?.get(Swipe.Up)?.toScene).isEqualTo(SceneFamilies.Home)
+ assertThat(kosmos.homeSceneFamilyResolver.resolvedScene.value).isEqualTo(Scenes.Gone)
}
private fun TestScope.lockDevice() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModelTest.kt
index 0b55bef..7ee20e5 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModelTest.kt
@@ -28,7 +28,6 @@
import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.deviceentry.data.repository.fakeDeviceEntryRepository
-import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
import com.android.systemui.flags.EnableSceneContainer
import com.android.systemui.flags.Flags
import com.android.systemui.flags.fakeFeatureFlagsClassic
@@ -36,16 +35,17 @@
import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus
import com.android.systemui.kosmos.testScope
import com.android.systemui.media.controls.data.repository.mediaFilterRepository
-import com.android.systemui.media.controls.domain.pipeline.MediaDataManager
import com.android.systemui.media.controls.domain.pipeline.interactor.mediaCarouselInteractor
import com.android.systemui.media.controls.shared.model.MediaData
import com.android.systemui.qs.FooterActionsController
import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsViewModel
import com.android.systemui.qs.ui.adapter.FakeQSSceneAdapter
import com.android.systemui.res.R
+import com.android.systemui.scene.domain.interactor.homeSceneFamilyResolver
import com.android.systemui.scene.domain.interactor.sceneBackInteractor
import com.android.systemui.scene.domain.interactor.sceneContainerStartable
import com.android.systemui.scene.domain.interactor.sceneInteractor
+import com.android.systemui.scene.shared.model.SceneFamilies
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.settings.brightness.ui.viewmodel.brightnessMirrorViewModel
import com.android.systemui.shade.ui.viewmodel.shadeHeaderViewModel
@@ -55,7 +55,6 @@
import com.android.systemui.util.mockito.mock
import com.android.systemui.util.mockito.whenever
import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
@@ -82,11 +81,8 @@
private val sceneBackInteractor = kosmos.sceneBackInteractor
private val sceneContainerStartable = kosmos.sceneContainerStartable
- private val mediaDataManager = mock<MediaDataManager>()
-
private lateinit var underTest: QuickSettingsSceneViewModel
- @OptIn(ExperimentalCoroutinesApi::class)
@Before
fun setUp() {
kosmos.fakeFeatureFlagsClassic.set(Flags.NEW_NETWORK_SLICE_UI, false)
@@ -95,7 +91,6 @@
underTest =
QuickSettingsSceneViewModel(
applicationScope = testScope.backgroundScope,
- deviceEntryInteractor = kosmos.deviceEntryInteractor,
brightnessMirrorViewModel = kosmos.brightnessMirrorViewModel,
shadeHeaderViewModel = kosmos.shadeHeaderViewModel,
qsSceneAdapter = qsFlexiglassAdapter,
@@ -112,6 +107,7 @@
testScope.runTest {
overrideResource(R.bool.config_use_split_notification_shade, false)
val destinations by collectLastValue(underTest.destinationScenes)
+ val homeScene by collectLastValue(kosmos.homeSceneFamilyResolver.resolvedScene)
qsFlexiglassAdapter.setCustomizing(false)
kosmos.fakeAuthenticationRepository.setAuthenticationMethod(
AuthenticationMethodModel.Pin
@@ -128,9 +124,10 @@
Swipe(
fromSource = Edge.Bottom,
direction = SwipeDirection.Up,
- ) to UserActionResult(Scenes.Gone)
+ ) to UserActionResult(SceneFamilies.Home)
)
)
+ assertThat(homeScene).isEqualTo(Scenes.Gone)
}
@Test
@@ -142,6 +139,7 @@
val currentScene by collectLastValue(sceneInteractor.currentScene)
val backScene by collectLastValue(sceneBackInteractor.backScene)
+ val homeScene by collectLastValue(kosmos.homeSceneFamilyResolver.resolvedScene)
sceneInteractor.changeScene(Scenes.Lockscreen, "reason")
sceneInteractor.changeScene(Scenes.QuickSettings, "reason")
assertThat(currentScene).isEqualTo(Scenes.QuickSettings)
@@ -155,9 +153,10 @@
Swipe(
fromSource = Edge.Bottom,
direction = SwipeDirection.Up,
- ) to UserActionResult(Scenes.Lockscreen)
+ ) to UserActionResult(SceneFamilies.Home)
)
)
+ assertThat(homeScene).isEqualTo(Scenes.Lockscreen)
}
@Test
@@ -165,6 +164,7 @@
testScope.runTest {
overrideResource(R.bool.config_use_split_notification_shade, false)
val destinations by collectLastValue(underTest.destinationScenes)
+ val homeScene by collectLastValue(kosmos.homeSceneFamilyResolver.resolvedScene)
qsFlexiglassAdapter.setCustomizing(false)
kosmos.fakeDeviceEntryRepository.setLockscreenEnabled(true)
kosmos.fakeAuthenticationRepository.setAuthenticationMethod(
@@ -179,9 +179,10 @@
Swipe(
fromSource = Edge.Bottom,
direction = SwipeDirection.Up,
- ) to UserActionResult(Scenes.Lockscreen)
+ ) to UserActionResult(SceneFamilies.Home)
)
)
+ assertThat(homeScene).isEqualTo(Scenes.Lockscreen)
}
@Test
@@ -199,6 +200,7 @@
testScope.runTest {
overrideResource(R.bool.config_use_split_notification_shade, true)
val destinations by collectLastValue(underTest.destinationScenes)
+ val homeScene by collectLastValue(kosmos.homeSceneFamilyResolver.resolvedScene)
qsFlexiglassAdapter.setCustomizing(false)
kosmos.fakeAuthenticationRepository.setAuthenticationMethod(
AuthenticationMethodModel.Pin
@@ -215,9 +217,10 @@
Swipe(
fromSource = Edge.Bottom,
direction = SwipeDirection.Up,
- ) to UserActionResult(Scenes.Gone),
+ ) to UserActionResult(SceneFamilies.Home)
)
)
+ assertThat(homeScene).isEqualTo(Scenes.Gone)
}
@Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeSceneViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeSceneViewModelTest.kt
index 034c2e9..f28ddeb 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeSceneViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeSceneViewModelTest.kt
@@ -30,7 +30,9 @@
import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFingerprintAuthRepository
import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus
import com.android.systemui.kosmos.testScope
+import com.android.systemui.scene.domain.interactor.homeSceneFamilyResolver
import com.android.systemui.scene.domain.interactor.sceneInteractor
+import com.android.systemui.scene.shared.model.SceneFamilies
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.shade.ui.viewmodel.quickSettingsShadeSceneViewModel
import com.android.systemui.testKosmos
@@ -60,38 +62,45 @@
fun upTransitionSceneKey_deviceLocked_lockscreen() =
testScope.runTest {
val destinationScenes by collectLastValue(underTest.destinationScenes)
+ val homeScene by collectLastValue(kosmos.homeSceneFamilyResolver.resolvedScene)
lockDevice()
- assertThat(destinationScenes?.get(Swipe.Up)?.toScene).isEqualTo(Scenes.Lockscreen)
+ assertThat(destinationScenes?.get(Swipe.Up)?.toScene).isEqualTo(SceneFamilies.Home)
+ assertThat(homeScene).isEqualTo(Scenes.Lockscreen)
}
@Test
fun upTransitionSceneKey_deviceUnlocked_gone() =
testScope.runTest {
val destinationScenes by collectLastValue(underTest.destinationScenes)
+ val homeScene by collectLastValue(kosmos.homeSceneFamilyResolver.resolvedScene)
lockDevice()
unlockDevice()
- assertThat(destinationScenes?.get(Swipe.Up)?.toScene).isEqualTo(Scenes.Gone)
+ assertThat(destinationScenes?.get(Swipe.Up)?.toScene).isEqualTo(SceneFamilies.Home)
+ assertThat(homeScene).isEqualTo(Scenes.Gone)
}
@Test
fun upTransitionSceneKey_authMethodSwipe_lockscreenNotDismissed_goesToLockscreen() =
testScope.runTest {
val destinationScenes by collectLastValue(underTest.destinationScenes)
+ val homeScene by collectLastValue(kosmos.homeSceneFamilyResolver.resolvedScene)
kosmos.fakeDeviceEntryRepository.setLockscreenEnabled(true)
kosmos.fakeAuthenticationRepository.setAuthenticationMethod(
AuthenticationMethodModel.None
)
sceneInteractor.changeScene(Scenes.Lockscreen, "reason")
- assertThat(destinationScenes?.get(Swipe.Up)?.toScene).isEqualTo(Scenes.Lockscreen)
+ assertThat(destinationScenes?.get(Swipe.Up)?.toScene).isEqualTo(SceneFamilies.Home)
+ assertThat(homeScene).isEqualTo(Scenes.Lockscreen)
}
@Test
fun upTransitionSceneKey_authMethodSwipe_lockscreenDismissed_goesToGone() =
testScope.runTest {
val destinationScenes by collectLastValue(underTest.destinationScenes)
+ val homeScene by collectLastValue(kosmos.homeSceneFamilyResolver.resolvedScene)
kosmos.fakeDeviceEntryRepository.setLockscreenEnabled(true)
kosmos.fakeAuthenticationRepository.setAuthenticationMethod(
AuthenticationMethodModel.None
@@ -99,7 +108,8 @@
runCurrent()
sceneInteractor.changeScene(Scenes.Gone, "reason")
- assertThat(destinationScenes?.get(Swipe.Up)?.toScene).isEqualTo(Scenes.Gone)
+ assertThat(destinationScenes?.get(Swipe.Up)?.toScene).isEqualTo(SceneFamilies.Home)
+ assertThat(homeScene).isEqualTo(Scenes.Gone)
}
private fun TestScope.lockDevice() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt
index 9e7e766..f8a62cb 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt
@@ -51,7 +51,6 @@
import com.android.systemui.keyguard.ui.viewmodel.KeyguardLongPressViewModel
import com.android.systemui.keyguard.ui.viewmodel.LockscreenSceneViewModel
import com.android.systemui.kosmos.testScope
-import com.android.systemui.media.controls.domain.pipeline.MediaDataManager
import com.android.systemui.media.controls.domain.pipeline.interactor.mediaCarouselInteractor
import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAsleepForTest
import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAwakeForTest
@@ -59,8 +58,10 @@
import com.android.systemui.qs.footerActionsController
import com.android.systemui.qs.footerActionsViewModelFactory
import com.android.systemui.qs.ui.adapter.FakeQSSceneAdapter
+import com.android.systemui.scene.domain.interactor.homeSceneFamilyResolver
import com.android.systemui.scene.domain.interactor.sceneContainerStartable
import com.android.systemui.scene.domain.interactor.sceneInteractor
+import com.android.systemui.scene.shared.model.SceneFamilies
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.scene.shared.model.fakeSceneDataSource
import com.android.systemui.scene.ui.viewmodel.SceneContainerViewModel
@@ -91,7 +92,6 @@
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import org.mockito.Mock
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
@@ -169,8 +169,6 @@
private val qsFlexiglassAdapter = FakeQSSceneAdapter(inflateDelegate = { mock() })
- @Mock private lateinit var mediaDataManager: MediaDataManager
-
private lateinit var emergencyAffordanceManager: EmergencyAffordanceManager
private lateinit var telecomManager: TelecomManager
private val fakeSceneDataSource = kosmos.fakeSceneDataSource
@@ -205,7 +203,6 @@
shadeSceneViewModel =
ShadeSceneViewModel(
applicationScope = testScope.backgroundScope,
- deviceEntryInteractor = deviceEntryInteractor,
shadeHeaderViewModel = kosmos.shadeHeaderViewModel,
qsSceneAdapter = qsFlexiglassAdapter,
notifications = kosmos.notificationsPlaceholderViewModel,
@@ -280,6 +277,7 @@
fun swipeUpOnShadeScene_withAuthMethodSwipe_lockscreenNotDismissed_goesToLockscreen() =
testScope.runTest {
val destinationScenes by collectLastValue(shadeSceneViewModel.destinationScenes)
+ val homeScene by collectLastValue(kosmos.homeSceneFamilyResolver.resolvedScene)
setAuthMethod(AuthenticationMethodModel.None, enableLockscreen = true)
assertCurrentScene(Scenes.Lockscreen)
@@ -288,9 +286,10 @@
assertCurrentScene(Scenes.Shade)
val upDestinationSceneKey = destinationScenes?.get(Swipe.Up)?.toScene
- assertThat(upDestinationSceneKey).isEqualTo(Scenes.Lockscreen)
+ assertThat(upDestinationSceneKey).isEqualTo(SceneFamilies.Home)
+ assertThat(homeScene).isEqualTo(Scenes.Lockscreen)
emulateUserDrivenTransition(
- to = upDestinationSceneKey,
+ to = homeScene,
)
}
@@ -299,6 +298,7 @@
testScope.runTest {
val destinationScenes by collectLastValue(shadeSceneViewModel.destinationScenes)
val canSwipeToEnter by collectLastValue(deviceEntryInteractor.canSwipeToEnter)
+ val homeScene by collectLastValue(kosmos.homeSceneFamilyResolver.resolvedScene)
setAuthMethod(AuthenticationMethodModel.None, enableLockscreen = true)
@@ -314,9 +314,10 @@
assertCurrentScene(Scenes.Shade)
val upDestinationSceneKey = destinationScenes?.get(Swipe.Up)?.toScene
- assertThat(upDestinationSceneKey).isEqualTo(Scenes.Gone)
+ assertThat(upDestinationSceneKey).isEqualTo(SceneFamilies.Home)
+ assertThat(homeScene).isEqualTo(Scenes.Gone)
emulateUserDrivenTransition(
- to = upDestinationSceneKey,
+ to = homeScene,
)
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt
index 229a711..92e6b16 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt
@@ -21,16 +21,20 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.compose.animation.scene.ObservableTransitionState
+import com.android.compose.animation.scene.SceneKey
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.flags.EnableSceneContainer
import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFingerprintAuthRepository
import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus
import com.android.systemui.kosmos.testScope
+import com.android.systemui.scene.data.repository.Idle
+import com.android.systemui.scene.data.repository.Transition
import com.android.systemui.scene.data.repository.sceneContainerRepository
+import com.android.systemui.scene.data.repository.setSceneTransition
import com.android.systemui.scene.sceneContainerConfig
import com.android.systemui.scene.sceneKeys
-import com.android.systemui.scene.shared.model.SceneContainerConfig
+import com.android.systemui.scene.shared.model.SceneFamilies
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.scene.shared.model.fakeSceneDataSource
import com.android.systemui.testKosmos
@@ -38,6 +42,7 @@
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.flow.toList
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import org.junit.Test
@@ -52,48 +57,27 @@
private val testScope = kosmos.testScope
private val fakeSceneDataSource = kosmos.fakeSceneDataSource
- private lateinit var underTest: SceneInteractor
+ private val underTest = kosmos.sceneInteractor
@Test
fun allSceneKeys() {
- underTest = kosmos.sceneInteractor
assertThat(underTest.allSceneKeys()).isEqualTo(kosmos.sceneKeys)
}
@Test
fun changeScene_toUnknownScene_doesNothing() =
testScope.runTest {
- val sceneKeys =
- listOf(
- Scenes.QuickSettings,
- Scenes.Shade,
- Scenes.Lockscreen,
- Scenes.Gone,
- Scenes.Communal,
- )
- val navigationDistances =
- mapOf(
- Scenes.Gone to 0,
- Scenes.Lockscreen to 0,
- Scenes.Communal to 1,
- Scenes.Shade to 2,
- Scenes.QuickSettings to 3,
- )
- kosmos.sceneContainerConfig =
- SceneContainerConfig(sceneKeys, Scenes.Lockscreen, navigationDistances)
- underTest = kosmos.sceneInteractor
val currentScene by collectLastValue(underTest.currentScene)
+ val unknownScene = SceneKey("UNKNOWN")
val previousScene = currentScene
- assertThat(previousScene).isNotEqualTo(Scenes.Bouncer)
- underTest.changeScene(Scenes.Bouncer, "reason")
+ assertThat(previousScene).isNotEqualTo(unknownScene)
+ underTest.changeScene(unknownScene, "reason")
assertThat(currentScene).isEqualTo(previousScene)
}
@Test
fun changeScene() =
testScope.runTest {
- underTest = kosmos.sceneInteractor
-
val currentScene by collectLastValue(underTest.currentScene)
assertThat(currentScene).isEqualTo(Scenes.Lockscreen)
@@ -104,8 +88,6 @@
@Test
fun changeScene_toGoneWhenUnl_doesNotThrow() =
testScope.runTest {
- underTest = kosmos.sceneInteractor
-
val currentScene by collectLastValue(underTest.currentScene)
assertThat(currentScene).isEqualTo(Scenes.Lockscreen)
@@ -120,15 +102,11 @@
@Test(expected = IllegalStateException::class)
fun changeScene_toGoneWhenStillLocked_throws() =
- testScope.runTest {
- underTest = kosmos.sceneInteractor
- underTest.changeScene(Scenes.Gone, "reason")
- }
+ testScope.runTest { underTest.changeScene(Scenes.Gone, "reason") }
@Test
fun changeScene_toGoneWhenTransitionToLockedFromGone() =
testScope.runTest {
- underTest = kosmos.sceneInteractor
val currentScene by collectLastValue(underTest.currentScene)
val transitionTo by collectLastValue(underTest.transitioningTo)
kosmos.sceneContainerRepository.setTransitionState(
@@ -151,39 +129,30 @@
}
@Test
+ fun changeScene_toHomeSceneFamily() =
+ testScope.runTest {
+ val currentScene by collectLastValue(underTest.currentScene)
+
+ underTest.changeScene(SceneFamilies.Home, "reason")
+ runCurrent()
+
+ assertThat(currentScene).isEqualTo(kosmos.homeSceneFamilyResolver.resolvedScene.value)
+ }
+
+ @Test
fun snapToScene_toUnknownScene_doesNothing() =
testScope.runTest {
- val sceneKeys =
- listOf(
- Scenes.QuickSettings,
- Scenes.Shade,
- Scenes.Lockscreen,
- Scenes.Gone,
- Scenes.Communal,
- )
- val navigationDistances =
- mapOf(
- Scenes.Gone to 0,
- Scenes.Lockscreen to 0,
- Scenes.Communal to 1,
- Scenes.Shade to 2,
- Scenes.QuickSettings to 3,
- )
- kosmos.sceneContainerConfig =
- SceneContainerConfig(sceneKeys, Scenes.Lockscreen, navigationDistances)
- underTest = kosmos.sceneInteractor
val currentScene by collectLastValue(underTest.currentScene)
val previousScene = currentScene
- assertThat(previousScene).isNotEqualTo(Scenes.Bouncer)
- underTest.snapToScene(Scenes.Bouncer, "reason")
+ val unknownScene = SceneKey("UNKNOWN")
+ assertThat(previousScene).isNotEqualTo(unknownScene)
+ underTest.snapToScene(unknownScene, "reason")
assertThat(currentScene).isEqualTo(previousScene)
}
@Test
fun snapToScene() =
testScope.runTest {
- underTest = kosmos.sceneInteractor
-
val currentScene by collectLastValue(underTest.currentScene)
assertThat(currentScene).isEqualTo(Scenes.Lockscreen)
@@ -194,8 +163,6 @@
@Test
fun snapToScene_toGoneWhenUnl_doesNotThrow() =
testScope.runTest {
- underTest = kosmos.sceneInteractor
-
val currentScene by collectLastValue(underTest.currentScene)
assertThat(currentScene).isEqualTo(Scenes.Lockscreen)
@@ -210,15 +177,22 @@
@Test(expected = IllegalStateException::class)
fun snapToScene_toGoneWhenStillLocked_throws() =
+ testScope.runTest { underTest.snapToScene(Scenes.Gone, "reason") }
+
+ @Test
+ fun snapToScene_toHomeSceneFamily() =
testScope.runTest {
- underTest = kosmos.sceneInteractor
- underTest.snapToScene(Scenes.Gone, "reason")
+ val currentScene by collectLastValue(underTest.currentScene)
+
+ underTest.snapToScene(SceneFamilies.Home, "reason")
+ runCurrent()
+
+ assertThat(currentScene).isEqualTo(kosmos.homeSceneFamilyResolver.resolvedScene.value)
}
@Test
fun sceneChanged_inDataSource() =
testScope.runTest {
- underTest = kosmos.sceneInteractor
val currentScene by collectLastValue(underTest.currentScene)
assertThat(currentScene).isEqualTo(Scenes.Lockscreen)
@@ -230,14 +204,14 @@
@Test
fun transitionState() =
testScope.runTest {
- underTest = kosmos.sceneInteractor
- val underTest = kosmos.sceneContainerRepository
+ val sceneContainerRepository = kosmos.sceneContainerRepository
val transitionState =
MutableStateFlow<ObservableTransitionState>(
ObservableTransitionState.Idle(Scenes.Lockscreen)
)
- underTest.setTransitionState(transitionState)
- val reflectedTransitionState by collectLastValue(underTest.transitionState)
+ sceneContainerRepository.setTransitionState(transitionState)
+ val reflectedTransitionState by
+ collectLastValue(sceneContainerRepository.transitionState)
assertThat(reflectedTransitionState).isEqualTo(transitionState.value)
val progress = MutableStateFlow(1f)
@@ -258,7 +232,7 @@
progress.value = 0.9f
assertThat(reflectedTransitionState).isEqualTo(transitionState.value)
- underTest.setTransitionState(null)
+ sceneContainerRepository.setTransitionState(null)
assertThat(reflectedTransitionState)
.isEqualTo(
ObservableTransitionState.Idle(kosmos.sceneContainerConfig.initialSceneKey)
@@ -268,7 +242,6 @@
@Test
fun transitioningTo() =
testScope.runTest {
- underTest = kosmos.sceneInteractor
val transitionState =
MutableStateFlow<ObservableTransitionState>(
ObservableTransitionState.Idle(underTest.currentScene.value)
@@ -306,7 +279,6 @@
@Test
fun isTransitionUserInputOngoing_idle_false() =
testScope.runTest {
- underTest = kosmos.sceneInteractor
val transitionState =
MutableStateFlow<ObservableTransitionState>(
ObservableTransitionState.Idle(Scenes.Shade)
@@ -321,7 +293,6 @@
@Test
fun isTransitionUserInputOngoing_transition_true() =
testScope.runTest {
- underTest = kosmos.sceneInteractor
val transitionState =
MutableStateFlow<ObservableTransitionState>(
ObservableTransitionState.Transition(
@@ -343,7 +314,6 @@
@Test
fun isTransitionUserInputOngoing_updateMidTransition_false() =
testScope.runTest {
- underTest = kosmos.sceneInteractor
val transitionState =
MutableStateFlow<ObservableTransitionState>(
ObservableTransitionState.Transition(
@@ -377,7 +347,6 @@
@Test
fun isTransitionUserInputOngoing_updateOnIdle_false() =
testScope.runTest {
- underTest = kosmos.sceneInteractor
val transitionState =
MutableStateFlow<ObservableTransitionState>(
ObservableTransitionState.Transition(
@@ -403,7 +372,6 @@
@Test
fun isVisible() =
testScope.runTest {
- underTest = kosmos.sceneInteractor
val isVisible by collectLastValue(underTest.isVisible)
assertThat(isVisible).isTrue()
@@ -417,7 +385,6 @@
@Test
fun isVisible_duringRemoteUserInteraction_forcedVisible() =
testScope.runTest {
- underTest = kosmos.sceneInteractor
underTest.setVisible(false, "reason")
val isVisible by collectLastValue(underTest.isVisible)
assertThat(isVisible).isFalse()
@@ -428,4 +395,57 @@
assertThat(isVisible).isFalse()
}
+
+ @Test
+ fun resolveSceneFamily_home() =
+ testScope.runTest {
+ assertThat(underTest.resolveSceneFamily(SceneFamilies.Home))
+ .isEqualTo(kosmos.homeSceneFamilyResolver.resolvedScene)
+ }
+
+ @Test
+ fun resolveSceneFamily_nonFamily() =
+ testScope.runTest {
+ val resolved = underTest.resolveSceneFamily(Scenes.Gone).toList()
+ assertThat(resolved).containsExactly(Scenes.Gone).inOrder()
+ }
+
+ @Test
+ fun transitionValue_test_idle() =
+ testScope.runTest {
+ val transitionValue by collectLastValue(underTest.transitionProgress(Scenes.Gone))
+
+ kosmos.setSceneTransition(Idle(Scenes.Gone))
+ assertThat(transitionValue).isEqualTo(1f)
+
+ kosmos.setSceneTransition(Idle(Scenes.Lockscreen))
+ assertThat(transitionValue).isEqualTo(0f)
+ }
+
+ @Test
+ fun transitionValue_test_transitions() =
+ testScope.runTest {
+ val transitionValue by collectLastValue(underTest.transitionProgress(Scenes.Gone))
+ val progress = MutableStateFlow(0f)
+
+ kosmos.setSceneTransition(
+ Transition(from = Scenes.Lockscreen, to = Scenes.Gone, progress = progress)
+ )
+ assertThat(transitionValue).isEqualTo(0f)
+
+ progress.value = 0.4f
+ assertThat(transitionValue).isEqualTo(0.4f)
+
+ kosmos.setSceneTransition(
+ Transition(from = Scenes.Gone, to = Scenes.Lockscreen, progress = progress)
+ )
+ progress.value = 0.7f
+ assertThat(transitionValue).isEqualTo(0.3f)
+
+ kosmos.setSceneTransition(
+ Transition(from = Scenes.Lockscreen, to = Scenes.Shade, progress = progress)
+ )
+ progress.value = 0.9f
+ assertThat(transitionValue).isEqualTo(0f)
+ }
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeBackActionInteractorImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeBackActionInteractorImplTest.kt
index 468c39d..3a5ff00 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeBackActionInteractorImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeBackActionInteractorImplTest.kt
@@ -29,6 +29,7 @@
import com.android.systemui.keyguard.data.repository.deviceEntryFingerprintAuthRepository
import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus
import com.android.systemui.kosmos.testScope
+import com.android.systemui.scene.domain.interactor.homeSceneFamilyResolver
import com.android.systemui.scene.domain.interactor.sceneInteractor
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.shared.recents.utilities.Utilities
@@ -36,6 +37,7 @@
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
@@ -77,6 +79,8 @@
@Test
fun animateCollapseQs_fullyCollapse_entered() =
testScope.runTest {
+ // Ensure that HomeSceneFamilyResolver is running
+ kosmos.homeSceneFamilyResolver.resolvedScene.launchIn(backgroundScope)
val actual by collectLastValue(sceneInteractor.currentScene)
enterDevice()
setScene(Scenes.QuickSettings)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt
index 482dc5d..f88d102 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt
@@ -27,7 +27,6 @@
import com.android.systemui.common.ui.data.repository.fakeConfigurationRepository
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.deviceentry.data.repository.fakeDeviceEntryRepository
-import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
import com.android.systemui.flags.EnableSceneContainer
import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFingerprintAuthRepository
import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus
@@ -40,7 +39,9 @@
import com.android.systemui.qs.footerActionsViewModelFactory
import com.android.systemui.qs.ui.adapter.FakeQSSceneAdapter
import com.android.systemui.res.R
+import com.android.systemui.scene.domain.interactor.homeSceneFamilyResolver
import com.android.systemui.scene.domain.interactor.sceneInteractor
+import com.android.systemui.scene.shared.model.SceneFamilies
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.scene.shared.model.TransitionKeys.ToSplitShade
import com.android.systemui.settings.brightness.ui.viewmodel.brightnessMirrorViewModel
@@ -75,7 +76,6 @@
private val kosmos = testKosmos()
private val testScope = kosmos.testScope
private val sceneInteractor by lazy { kosmos.sceneInteractor }
- private val deviceEntryInteractor by lazy { kosmos.deviceEntryInteractor }
private val shadeRepository by lazy { kosmos.shadeRepository }
private val qsSceneAdapter = FakeQSSceneAdapter({ mock() })
@@ -91,7 +91,6 @@
underTest =
ShadeSceneViewModel(
applicationScope = testScope.backgroundScope,
- deviceEntryInteractor = deviceEntryInteractor,
shadeHeaderViewModel = kosmos.shadeHeaderViewModel,
qsSceneAdapter = qsSceneAdapter,
notifications = kosmos.notificationsPlaceholderViewModel,
@@ -109,18 +108,21 @@
fun upTransitionSceneKey_deviceLocked_lockScreen() =
testScope.runTest {
val destinationScenes by collectLastValue(underTest.destinationScenes)
+ val homeScene by collectLastValue(kosmos.homeSceneFamilyResolver.resolvedScene)
kosmos.fakeAuthenticationRepository.setAuthenticationMethod(
AuthenticationMethodModel.Pin
)
assertThat(destinationScenes?.get(Swipe(SwipeDirection.Up))?.toScene)
- .isEqualTo(Scenes.Lockscreen)
+ .isEqualTo(SceneFamilies.Home)
+ assertThat(homeScene).isEqualTo(Scenes.Lockscreen)
}
@Test
fun upTransitionSceneKey_deviceUnlocked_gone() =
testScope.runTest {
val destinationScenes by collectLastValue(underTest.destinationScenes)
+ val homeScene by collectLastValue(kosmos.homeSceneFamilyResolver.resolvedScene)
kosmos.fakeAuthenticationRepository.setAuthenticationMethod(
AuthenticationMethodModel.Pin
)
@@ -129,13 +131,15 @@
)
assertThat(destinationScenes?.get(Swipe(SwipeDirection.Up))?.toScene)
- .isEqualTo(Scenes.Gone)
+ .isEqualTo(SceneFamilies.Home)
+ assertThat(homeScene).isEqualTo(Scenes.Gone)
}
@Test
fun upTransitionSceneKey_authMethodSwipe_lockscreenNotDismissed_goesToLockscreen() =
testScope.runTest {
val destinationScenes by collectLastValue(underTest.destinationScenes)
+ val homeScene by collectLastValue(kosmos.homeSceneFamilyResolver.resolvedScene)
kosmos.fakeDeviceEntryRepository.setLockscreenEnabled(true)
kosmos.fakeAuthenticationRepository.setAuthenticationMethod(
AuthenticationMethodModel.None
@@ -143,13 +147,15 @@
sceneInteractor.changeScene(Scenes.Lockscreen, "reason")
assertThat(destinationScenes?.get(Swipe(SwipeDirection.Up))?.toScene)
- .isEqualTo(Scenes.Lockscreen)
+ .isEqualTo(SceneFamilies.Home)
+ assertThat(homeScene).isEqualTo(Scenes.Lockscreen)
}
@Test
fun upTransitionSceneKey_authMethodSwipe_lockscreenDismissed_goesToGone() =
testScope.runTest {
val destinationScenes by collectLastValue(underTest.destinationScenes)
+ val homeScene by collectLastValue(kosmos.homeSceneFamilyResolver.resolvedScene)
kosmos.fakeDeviceEntryRepository.setLockscreenEnabled(true)
kosmos.fakeAuthenticationRepository.setAuthenticationMethod(
AuthenticationMethodModel.None
@@ -158,7 +164,8 @@
sceneInteractor.changeScene(Scenes.Gone, "reason")
assertThat(destinationScenes?.get(Swipe(SwipeDirection.Up))?.toScene)
- .isEqualTo(Scenes.Gone)
+ .isEqualTo(SceneFamilies.Home)
+ assertThat(homeScene).isEqualTo(Scenes.Gone)
}
@Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/BaseHeadsUpManagerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/BaseHeadsUpManagerTest.java
index 88bef91..206b39c 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/BaseHeadsUpManagerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/BaseHeadsUpManagerTest.java
@@ -627,7 +627,7 @@
hum.onEntryAdded(entryToPin);
assertEquals(2, mUiEventLoggerFake.numLogs());
- assertEquals(AvalancheController.ThrottleEvent.SHOWN.getId(),
+ assertEquals(AvalancheController.ThrottleEvent.AVALANCHE_THROTTLING_HUN_SHOWN.getId(),
mUiEventLoggerFake.eventId(0));
assertEquals(BaseHeadsUpManager.NotificationPeekEvent.NOTIFICATION_PEEK.getId(),
mUiEventLoggerFake.eventId(1));
diff --git a/packages/SystemUI/res/layout-land/volume_dialog.xml b/packages/SystemUI/res/layout-land/volume_dialog.xml
index 5ce2601..08edf59 100644
--- a/packages/SystemUI/res/layout-land/volume_dialog.xml
+++ b/packages/SystemUI/res/layout-land/volume_dialog.xml
@@ -13,9 +13,7 @@
~ See the License for the specific language governing permissions and
~ limitations under the License
-->
-<FrameLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:sysui="http://schemas.android.com/apk/res-auto"
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
android:id="@+id/volume_dialog_container"
android:layout_width="wrap_content"
@@ -97,16 +95,18 @@
android:paddingLeft="@dimen/volume_dialog_ringer_rows_padding"
android:paddingBottom="@dimen/volume_dialog_ringer_rows_padding"
android:paddingRight="@dimen/volume_dialog_ringer_rows_padding">
+
<com.android.keyguard.AlphaOptimizedImageButton
android:id="@+id/settings"
- android:src="@drawable/horizontal_ellipsis"
android:layout_width="@dimen/volume_dialog_tap_target_size"
android:layout_height="@dimen/volume_dialog_tap_target_size"
android:layout_gravity="center"
- android:contentDescription="@string/accessibility_volume_settings"
android:background="@drawable/ripple_drawable_20dp"
- android:tint="?androidprv:attr/colorAccent"
- android:soundEffectsEnabled="false" />
+ android:contentDescription="@string/accessibility_volume_settings"
+ android:scaleType="centerInside"
+ android:soundEffectsEnabled="false"
+ android:src="@drawable/horizontal_ellipsis"
+ android:tint="?androidprv:attr/colorAccent" />
</FrameLayout>
</LinearLayout>
diff --git a/packages/SystemUI/res/layout/auth_container_view.xml b/packages/SystemUI/res/layout/auth_container_view.xml
index 2a1ce1f..cc5a27d 100644
--- a/packages/SystemUI/res/layout/auth_container_view.xml
+++ b/packages/SystemUI/res/layout/auth_container_view.xml
@@ -28,9 +28,9 @@
<View
android:id="@+id/panel"
+ style="@style/AuthNonCredentialPanelStyle"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:background="?androidprv:attr/materialColorSurfaceContainer"
android:elevation="@dimen/biometric_dialog_elevation"/>
<ScrollView
diff --git a/packages/SystemUI/res/layout/hearing_devices_preset_dropdown_item.xml b/packages/SystemUI/res/layout/hearing_devices_preset_dropdown_item.xml
index 1d9307b..17c0222 100644
--- a/packages/SystemUI/res/layout/hearing_devices_preset_dropdown_item.xml
+++ b/packages/SystemUI/res/layout/hearing_devices_preset_dropdown_item.xml
@@ -22,4 +22,5 @@
android:minHeight="@dimen/hearing_devices_preset_spinner_height"
android:paddingStart="@dimen/hearing_devices_preset_spinner_text_padding_start"
android:gravity="center_vertical"
+ android:textDirection="locale"
android:ellipsize="end" />
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/hearing_devices_preset_spinner_selected.xml b/packages/SystemUI/res/layout/hearing_devices_preset_spinner_selected.xml
index 77172ca..d512e7c 100644
--- a/packages/SystemUI/res/layout/hearing_devices_preset_spinner_selected.xml
+++ b/packages/SystemUI/res/layout/hearing_devices_preset_spinner_selected.xml
@@ -32,6 +32,7 @@
android:fontFamily="@*android:string/config_headlineFontFamilyMedium"
android:textSize="14sp"
android:gravity="center_vertical"
+ android:textDirection="locale"
android:layout_weight="1" />
<TextView
android:id="@+id/hearing_devices_preset_option_text"
@@ -42,5 +43,6 @@
android:gravity="center_vertical"
android:ellipsize="end"
android:maxLines="1"
+ android:textDirection="locale"
android:layout_weight="1" />
</LinearLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index d308c3d..d979abb 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -912,6 +912,10 @@
obvious when corner radii differ.-->
<dimen name="communal_enforced_rounded_corner_max_radius">28dp</dimen>
+ <!-- Width and height used to filter widgets displayed in the communal widget picker -->
+ <dimen name="communal_widget_picker_desired_width">360dp</dimen>
+ <dimen name="communal_widget_picker_desired_height">240dp</dimen>
+
<!-- The width/height of the unlock icon view on keyguard. -->
<dimen name="keyguard_lock_height">42dp</dimen>
<dimen name="keyguard_lock_padding">20dp</dimen>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 1e0adec..73b7586 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -338,8 +338,11 @@
<item name="android:textSize">16sp</item>
</style>
- <style name="AuthCredentialPanelStyle">
+ <style name="AuthNonCredentialPanelStyle">
<item name="android:background">?androidprv:attr/materialColorSurfaceBright</item>
+ </style>
+
+ <style name="AuthCredentialPanelStyle" parent="AuthNonCredentialPanelStyle">
<item name="android:clickable">true</item>
<item name="android:clipToOutline">true</item>
<item name="android:importantForAccessibility">no</item>
diff --git a/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt b/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt
index 86c807b..5dcf161 100644
--- a/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt
+++ b/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt
@@ -178,6 +178,7 @@
smallClockOnAttachStateChangeListener =
object : OnAttachStateChangeListener {
var pastVisibility: Int? = null
+
override fun onViewAttachedToWindow(view: View) {
clock.events.onTimeFormatChanged(DateFormat.is24HourFormat(context))
// Match the asing for view.parent's layout classes.
@@ -213,6 +214,7 @@
override fun onViewAttachedToWindow(p0: View) {
clock.events.onTimeFormatChanged(DateFormat.is24HourFormat(context))
}
+
override fun onViewDetachedFromWindow(p0: View) {}
}
clock.largeClock.view.addOnAttachStateChangeListener(largeClockOnAttachStateChangeListener)
@@ -284,8 +286,10 @@
var smallRegionSampler: RegionSampler? = null
private set
+
var largeRegionSampler: RegionSampler? = null
private set
+
var smallTimeListener: TimeListener? = null
var largeTimeListener: TimeListener? = null
val shouldTimeListenerRun: Boolean
@@ -560,7 +564,7 @@
internal fun listenForAnyStateToAodTransition(scope: CoroutineScope): Job {
return scope.launch {
keyguardTransitionInteractor
- .transitionStepsToState(AOD)
+ .transition(Edge.create(to = AOD))
.filter { it.transitionState == TransitionState.STARTED }
.filter { it.from != LOCKSCREEN }
.collect { handleDoze(1f) }
@@ -571,7 +575,7 @@
internal fun listenForAnyStateToLockscreenTransition(scope: CoroutineScope): Job {
return scope.launch {
keyguardTransitionInteractor
- .transitionStepsToState(LOCKSCREEN)
+ .transition(Edge.create(to = LOCKSCREEN))
.filter { it.transitionState == TransitionState.STARTED }
.filter { it.from != AOD }
.collect { handleDoze(0f) }
@@ -586,7 +590,7 @@
internal fun listenForAnyStateToDozingTransition(scope: CoroutineScope): Job {
return scope.launch {
keyguardTransitionInteractor
- .transitionStepsToState(DOZING)
+ .transition(Edge.create(to = DOZING))
.filter { it.transitionState == TransitionState.FINISHED }
.collect { handleDoze(1f) }
}
diff --git a/packages/SystemUI/src/com/android/keyguard/LegacyLockIconViewController.java b/packages/SystemUI/src/com/android/keyguard/LegacyLockIconViewController.java
index a9fd340..03b13fe 100644
--- a/packages/SystemUI/src/com/android/keyguard/LegacyLockIconViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/LegacyLockIconViewController.java
@@ -70,7 +70,7 @@
import com.android.systemui.keyguard.MigrateClocksToBlueprint;
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor;
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor;
-import com.android.systemui.keyguard.shared.model.TransitionStep;
+import com.android.systemui.keyguard.shared.model.KeyguardState;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.res.R;
@@ -167,9 +167,9 @@
private LockIconView mView;
@VisibleForTesting
- final Consumer<TransitionStep> mDozeTransitionCallback = (TransitionStep step) -> {
- mInterpolatedDarkAmount = step.getValue();
- mView.setDozeAmount(step.getValue());
+ final Consumer<Float> mDozeTransitionCallback = (Float value) -> {
+ mInterpolatedDarkAmount = value;
+ mView.setDozeAmount(value);
updateBurnInOffsets();
};
@@ -265,7 +265,7 @@
mView.setAccessibilityDelegate(mAccessibilityDelegate);
if (mFeatureFlags.isEnabled(DOZING_MIGRATION_1)) {
- collectFlow(mView, mTransitionInteractor.getDozeAmountTransition(),
+ collectFlow(mView, mTransitionInteractor.transitionValue(KeyguardState.AOD),
mDozeTransitionCallback);
collectFlow(mView, mKeyguardInteractor.isDozing(), mIsDozingCallback);
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
index 177aad9..430ff07 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
@@ -515,7 +515,9 @@
} else {
throw new IllegalStateException("Unknown credential type: " + credentialType);
}
- mCredentialView = factory.inflate(layoutResourceId, null, false);
+ // TODO(b/288175645): Once AuthContainerView is removed, set 0dp in credential view xml
+ // files with the corresponding left/right or top/bottom constraints being set to "parent".
+ mCredentialView = factory.inflate(layoutResourceId, mLayout, false);
// The background is used for detecting taps / cancelling authentication. Since the
// credential view is full-screen and should not be canceled from background taps,
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerLegacy.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerLegacy.kt
index 298b87d..c3d9240 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerLegacy.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerLegacy.kt
@@ -39,7 +39,6 @@
import com.android.systemui.keyguard.shared.model.KeyguardState.GONE
import com.android.systemui.keyguard.shared.model.KeyguardState.OCCLUDED
import com.android.systemui.keyguard.shared.model.KeyguardState.PRIMARY_BOUNCER
-import com.android.systemui.keyguard.shared.model.TransitionState
import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.res.R
@@ -59,7 +58,6 @@
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.Job
-import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch
/** Class that coordinates non-HBM animations during keyguard authentication. */
@@ -307,27 +305,12 @@
@VisibleForTesting
suspend fun listenForLockscreenAodTransitions(scope: CoroutineScope): Job {
return scope.launch {
- transitionInteractor.dozeAmountTransition.collect { transitionStep ->
- if (
- transitionStep.from == AOD &&
- transitionStep.transitionState == TransitionState.CANCELED
- ) {
- if (transitionInteractor.startedKeyguardTransitionStep.first().to != AOD) {
- // If the next started transition isn't transitioning back to AOD, force
- // doze amount to be 0f (as if the transition to the lockscreen completed).
- view.onDozeAmountChanged(
- 0f,
- 0f,
- UdfpsKeyguardViewLegacy.ANIMATION_NONE,
- )
- }
- } else {
- view.onDozeAmountChanged(
- transitionStep.value,
- transitionStep.value,
- UdfpsKeyguardViewLegacy.ANIMATION_BETWEEN_AOD_AND_LOCKSCREEN,
- )
- }
+ transitionInteractor.transitionValue(AOD).collect {
+ view.onDozeAmountChanged(
+ it,
+ it,
+ UdfpsKeyguardViewLegacy.ANIMATION_BETWEEN_AOD_AND_LOCKSCREEN,
+ )
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/CommunalDreamStartable.kt b/packages/SystemUI/src/com/android/systemui/communal/CommunalDreamStartable.kt
index 8993a3b..38f51da 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/CommunalDreamStartable.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/CommunalDreamStartable.kt
@@ -19,23 +19,25 @@
import android.annotation.SuppressLint
import android.app.DreamManager
import com.android.systemui.CoreStartable
-import com.android.systemui.Flags.glanceableHubAllowKeyguardWhenDreaming
import com.android.systemui.Flags.communalHub
+import com.android.systemui.Flags.glanceableHubAllowKeyguardWhenDreaming
import com.android.systemui.Flags.restartDreamOnUnocclude
-import com.android.systemui.communal.domain.interactor.CommunalInteractor
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
+import com.android.systemui.keyguard.shared.model.Edge
import com.android.systemui.keyguard.shared.model.KeyguardState
+import com.android.systemui.keyguard.shared.model.TransitionState
+import com.android.systemui.keyguard.shared.model.filterState
import com.android.systemui.power.domain.interactor.PowerInteractor
-import com.android.systemui.util.kotlin.Utils.Companion.sample
-import com.android.systemui.util.kotlin.sample
+import com.android.systemui.scene.shared.model.Scenes
+import com.android.systemui.util.kotlin.Utils.Companion.sampleFilter
+import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
-import javax.inject.Inject
/**
* A [CoreStartable] responsible for automatically starting the dream when the communal hub is
@@ -48,7 +50,6 @@
private val powerInteractor: PowerInteractor,
private val keyguardInteractor: KeyguardInteractor,
private val keyguardTransitionInteractor: KeyguardTransitionInteractor,
- private val communalInteractor: CommunalInteractor,
private val dreamManager: DreamManager,
@Background private val bgScope: CoroutineScope,
) : CoreStartable {
@@ -60,31 +61,28 @@
// Return to dream from occluded when not already dreaming.
if (restartDreamOnUnocclude()) {
- keyguardTransitionInteractor.startedKeyguardTransitionStep
- .sample(keyguardInteractor.isDreaming, ::Pair)
- .filter {
- it.first.from == KeyguardState.OCCLUDED &&
- it.first.to == KeyguardState.DREAMING &&
- !it.second
- }
+ keyguardTransitionInteractor
+ .transition(Edge.create(from = KeyguardState.OCCLUDED, to = KeyguardState.DREAMING))
+ .filterState(TransitionState.STARTED)
+ .sampleFilter(keyguardInteractor.isDreaming) { isDreaming -> !isDreaming }
.onEach { dreamManager.startDream() }
.launchIn(bgScope)
}
// Restart the dream underneath the hub in order to support the ability to swipe
// away the hub to enter the dream.
- keyguardTransitionInteractor.finishedKeyguardState
- .sample(powerInteractor.isAwake, keyguardInteractor.isDreaming)
- .onEach { (finishedState, isAwake, dreaming) ->
- if (
- finishedState == KeyguardState.GLANCEABLE_HUB &&
- !dreaming &&
- !glanceableHubAllowKeyguardWhenDreaming() &&
- dreamManager.canStartDreaming(isAwake)
- ) {
- dreamManager.startDream()
- }
+ keyguardTransitionInteractor
+ .transition(
+ edge = Edge.create(to = Scenes.Communal),
+ edgeWithoutSceneContainer = Edge.create(to = KeyguardState.GLANCEABLE_HUB)
+ )
+ .filterState(TransitionState.FINISHED)
+ .sampleFilter(powerInteractor.isAwake) { isAwake ->
+ dreamManager.canStartDreaming(isAwake)
}
+ .sampleFilter(keyguardInteractor.isDreaming) { isDreaming -> !isDreaming }
+ .filter { !glanceableHubAllowKeyguardWhenDreaming() }
+ .onEach { dreamManager.startDream() }
.launchIn(bgScope)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalSceneRepository.kt b/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalSceneRepository.kt
index 260dcba..7a4006d 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalSceneRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalSceneRepository.kt
@@ -28,6 +28,7 @@
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
@@ -51,7 +52,7 @@
fun changeScene(toScene: SceneKey, transitionKey: TransitionKey? = null)
/** Immediately snaps to the desired scene. */
- fun snapToScene(toScene: SceneKey)
+ fun snapToScene(toScene: SceneKey, delayMillis: Long = 0)
/**
* Updates the transition state of the hub [SceneTransitionLayout].
@@ -92,10 +93,11 @@
}
}
- override fun snapToScene(toScene: SceneKey) {
+ override fun snapToScene(toScene: SceneKey, delayMillis: Long) {
applicationScope.launch {
// SceneTransitionLayout state updates must be triggered on the thread the STL was
// created on.
+ delay(delayMillis)
sceneDataSource.snapToScene(toScene)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt
index fdb40fb..3e513f8 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt
@@ -46,6 +46,7 @@
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
+import com.android.systemui.keyguard.shared.model.Edge
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.log.LogBuffer
import com.android.systemui.log.core.Logger
@@ -164,7 +165,7 @@
/** Whether to start dreaming when returning from occluded */
val dreamFromOccluded: Flow<Boolean> =
keyguardTransitionInteractor
- .transitionStepsToState(KeyguardState.OCCLUDED)
+ .transition(Edge.create(to = KeyguardState.OCCLUDED))
.map { it.from == KeyguardState.DREAMING }
.stateIn(scope = applicationScope, SharingStarted.Eagerly, false)
diff --git a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSceneInteractor.kt b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSceneInteractor.kt
index 5cfe979..0dab67c 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSceneInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSceneInteractor.kt
@@ -53,8 +53,8 @@
}
/** Immediately snaps to the new scene. */
- fun snapToScene(newScene: SceneKey) {
- communalSceneRepository.snapToScene(newScene)
+ fun snapToScene(newScene: SceneKey, delayMillis: Long = 0) {
+ communalSceneRepository.snapToScene(newScene, delayMillis)
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/communal/shared/model/CommunalBackgroundType.kt b/packages/SystemUI/src/com/android/systemui/communal/shared/model/CommunalBackgroundType.kt
index 8b816db..4eaba06 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/shared/model/CommunalBackgroundType.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/shared/model/CommunalBackgroundType.kt
@@ -21,4 +21,5 @@
DEFAULT(0),
STATIC_GRADIENT(1),
ANIMATED(2),
+ NONE(3),
}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalEditModeViewModel.kt b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalEditModeViewModel.kt
index bc65ccb..5312aec 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalEditModeViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalEditModeViewModel.kt
@@ -24,6 +24,7 @@
import android.util.Log
import androidx.activity.result.ActivityResultLauncher
import com.android.internal.logging.UiEventLogger
+import com.android.systemui.Flags.enableWidgetPickerSizeFilter
import com.android.systemui.communal.domain.interactor.CommunalInteractor
import com.android.systemui.communal.domain.interactor.CommunalSceneInteractor
import com.android.systemui.communal.domain.interactor.CommunalSettingsInteractor
@@ -36,6 +37,7 @@
import com.android.systemui.log.dagger.CommunalLog
import com.android.systemui.media.controls.ui.view.MediaHost
import com.android.systemui.media.dagger.MediaModule
+import com.android.systemui.res.R
import javax.inject.Inject
import javax.inject.Named
import kotlinx.coroutines.CoroutineDispatcher
@@ -138,6 +140,16 @@
return Intent(Intent.ACTION_PICK).apply {
setPackage(packageName)
+ if (enableWidgetPickerSizeFilter()) {
+ putExtra(
+ EXTRA_DESIRED_WIDGET_WIDTH,
+ resources.getDimensionPixelSize(R.dimen.communal_widget_picker_desired_width)
+ )
+ putExtra(
+ EXTRA_DESIRED_WIDGET_HEIGHT,
+ resources.getDimensionPixelSize(R.dimen.communal_widget_picker_desired_height)
+ )
+ }
putExtra(
AppWidgetManager.EXTRA_CATEGORY_FILTER,
communalSettingsInteractor.communalWidgetCategories.value
@@ -163,6 +175,8 @@
companion object {
private const val TAG = "CommunalEditModeViewModel"
+ private const val EXTRA_DESIRED_WIDGET_WIDTH = "desired_widget_width"
+ private const val EXTRA_DESIRED_WIDGET_HEIGHT = "desired_widget_height"
private const val EXTRA_UI_SURFACE_KEY = "ui_surface"
private const val EXTRA_UI_SURFACE_VALUE = "widgets_hub"
const val EXTRA_ADDED_APP_WIDGETS_KEY = "added_app_widgets"
diff --git a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalTransitionViewModel.kt
index 9114aab..7a20ebc 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalTransitionViewModel.kt
@@ -21,12 +21,14 @@
import com.android.systemui.communal.util.CommunalColors
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
+import com.android.systemui.keyguard.shared.model.Edge
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.shared.model.TransitionState
import com.android.systemui.keyguard.ui.viewmodel.DreamingToGlanceableHubTransitionViewModel
import com.android.systemui.keyguard.ui.viewmodel.GlanceableHubToDreamingTransitionViewModel
import com.android.systemui.keyguard.ui.viewmodel.GlanceableHubToLockscreenTransitionViewModel
import com.android.systemui.keyguard.ui.viewmodel.LockscreenToGlanceableHubTransitionViewModel
+import com.android.systemui.scene.shared.model.Scenes
import javax.inject.Inject
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
@@ -53,7 +55,7 @@
// Show UMO on glanceable hub immediately on transition into glanceable hub
private val showUmoFromOccludedToGlanceableHub: Flow<Boolean> =
keyguardTransitionInteractor
- .transitionStepsFromState(KeyguardState.OCCLUDED)
+ .transition(Edge.create(from = KeyguardState.OCCLUDED))
.filter {
it.to == KeyguardState.GLANCEABLE_HUB &&
(it.transitionState == TransitionState.STARTED ||
@@ -63,7 +65,10 @@
private val showUmoFromGlanceableHubToOccluded: Flow<Boolean> =
keyguardTransitionInteractor
- .transitionStepsFromState(KeyguardState.GLANCEABLE_HUB)
+ .transition(
+ edge = Edge.create(from = Scenes.Communal),
+ edgeWithoutSceneContainer = Edge.create(from = KeyguardState.GLANCEABLE_HUB)
+ )
.filter {
it.to == KeyguardState.OCCLUDED &&
(it.transitionState == TransitionState.FINISHED ||
@@ -91,11 +96,12 @@
val showCommunalFromOccluded: Flow<Boolean> = communalInteractor.showCommunalFromOccluded
val transitionFromOccludedEnded =
- keyguardTransitionInteractor.transitionStepsFromState(KeyguardState.OCCLUDED).filter { step
- ->
- step.transitionState == TransitionState.FINISHED ||
- step.transitionState == TransitionState.CANCELED
- }
+ keyguardTransitionInteractor
+ .transition(Edge.create(from = KeyguardState.OCCLUDED))
+ .filter { step ->
+ step.transitionState == TransitionState.FINISHED ||
+ step.transitionState == TransitionState.CANCELED
+ }
val recentsBackgroundColor: Flow<Color?> =
combine(showCommunalFromOccluded, communalColors.backgroundColor) {
diff --git a/packages/SystemUI/src/com/android/systemui/communal/widgets/SmartspaceAppWidgetHostView.kt b/packages/SystemUI/src/com/android/systemui/communal/widgets/SmartspaceAppWidgetHostView.kt
new file mode 100644
index 0000000..7f11463
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/communal/widgets/SmartspaceAppWidgetHostView.kt
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.communal.widgets
+
+import android.appwidget.AppWidgetHostView
+import android.appwidget.AppWidgetProviderInfo
+import android.content.Context
+import com.android.systemui.animation.LaunchableView
+import com.android.systemui.animation.LaunchableViewDelegate
+
+/** AppWidgetHostView that displays in communal hub to show smartspace content. */
+class SmartspaceAppWidgetHostView(context: Context) : AppWidgetHostView(context), LaunchableView {
+ private val launchableViewDelegate =
+ LaunchableViewDelegate(
+ this,
+ superSetVisibility = { super.setVisibility(it) },
+ )
+
+ override fun setAppWidget(appWidgetId: Int, info: AppWidgetProviderInfo?) {
+ super.setAppWidget(appWidgetId, info)
+ setPadding(0, 0, 0, 0)
+ }
+
+ override fun getRemoteContextEnsuringCorrectCachedApkPath(): Context? {
+ // Silence errors
+ return null
+ }
+
+ override fun setShouldBlockVisibilityChanges(block: Boolean) =
+ launchableViewDelegate.setShouldBlockVisibilityChanges(block)
+
+ override fun setVisibility(visibility: Int) = launchableViewDelegate.setVisibility(visibility)
+}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/widgets/WidgetInteractionHandler.kt b/packages/SystemUI/src/com/android/systemui/communal/widgets/WidgetInteractionHandler.kt
index 51a3a6d..e88a8b5 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/widgets/WidgetInteractionHandler.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/widgets/WidgetInteractionHandler.kt
@@ -18,6 +18,7 @@
import android.app.ActivityOptions
import android.app.PendingIntent
+import android.appwidget.AppWidgetHostView
import android.content.Intent
import android.util.Pair
import android.view.View
@@ -26,9 +27,11 @@
import androidx.core.util.component2
import com.android.systemui.animation.ActivityTransitionAnimator
import com.android.systemui.common.ui.view.getNearestParent
+import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.plugins.ActivityStarter
import javax.inject.Inject
+@SysUISingleton
class WidgetInteractionHandler
@Inject
constructor(
@@ -55,7 +58,7 @@
pendingIntent: PendingIntent,
launchOptions: Pair<Intent, ActivityOptions>,
): Boolean {
- val hostView = view.getNearestParent<CommunalAppWidgetHostView>()
+ val hostView = view.getNearestParent<AppWidgetHostView>()
val animationController = hostView?.let(ActivityTransitionAnimator.Controller::fromView)
val (fillInIntent, activityOptions) = launchOptions
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSystemUIModule.java
index 7aab37e..9f0fc51 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSystemUIModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSystemUIModule.java
@@ -31,6 +31,7 @@
import com.android.systemui.dock.DockManager;
import com.android.systemui.dock.DockManagerImpl;
import com.android.systemui.doze.DozeHost;
+import com.android.systemui.keyboard.shortcut.ShortcutHelperModule;
import com.android.systemui.keyguard.ui.composable.blueprint.DefaultBlueprintModule;
import com.android.systemui.keyguard.ui.view.layout.blueprints.KeyguardBlueprintModule;
import com.android.systemui.keyguard.ui.view.layout.sections.KeyguardSectionsModule;
@@ -137,7 +138,8 @@
UnfoldTransitionModule.Startables.class,
ToastModule.class,
VolumeModule.class,
- WallpaperModule.class
+ WallpaperModule.class,
+ ShortcutHelperModule.class,
})
public abstract class ReferenceSystemUIModule {
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/KeyboardModule.kt b/packages/SystemUI/src/com/android/systemui/keyboard/KeyboardModule.kt
index fc9406b..c6fb4f9 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/KeyboardModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/KeyboardModule.kt
@@ -19,13 +19,12 @@
import com.android.systemui.keyboard.data.repository.KeyboardRepository
import com.android.systemui.keyboard.data.repository.KeyboardRepositoryImpl
-import com.android.systemui.keyboard.shortcut.ShortcutHelperModule
import com.android.systemui.keyboard.stickykeys.data.repository.StickyKeysRepository
import com.android.systemui.keyboard.stickykeys.data.repository.StickyKeysRepositoryImpl
import dagger.Binds
import dagger.Module
-@Module(includes = [ShortcutHelperModule::class])
+@Module
abstract class KeyboardModule {
@Binds
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/GlanceableHubQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/GlanceableHubQuickAffordanceConfig.kt
index d09b9f6..5d54126 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/GlanceableHubQuickAffordanceConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/GlanceableHubQuickAffordanceConfig.kt
@@ -38,6 +38,7 @@
) : KeyguardQuickAffordanceConfig {
override val key: String = BuiltInKeyguardQuickAffordanceKeys.GLANCEABLE_HUB
+
override fun pickerName(): String = "Glanceable hub"
override val pickerIconResourceId = R.drawable.ic_widgets
@@ -52,6 +53,10 @@
}
}
+ override suspend fun getPickerScreenState(): KeyguardQuickAffordanceConfig.PickerScreenState {
+ return KeyguardQuickAffordanceConfig.PickerScreenState.UnavailableOnDevice
+ }
+
override fun onTriggered(
expandable: Expandable?
): KeyguardQuickAffordanceConfig.OnTriggeredResult {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepository.kt
index 8ec460a..1b201ce 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepository.kt
@@ -20,6 +20,7 @@
import android.animation.ValueAnimator
import android.animation.ValueAnimator.AnimatorUpdateListener
import android.annotation.FloatRange
+import android.annotation.SuppressLint
import android.os.Trace
import android.util.Log
import com.android.app.tracing.coroutines.withContext
@@ -117,10 +118,11 @@
constructor(
@Main val mainDispatcher: CoroutineDispatcher,
) : KeyguardTransitionRepository {
- /*
- * Each transition between [KeyguardState]s will have an associated Flow.
- * In order to collect these events, clients should call [transition].
+ /**
+ * Each transition between [KeyguardState]s will have an associated Flow. In order to collect
+ * these events, clients should call [transition].
*/
+ @SuppressLint("SharedFlowCreation")
private val _transitions =
MutableSharedFlow<TransitionStep>(
replay = 2,
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractor.kt
index 756c6c2..118ea16 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractor.kt
@@ -24,10 +24,10 @@
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.keyguard.KeyguardWmStateRefactor
import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository
+import com.android.systemui.keyguard.shared.model.Edge
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.power.domain.interactor.PowerInteractor
import com.android.systemui.scene.shared.flag.SceneContainerFlag
-import com.android.systemui.util.kotlin.Utils.Companion.sample as sampleCombine
import com.android.wm.shell.animation.Interpolators
import javax.inject.Inject
import kotlin.time.Duration.Companion.milliseconds
@@ -46,6 +46,7 @@
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.launch
+import com.android.systemui.util.kotlin.Utils.Companion.sample as sampleCombine
@ExperimentalCoroutinesApi
@SysUISingleton
@@ -83,7 +84,7 @@
val surfaceBehindVisibility: Flow<Boolean?> =
combine(
transitionInteractor.startedKeyguardTransitionStep,
- transitionInteractor.transitionStepsFromState(KeyguardState.ALTERNATE_BOUNCER)
+ transitionInteractor.transition(Edge.create(from = KeyguardState.ALTERNATE_BOUNCER))
) { startedStep, fromBouncerStep ->
if (startedStep.to != KeyguardState.GONE) {
return@combine null
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGoneTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGoneTransitionInteractor.kt
index a540d76..f5b12a2 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGoneTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGoneTransitionInteractor.kt
@@ -169,6 +169,7 @@
KeyguardState.AOD -> TO_AOD_DURATION
KeyguardState.DOZING -> TO_DOZING_DURATION
KeyguardState.LOCKSCREEN -> TO_LOCKSCREEN_DURATION
+ KeyguardState.GLANCEABLE_HUB -> TO_GLANCEABLE_HUB_DURATION
else -> DEFAULT_DURATION
}.inWholeMilliseconds
}
@@ -181,5 +182,6 @@
val TO_AOD_DURATION = 1300.milliseconds
val TO_DOZING_DURATION = 933.milliseconds
val TO_LOCKSCREEN_DURATION = DEFAULT_DURATION
+ val TO_GLANCEABLE_HUB_DURATION = DEFAULT_DURATION
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractor.kt
index 8cf4b53..aaf935f 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractor.kt
@@ -25,10 +25,12 @@
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.keyguard.KeyguardWmStateRefactor
import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository
+import com.android.systemui.keyguard.shared.model.Edge
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.shared.model.TransitionModeOnCanceled
import com.android.systemui.power.domain.interactor.PowerInteractor
import com.android.systemui.scene.shared.flag.SceneContainerFlag
+import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.user.domain.interactor.SelectedUserInteractor
import com.android.systemui.util.kotlin.Utils.Companion.sample
import com.android.systemui.util.kotlin.sample
@@ -81,7 +83,10 @@
val surfaceBehindVisibility: Flow<Boolean?> =
combine(
transitionInteractor.startedKeyguardTransitionStep,
- transitionInteractor.transitionStepsFromState(KeyguardState.PRIMARY_BOUNCER)
+ transitionInteractor.transition(
+ edge = Edge.create(from = Scenes.Bouncer),
+ edgeWithoutSceneContainer = Edge.create(from = KeyguardState.PRIMARY_BOUNCER)
+ )
) { startedStep, fromBouncerStep ->
if (startedStep.to != KeyguardState.GONE) {
return@combine null
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt
index 73835a3c..48660f2 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt
@@ -50,7 +50,7 @@
import com.android.systemui.statusbar.CommandQueue
import com.android.systemui.statusbar.notification.NotificationUtils.interpolate
import com.android.systemui.statusbar.notification.stack.domain.interactor.SharedNotificationContainerInteractor
-import com.android.systemui.util.kotlin.Utils.Companion.sample as sampleCombine
+import com.android.systemui.util.kotlin.Utils.Companion.sampleFilter
import com.android.systemui.util.kotlin.pairwise
import com.android.systemui.util.kotlin.sample
import javax.inject.Inject
@@ -77,6 +77,7 @@
import kotlinx.coroutines.flow.merge
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.flow.stateIn
+import com.android.systemui.util.kotlin.Utils.Companion.sample as sampleCombine
/**
* Encapsulates business-logic related to the keyguard but not to a more specific part within it.
@@ -91,7 +92,7 @@
bouncerRepository: KeyguardBouncerRepository,
configurationInteractor: ConfigurationInteractor,
shadeRepository: ShadeRepository,
- keyguardTransitionInteractor: KeyguardTransitionInteractor,
+ private val keyguardTransitionInteractor: KeyguardTransitionInteractor,
sceneInteractorProvider: Provider<SceneInteractor>,
private val fromGoneTransitionInteractor: Provider<FromGoneTransitionInteractor>,
private val fromLockscreenTransitionInteractor: Provider<FromLockscreenTransitionInteractor>,
@@ -248,21 +249,17 @@
val isKeyguardGoingAway: Flow<Boolean> = repository.isKeyguardGoingAway
/** Keyguard can be clipped at the top as the shade is dragged */
- val topClippingBounds: Flow<Int?> =
- combineTransform(
- configurationInteractor.onAnyConfigurationChange,
+ val topClippingBounds: Flow<Int?> by lazy {
+ repository.topClippingBounds
+ .sampleFilter(
keyguardTransitionInteractor
- .transitionValue(GONE)
- .map { it == 1f }
- .onStart { emit(false) }
- .distinctUntilChanged(),
- repository.topClippingBounds
- ) { _, isGone, topClippingBounds ->
- if (!isGone) {
- emit(topClippingBounds)
- }
+ .transitionValue(scene = Scenes.Gone, stateWithoutSceneContainer = GONE)
+ .onStart { emit(0f) }
+ ) { goneValue ->
+ goneValue != 1f
}
.distinctUntilChanged()
+ }
/** Last point that [KeyguardRootView] view was tapped */
val lastRootViewTapPosition: Flow<Point?> = repository.lastRootViewTapPosition.asStateFlow()
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt
index 2766b71..37272dc 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt
@@ -223,6 +223,17 @@
}
}
+ fun transitionValue(
+ scene: SceneKey,
+ stateWithoutSceneContainer: KeyguardState,
+ ): Flow<Float> {
+ return if (SceneContainerFlag.isEnabled) {
+ sceneInteractor.get().transitionProgress(scene)
+ } else {
+ transitionValue(stateWithoutSceneContainer)
+ }
+ }
+
/**
* The amount of transition into or out of the given [KeyguardState].
*
@@ -232,26 +243,13 @@
fun transitionValue(
state: KeyguardState,
): Flow<Float> {
+ if (SceneContainerFlag.isEnabled && state != state.mapToSceneContainerState()) {
+ Log.e(TAG, "SceneContainer is enabled but a deprecated state $state is used.")
+ return transitionValue(state.mapToSceneContainerScene()!!, state)
+ }
return getTransitionValueFlow(state)
}
- /**
- * AOD<->* transition information, mapped to dozeAmount range of AOD (1f) <->
- * * (0f).
- */
- @SuppressLint("SharedFlowCreation")
- val dozeAmountTransition: Flow<TransitionStep> =
- repository.transitions
- .filter { step -> step.from == AOD || step.to == AOD }
- .map { step ->
- if (step.from == AOD) {
- step.copy(value = 1 - step.value)
- } else {
- step
- }
- }
- .shareIn(scope, SharingStarted.Eagerly, replay = 1)
-
/** The last [TransitionStep] with a [TransitionState] of STARTED */
val startedKeyguardTransitionStep: Flow<TransitionStep> =
repository.transitions.filter { step -> step.transitionState == TransitionState.STARTED }
@@ -267,8 +265,6 @@
.map { step -> step.to }
.shareIn(scope, SharingStarted.Eagerly, replay = 1)
- val currentTransitionInfo: StateFlow<TransitionInfo> = repository.currentTransitionInfoInternal
-
/** The from state of the last [TransitionState.STARTED] transition. */
// TODO: is it performant to have several SharedFlows side by side instead of one?
@SuppressLint("SharedFlowCreation")
@@ -415,14 +411,6 @@
/** Whether we've currently STARTED a transition and haven't yet FINISHED it. */
val isInTransitionToAnyState = isInTransitionWhere({ true }, { true })
- fun transitionStepsFromState(fromState: KeyguardState): Flow<TransitionStep> {
- return transition(Edge.create(from = fromState, to = null))
- }
-
- fun transitionStepsToState(toState: KeyguardState): Flow<TransitionStep> {
- return transition(Edge.create(from = null, to = toState))
- }
-
/**
* Called to start a transition that will ultimately dismiss the keyguard from the current
* state.
@@ -558,10 +546,6 @@
return currentKeyguardState.replayCache.last()
}
- fun getStartedState(): KeyguardState {
- return startedKeyguardState.replayCache.last()
- }
-
fun getStartedFromState(): KeyguardState {
return startedKeyguardFromState.replayCache.last()
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/scenetransition/LockscreenSceneTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/scenetransition/LockscreenSceneTransitionInteractor.kt
index 3baeb76..9b3ba7d 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/scenetransition/LockscreenSceneTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/scenetransition/LockscreenSceneTransitionInteractor.kt
@@ -131,7 +131,7 @@
val newTransition =
TransitionInfo(
ownerName = this::class.java.simpleName,
- from = transitionInteractor.currentTransitionInfo.value.to,
+ from = transitionInteractor.currentTransitionInfoInternal.value.to,
to = state,
animator = null,
modeOnCanceled = TransitionModeOnCanceled.REVERSE
@@ -150,7 +150,7 @@
private suspend fun handleTransition(transition: ObservableTransitionState.Transition) {
if (transition.fromScene == Scenes.Lockscreen) {
if (currentTransitionId != null) {
- val currentToState = transitionInteractor.currentTransitionInfo.value.to
+ val currentToState = transitionInteractor.currentTransitionInfoInternal.value.to
if (currentToState == UNDEFINED) {
transitionKtfTo(transitionInteractor.getStartedFromState())
}
@@ -201,7 +201,7 @@
}
private suspend fun startTransitionFromLockscreen() {
- val currentState = transitionInteractor.currentTransitionInfo.value.to
+ val currentState = transitionInteractor.currentTransitionInfoInternal.value.to
val newTransition =
TransitionInfo(
ownerName = this::class.java.simpleName,
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/Edge.kt b/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/Edge.kt
index c1e8d22..1306b26 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/Edge.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/Edge.kt
@@ -96,10 +96,23 @@
companion object {
private const val TAG = "Edge"
+ @JvmStatic
+ @JvmOverloads
fun create(from: KeyguardState? = null, to: KeyguardState? = null) = StateToState(from, to)
+ @JvmStatic
+ @JvmOverloads
fun create(from: KeyguardState? = null, to: SceneKey) = StateToScene(from, to)
+ @JvmStatic
+ @JvmOverloads
fun create(from: SceneKey, to: KeyguardState? = null) = SceneToState(from, to)
+
+ /**
+ * This edge is a placeholder for when an edge needs to be passed but there is no edge for
+ * this flag configuration available. Usually for Scene <-> Scene edges with scene container
+ * enabled where these edges are managed by STL separately.
+ */
+ val INVALID = StateToState(UNDEFINED, UNDEFINED)
}
}
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 2b4c4af..0a8c190 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
@@ -15,6 +15,9 @@
*/
package com.android.systemui.keyguard.shared.model
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.filter
+
/** This information will flow from the [KeyguardTransitionRepository] to control the UI layer */
data class TransitionStep
@JvmOverloads
@@ -39,3 +42,6 @@
return to == state && transitionState == TransitionState.FINISHED
}
}
+
+fun Flow<TransitionStep>.filterState(transitionState: TransitionState) =
+ this.filter { it.transitionState == transitionState }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/transitions/DeviceEntryIconTransitionModule.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/transitions/DeviceEntryIconTransitionModule.kt
index 1f4bc61..ecdc21c 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/transitions/DeviceEntryIconTransitionModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/transitions/DeviceEntryIconTransitionModule.kt
@@ -35,6 +35,7 @@
import com.android.systemui.keyguard.ui.viewmodel.GlanceableHubToOccludedTransitionViewModel
import com.android.systemui.keyguard.ui.viewmodel.GoneToAodTransitionViewModel
import com.android.systemui.keyguard.ui.viewmodel.GoneToDozingTransitionViewModel
+import com.android.systemui.keyguard.ui.viewmodel.GoneToGlanceableHubTransitionViewModel
import com.android.systemui.keyguard.ui.viewmodel.GoneToLockscreenTransitionViewModel
import com.android.systemui.keyguard.ui.viewmodel.LockscreenToAodTransitionViewModel
import com.android.systemui.keyguard.ui.viewmodel.LockscreenToDozingTransitionViewModel
@@ -246,4 +247,10 @@
abstract fun occludedToGlanceableHub(
impl: OccludedToGlanceableHubTransitionViewModel
): DeviceEntryIconTransition
+
+ @Binds
+ @IntoSet
+ abstract fun goneToGlanceableHub(
+ impl: GoneToGlanceableHubTransitionViewModel
+ ): DeviceEntryIconTransition
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModel.kt
index c05a1b7..d9a6d64 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModel.kt
@@ -29,6 +29,7 @@
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
import com.android.systemui.keyguard.shared.model.BurnInModel
import com.android.systemui.keyguard.shared.model.ClockSize
+import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.ui.StateToValue
import com.android.systemui.res.R
import javax.inject.Inject
@@ -111,8 +112,8 @@
params: BurnInParameters,
): Flow<BurnInModel> {
return combine(
- keyguardTransitionInteractor.dozeAmountTransition.map {
- Interpolators.FAST_OUT_SLOW_IN.getInterpolation(it.value)
+ keyguardTransitionInteractor.transitionValue(KeyguardState.AOD).map {
+ Interpolators.FAST_OUT_SLOW_IN.getInterpolation(it)
},
burnInInteractor.burnIn(
xDimenResourceId = R.dimen.burn_in_prevention_offset_x,
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GoneToGlanceableHubTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GoneToGlanceableHubTransitionViewModel.kt
new file mode 100644
index 0000000..8eab406
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GoneToGlanceableHubTransitionViewModel.kt
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyguard.ui.viewmodel
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.keyguard.domain.interactor.FromGoneTransitionInteractor.Companion.TO_GLANCEABLE_HUB_DURATION
+import com.android.systemui.keyguard.shared.model.Edge
+import com.android.systemui.keyguard.shared.model.KeyguardState.GLANCEABLE_HUB
+import com.android.systemui.keyguard.shared.model.KeyguardState.GONE
+import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow
+import com.android.systemui.keyguard.ui.transitions.DeviceEntryIconTransition
+import com.android.systemui.scene.shared.model.Scenes
+import javax.inject.Inject
+import kotlin.time.Duration.Companion.milliseconds
+import kotlinx.coroutines.flow.Flow
+
+@SysUISingleton
+class GoneToGlanceableHubTransitionViewModel
+@Inject
+constructor(
+ animationFlow: KeyguardTransitionAnimationFlow,
+) : DeviceEntryIconTransition {
+
+ private val transitionAnimation =
+ animationFlow
+ .setup(duration = TO_GLANCEABLE_HUB_DURATION, edge = Edge.create(GONE, Scenes.Communal))
+ .setupWithoutSceneContainer(edge = Edge.create(GONE, GLANCEABLE_HUB))
+
+ override val deviceEntryParentViewAlpha: Flow<Float> =
+ transitionAnimation.sharedFlow(
+ duration = 167.milliseconds,
+ onStep = { it },
+ onCancel = { 0f },
+ onFinish = { 1f },
+ )
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt
index ee52ad0..5027524 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt
@@ -203,7 +203,7 @@
combine(
communalInteractor.isIdleOnCommunal,
keyguardTransitionInteractor
- .transitionValue(GONE)
+ .transitionValue(scene = Scenes.Gone, stateWithoutSceneContainer = GONE)
.map { it == 1f }
.onStart { emit(false) },
keyguardTransitionInteractor
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaDataProcessor.kt b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaDataProcessor.kt
index 8e985e1..37dffd1 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaDataProcessor.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaDataProcessor.kt
@@ -107,6 +107,7 @@
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.launch
@@ -371,6 +372,7 @@
.onStart { emit(Unit) }
.map { allowMediaRecommendations() }
.distinctUntilChanged()
+ .flowOn(backgroundDispatcher)
// only track the most recent emission
.collectLatest {
allowMediaRecommendations = it
diff --git a/packages/SystemUI/src/com/android/systemui/media/muteawait/MediaMuteAwaitConnectionManager.kt b/packages/SystemUI/src/com/android/systemui/media/muteawait/MediaMuteAwaitConnectionManager.kt
index f47954a..3a292e7 100644
--- a/packages/SystemUI/src/com/android/systemui/media/muteawait/MediaMuteAwaitConnectionManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/muteawait/MediaMuteAwaitConnectionManager.kt
@@ -94,7 +94,7 @@
}
private fun AudioDeviceAttributes.getIcon(): Drawable {
- return deviceIconUtil.getIconFromAudioDeviceType(this.type, context)
+ return deviceIconUtil.getIconFromAudioDeviceType(this.type)
}
private fun IntArray.hasMedia() = USAGE_MEDIA in this
diff --git a/packages/SystemUI/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeSceneViewModel.kt b/packages/SystemUI/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeSceneViewModel.kt
index f677ec1b..d0c7fbc 100644
--- a/packages/SystemUI/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeSceneViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeSceneViewModel.kt
@@ -17,41 +17,25 @@
package com.android.systemui.notifications.ui.viewmodel
import com.android.compose.animation.scene.Back
-import com.android.compose.animation.scene.SceneKey
import com.android.compose.animation.scene.Swipe
import com.android.compose.animation.scene.UserAction
import com.android.compose.animation.scene.UserActionResult
import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.dagger.qualifiers.Application
-import com.android.systemui.shade.ui.viewmodel.OverlayShadeViewModel
+import com.android.systemui.scene.shared.model.SceneFamilies
import javax.inject.Inject
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
-import kotlinx.coroutines.flow.map
-import kotlinx.coroutines.flow.stateIn
+import kotlinx.coroutines.flow.asStateFlow
/** Models UI state and handles user input for the Notifications Shade scene. */
@SysUISingleton
-class NotificationsShadeSceneViewModel
-@Inject
-constructor(
- @Application private val applicationScope: CoroutineScope,
- overlayShadeViewModel: OverlayShadeViewModel,
-) {
+class NotificationsShadeSceneViewModel @Inject constructor() {
val destinationScenes: StateFlow<Map<UserAction, UserActionResult>> =
- overlayShadeViewModel.backgroundScene
- .map(::destinationScenes)
- .stateIn(
- scope = applicationScope,
- started = SharingStarted.WhileSubscribed(),
- initialValue = destinationScenes(overlayShadeViewModel.backgroundScene.value),
+ MutableStateFlow(
+ mapOf(
+ Swipe.Up to SceneFamilies.Home,
+ Back to SceneFamilies.Home,
+ )
)
-
- private fun destinationScenes(backgroundScene: SceneKey): Map<UserAction, UserActionResult> {
- return mapOf(
- Swipe.Up to backgroundScene,
- Back to backgroundScene,
- )
- }
+ .asStateFlow()
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModel.kt
index 6cf2e52..79cdfec 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModel.kt
@@ -14,8 +14,6 @@
* limitations under the License.
*/
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
package com.android.systemui.qs.ui.viewmodel
import androidx.lifecycle.LifecycleOwner
@@ -28,12 +26,12 @@
import com.android.compose.animation.scene.UserActionResult
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
-import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor
import com.android.systemui.media.controls.domain.pipeline.interactor.MediaCarouselInteractor
import com.android.systemui.qs.FooterActionsController
import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsViewModel
import com.android.systemui.qs.ui.adapter.QSSceneAdapter
import com.android.systemui.scene.domain.interactor.SceneBackInteractor
+import com.android.systemui.scene.shared.model.SceneFamilies
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.settings.brightness.ui.viewModel.BrightnessMirrorViewModel
import com.android.systemui.shade.ui.viewmodel.ShadeHeaderViewModel
@@ -41,7 +39,6 @@
import java.util.concurrent.atomic.AtomicBoolean
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.combine
@@ -55,7 +52,6 @@
@Inject
constructor(
@Application private val applicationScope: CoroutineScope,
- deviceEntryInteractor: DeviceEntryInteractor,
val brightnessMirrorViewModel: BrightnessMirrorViewModel,
val shadeHeaderViewModel: ShadeHeaderViewModel,
val qsSceneAdapter: QSSceneAdapter,
@@ -77,25 +73,15 @@
val destinationScenes: StateFlow<Map<UserAction, UserActionResult>> =
combine(
- deviceEntryInteractor.isUnlocked,
- deviceEntryInteractor.canSwipeToEnter,
qsSceneAdapter.isCustomizerShowing,
backScene,
- ) { isUnlocked, canSwipeToDismiss, isCustomizerShowing, backScene ->
- destinationScenes(
- isUnlocked,
- canSwipeToDismiss,
- isCustomizerShowing,
- backScene,
- )
- }
+ transform = ::destinationScenes,
+ )
.stateIn(
scope = applicationScope,
started = SharingStarted.WhileSubscribed(),
initialValue =
destinationScenes(
- isUnlocked = deviceEntryInteractor.isUnlocked.value,
- canSwipeToDismiss = deviceEntryInteractor.canSwipeToEnter.value,
isCustomizing = qsSceneAdapter.isCustomizerShowing.value,
backScene = backScene.value,
),
@@ -104,18 +90,9 @@
val isMediaVisible: StateFlow<Boolean> = mediaCarouselInteractor.hasAnyMediaOrRecommendation
private fun destinationScenes(
- isUnlocked: Boolean,
- canSwipeToDismiss: Boolean?,
isCustomizing: Boolean,
backScene: SceneKey?,
): Map<UserAction, UserActionResult> {
- val upBottomEdge =
- when {
- canSwipeToDismiss == true -> Scenes.Lockscreen
- isUnlocked -> Scenes.Gone
- else -> Scenes.Lockscreen
- }
-
return buildMap {
if (isCustomizing) {
// TODO(b/332749288) Empty map so there are no back handlers and back can close
@@ -127,11 +104,8 @@
put(Back, UserActionResult(backScene ?: Scenes.Shade))
put(Swipe(SwipeDirection.Up), UserActionResult(backScene ?: Scenes.Shade))
put(
- Swipe(
- fromSource = Edge.Bottom,
- direction = SwipeDirection.Up,
- ),
- UserActionResult(upBottomEdge),
+ Swipe(fromSource = Edge.Bottom, direction = SwipeDirection.Up),
+ UserActionResult(SceneFamilies.Home),
)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeSceneViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeSceneViewModel.kt
index c1a5646..bd748d5 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeSceneViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeSceneViewModel.kt
@@ -17,30 +17,26 @@
package com.android.systemui.qs.ui.viewmodel
import com.android.compose.animation.scene.Back
-import com.android.compose.animation.scene.SceneKey
import com.android.compose.animation.scene.Swipe
import com.android.compose.animation.scene.UserAction
import com.android.compose.animation.scene.UserActionResult
import com.android.systemui.brightness.ui.viewmodel.BrightnessSliderViewModel
import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.qs.panels.ui.viewmodel.EditModeViewModel
import com.android.systemui.qs.panels.ui.viewmodel.TileGridViewModel
import com.android.systemui.qs.ui.adapter.QSSceneAdapter
+import com.android.systemui.scene.shared.model.SceneFamilies
import com.android.systemui.shade.ui.viewmodel.OverlayShadeViewModel
import javax.inject.Inject
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
-import kotlinx.coroutines.flow.map
-import kotlinx.coroutines.flow.stateIn
+import kotlinx.coroutines.flow.asStateFlow
/** Models UI state and handles user input for the Quick Settings Shade scene. */
@SysUISingleton
class QuickSettingsShadeSceneViewModel
@Inject
constructor(
- @Application private val applicationScope: CoroutineScope,
val overlayShadeViewModel: OverlayShadeViewModel,
val brightnessSliderViewModel: BrightnessSliderViewModel,
val tileGridViewModel: TileGridViewModel,
@@ -48,18 +44,11 @@
val qsSceneAdapter: QSSceneAdapter,
) {
val destinationScenes: StateFlow<Map<UserAction, UserActionResult>> =
- overlayShadeViewModel.backgroundScene
- .map(::destinationScenes)
- .stateIn(
- scope = applicationScope,
- started = SharingStarted.WhileSubscribed(),
- initialValue = destinationScenes(overlayShadeViewModel.backgroundScene.value),
+ MutableStateFlow(
+ mapOf(
+ Swipe.Up to SceneFamilies.Home,
+ Back to SceneFamilies.Home,
+ )
)
-
- private fun destinationScenes(backgroundScene: SceneKey): Map<UserAction, UserActionResult> {
- return mapOf(
- Swipe.Up to backgroundScene,
- Back to backgroundScene,
- )
- }
+ .asStateFlow()
}
diff --git a/packages/SystemUI/src/com/android/systemui/scene/KeyguardlessSceneContainerFrameworkModule.kt b/packages/SystemUI/src/com/android/systemui/scene/KeyguardlessSceneContainerFrameworkModule.kt
index 7a9d09a..da23936 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/KeyguardlessSceneContainerFrameworkModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/KeyguardlessSceneContainerFrameworkModule.kt
@@ -18,6 +18,7 @@
import com.android.systemui.CoreStartable
import com.android.systemui.notifications.ui.composable.NotificationsShadeSessionModule
+import com.android.systemui.scene.domain.SceneDomainModule
import com.android.systemui.scene.domain.interactor.WindowRootViewVisibilityInteractor
import com.android.systemui.scene.domain.startable.SceneContainerStartable
import com.android.systemui.scene.domain.startable.ScrimStartable
@@ -40,6 +41,7 @@
NotificationsShadeSessionModule::class,
QuickSettingsSceneModule::class,
ShadeSceneModule::class,
+ SceneDomainModule::class,
],
)
interface KeyguardlessSceneContainerFrameworkModule {
diff --git a/packages/SystemUI/src/com/android/systemui/scene/SceneContainerFrameworkModule.kt b/packages/SystemUI/src/com/android/systemui/scene/SceneContainerFrameworkModule.kt
index 7e6dfb8..a0cf82a 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/SceneContainerFrameworkModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/SceneContainerFrameworkModule.kt
@@ -19,6 +19,7 @@
import com.android.systemui.CoreStartable
import com.android.systemui.bouncer.shared.flag.ComposeBouncerFlagsModule
import com.android.systemui.notifications.ui.composable.NotificationsShadeSessionModule
+import com.android.systemui.scene.domain.SceneDomainModule
import com.android.systemui.scene.domain.interactor.WindowRootViewVisibilityInteractor
import com.android.systemui.scene.domain.startable.SceneContainerStartable
import com.android.systemui.scene.domain.startable.ScrimStartable
@@ -46,6 +47,7 @@
QuickSettingsShadeSceneModule::class,
NotificationsShadeSceneModule::class,
NotificationsShadeSessionModule::class,
+ SceneDomainModule::class,
],
)
interface SceneContainerFrameworkModule {
diff --git a/packages/SystemUI/src/com/android/systemui/scene/ShadelessSceneContainerFrameworkModule.kt b/packages/SystemUI/src/com/android/systemui/scene/ShadelessSceneContainerFrameworkModule.kt
index b918277..a326ec1 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/ShadelessSceneContainerFrameworkModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/ShadelessSceneContainerFrameworkModule.kt
@@ -16,6 +16,7 @@
package com.android.systemui.scene
+import com.android.systemui.scene.domain.SceneDomainModule
import com.android.systemui.scene.shared.model.SceneContainerConfig
import com.android.systemui.scene.shared.model.Scenes
import dagger.Module
@@ -29,6 +30,7 @@
EmptySceneModule::class,
GoneSceneModule::class,
LockscreenSceneModule::class,
+ SceneDomainModule::class,
],
)
object ShadelessSceneContainerFrameworkModule {
diff --git a/packages/SystemUI/src/com/android/systemui/scene/domain/SceneDomainModule.kt b/packages/SystemUI/src/com/android/systemui/scene/domain/SceneDomainModule.kt
new file mode 100644
index 0000000..9b2a6dd
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/scene/domain/SceneDomainModule.kt
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.scene.domain
+
+import com.android.systemui.scene.domain.resolver.HomeSceneFamilyResolverModule
+import com.android.systemui.scene.domain.resolver.SceneResolverModule
+import dagger.Module
+
+@Module(
+ includes =
+ [
+ HomeSceneFamilyResolverModule::class,
+ SceneResolverModule::class,
+ ]
+)
+object SceneDomainModule
diff --git a/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneInteractor.kt b/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneInteractor.kt
index b1700e3..998537c 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneInteractor.kt
@@ -23,9 +23,12 @@
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.deviceentry.domain.interactor.DeviceUnlockedInteractor
import com.android.systemui.scene.data.repository.SceneContainerRepository
+import com.android.systemui.scene.domain.resolver.SceneResolver
import com.android.systemui.scene.shared.logger.SceneLogger
+import com.android.systemui.scene.shared.model.SceneFamilies
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.util.kotlin.pairwiseBy
+import dagger.Lazy
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -52,6 +55,7 @@
@Application private val applicationScope: CoroutineScope,
private val repository: SceneContainerRepository,
private val logger: SceneLogger,
+ private val sceneFamilyResolvers: Lazy<Map<SceneKey, @JvmSuppressWildcards SceneResolver>>,
private val deviceUnlockedInteractor: DeviceUnlockedInteractor,
) {
@@ -152,6 +156,28 @@
)
/**
+ * The amount of transition into or out of the given [scene].
+ *
+ * The value will be `0` if not in this scene or `1` when fully in the given scene.
+ */
+ fun transitionProgress(scene: SceneKey): Flow<Float> {
+ return transitionState.flatMapLatest { transition ->
+ when (transition) {
+ is ObservableTransitionState.Idle -> {
+ flowOf(if (transition.currentScene == scene) 1f else 0f)
+ }
+ is ObservableTransitionState.Transition -> {
+ when {
+ transition.toScene == scene -> transition.progress
+ transition.fromScene == scene -> transition.progress.map { 1f - it }
+ else -> flowOf(0f)
+ }
+ }
+ }
+ }
+ }
+
+ /**
* Returns the keys of all scenes in the container.
*
* The scenes will be sorted in z-order such that the last one is the one that should be
@@ -180,10 +206,11 @@
sceneState: Any? = null,
) {
val currentSceneKey = currentScene.value
+ val resolvedScene = sceneFamilyResolvers.get()[toScene]?.resolvedScene?.value ?: toScene
if (
!validateSceneChange(
from = currentSceneKey,
- to = toScene,
+ to = resolvedScene,
loggingReason = loggingReason,
)
) {
@@ -192,13 +219,13 @@
logger.logSceneChangeRequested(
from = currentSceneKey,
- to = toScene,
+ to = resolvedScene,
reason = loggingReason,
isInstant = false,
)
- onSceneAboutToChangeListener.forEach { it.onSceneAboutToChange(toScene, sceneState) }
- repository.changeScene(toScene, transitionKey)
+ onSceneAboutToChangeListener.forEach { it.onSceneAboutToChange(resolvedScene, sceneState) }
+ repository.changeScene(resolvedScene, transitionKey)
}
/**
@@ -212,10 +239,11 @@
loggingReason: String,
) {
val currentSceneKey = currentScene.value
+ val resolvedScene = sceneFamilyResolvers.get()[toScene]?.resolvedScene?.value ?: toScene
if (
!validateSceneChange(
from = currentSceneKey,
- to = toScene,
+ to = resolvedScene,
loggingReason = loggingReason,
)
) {
@@ -224,12 +252,12 @@
logger.logSceneChangeRequested(
from = currentSceneKey,
- to = toScene,
+ to = resolvedScene,
reason = loggingReason,
isInstant = true,
)
- repository.snapToScene(toScene)
+ repository.snapToScene(resolvedScene)
}
/**
@@ -288,6 +316,13 @@
repository.setTransitionState(transitionState)
}
+ /**
+ * Returns the [concrete scene][Scenes] for [sceneKey] if it is a [scene family][SceneFamilies],
+ * otherwise returns a singleton [Flow] containing [sceneKey].
+ */
+ fun resolveSceneFamily(sceneKey: SceneKey): Flow<SceneKey> =
+ sceneFamilyResolvers.get()[sceneKey]?.resolvedScene ?: flowOf(sceneKey)
+
private fun isVisibleInternal(
raw: Boolean = repository.isVisible.value,
isRemoteUserInteractionOngoing: Boolean = repository.isRemoteUserInteractionOngoing.value,
diff --git a/packages/SystemUI/src/com/android/systemui/scene/domain/resolver/HomeSceneFamilyResolver.kt b/packages/SystemUI/src/com/android/systemui/scene/domain/resolver/HomeSceneFamilyResolver.kt
new file mode 100644
index 0000000..f19929c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/scene/domain/resolver/HomeSceneFamilyResolver.kt
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+@file:OptIn(ExperimentalCoroutinesApi::class)
+
+package com.android.systemui.scene.domain.resolver
+
+import com.android.compose.animation.scene.SceneKey
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor
+import com.android.systemui.scene.shared.model.SceneFamilies
+import com.android.systemui.scene.shared.model.Scenes
+import dagger.Binds
+import dagger.Module
+import dagger.multibindings.IntoSet
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.stateIn
+
+/**
+ * Resolver for [SceneFamilies.Home]. The "home" scene family resolves to the scene that is
+ * currently underneath any "overlay" scene, such as shades or bouncer.
+ */
+@SysUISingleton
+class HomeSceneFamilyResolver
+@Inject
+constructor(
+ @Application private val applicationScope: CoroutineScope,
+ deviceEntryInteractor: DeviceEntryInteractor,
+) : SceneResolver {
+ override val targetFamily: SceneKey = SceneFamilies.Home
+
+ override val resolvedScene: StateFlow<SceneKey> =
+ combine(
+ deviceEntryInteractor.canSwipeToEnter,
+ deviceEntryInteractor.isUnlocked,
+ transform = ::homeScene,
+ )
+ .stateIn(
+ scope = applicationScope,
+ started = SharingStarted.WhileSubscribed(),
+ initialValue =
+ homeScene(
+ deviceEntryInteractor.canSwipeToEnter.value,
+ deviceEntryInteractor.isUnlocked.value,
+ )
+ )
+
+ private fun homeScene(canSwipeToEnter: Boolean?, isUnlocked: Boolean): SceneKey =
+ when {
+ canSwipeToEnter == true -> Scenes.Lockscreen
+ isUnlocked -> Scenes.Gone
+ else -> Scenes.Lockscreen
+ }
+}
+
+@Module
+interface HomeSceneFamilyResolverModule {
+ @Binds @IntoSet fun provideSceneResolver(interactor: HomeSceneFamilyResolver): SceneResolver
+}
diff --git a/packages/SystemUI/src/com/android/systemui/scene/domain/resolver/SceneResolver.kt b/packages/SystemUI/src/com/android/systemui/scene/domain/resolver/SceneResolver.kt
new file mode 100644
index 0000000..8372529
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/scene/domain/resolver/SceneResolver.kt
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.scene.domain.resolver
+
+import com.android.compose.animation.scene.SceneKey
+import dagger.Module
+import dagger.Provides
+import dagger.multibindings.Multibinds
+import kotlinx.coroutines.flow.StateFlow
+
+/** Resolves [concrete scenes][Scenes] from a [scene family][SceneFamilies]. */
+interface SceneResolver {
+ /** The scene family that this resolves. */
+ val targetFamily: SceneKey
+
+ /** The concrete scene that [targetFamily] is currently resolved to. */
+ val resolvedScene: StateFlow<SceneKey>
+}
+
+@Module
+interface SceneResolverModule {
+
+ @Multibinds fun resolverSet(): Set<@JvmSuppressWildcards SceneResolver>
+
+ companion object {
+ @Provides
+ fun provideResolverMap(
+ resolverSet: Set<@JvmSuppressWildcards SceneResolver>
+ ): Map<SceneKey, SceneResolver> = resolverSet.associateBy { it.targetFamily }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModel.kt b/packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModel.kt
index 09c80b0..ab24e0b 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModel.kt
@@ -34,6 +34,8 @@
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
/** Models UI state for the scene container. */
@@ -61,7 +63,9 @@
val isVisible: StateFlow<Boolean> = sceneInteractor.isVisible
private val destinationScenesBySceneKey =
- scenes.associate { scene -> scene.key to scene.destinationScenes }
+ scenes.associate { scene ->
+ scene.key to scene.destinationScenes.flatMapLatestConflated { replaceSceneFamilies(it) }
+ }
fun currentDestinationScenes(
scope: CoroutineScope,
@@ -140,7 +144,24 @@
val fromLockscreenScene = currentScene.value == Scenes.Lockscreen
!fromLockscreenScene || !isFalseTouch
- }
- ?: true
+ } ?: true
+ }
+
+ private fun replaceSceneFamilies(
+ destinationScenes: Map<UserAction, UserActionResult>,
+ ): Flow<Map<UserAction, UserActionResult>> {
+ return destinationScenes
+ .mapValues { (_, actionResult) ->
+ sceneInteractor.resolveSceneFamily(actionResult.toScene).map { scene ->
+ actionResult.copy(toScene = scene)
+ }
+ }
+ .combineValueFlows()
}
}
+
+private fun <K, V> Map<K, Flow<V>>.combineValueFlows(): Flow<Map<K, V>> =
+ combine(
+ asIterable().map { (k, fv) -> fv.map { k to it } },
+ transform = Array<Pair<K, V>>::toMap,
+ )
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java
index c01b7b6..1df085b 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java
@@ -227,7 +227,7 @@
bouncerViewBinder.bind(mView.findViewById(R.id.keyguard_bouncer_container));
collectFlow(mView, keyguardTransitionInteractor.transition(
- Edge.Companion.create(LOCKSCREEN, DREAMING)),
+ Edge.create(LOCKSCREEN, DREAMING)),
mLockscreenToDreamingTransition);
collectFlow(
mView,
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeControllerSceneImpl.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeControllerSceneImpl.kt
index 884ccef..ac1f971 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeControllerSceneImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeControllerSceneImpl.kt
@@ -17,16 +17,14 @@
package com.android.systemui.shade
import android.view.MotionEvent
-import com.android.compose.animation.scene.SceneKey
import com.android.systemui.assist.AssistManager
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dagger.qualifiers.Main
-import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor
-import com.android.systemui.deviceentry.domain.interactor.DeviceUnlockedInteractor
import com.android.systemui.log.LogBuffer
import com.android.systemui.log.dagger.ShadeTouchLog
import com.android.systemui.scene.domain.interactor.SceneInteractor
+import com.android.systemui.scene.shared.model.SceneFamilies
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.scene.shared.model.TransitionKeys.SlightlyFasterShadeCollapse
import com.android.systemui.shade.ShadeController.ShadeVisibilityListener
@@ -61,8 +59,6 @@
@Background private val scope: CoroutineScope,
private val shadeInteractor: ShadeInteractor,
private val sceneInteractor: SceneInteractor,
- private val deviceEntryInteractor: DeviceEntryInteractor,
- private val deviceUnlockedInteractor: DeviceUnlockedInteractor,
private val notificationStackScrollLayout: NotificationStackScrollLayout,
@ShadeTouchLog private val touchLog: LogBuffer,
private val vibratorHelper: VibratorHelper,
@@ -100,7 +96,7 @@
override fun instantCollapseShade() {
sceneInteractor.snapToScene(
- getCollapseDestinationScene(),
+ SceneFamilies.Home,
"hide shade",
)
}
@@ -140,24 +136,12 @@
private fun animateCollapseShadeInternal() {
sceneInteractor.changeScene(
- getCollapseDestinationScene(), // TODO(b/336581871): add sceneState?
+ SceneFamilies.Home, // TODO(b/336581871): add sceneState?
"ShadeController.animateCollapseShade",
SlightlyFasterShadeCollapse,
)
}
- private fun getCollapseDestinationScene(): SceneKey {
- // Always check whether device is unlocked before transitioning to gone scene.
- return if (
- deviceUnlockedInteractor.deviceUnlockStatus.value.isUnlocked &&
- deviceEntryInteractor.isDeviceEntered.value
- ) {
- Scenes.Gone
- } else {
- Scenes.Lockscreen
- }
- }
-
override fun cancelExpansionAndCollapseShade() {
// TODO do we need to actually cancel the touch session?
animateCollapseShade()
diff --git a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeBackActionInteractorImpl.kt b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeBackActionInteractorImpl.kt
index 55bd8c6..3a483f4 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeBackActionInteractorImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeBackActionInteractorImpl.kt
@@ -18,6 +18,7 @@
import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor
import com.android.systemui.scene.domain.interactor.SceneInteractor
+import com.android.systemui.scene.shared.model.SceneFamilies
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.shade.shared.model.ShadeMode
import javax.inject.Inject
@@ -36,11 +37,7 @@
if (shadeInteractor.isQsExpanded.value) {
val key =
if (fullyCollapse || shadeInteractor.shadeMode.value is ShadeMode.Dual) {
- if (deviceEntryInteractor.isDeviceEntered.value) {
- Scenes.Gone
- } else {
- Scenes.Lockscreen
- }
+ SceneFamilies.Home
} else {
Scenes.Shade
}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/OverlayShadeViewModel.kt b/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/OverlayShadeViewModel.kt
index b8dd628..0314091 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/OverlayShadeViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/OverlayShadeViewModel.kt
@@ -19,49 +19,41 @@
import com.android.compose.animation.scene.SceneKey
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
-import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor
import com.android.systemui.scene.domain.interactor.SceneInteractor
+import com.android.systemui.scene.shared.model.SceneFamilies
import com.android.systemui.scene.shared.model.Scenes
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
-import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
/**
* Models UI state and handles user input for the overlay shade UI, which shows a shade as an
* overlay on top of another scene UI.
*/
-@OptIn(ExperimentalCoroutinesApi::class)
@SysUISingleton
class OverlayShadeViewModel
@Inject
constructor(
- @Application private val applicationScope: CoroutineScope,
+ @Application applicationScope: CoroutineScope,
private val sceneInteractor: SceneInteractor,
- deviceEntryInteractor: DeviceEntryInteractor,
) {
/** The scene to show in the background when the overlay shade is open. */
val backgroundScene: StateFlow<SceneKey> =
- deviceEntryInteractor.isDeviceEntered
- .map(::backgroundScene)
+ sceneInteractor
+ .resolveSceneFamily(SceneFamilies.Home)
.stateIn(
scope = applicationScope,
started = SharingStarted.WhileSubscribed(),
- initialValue = backgroundScene(deviceEntryInteractor.isDeviceEntered.value)
+ initialValue = Scenes.Lockscreen,
)
/** Notifies that the user has clicked the semi-transparent background scrim. */
fun onScrimClicked() {
sceneInteractor.changeScene(
- toScene = backgroundScene.value,
+ toScene = SceneFamilies.Home,
loggingReason = "Shade scrim clicked",
)
}
-
- private fun backgroundScene(isDeviceEntered: Boolean): SceneKey {
- return if (isDeviceEntered) Scenes.Gone else Scenes.Lockscreen
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModel.kt b/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModel.kt
index e4a2424..b0100b9 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModel.kt
@@ -26,12 +26,12 @@
import com.android.compose.animation.scene.UserActionResult
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
-import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor
import com.android.systemui.media.controls.domain.pipeline.interactor.MediaCarouselInteractor
import com.android.systemui.qs.FooterActionsController
import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsViewModel
import com.android.systemui.qs.ui.adapter.QSSceneAdapter
import com.android.systemui.scene.domain.interactor.SceneInteractor
+import com.android.systemui.scene.shared.model.SceneFamilies
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.scene.shared.model.TransitionKeys.ToSplitShade
import com.android.systemui.settings.brightness.ui.viewModel.BrightnessMirrorViewModel
@@ -39,6 +39,7 @@
import com.android.systemui.shade.shared.model.ShadeMode
import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationsPlaceholderViewModel
import com.android.systemui.unfold.domain.interactor.UnfoldTransitionInteractor
+import com.android.systemui.utils.coroutines.flow.flatMapLatestConflated
import java.util.concurrent.atomic.AtomicBoolean
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
@@ -47,6 +48,7 @@
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
@@ -56,7 +58,6 @@
@Inject
constructor(
@Application private val applicationScope: CoroutineScope,
- deviceEntryInteractor: DeviceEntryInteractor,
val qsSceneAdapter: QSSceneAdapter,
val shadeHeaderViewModel: ShadeHeaderViewModel,
val notifications: NotificationsPlaceholderViewModel,
@@ -70,16 +71,12 @@
) {
val destinationScenes: StateFlow<Map<UserAction, UserActionResult>> =
combine(
- deviceEntryInteractor.isUnlocked,
- deviceEntryInteractor.canSwipeToEnter,
shadeInteractor.shadeMode,
- qsSceneAdapter.isCustomizerShowing
- ) { isUnlocked, canSwipeToDismiss, shadeMode, isCustomizerShowing ->
+ qsSceneAdapter.isCustomizerShowing,
+ ) { shadeMode, isCustomizerShowing ->
destinationScenes(
- isUnlocked = isUnlocked,
- canSwipeToDismiss = canSwipeToDismiss,
shadeMode = shadeMode,
- isCustomizing = isCustomizerShowing
+ isCustomizing = isCustomizerShowing,
)
}
.stateIn(
@@ -87,8 +84,6 @@
started = SharingStarted.WhileSubscribed(),
initialValue =
destinationScenes(
- isUnlocked = deviceEntryInteractor.isUnlocked.value,
- canSwipeToDismiss = deviceEntryInteractor.canSwipeToEnter.value,
shadeMode = shadeInteractor.shadeMode.value,
isCustomizing = qsSceneAdapter.isCustomizerShowing.value,
),
@@ -100,6 +95,9 @@
/** Whether or not the shade container should be clickable. */
val isClickable: StateFlow<Boolean> =
upDestinationSceneKey
+ .flatMapLatestConflated { key ->
+ key?.let { sceneInteractor.resolveSceneFamily(key) } ?: flowOf(null)
+ }
.map { it == Scenes.Lockscreen }
.stateIn(
scope = applicationScope,
@@ -138,27 +136,22 @@
}
private fun destinationScenes(
- isUnlocked: Boolean,
- canSwipeToDismiss: Boolean?,
shadeMode: ShadeMode,
isCustomizing: Boolean,
): Map<UserAction, UserActionResult> {
- val up =
- when {
- canSwipeToDismiss == true -> Scenes.Lockscreen
- isUnlocked -> Scenes.Gone
- else -> Scenes.Lockscreen
- }
-
- val upTransitionKey = ToSplitShade.takeIf { shadeMode is ShadeMode.Split }
-
- val down = Scenes.QuickSettings.takeIf { shadeMode is ShadeMode.Single }
-
return buildMap {
if (!isCustomizing) {
- this[Swipe(SwipeDirection.Up)] = UserActionResult(up, upTransitionKey)
+ set(
+ Swipe(SwipeDirection.Up),
+ UserActionResult(
+ SceneFamilies.Home,
+ ToSplitShade.takeIf { shadeMode is ShadeMode.Split }
+ )
+ )
} // TODO(b/330200163) Add an else to be able to collapse the shade while customizing
- down?.let { this[Swipe(SwipeDirection.Down)] = UserActionResult(down) }
+ if (shadeMode is ShadeMode.Single) {
+ set(Swipe(SwipeDirection.Down), UserActionResult(Scenes.QuickSettings))
+ }
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/AvalancheProvider.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/AvalancheProvider.kt
index c29d700..a8fd082 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/AvalancheProvider.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/AvalancheProvider.kt
@@ -24,6 +24,7 @@
import com.android.internal.logging.UiEventLogger
import com.android.systemui.broadcast.BroadcastDispatcher
import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.statusbar.notification.interruption.AvalancheSuppressor.AvalancheEvent
import javax.inject.Inject
// Class to track avalanche trigger event time.
@@ -31,37 +32,41 @@
class AvalancheProvider
@Inject
constructor(
- private val broadcastDispatcher: BroadcastDispatcher,
- private val logger: VisualInterruptionDecisionLogger,
- private val uiEventLogger: UiEventLogger,
+ private val broadcastDispatcher: BroadcastDispatcher,
+ private val logger: VisualInterruptionDecisionLogger,
+ private val uiEventLogger: UiEventLogger,
) {
val TAG = "AvalancheProvider"
val timeoutMs = 120000
var startTime: Long = 0L
- private val avalancheTriggerIntents = mutableSetOf(
+ private val avalancheTriggerIntents =
+ mutableSetOf(
Intent.ACTION_AIRPLANE_MODE_CHANGED,
Intent.ACTION_BOOT_COMPLETED,
Intent.ACTION_MANAGED_PROFILE_AVAILABLE,
Intent.ACTION_USER_SWITCHED
- )
+ )
- private val broadcastReceiver: BroadcastReceiver = object : BroadcastReceiver() {
- override fun onReceive(context: Context, intent: Intent) {
- if (intent.action in avalancheTriggerIntents) {
+ private val broadcastReceiver: BroadcastReceiver =
+ object : BroadcastReceiver() {
+ override fun onReceive(context: Context, intent: Intent) {
+ if (intent.action in avalancheTriggerIntents) {
- // Ignore when airplane mode turned on
- if (intent.action == Intent.ACTION_AIRPLANE_MODE_CHANGED
- && intent.getBooleanExtra(/* name= */ "state", /* defaultValue */ false)) {
- Log.d(TAG, "broadcastReceiver: ignore airplane mode on")
- return
+ // Ignore when airplane mode turned on
+ if (
+ intent.action == Intent.ACTION_AIRPLANE_MODE_CHANGED &&
+ intent.getBooleanExtra(/* name= */ "state", /* defaultValue */ false)
+ ) {
+ Log.d(TAG, "broadcastReceiver: ignore airplane mode on")
+ return
+ }
+ Log.d(TAG, "broadcastReceiver received intent.action=" + intent.action)
+ uiEventLogger.log(AvalancheEvent.AVALANCHE_SUPPRESSOR_RECEIVED_TRIGGERING_EVENT)
+ startTime = System.currentTimeMillis()
}
- Log.d(TAG, "broadcastReceiver received intent.action=" + intent.action)
- uiEventLogger.log(AvalancheSuppressor.AvalancheEvent.START);
- startTime = System.currentTimeMillis()
}
}
- }
fun register() {
val intentFilter = IntentFilter()
@@ -70,4 +75,4 @@
}
broadcastDispatcher.registerReceiver(broadcastReceiver, intentFilter)
}
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/CommonVisualInterruptionSuppressors.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/CommonVisualInterruptionSuppressors.kt
index f84b5f4..367aaad 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/CommonVisualInterruptionSuppressors.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/CommonVisualInterruptionSuppressors.kt
@@ -270,32 +270,26 @@
}
enum class AvalancheEvent(private val id: Int) : UiEventLogger.UiEventEnum {
- @UiEvent(
- doc =
- "An avalanche event occurred but this notification was suppressed by a " +
- "non-avalanche suppressor."
- )
- START(1802),
- @UiEvent(doc = "HUN was suppressed in avalanche.") SUPPRESS(1803),
- @UiEvent(doc = "HUN allowed during avalanche because it is high priority.")
- ALLOW_CONVERSATION_AFTER_AVALANCHE(1804),
- @UiEvent(doc = "HUN allowed during avalanche because it is a high priority conversation.")
- ALLOW_HIGH_PRIORITY_CONVERSATION_ANY_TIME(1805),
- @UiEvent(doc = "HUN allowed during avalanche because it is a call.") ALLOW_CALLSTYLE(1806),
+ @UiEvent(doc = "An avalanche event occurred, and a suppression period will start now.")
+ AVALANCHE_SUPPRESSOR_RECEIVED_TRIGGERING_EVENT(1824),
+ @UiEvent(doc = "HUN was suppressed in avalanche.")
+ AVALANCHE_SUPPRESSOR_HUN_SUPPRESSED(1825),
+ @UiEvent(doc = "HUN allowed during avalanche because conversation newer than the trigger.")
+ AVALANCHE_SUPPRESSOR_HUN_ALLOWED_NEW_CONVERSATION(1826),
+ @UiEvent(doc = "HUN allowed during avalanche because it is a priority conversation.")
+ AVALANCHE_SUPPRESSOR_HUN_ALLOWED_PRIORITY_CONVERSATION(1827),
+ @UiEvent(doc = "HUN allowed during avalanche because it is a CallStyle notification.")
+ AVALANCHE_SUPPRESSOR_HUN_ALLOWED_CALL_STYLE(1828),
+ @UiEvent(doc = "HUN allowed during avalanche because it is a reminder notification.")
+ AVALANCHE_SUPPRESSOR_HUN_ALLOWED_CATEGORY_REMINDER(1829),
@UiEvent(doc = "HUN allowed during avalanche because it is a calendar notification.")
- ALLOW_CATEGORY_REMINDER(1807),
- @UiEvent(doc = "HUN allowed during avalanche because it is a calendar notification.")
- ALLOW_CATEGORY_EVENT(1808),
- @UiEvent(
- doc =
- "HUN allowed during avalanche because it has a full screen intent and " +
- "the full screen intent permission is granted."
- )
- ALLOW_FSI_WITH_PERMISSION_ON(1809),
+ AVALANCHE_SUPPRESSOR_HUN_ALLOWED_CATEGORY_EVENT(1830),
+ @UiEvent(doc = "HUN allowed during avalanche because it has FSI.")
+ AVALANCHE_SUPPRESSOR_HUN_ALLOWED_FSI_WITH_PERMISSION(1831),
@UiEvent(doc = "HUN allowed during avalanche because it is colorized.")
- ALLOW_COLORIZED(1810),
+ AVALANCHE_SUPPRESSOR_HUN_ALLOWED_COLORIZED(1832),
@UiEvent(doc = "HUN allowed during avalanche because it is an emergency notification.")
- ALLOW_EMERGENCY(1811);
+ AVALANCHE_SUPPRESSOR_HUN_ALLOWED_EMERGENCY(1833);
override fun getId(): Int {
return id
@@ -323,46 +317,46 @@
entry.ranking.isConversation &&
entry.sbn.notification.getWhen() > avalancheProvider.startTime
) {
- uiEventLogger.log(AvalancheEvent.ALLOW_CONVERSATION_AFTER_AVALANCHE)
+ uiEventLogger.log(AvalancheEvent.AVALANCHE_SUPPRESSOR_HUN_ALLOWED_NEW_CONVERSATION)
return State.ALLOW_CONVERSATION_AFTER_AVALANCHE
}
if (entry.channel?.isImportantConversation == true) {
- uiEventLogger.log(AvalancheEvent.ALLOW_HIGH_PRIORITY_CONVERSATION_ANY_TIME)
+ uiEventLogger.log(AvalancheEvent.AVALANCHE_SUPPRESSOR_HUN_ALLOWED_PRIORITY_CONVERSATION)
return State.ALLOW_HIGH_PRIORITY_CONVERSATION_ANY_TIME
}
if (entry.sbn.notification.isStyle(Notification.CallStyle::class.java)) {
- uiEventLogger.log(AvalancheEvent.ALLOW_CALLSTYLE)
+ uiEventLogger.log(AvalancheEvent.AVALANCHE_SUPPRESSOR_HUN_ALLOWED_CALL_STYLE)
return State.ALLOW_CALLSTYLE
}
if (entry.sbn.notification.category == CATEGORY_REMINDER) {
- uiEventLogger.log(AvalancheEvent.ALLOW_CATEGORY_REMINDER)
+ uiEventLogger.log(AvalancheEvent.AVALANCHE_SUPPRESSOR_HUN_ALLOWED_CATEGORY_REMINDER)
return State.ALLOW_CATEGORY_REMINDER
}
if (entry.sbn.notification.category == CATEGORY_EVENT) {
- uiEventLogger.log(AvalancheEvent.ALLOW_CATEGORY_EVENT)
+ uiEventLogger.log(AvalancheEvent.AVALANCHE_SUPPRESSOR_HUN_ALLOWED_CATEGORY_EVENT)
return State.ALLOW_CATEGORY_EVENT
}
if (entry.sbn.notification.fullScreenIntent != null) {
- uiEventLogger.log(AvalancheEvent.ALLOW_FSI_WITH_PERMISSION_ON)
+ uiEventLogger.log(AvalancheEvent.AVALANCHE_SUPPRESSOR_HUN_ALLOWED_FSI_WITH_PERMISSION)
return State.ALLOW_FSI_WITH_PERMISSION_ON
}
if (entry.sbn.notification.isColorized) {
- uiEventLogger.log(AvalancheEvent.ALLOW_COLORIZED)
+ uiEventLogger.log(AvalancheEvent.AVALANCHE_SUPPRESSOR_HUN_ALLOWED_COLORIZED)
return State.ALLOW_COLORIZED
}
if (
packageManager.checkPermission(RECEIVE_EMERGENCY_BROADCAST, entry.sbn.packageName) ==
PERMISSION_GRANTED
) {
- uiEventLogger.log(AvalancheEvent.ALLOW_EMERGENCY)
+ uiEventLogger.log(AvalancheEvent.AVALANCHE_SUPPRESSOR_HUN_ALLOWED_EMERGENCY)
return State.ALLOW_EMERGENCY
}
- uiEventLogger.log(AvalancheEvent.SUPPRESS)
+ uiEventLogger.log(AvalancheEvent.AVALANCHE_SUPPRESSOR_HUN_SUPPRESSED)
return State.SUPPRESS
}
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 fe22cc6..b77321b 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
@@ -833,6 +833,23 @@
int y = 0;
drawDebugInfo(canvas, y, Color.RED, /* label= */ "y = " + y);
+ if (SceneContainerFlag.isEnabled()) {
+ y = (int) mScrollViewFields.getStackTop();
+ drawDebugInfo(canvas, y, Color.RED, /* label= */ "getStackTop() = " + y);
+
+ y = (int) mScrollViewFields.getStackBottom();
+ drawDebugInfo(canvas, y, Color.MAGENTA, /* label= */ "getStackBottom() = " + y);
+
+ y = (int) mScrollViewFields.getHeadsUpTop();
+ drawDebugInfo(canvas, y, Color.GREEN, /* label= */ "getHeadsUpTop() = " + y);
+
+ y += getTopHeadsUpHeight();
+ drawDebugInfo(canvas, y, Color.BLUE,
+ /* label= */ "getHeadsUpTop() + getTopHeadsUpHeight() = " + y);
+
+ return; // the rest of the fields are not important in Flexiglass
+ }
+
y = getTopPadding();
drawDebugInfo(canvas, y, Color.RED, /* label= */ "getTopPadding() = " + y);
@@ -3471,6 +3488,7 @@
}
if (isUpOrCancel) {
+ mScrollViewFields.sendCurrentGestureOverscroll(false);
setIsBeingDragged(false);
}
return false;
@@ -3606,7 +3624,6 @@
if (mIsBeingDragged) {
// Defer actual scrolling to the scene framework if enabled
if (SceneContainerFlag.isEnabled()) {
- setIsBeingDragged(false);
return false;
}
// Scroll to follow the motion event
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt
index 6dfaec9..6a8c43a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt
@@ -441,7 +441,7 @@
anyOf(
*toFlowArray(statesForHiddenKeyguard) { state ->
keyguardTransitionInteractor
- .transitionStepsToState(state)
+ .transition(Edge.create(to = state))
.map { it.value > 0f && it.transitionState == RUNNING }
.onStart { emit(false) }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LegacyActivityStarterInternalImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LegacyActivityStarterInternalImpl.kt
index fc29eab..e5fc4e2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LegacyActivityStarterInternalImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LegacyActivityStarterInternalImpl.kt
@@ -555,7 +555,12 @@
override fun onTransitionAnimationStart(isExpandingFullyAbove: Boolean) {
super.onTransitionAnimationStart(isExpandingFullyAbove)
-
+ if (communalHub()) {
+ communalSceneInteractor.snapToScene(
+ CommunalScenes.Blank,
+ ActivityTransitionAnimator.TIMINGS.totalDuration
+ )
+ }
// Double check that the keyguard is still showing and not going
// away, but if so set the keyguard occluded. Typically, WM will let
// KeyguardViewMediator know directly, but we're overriding that to
@@ -581,9 +586,6 @@
// collapse the shade (or at least run the post collapse runnables)
// later on.
centralSurfaces?.setIsLaunchingActivityOverLockscreen(false, false)
- if (communalHub()) {
- communalSceneInteractor.snapToScene(CommunalScenes.Blank)
- }
delegate.onTransitionAnimationEnd(isExpandingFullyAbove)
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index db4f0af..b40bf56 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -73,6 +73,7 @@
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor;
import com.android.systemui.keyguard.domain.interactor.WindowManagerLockscreenVisibilityInteractor;
import com.android.systemui.keyguard.shared.model.DismissAction;
+import com.android.systemui.keyguard.shared.model.Edge;
import com.android.systemui.keyguard.shared.model.KeyguardDone;
import com.android.systemui.keyguard.shared.model.KeyguardState;
import com.android.systemui.keyguard.shared.model.TransitionStep;
@@ -508,8 +509,8 @@
mListenForCanShowAlternateBouncer = null;
if (!DeviceEntryUdfpsRefactor.isEnabled()) {
mListenForAlternateBouncerTransitionSteps = mJavaAdapter.alwaysCollectFlow(
- mKeyguardTransitionInteractor.transitionStepsFromState(
- KeyguardState.ALTERNATE_BOUNCER),
+ mKeyguardTransitionInteractor
+ .transition(Edge.create(KeyguardState.ALTERNATE_BOUNCER)),
this::consumeFromAlternateBouncerTransitionSteps
);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/AvalancheController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/AvalancheController.kt
index a972985..32774e0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/AvalancheController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/AvalancheController.kt
@@ -35,10 +35,7 @@
@SysUISingleton
class AvalancheController
@Inject
-constructor(
- dumpManager: DumpManager,
- private val uiEventLogger: UiEventLogger
-) : Dumpable {
+constructor(dumpManager: DumpManager, private val uiEventLogger: UiEventLogger) : Dumpable {
private val tag = "AvalancheController"
private val debug = Compile.IS_DEBUG && Log.isLoggable(tag, Log.DEBUG)
@@ -69,14 +66,11 @@
@VisibleForTesting var debugDropSet: MutableSet<HeadsUpEntry> = HashSet()
enum class ThrottleEvent(private val id: Int) : UiEventLogger.UiEventEnum {
- @UiEvent(doc = "HUN was shown.")
- SHOWN(1812),
-
+ @UiEvent(doc = "HUN was shown.") AVALANCHE_THROTTLING_HUN_SHOWN(1821),
@UiEvent(doc = "HUN was dropped to show higher priority HUNs.")
- DROPPED(1813),
-
+ AVALANCHE_THROTTLING_HUN_DROPPED(1822),
@UiEvent(doc = "HUN was removed while waiting to show.")
- REMOVED(1814);
+ AVALANCHE_THROTTLING_HUN_REMOVED(1823);
override fun getId(): Int {
return id
@@ -97,7 +91,7 @@
runnable.run()
return
}
- log { "\n "}
+ log { "\n " }
val fn = "$label => AvalancheController.update ${getKey(entry)}"
if (entry == null) {
log { "Entry is NULL, stop update." }
@@ -129,9 +123,10 @@
// HeadsUpEntry.updateEntry recursively calls AvalancheController#update
// and goes to the isShowing case above
headsUpEntryShowing!!.updateEntry(
- /* updatePostTime= */ false,
- /* updateEarliestRemovalTime= */ false,
- /* reason= */ "avalanche duration update")
+ /* updatePostTime= */ false,
+ /* updateEarliestRemovalTime= */ false,
+ /* reason= */ "avalanche duration update"
+ )
}
}
logState("after $fn")
@@ -152,7 +147,7 @@
runnable.run()
return
}
- log { "\n "}
+ log { "\n " }
val fn = "$label => AvalancheController.delete " + getKey(entry)
if (entry == null) {
log { "$fn => entry NULL, running runnable" }
@@ -163,7 +158,7 @@
log { "$fn => remove from next" }
if (entry in nextMap) nextMap.remove(entry)
if (entry in nextList) nextList.remove(entry)
- uiEventLogger.log(ThrottleEvent.REMOVED)
+ uiEventLogger.log(ThrottleEvent.AVALANCHE_THROTTLING_HUN_REMOVED)
} else if (entry in debugDropSet) {
log { "$fn => remove from dropset" }
debugDropSet.remove(entry)
@@ -287,7 +282,7 @@
private fun showNow(entry: HeadsUpEntry, runnableList: MutableList<Runnable>) {
log { "SHOW: " + getKey(entry) }
- uiEventLogger.log(ThrottleEvent.SHOWN)
+ uiEventLogger.log(ThrottleEvent.AVALANCHE_THROTTLING_HUN_SHOWN)
headsUpEntryShowing = entry
runnableList.forEach {
@@ -318,7 +313,7 @@
// Log dropped HUNs
for (e in listToDrop) {
- uiEventLogger.log(ThrottleEvent.DROPPED)
+ uiEventLogger.log(ThrottleEvent.AVALANCHE_THROTTLING_HUN_DROPPED)
}
if (debug) {
diff --git a/packages/SystemUI/src/com/android/systemui/util/kotlin/Utils.kt b/packages/SystemUI/src/com/android/systemui/util/kotlin/Utils.kt
index 405b57a..d9a2e95 100644
--- a/packages/SystemUI/src/com/android/systemui/util/kotlin/Utils.kt
+++ b/packages/SystemUI/src/com/android/systemui/util/kotlin/Utils.kt
@@ -19,19 +19,24 @@
import android.content.Context
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.filter
+import kotlinx.coroutines.flow.map
class Utils {
companion object {
fun <A, B, C> toTriple(a: A, bc: Pair<B, C>) = Triple(a, bc.first, bc.second)
+
fun <A, B, C> toTriple(ab: Pair<A, B>, c: C) = Triple(ab.first, ab.second, c)
fun <A, B, C, D> toQuad(a: A, b: B, c: C, d: D) = Quad(a, b, c, d)
+
fun <A, B, C, D> toQuad(a: A, bcd: Triple<B, C, D>) =
Quad(a, bcd.first, bcd.second, bcd.third)
fun <A, B, C, D> toQuad(abc: Triple<A, B, C>, d: D) =
Quad(abc.first, abc.second, abc.third, d)
fun <A, B, C, D, E> toQuint(a: A, b: B, c: C, d: D, e: E) = Quint(a, b, c, d, e)
+
fun <A, B, C, D, E> toQuint(a: A, bcde: Quad<B, C, D, E>) =
Quint(a, bcde.first, bcde.second, bcde.third, bcde.fourth)
@@ -50,6 +55,14 @@
)
/**
+ * Samples the provided flow, performs a filter on the sampled value, then returns the
+ * original value.
+ */
+ fun <A, B> Flow<A>.sampleFilter(b: Flow<B>, predicate: (B) -> Boolean): Flow<A> {
+ return this.sample(b, ::Pair).filter { (_, b) -> predicate(b) }.map { (a, _) -> a }
+ }
+
+ /**
* Samples the provided flows, emitting a tuple of the original flow's value as well as each
* of the combined flows' values.
*
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt
index 5702a8c..69a6f2a 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt
@@ -348,7 +348,8 @@
fun listenForTransitionToAodFromGone_updatesClockDozeAmountToOne() =
runBlocking(IMMEDIATE) {
val transitionStep = MutableStateFlow(TransitionStep())
- whenever(keyguardTransitionInteractor.transitionStepsToState(AOD))
+ whenever(keyguardTransitionInteractor
+ .transition(Edge.create(to = AOD)))
.thenReturn(transitionStep)
val job = underTest.listenForAnyStateToAodTransition(this)
@@ -369,7 +370,8 @@
fun listenForTransitionToLSFromOccluded_updatesClockDozeAmountToZero() =
runBlocking(IMMEDIATE) {
val transitionStep = MutableStateFlow(TransitionStep())
- whenever(keyguardTransitionInteractor.transitionStepsToState(LOCKSCREEN))
+ whenever(keyguardTransitionInteractor
+ .transition(Edge.create(to = LOCKSCREEN)))
.thenReturn(transitionStep)
val job = underTest.listenForAnyStateToLockscreenTransition(this)
@@ -390,7 +392,8 @@
fun listenForTransitionToAodFromLockscreen_neverUpdatesClockDozeAmount() =
runBlocking(IMMEDIATE) {
val transitionStep = MutableStateFlow(TransitionStep())
- whenever(keyguardTransitionInteractor.transitionStepsToState(AOD))
+ whenever(keyguardTransitionInteractor
+ .transition(Edge.create(to = AOD)))
.thenReturn(transitionStep)
val job = underTest.listenForAnyStateToAodTransition(this)
@@ -411,7 +414,8 @@
fun listenForAnyStateToLockscreenTransition_neverUpdatesClockDozeAmount() =
runBlocking(IMMEDIATE) {
val transitionStep = MutableStateFlow(TransitionStep())
- whenever(keyguardTransitionInteractor.transitionStepsToState(LOCKSCREEN))
+ whenever(keyguardTransitionInteractor
+ .transition(Edge.create(to = LOCKSCREEN)))
.thenReturn(transitionStep)
val job = underTest.listenForAnyStateToLockscreenTransition(this)
@@ -432,7 +436,8 @@
fun listenForAnyStateToDozingTransition_UpdatesClockDozeAmountToOne() =
runBlocking(IMMEDIATE) {
val transitionStep = MutableStateFlow(TransitionStep())
- whenever(keyguardTransitionInteractor.transitionStepsToState(DOZING))
+ whenever(keyguardTransitionInteractor
+ .transition(Edge.create(to = DOZING)))
.thenReturn(transitionStep)
val job = underTest.listenForAnyStateToDozingTransition(this)
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/LegacyLockIconViewControllerWithCoroutinesTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/LegacyLockIconViewControllerWithCoroutinesTest.kt
index 25a87b8..9580139 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/LegacyLockIconViewControllerWithCoroutinesTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/LegacyLockIconViewControllerWithCoroutinesTest.kt
@@ -22,10 +22,6 @@
import com.android.keyguard.LockIconView.ICON_LOCK
import com.android.systemui.doze.util.getBurnInOffset
import com.android.systemui.flags.Flags.LOCKSCREEN_WALLPAPER_DREAM_ENABLED
-import com.android.systemui.keyguard.shared.model.KeyguardState.AOD
-import com.android.systemui.keyguard.shared.model.KeyguardState.LOCKSCREEN
-import com.android.systemui.keyguard.shared.model.TransitionState.FINISHED
-import com.android.systemui.keyguard.shared.model.TransitionStep
import com.android.systemui.statusbar.StatusBarState
import com.android.systemui.util.mockito.whenever
import kotlinx.coroutines.Dispatchers
@@ -104,7 +100,7 @@
// WHEN dozing updates
mUnderTest.mIsDozingCallback.accept(true)
- mUnderTest.mDozeTransitionCallback.accept(TransitionStep(LOCKSCREEN, AOD, 1f, FINISHED))
+ mUnderTest.mDozeTransitionCallback.accept(1f)
// THEN the view's translation is updated to use the AoD burn-in offsets
verify(mLockIconView).setTranslationY(burnInOffset.toFloat())
@@ -113,7 +109,7 @@
// WHEN the device is no longer dozing
mUnderTest.mIsDozingCallback.accept(false)
- mUnderTest.mDozeTransitionCallback.accept(TransitionStep(AOD, LOCKSCREEN, 0f, FINISHED))
+ mUnderTest.mDozeTransitionCallback.accept(0f)
// THEN the view is updated to NO translation (no burn-in offsets anymore)
verify(mLockIconView).setTranslationY(0f)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/AccessibilityLoggerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/accessibility/AccessibilityLoggerTest.kt
index deacac3..1ce21e77 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/AccessibilityLoggerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/AccessibilityLoggerTest.kt
@@ -16,7 +16,7 @@
package com.android.systemui.accessibility
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.internal.logging.UiEventLogger
import com.android.systemui.SysuiTestCase
@@ -34,7 +34,7 @@
import org.mockito.junit.MockitoJUnit
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
class AccessibilityLoggerTest : SysuiTestCase() {
@JvmField @Rule val mockito = MockitoJUnit.rule()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/DisplayIdIndexSupplierTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/DisplayIdIndexSupplierTest.java
index 9cb4fb3..cb8cfc2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/DisplayIdIndexSupplierTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/DisplayIdIndexSupplierTest.java
@@ -20,10 +20,10 @@
import static org.junit.Assert.assertNotNull;
import android.hardware.display.DisplayManager;
-import android.testing.AndroidTestingRunner;
import android.view.Display;
import androidx.annotation.NonNull;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
@@ -33,7 +33,7 @@
import org.junit.runner.RunWith;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
public class DisplayIdIndexSupplierTest extends SysuiTestCase {
private DisplayIdIndexSupplier<Object> mDisplayIdIndexSupplier;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/IMagnificationConnectionTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/IMagnificationConnectionTest.java
index 3164f8e..5bfb3cf 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/IMagnificationConnectionTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/IMagnificationConnectionTest.java
@@ -37,7 +37,6 @@
import android.platform.test.flag.junit.CheckFlagsRule;
import android.platform.test.flag.junit.DeviceFlagsValueProvider;
import android.provider.Settings;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.view.Display;
import android.view.accessibility.AccessibilityManager;
@@ -45,6 +44,7 @@
import android.view.accessibility.IMagnificationConnectionCallback;
import android.view.accessibility.IRemoteMagnificationAnimationCallback;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.Flags;
@@ -67,7 +67,7 @@
* {@link Magnification}
*/
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
public class IMagnificationConnectionTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationGestureDetectorTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationGestureDetectorTest.java
index ad02179..7b06dd6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationGestureDetectorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationGestureDetectorTest.java
@@ -26,11 +26,11 @@
import android.os.Handler;
import android.os.SystemClock;
-import android.testing.AndroidTestingRunner;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
@@ -45,7 +45,7 @@
import org.mockito.MockitoAnnotations;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
public class MagnificationGestureDetectorTest extends SysuiTestCase {
private static final float ACTION_DOWN_X = 100;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationModeSwitchTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationModeSwitchTest.java
index 1a88545..5be1180 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationModeSwitchTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationModeSwitchTest.java
@@ -58,7 +58,6 @@
import android.graphics.Rect;
import android.os.Handler;
import android.os.SystemClock;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.view.Choreographer;
import android.view.MotionEvent;
@@ -71,6 +70,7 @@
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.ImageView;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.internal.graphics.SfVsyncFrameCallbackProvider;
@@ -90,7 +90,7 @@
import java.util.List;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
public class MagnificationModeSwitchTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationSettingsControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationSettingsControllerTest.java
index 9eead6a..d0f8e78 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationSettingsControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationSettingsControllerTest.java
@@ -22,9 +22,9 @@
import static org.mockito.Mockito.verify;
import android.content.pm.ActivityInfo;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.internal.graphics.SfVsyncFrameCallbackProvider;
@@ -40,7 +40,7 @@
import org.mockito.MockitoAnnotations;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
/** Tests the MagnificationSettingsController. */
@TestableLooper.RunWithLooper(setAsMainLooper = true)
public class MagnificationSettingsControllerTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationTest.java
index bbdd805..ffba25c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationTest.java
@@ -40,13 +40,13 @@
import android.graphics.Rect;
import android.hardware.display.DisplayManager;
import android.os.RemoteException;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.view.Display;
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.IMagnificationConnection;
import android.view.accessibility.IMagnificationConnectionCallback;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
@@ -64,7 +64,7 @@
import org.mockito.MockitoAnnotations;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@TestableLooper.RunWithLooper
public class MagnificationTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/MirrorWindowControlTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/MirrorWindowControlTest.java
index e81613e..8f9b7c8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/MirrorWindowControlTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/MirrorWindowControlTest.java
@@ -27,12 +27,12 @@
import android.content.Context;
import android.graphics.Point;
-import android.testing.AndroidTestingRunner;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
@@ -45,7 +45,7 @@
import org.mockito.MockitoAnnotations;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
public class MirrorWindowControlTest extends SysuiTestCase {
@Mock WindowManager mWindowManager;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/ModeSwitchesControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/ModeSwitchesControllerTest.java
index 3c97423..6e94297 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/ModeSwitchesControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/ModeSwitchesControllerTest.java
@@ -21,11 +21,11 @@
import android.content.pm.ActivityInfo;
import android.hardware.display.DisplayManager;
import android.provider.Settings;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.view.Display;
import android.view.View;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
@@ -39,7 +39,7 @@
import org.mockito.MockitoAnnotations;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
/** Tests the ModeSwitchesController. */
@TestableLooper.RunWithLooper(setAsMainLooper = true)
public class ModeSwitchesControllerTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/SecureSettingsContentObserverTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/SecureSettingsContentObserverTest.java
index 9c601a8..9222fc2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/SecureSettingsContentObserverTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/SecureSettingsContentObserverTest.java
@@ -21,8 +21,8 @@
import android.app.ActivityManager;
import android.content.Context;
import android.provider.Settings;
-import android.testing.AndroidTestingRunner;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
@@ -34,7 +34,7 @@
import org.mockito.Mockito;
/** Test for {@link SecureSettingsContentObserver}. */
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@SmallTest
public class SecureSettingsContentObserverTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/SystemActionsTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/SystemActionsTest.java
index c674294..f46b2f9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/SystemActionsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/SystemActionsTest.java
@@ -28,10 +28,10 @@
import android.os.RemoteException;
import android.telecom.TelecomManager;
import android.telephony.TelephonyManager;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.view.KeyEvent;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
@@ -55,7 +55,7 @@
@TestableLooper.RunWithLooper
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
public class SystemActionsTest extends SysuiTestCase {
@Mock
private UserTracker mUserTracker;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java
index cb42078..f57003e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java
@@ -72,7 +72,6 @@
import android.platform.test.flag.junit.CheckFlagsRule;
import android.platform.test.flag.junit.DeviceFlagsValueProvider;
import android.provider.Settings;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.testing.TestableResources;
import android.text.TextUtils;
@@ -90,6 +89,7 @@
import android.view.accessibility.IRemoteMagnificationAnimationCallback;
import androidx.test.InstrumentationRegistry;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.LargeTest;
import com.android.internal.graphics.SfVsyncFrameCallbackProvider;
@@ -125,7 +125,7 @@
@LargeTest
@TestableLooper.RunWithLooper
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@RequiresFlagsDisabled(Flags.FLAG_CREATE_WINDOWLESS_WINDOW_MAGNIFIER)
public class WindowMagnificationControllerTest extends SysuiTestCase {
@@ -1511,4 +1511,4 @@
});
}
}
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerWindowlessMagnifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerWindowlessMagnifierTest.java
index 01e4d58..e272682 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerWindowlessMagnifierTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerWindowlessMagnifierTest.java
@@ -71,7 +71,6 @@
import android.platform.test.flag.junit.CheckFlagsRule;
import android.platform.test.flag.junit.DeviceFlagsValueProvider;
import android.provider.Settings;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.testing.TestableResources;
import android.text.TextUtils;
@@ -94,6 +93,7 @@
import android.window.InputTransferToken;
import androidx.test.InstrumentationRegistry;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.LargeTest;
import com.android.systemui.Flags;
@@ -129,7 +129,7 @@
@LargeTest
@TestableLooper.RunWithLooper
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@RequiresFlagsEnabled(Flags.FLAG_CREATE_WINDOWLESS_WINDOW_MAGNIFIER)
public class WindowMagnificationControllerWindowlessMagnifierTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationFrameSizePrefsTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationFrameSizePrefsTest.java
index 93c0eea..ad9053a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationFrameSizePrefsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationFrameSizePrefsTest.java
@@ -23,10 +23,10 @@
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.util.Size;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
@@ -37,7 +37,7 @@
import org.junit.runner.RunWith;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@TestableLooper.RunWithLooper
public class WindowMagnificationFrameSizePrefsTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationSettingsTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationSettingsTest.java
index 138fed2..003f7e4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationSettingsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationSettingsTest.java
@@ -47,7 +47,6 @@
import android.graphics.Rect;
import android.os.UserHandle;
import android.provider.Settings;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.view.View;
import android.view.ViewGroup;
@@ -59,6 +58,7 @@
import android.widget.LinearLayout;
import androidx.test.InstrumentationRegistry;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.internal.graphics.SfVsyncFrameCallbackProvider;
@@ -77,7 +77,7 @@
import org.mockito.MockitoAnnotations;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@TestableLooper.RunWithLooper
public class WindowMagnificationSettingsTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/data/repository/AccessibilityRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/accessibility/data/repository/AccessibilityRepositoryTest.kt
index aff52f5..c4a92bf 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/data/repository/AccessibilityRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/data/repository/AccessibilityRepositoryTest.kt
@@ -18,8 +18,8 @@
package com.android.systemui.accessibility.data.repository
-import android.testing.AndroidTestingRunner
import android.view.accessibility.AccessibilityManager
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
@@ -37,7 +37,7 @@
import org.mockito.junit.MockitoJUnit
import org.mockito.junit.MockitoRule
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@SmallTest
class AccessibilityRepositoryTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuControllerTest.java
index 095c945..b71739a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuControllerTest.java
@@ -30,11 +30,11 @@
import android.hardware.display.DisplayManager;
import android.os.UserHandle;
import android.provider.Settings;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityManager;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.keyguard.KeyguardUpdateMonitor;
@@ -59,7 +59,7 @@
import org.mockito.junit.MockitoRule;
/** Test for {@link AccessibilityFloatingMenuController}. */
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
@SmallTest
public class AccessibilityFloatingMenuControllerTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityTargetAdapterTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityTargetAdapterTest.java
index 630db62..b08f97a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityTargetAdapterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityTargetAdapterTest.java
@@ -21,10 +21,10 @@
import static org.mockito.Mockito.when;
import android.graphics.drawable.Drawable;
-import android.testing.AndroidTestingRunner;
import android.view.LayoutInflater;
import android.view.View;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.internal.accessibility.dialog.AccessibilityTarget;
@@ -43,7 +43,7 @@
/** Tests for {@link AccessibilityTargetAdapter}. */
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
public class AccessibilityTargetAdapterTest extends SysuiTestCase {
@Mock
private AccessibilityTarget mAccessibilityTarget;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AnnotationLinkSpanTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AnnotationLinkSpanTest.java
index 4b87588..5b2afe7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AnnotationLinkSpanTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AnnotationLinkSpanTest.java
@@ -20,10 +20,10 @@
import static org.mockito.Mockito.mock;
-import android.testing.AndroidTestingRunner;
import android.text.SpannableStringBuilder;
import android.view.View;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
@@ -37,7 +37,7 @@
/** Tests for {@link AnnotationLinkSpan}. */
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
public class AnnotationLinkSpanTest extends SysuiTestCase {
private AnnotationLinkSpan.LinkInfo mLinkInfo;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/DragToInteractAnimationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/DragToInteractAnimationControllerTest.java
index abc95bc..19b2700 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/DragToInteractAnimationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/DragToInteractAnimationControllerTest.java
@@ -22,11 +22,11 @@
import android.annotation.NonNull;
import android.platform.test.annotations.DisableFlags;
import android.platform.test.annotations.EnableFlags;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityManager;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.Flags;
@@ -46,7 +46,7 @@
/** Tests for {@link DragToInteractAnimationController}. */
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@TestableLooper.RunWithLooper
public class DragToInteractAnimationControllerTest extends SysuiTestCase {
private DragToInteractAnimationController mDragToInteractAnimationController;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuEduTooltipViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuEduTooltipViewTest.java
index 34a2e87..b597737 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuEduTooltipViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuEduTooltipViewTest.java
@@ -19,11 +19,11 @@
import static com.google.common.truth.Truth.assertThat;
import android.content.res.Resources;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.view.WindowManager;
import android.widget.TextView;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
@@ -35,7 +35,7 @@
/** Tests for {@link MenuEduTooltipView}. */
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@TestableLooper.RunWithLooper
public class MenuEduTooltipViewTest extends SysuiTestCase {
private MenuViewAppearance mMenuViewAppearance;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuInfoRepositoryTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuInfoRepositoryTest.java
index 1faa8ac..24f3a29 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuInfoRepositoryTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuInfoRepositoryTest.java
@@ -25,9 +25,9 @@
import android.content.Context;
import android.content.res.Configuration;
-import android.testing.AndroidTestingRunner;
import android.view.accessibility.AccessibilityManager;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
@@ -47,7 +47,7 @@
import java.util.Locale;
/** Tests for {@link MenuInfoRepository}. */
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@SmallTest
public class MenuInfoRepositoryTest extends SysuiTestCase {
@Rule
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuItemAccessibilityDelegateTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuItemAccessibilityDelegateTest.java
index 1f7d033..c5509ac 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuItemAccessibilityDelegateTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuItemAccessibilityDelegateTest.java
@@ -30,7 +30,6 @@
import android.graphics.Rect;
import android.platform.test.annotations.DisableFlags;
import android.platform.test.annotations.EnableFlags;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityManager;
@@ -39,6 +38,7 @@
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.RecyclerViewAccessibilityDelegate;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.Flags;
@@ -60,7 +60,7 @@
/** Tests for {@link MenuItemAccessibilityDelegate}. */
@SmallTest
@TestableLooper.RunWithLooper
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
public class MenuItemAccessibilityDelegateTest extends SysuiTestCase {
@Rule
public MockitoRule mockito = MockitoJUnit.rule();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuListViewTouchHandlerTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuListViewTouchHandlerTest.java
index 9e8c6b3..4373c88 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuListViewTouchHandlerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuListViewTouchHandlerTest.java
@@ -30,7 +30,6 @@
import android.platform.test.annotations.DisableFlags;
import android.platform.test.annotations.EnableFlags;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.view.MotionEvent;
import android.view.WindowManager;
@@ -38,6 +37,7 @@
import androidx.dynamicanimation.animation.DynamicAnimation;
import androidx.recyclerview.widget.RecyclerView;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.internal.accessibility.dialog.AccessibilityTarget;
@@ -62,7 +62,7 @@
import java.util.List;
/** Tests for {@link MenuListViewTouchHandler}. */
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
@SmallTest
public class MenuListViewTouchHandlerTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuNotificationFactoryTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuNotificationFactoryTest.java
index 9dd337e..2746fef 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuNotificationFactoryTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuNotificationFactoryTest.java
@@ -19,8 +19,8 @@
import static com.google.common.truth.Truth.assertThat;
import android.app.Notification;
-import android.testing.AndroidTestingRunner;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
@@ -29,7 +29,7 @@
import org.junit.Test;
import org.junit.runner.RunWith;
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@SmallTest
public class MenuNotificationFactoryTest extends SysuiTestCase {
private MenuNotificationFactory mMenuNotificationFactory;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerControllerTest.java
index 31824ec..bd1a7f0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerControllerTest.java
@@ -27,7 +27,6 @@
import android.content.Context;
import android.graphics.Insets;
import android.graphics.Rect;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.view.View;
import android.view.ViewGroup;
@@ -36,6 +35,7 @@
import android.view.WindowMetrics;
import android.view.accessibility.AccessibilityManager;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
@@ -50,7 +50,7 @@
import org.mockito.junit.MockitoRule;
/** Tests for {@link MenuViewLayerController}. */
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
@SmallTest
public class MenuViewLayerControllerTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerTest.java
index 05d7560..38095c8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerTest.java
@@ -61,7 +61,6 @@
import android.platform.test.annotations.DisableFlags;
import android.platform.test.annotations.EnableFlags;
import android.provider.Settings;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.util.ArraySet;
import android.view.View;
@@ -72,6 +71,7 @@
import androidx.dynamicanimation.animation.DynamicAnimation;
import androidx.dynamicanimation.animation.SpringAnimation;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.internal.accessibility.common.ShortcutConstants;
@@ -101,7 +101,7 @@
import java.util.List;
/** Tests for {@link MenuViewLayer}. */
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
@SmallTest
public class MenuViewLayerTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuViewTest.java
index f6288b6..103449b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuViewTest.java
@@ -29,11 +29,11 @@
import android.graphics.Rect;
import android.graphics.drawable.GradientDrawable;
import android.platform.test.annotations.EnableFlags;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityManager;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.Flags;
@@ -53,7 +53,7 @@
import org.mockito.junit.MockitoRule;
/** Tests for {@link MenuView}. */
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
@SmallTest
public class MenuViewTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/PositionTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/PositionTest.java
index 05f306b..8fb71fa 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/PositionTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/PositionTest.java
@@ -18,8 +18,8 @@
import static com.google.common.truth.Truth.assertThat;
-import android.testing.AndroidTestingRunner;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
@@ -29,7 +29,7 @@
/** Tests for {@link Position}. */
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
public class PositionTest extends SysuiTestCase {
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/RadiiAnimatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/RadiiAnimatorTest.java
index d77a80a..f67e8d0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/RadiiAnimatorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/RadiiAnimatorTest.java
@@ -20,8 +20,8 @@
import android.os.Handler;
import android.os.Looper;
-import android.testing.AndroidTestingRunner;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
@@ -35,7 +35,7 @@
/** Tests for {@link RadiiAnimator}. */
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
public class RadiiAnimatorTest extends SysuiTestCase {
float[] mResultRadii = new float[RadiiAnimator.RADII_COUNT];
final AtomicBoolean mAnimationStarted = new AtomicBoolean(false);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/fontscaling/FontScalingDialogDelegateTest.kt b/packages/SystemUI/tests/src/com/android/systemui/accessibility/fontscaling/FontScalingDialogDelegateTest.kt
index e371b39..0bd00fb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/fontscaling/FontScalingDialogDelegateTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/fontscaling/FontScalingDialogDelegateTest.kt
@@ -18,12 +18,12 @@
import android.content.res.Configuration
import android.os.Handler
import android.provider.Settings
-import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.Button
import android.widget.SeekBar
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.animation.DialogTransitionAnimator
@@ -58,7 +58,7 @@
/** Tests for [FontScalingDialogDelegate]. */
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
class FontScalingDialogDelegateTest : SysuiTestCase() {
private lateinit var fontScalingDialogDelegate: FontScalingDialogDelegate
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegateTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegateTest.java
index 0db0de2..8f7dc7cf 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegateTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegateTest.java
@@ -39,11 +39,11 @@
import android.os.Handler;
import android.platform.test.annotations.EnableFlags;
import android.provider.Settings;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.view.View;
import android.widget.LinearLayout;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.settingslib.bluetooth.BluetoothEventManager;
@@ -78,7 +78,7 @@
import java.util.List;
/** Tests for {@link HearingDevicesDialogDelegate}. */
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
@SmallTest
public class HearingDevicesDialogDelegateTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogManagerTest.java
index cb9c26c..09aa2868 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogManagerTest.java
@@ -21,9 +21,10 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-import android.testing.AndroidTestingRunner;
+import android.bluetooth.BluetoothDevice;
import android.testing.TestableLooper;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
@@ -42,7 +43,7 @@
import org.mockito.junit.MockitoRule;
/** Tests for {@link HearingDevicesDialogManager}. */
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
@SmallTest
public class HearingDevicesDialogManagerTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/hearingaid/HearingDevicesListAdapterTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/hearingaid/HearingDevicesListAdapterTest.java
index d16db65..9359adf 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/hearingaid/HearingDevicesListAdapterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/hearingaid/HearingDevicesListAdapterTest.java
@@ -20,9 +20,9 @@
import static org.mockito.Mockito.when;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
@@ -41,7 +41,7 @@
import java.util.List;
/** Tests for {@link HearingDevicesListAdapter}. */
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
@SmallTest
public class HearingDevicesListAdapterTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/hearingaid/HearingDevicesToolItemParserTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/hearingaid/HearingDevicesToolItemParserTest.java
index 7172923..17ce1dd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/hearingaid/HearingDevicesToolItemParserTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/hearingaid/HearingDevicesToolItemParserTest.java
@@ -28,9 +28,9 @@
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
@@ -48,7 +48,7 @@
/**
* Tests for {@link HearingDevicesToolItemParser}.
*/
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
@SmallTest
public class HearingDevicesToolItemParserTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/ambient/touch/InputSessionTest.java b/packages/SystemUI/tests/src/com/android/systemui/ambient/touch/InputSessionTest.java
index 2f4999b..8fca557 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/ambient/touch/InputSessionTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/ambient/touch/InputSessionTest.java
@@ -24,13 +24,13 @@
import static org.mockito.Mockito.when;
import android.platform.test.annotations.EnableFlags;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.view.Choreographer;
import android.view.GestureDetector;
import android.view.InputEvent;
import android.view.MotionEvent;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.Flags;
@@ -50,7 +50,7 @@
* A test suite for exercising {@link InputSession}.
*/
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@TestableLooper.RunWithLooper()
public class InputSessionTest extends SysuiTestCase {
@Mock
diff --git a/packages/SystemUI/tests/src/com/android/systemui/ambient/touch/TouchMonitorTest.java b/packages/SystemUI/tests/src/com/android/systemui/ambient/touch/TouchMonitorTest.java
index 358e8cb..4118c90 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/ambient/touch/TouchMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/ambient/touch/TouchMonitorTest.java
@@ -36,7 +36,6 @@
import android.hardware.display.DisplayManager;
import android.platform.test.annotations.DisableFlags;
import android.platform.test.annotations.EnableFlags;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.view.GestureDetector;
import android.view.IWindowManager;
@@ -50,6 +49,7 @@
import androidx.lifecycle.LifecycleObserver;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.LifecycleRegistry;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.Flags;
@@ -79,7 +79,7 @@
import java.util.stream.Stream;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
public class TouchMonitorTest extends SysuiTestCase {
private KosmosJavaAdapter mKosmos;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityTransitionAnimatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityTransitionAnimatorTest.kt
index 70a544c..9aaf295 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityTransitionAnimatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityTransitionAnimatorTest.kt
@@ -9,7 +9,6 @@
import android.graphics.Rect
import android.os.Looper
import android.platform.test.flag.junit.SetFlagsRule
-import android.testing.AndroidTestingRunner
import android.testing.TestableLooper.RunWithLooper
import android.view.IRemoteAnimationFinishedCallback
import android.view.RemoteAnimationAdapter
@@ -20,6 +19,7 @@
import android.widget.LinearLayout
import android.window.RemoteTransition
import android.window.TransitionFilter
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.shared.Flags
@@ -49,7 +49,7 @@
import org.mockito.junit.MockitoJUnit
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@RunWithLooper
class ActivityTransitionAnimatorTest : SysuiTestCase() {
private val transitionContainer = LinearLayout(mContext)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/animation/AnimatorTestRuleOrderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/animation/AnimatorTestRuleOrderTest.kt
index e3be3822..37f549a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/animation/AnimatorTestRuleOrderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/animation/AnimatorTestRuleOrderTest.kt
@@ -16,9 +16,9 @@
package com.android.systemui.animation
-import android.testing.AndroidTestingRunner
import android.testing.TestableLooper.RunWithLooper
import androidx.core.animation.doOnEnd
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.FlakyTest
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
@@ -28,7 +28,7 @@
import org.junit.Test
import org.junit.runner.RunWith
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@SmallTest
@RunWithLooper
@FlakyTest(bugId = 302149604)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/animation/DialogTransitionAnimatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/animation/DialogTransitionAnimatorTest.kt
index e14762cd..a60fb76 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/animation/DialogTransitionAnimatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/animation/DialogTransitionAnimatorTest.kt
@@ -5,7 +5,6 @@
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.os.Bundle
-import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
import android.testing.ViewUtils
import android.view.View
@@ -14,6 +13,7 @@
import android.view.WindowManager
import android.widget.FrameLayout
import android.widget.LinearLayout
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.internal.jank.Cuj
import com.android.internal.policy.DecorView
@@ -39,7 +39,7 @@
import org.mockito.junit.MockitoRule
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@TestableLooper.RunWithLooper
class DialogTransitionAnimatorTest : SysuiTestCase() {
private val kosmos = testKosmos()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/animation/FontInterpolatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/animation/FontInterpolatorTest.kt
index 5e1a8e1..ec42b7f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/animation/FontInterpolatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/animation/FontInterpolatorTest.kt
@@ -20,14 +20,14 @@
import android.graphics.fonts.Font
import android.graphics.fonts.FontVariationAxis
import android.graphics.text.TextRunShaper
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@SmallTest
class FontInterpolatorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/animation/FontVariationUtilsTest.kt b/packages/SystemUI/tests/src/com/android/systemui/animation/FontVariationUtilsTest.kt
index 070cad7..b0f81c0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/animation/FontVariationUtilsTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/animation/FontVariationUtilsTest.kt
@@ -1,6 +1,6 @@
package com.android.systemui.animation
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import junit.framework.Assert
@@ -12,7 +12,7 @@
private const val TAG_OPSZ = "opsz"
private const val TAG_ROND = "ROND"
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@SmallTest
class FontVariationUtilsTest : SysuiTestCase() {
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/animation/GhostedViewTransitionAnimatorControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/animation/GhostedViewTransitionAnimatorControllerTest.kt
index 42fcd54..e492c63 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/animation/GhostedViewTransitionAnimatorControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/animation/GhostedViewTransitionAnimatorControllerTest.kt
@@ -17,10 +17,10 @@
package com.android.systemui.animation
import android.os.HandlerThread
-import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
import android.view.View
import android.widget.FrameLayout
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.internal.jank.InteractionJankMonitor
import com.android.systemui.SysuiTestCase
@@ -31,7 +31,7 @@
import org.junit.runner.RunWith
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@TestableLooper.RunWithLooper
class GhostedViewTransitionAnimatorControllerTest : SysuiTestCase() {
companion object {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/animation/TextAnimatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/animation/TextAnimatorTest.kt
index 263d375..6ba1715 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/animation/TextAnimatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/animation/TextAnimatorTest.kt
@@ -19,10 +19,10 @@
import android.animation.AnimatorListenerAdapter
import android.animation.ValueAnimator
import android.graphics.Typeface
-import android.testing.AndroidTestingRunner
import android.text.Layout
import android.text.StaticLayout
import android.text.TextPaint
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.google.common.truth.Truth.assertThat
@@ -38,7 +38,7 @@
import org.mockito.Mockito.verify
import org.mockito.Mockito.`when`
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@SmallTest
class TextAnimatorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/animation/TextInterpolatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/animation/TextInterpolatorTest.kt
index f6fcd16..cca5f35 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/animation/TextInterpolatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/animation/TextInterpolatorTest.kt
@@ -22,12 +22,12 @@
import android.graphics.Typeface
import android.graphics.fonts.Font
import android.graphics.fonts.FontFamily
-import android.testing.AndroidTestingRunner
import android.text.Layout
import android.text.StaticLayout
import android.text.TextDirectionHeuristic
import android.text.TextDirectionHeuristics
import android.text.TextPaint
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.google.common.truth.Truth.assertThat
@@ -62,7 +62,7 @@
typeface = Font.Builder(VF_FONT).setFontVariationSettings("'wght' 700").build().toTypeface()
}
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@SmallTest
class TextInterpolatorTest : SysuiTestCase() {
lateinit var typefaceCache: TypefaceVariantCache
@@ -330,4 +330,4 @@
Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888).also { draw(Canvas(it)) }!!
private fun TextInterpolator.toBitmap(width: Int, height: Int) =
- Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888).also { draw(Canvas(it)) }
\ No newline at end of file
+ Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888).also { draw(Canvas(it)) }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/animation/ViewHierarchyAnimatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/animation/ViewHierarchyAnimatorTest.kt
index c2e6db3..a8c3af9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/animation/ViewHierarchyAnimatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/animation/ViewHierarchyAnimatorTest.kt
@@ -1,12 +1,12 @@
package com.android.systemui.animation
import android.animation.ObjectAnimator
-import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
import android.view.View
import android.view.ViewGroup
import android.widget.LinearLayout
import android.widget.RelativeLayout
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.app.animation.Interpolators
import com.android.systemui.SysuiTestCase
@@ -22,7 +22,7 @@
import org.junit.runner.RunWith
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@TestableLooper.RunWithLooper
class
ViewHierarchyAnimatorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/animation/back/BackAnimationSpecTest.kt b/packages/SystemUI/tests/src/com/android/systemui/animation/back/BackAnimationSpecTest.kt
index 0ed84ea..4809d0e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/animation/back/BackAnimationSpecTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/animation/back/BackAnimationSpecTest.kt
@@ -2,6 +2,7 @@
import android.util.DisplayMetrics
import android.window.BackEvent
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.util.dpToPx
@@ -9,12 +10,11 @@
import junit.framework.TestCase.assertEquals
import org.junit.Test
import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
private data class BackInput(val progressX: Float, val progressY: Float, val edge: Int)
@SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
class BackAnimationSpecTest : SysuiTestCase() {
private var displayMetrics =
DisplayMetrics().apply {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/animation/back/BackTransformationTest.kt b/packages/SystemUI/tests/src/com/android/systemui/animation/back/BackTransformationTest.kt
index 44a5467..d898d1c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/animation/back/BackTransformationTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/animation/back/BackTransformationTest.kt
@@ -1,6 +1,7 @@
package com.android.systemui.animation.back
import android.view.View
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.util.mockito.mock
@@ -8,13 +9,12 @@
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
import org.mockito.Mockito.verify
import org.mockito.Mockito.verifyNoMoreInteractions
import org.mockito.kotlin.whenever
@SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
class BackTransformationTest : SysuiTestCase() {
private val targetView: View = mock()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/animation/back/OnBackAnimationCallbackExtensionTest.kt b/packages/SystemUI/tests/src/com/android/systemui/animation/back/OnBackAnimationCallbackExtensionTest.kt
index 314abda..9548e29 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/animation/back/OnBackAnimationCallbackExtensionTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/animation/back/OnBackAnimationCallbackExtensionTest.kt
@@ -2,6 +2,7 @@
import android.util.DisplayMetrics
import android.window.BackEvent
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.util.mockito.argumentCaptor
@@ -10,11 +11,10 @@
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
import org.mockito.Mockito.verify
@SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
class OnBackAnimationCallbackExtensionTest : SysuiTestCase() {
private val onBackProgress: (BackTransformation) -> Unit = mock()
private val onBackStart: (BackEvent) -> Unit = mock()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/appops/AppOpsControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/appops/AppOpsControllerTest.java
index 0d464cf..476d6e3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/appops/AppOpsControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/appops/AppOpsControllerTest.java
@@ -49,9 +49,9 @@
import android.media.AudioRecordingConfiguration;
import android.os.Looper;
import android.os.UserHandle;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.internal.R;
@@ -75,7 +75,7 @@
import java.util.Map;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@TestableLooper.RunWithLooper
public class AppOpsControllerTest extends SysuiTestCase {
private static final String TEST_PACKAGE_NAME = "test";
diff --git a/packages/SystemUI/tests/src/com/android/systemui/assist/ui/DisplayUtilsTest.java b/packages/SystemUI/tests/src/com/android/systemui/assist/ui/DisplayUtilsTest.java
index 4d582ab..828d367 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/assist/ui/DisplayUtilsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/assist/ui/DisplayUtilsTest.java
@@ -21,8 +21,8 @@
import android.content.Context;
import android.content.res.Resources;
-import android.testing.AndroidTestingRunner;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
@@ -35,7 +35,7 @@
import org.mockito.MockitoAnnotations;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
public class DisplayUtilsTest extends SysuiTestCase {
@Mock
diff --git a/packages/SystemUI/tests/src/com/android/systemui/battery/BatteryMeterViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/battery/BatteryMeterViewTest.kt
index 3c073d5..2bd0976 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/battery/BatteryMeterViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/battery/BatteryMeterViewTest.kt
@@ -17,9 +17,9 @@
import android.platform.test.annotations.DisableFlags
import android.platform.test.annotations.EnableFlags
-import android.testing.AndroidTestingRunner
import android.testing.TestableLooper.RunWithLooper
import android.widget.ImageView
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.settingslib.flags.Flags.FLAG_NEW_STATUS_BAR_ICONS
import com.android.systemui.res.R
@@ -33,7 +33,7 @@
import org.mockito.MockitoAnnotations
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@RunWithLooper
class BatteryMeterViewTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthRippleControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthRippleControllerTest.kt
index 7c03d78..6dc4b10 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthRippleControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthRippleControllerTest.kt
@@ -19,9 +19,9 @@
import android.graphics.Point
import android.hardware.biometrics.BiometricSourceType
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal
-import android.testing.AndroidTestingRunner
import android.testing.TestableLooper.RunWithLooper
import android.util.DisplayMetrics
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession
import com.android.keyguard.KeyguardUpdateMonitor
@@ -67,7 +67,7 @@
@ExperimentalCoroutinesApi
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
class AuthRippleControllerTest : SysuiTestCase() {
private lateinit var staticMockSession: MockitoSession
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/BiometricNotificationDialogFactoryTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/BiometricNotificationDialogFactoryTest.java
index d2c6957..197cb84 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/BiometricNotificationDialogFactoryTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/BiometricNotificationDialogFactoryTest.java
@@ -33,9 +33,9 @@
import android.hardware.face.FaceManager;
import android.hardware.fingerprint.FingerprintManager;
import android.provider.Settings;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
@@ -53,7 +53,7 @@
import java.util.concurrent.ExecutionException;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
public class BiometricNotificationDialogFactoryTest extends SysuiTestCase {
@Rule
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/BiometricNotificationServiceTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/BiometricNotificationServiceTest.java
index a279d3e..20d9433 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/BiometricNotificationServiceTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/BiometricNotificationServiceTest.java
@@ -36,9 +36,9 @@
import android.hardware.fingerprint.FingerprintManager;
import android.os.Handler;
import android.os.UserHandle;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.keyguard.KeyguardUpdateMonitor;
@@ -58,7 +58,7 @@
import java.util.Optional;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
public class BiometricNotificationServiceTest extends SysuiTestCase {
@Rule
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsUtilsTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsUtilsTest.java
index 5b6aee6..d26ccbc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsUtilsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsUtilsTest.java
@@ -23,6 +23,7 @@
import android.hardware.fingerprint.FingerprintSensorProperties;
import android.view.Surface;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
@@ -33,11 +34,10 @@
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
-@RunWith(JUnit4.class)
+@RunWith(AndroidJUnit4.class)
@SmallTest
public class UdfpsUtilsTest extends SysuiTestCase {
@Rule
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/data/repository/BiometricStatusRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/data/repository/BiometricStatusRepositoryTest.kt
index b3e845f..d215047 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/data/repository/BiometricStatusRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/data/repository/BiometricStatusRepositoryTest.kt
@@ -29,6 +29,7 @@
import android.hardware.biometrics.events.AuthenticationAcquiredInfo
import android.hardware.biometrics.events.AuthenticationStartedInfo
import android.hardware.biometrics.events.AuthenticationStoppedInfo
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.biometrics.shared.model.AuthenticationReason
@@ -46,7 +47,6 @@
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
import org.mockito.Mock
import org.mockito.Mockito.verify
import org.mockito.junit.MockitoJUnit
@@ -54,7 +54,7 @@
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
class BiometricStatusRepositoryTest : SysuiTestCase() {
@JvmField @Rule var mockitoRule: MockitoRule = MockitoJUnit.rule()
@Mock private lateinit var biometricManager: BiometricManager
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/data/repository/DisplayStateRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/data/repository/DisplayStateRepositoryTest.kt
index eae953e..d9b7161 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/data/repository/DisplayStateRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/data/repository/DisplayStateRepositoryTest.kt
@@ -21,6 +21,7 @@
import android.view.Display.DEFAULT_DISPLAY
import android.view.DisplayInfo
import android.view.Surface
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.biometrics.data.repository.DisplayStateRepository
@@ -42,12 +43,11 @@
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
import org.mockito.Mockito.spy
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
class DisplayStateRepositoryTest : SysuiTestCase() {
private val display = mock<Display>()
private val testScope = TestScope(StandardTestDispatcher())
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/data/repository/FacePropertyRepositoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/data/repository/FacePropertyRepositoryImplTest.kt
index f5e96c9..9c11405 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/data/repository/FacePropertyRepositoryImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/data/repository/FacePropertyRepositoryImplTest.kt
@@ -26,6 +26,7 @@
import android.hardware.face.FaceManager
import android.hardware.face.FaceSensorPropertiesInternal
import android.hardware.face.IFaceAuthenticatorsRegisteredCallback
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.biometrics.shared.model.LockoutMode
@@ -46,7 +47,6 @@
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
import org.mockito.ArgumentCaptor
import org.mockito.Captor
import org.mockito.Mock
@@ -57,7 +57,7 @@
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
class FacePropertyRepositoryImplTest : SysuiTestCase() {
companion object {
private const val LOGICAL_CAMERA_ID_OUTER_FRONT = "0"
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/data/repository/FaceSettingsRepositoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/data/repository/FaceSettingsRepositoryImplTest.kt
index 6391986..0209ab8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/data/repository/FaceSettingsRepositoryImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/data/repository/FaceSettingsRepositoryImplTest.kt
@@ -19,6 +19,7 @@
import android.database.ContentObserver
import android.os.Handler
import android.provider.Settings.Secure.FACE_UNLOCK_ALWAYS_REQUIRE_CONFIRMATION
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
@@ -35,7 +36,6 @@
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
import org.mockito.ArgumentMatchers.anyBoolean
import org.mockito.ArgumentMatchers.anyInt
import org.mockito.Mock
@@ -47,7 +47,7 @@
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
class FaceSettingsRepositoryImplTest : SysuiTestCase() {
@JvmField @Rule var mockitoRule = MockitoJUnit.rule()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/data/repository/FingerprintRepositoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/data/repository/FingerprintRepositoryImplTest.kt
index 7808c41..ff5a419f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/data/repository/FingerprintRepositoryImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/data/repository/FingerprintRepositoryImplTest.kt
@@ -23,6 +23,7 @@
import android.hardware.fingerprint.FingerprintSensorProperties
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal
import android.hardware.fingerprint.IFingerprintAuthenticatorsRegisteredCallback
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.biometrics.shared.model.FingerprintSensorType
@@ -38,7 +39,6 @@
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
import org.mockito.ArgumentCaptor
import org.mockito.Captor
import org.mockito.Mock
@@ -47,7 +47,7 @@
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
class FingerprintRepositoryImplTest : SysuiTestCase() {
@JvmField @Rule var mockitoRule = MockitoJUnit.rule()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/data/repository/PromptRepositoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/data/repository/PromptRepositoryImplTest.kt
index 2682633..22971bc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/data/repository/PromptRepositoryImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/data/repository/PromptRepositoryImplTest.kt
@@ -17,6 +17,7 @@
package com.android.systemui.biometrics.data.repository
import android.hardware.biometrics.PromptInfo
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.biometrics.AuthController
@@ -37,7 +38,6 @@
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
import org.mockito.ArgumentMatchers.eq
import org.mockito.Mock
import org.mockito.Mockito.verify
@@ -51,7 +51,7 @@
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
class PromptRepositoryImplTest : SysuiTestCase() {
@JvmField @Rule var mockitoRule = MockitoJUnit.rule()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/BiometricStatusInteractorImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/BiometricStatusInteractorImplTest.kt
index 4cff3e6..5d2d20c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/BiometricStatusInteractorImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/BiometricStatusInteractorImplTest.kt
@@ -19,6 +19,7 @@
import android.app.ActivityManager
import android.content.ComponentName
import android.hardware.biometrics.BiometricFingerprintConstants
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.app.activityTaskManager
import com.android.systemui.SysuiTestCase
@@ -37,13 +38,12 @@
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
import org.mockito.Mockito
import org.mockito.Mockito.`when`
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
class BiometricStatusInteractorImplTest : SysuiTestCase() {
private val kosmos = testKosmos()
private lateinit var underTest: BiometricStatusInteractorImpl
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/CredentialInteractorImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/CredentialInteractorImplTest.kt
index 8690d4e..4856f15 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/CredentialInteractorImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/CredentialInteractorImplTest.kt
@@ -4,6 +4,7 @@
import android.app.admin.DevicePolicyResourcesManager
import android.content.pm.UserInfo
import android.os.UserManager
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.internal.widget.LockPatternUtils
import com.android.internal.widget.LockscreenCredential
@@ -25,7 +26,6 @@
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
import org.mockito.ArgumentMatchers.anyInt
import org.mockito.ArgumentMatchers.anyLong
import org.mockito.Mock
@@ -38,7 +38,7 @@
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
class CredentialInteractorImplTest : SysuiTestCase() {
@JvmField @Rule var mockitoRule = MockitoJUnit.rule()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/DisplayStateInteractorImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/DisplayStateInteractorImplTest.kt
index 31bdde2..f40b6b0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/DisplayStateInteractorImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/DisplayStateInteractorImplTest.kt
@@ -1,5 +1,6 @@
package com.android.systemui.biometrics.domain.interactor
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.biometrics.data.repository.FakeDisplayStateRepository
@@ -22,14 +23,13 @@
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
import org.mockito.Mock
import org.mockito.Mockito.verify
import org.mockito.junit.MockitoJUnit
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
class DisplayStateInteractorImplTest : SysuiTestCase() {
@JvmField @Rule var mockitoRule = MockitoJUnit.rule()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/LogContextInteractorImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/LogContextInteractorImplTest.kt
index 3f83ce3..a58efd3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/LogContextInteractorImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/LogContextInteractorImplTest.kt
@@ -19,6 +19,7 @@
import android.hardware.biometrics.AuthenticateOptions
import android.hardware.biometrics.IBiometricContextListener
import android.hardware.biometrics.IBiometricContextListener.FoldState
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
@@ -40,12 +41,11 @@
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
import org.mockito.junit.MockitoJUnit
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
class LogContextInteractorImplTest : SysuiTestCase() {
@JvmField @Rule var mockitoRule = MockitoJUnit.rule()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/PromptCredentialInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/PromptCredentialInteractorTest.kt
index c4d0d23..5a36376 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/PromptCredentialInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/PromptCredentialInteractorTest.kt
@@ -3,6 +3,7 @@
import android.hardware.biometrics.PromptContentViewWithMoreOptionsButton
import android.hardware.biometrics.PromptInfo
import android.hardware.biometrics.PromptVerticalListContentView
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.biometrics.data.repository.FakePromptRepository
@@ -29,7 +30,6 @@
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
import org.mockito.junit.MockitoJUnit
private const val USER_ID = 22
@@ -39,7 +39,7 @@
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
class PromptCredentialInteractorTest : SysuiTestCase() {
@JvmField @Rule var mockitoRule = MockitoJUnit.rule()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/PromptSelectorInteractorImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/PromptSelectorInteractorImplTest.kt
index 6e78e33..720f207 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/PromptSelectorInteractorImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/PromptSelectorInteractorImplTest.kt
@@ -22,6 +22,7 @@
import android.hardware.biometrics.PromptContentViewWithMoreOptionsButton
import android.hardware.biometrics.PromptInfo
import android.hardware.biometrics.PromptVerticalListContentView
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.internal.widget.LockPatternUtils
import com.android.systemui.SysuiTestCase
@@ -47,13 +48,12 @@
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
import org.mockito.Mock
import org.mockito.junit.MockitoJUnit
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
class PromptSelectorInteractorImplTest : SysuiTestCase() {
companion object {
private const val TITLE = "hey there"
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/UdfpsOverlayInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/UdfpsOverlayInteractorTest.kt
index 5e7adb7..3d63c5b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/UdfpsOverlayInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/UdfpsOverlayInteractorTest.kt
@@ -19,6 +19,7 @@
import android.graphics.Rect
import android.view.MotionEvent
import android.view.Surface
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.biometrics.AuthController
@@ -34,7 +35,6 @@
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
import org.mockito.ArgumentCaptor
import org.mockito.ArgumentMatchers.anyInt
import org.mockito.Captor
@@ -44,7 +44,7 @@
import org.mockito.junit.MockitoJUnit
@SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
class UdfpsOverlayInteractorTest : SysuiTestCase() {
@JvmField @Rule var mockitoRule = MockitoJUnit.rule()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/model/BiometricPromptRequestTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/model/BiometricPromptRequestTest.kt
index d10b935..1f6a8b8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/model/BiometricPromptRequestTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/model/BiometricPromptRequestTest.kt
@@ -4,6 +4,7 @@
import android.hardware.biometrics.PromptContentItemBulletedText
import android.hardware.biometrics.PromptContentViewWithMoreOptionsButton
import android.hardware.biometrics.PromptVerticalListContentView
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.biometrics.fingerprintSensorPropertiesInternal
@@ -15,14 +16,13 @@
import com.google.common.util.concurrent.MoreExecutors
import org.junit.Test
import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
private const val USER_ID = 2
private const val OPERATION_ID = 8L
private const val OP_PACKAGE_NAME = "biometric.testapp"
@SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
class BiometricPromptRequestTest : SysuiTestCase() {
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/shared/model/BiometricModalitiesTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/shared/model/BiometricModalitiesTest.kt
index 74c4313..4d8fafc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/shared/model/BiometricModalitiesTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/shared/model/BiometricModalitiesTest.kt
@@ -17,6 +17,7 @@
package com.android.systemui.biometrics.shared.model
import android.hardware.fingerprint.FingerprintSensorProperties
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.biometrics.faceSensorPropertiesInternal
@@ -24,10 +25,9 @@
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
@SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
class BiometricModalitiesTest : SysuiTestCase() {
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/udfps/BoundingBoxOverlapDetectorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/udfps/BoundingBoxOverlapDetectorTest.kt
index 95b72d5..f9bedc9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/udfps/BoundingBoxOverlapDetectorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/udfps/BoundingBoxOverlapDetectorTest.kt
@@ -21,12 +21,13 @@
import com.android.systemui.SysuiTestCase
import com.google.common.truth.Truth.assertThat
import org.junit.Test
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4
+import platform.test.runner.parameterized.Parameters
+import platform.test.runner.parameterized.Parameter
import org.junit.runner.RunWith
-import org.junit.runners.Parameterized
-import org.junit.runners.Parameterized.Parameters
@SmallTest
-@RunWith(Parameterized::class)
+@RunWith(ParameterizedAndroidJunit4::class)
class BoundingBoxOverlapDetectorTest(val testCase: TestCase) : SysuiTestCase() {
val underTest = BoundingBoxOverlapDetector(1f)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/udfps/EllipseOverlapDetectorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/udfps/EllipseOverlapDetectorTest.kt
index 317141b..33ddbf1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/udfps/EllipseOverlapDetectorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/udfps/EllipseOverlapDetectorTest.kt
@@ -22,12 +22,13 @@
import com.android.systemui.biometrics.EllipseOverlapDetectorParams
import com.google.common.truth.Truth.assertThat
import org.junit.Test
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4
+import platform.test.runner.parameterized.Parameters
+import platform.test.runner.parameterized.Parameter
import org.junit.runner.RunWith
-import org.junit.runners.Parameterized
-import org.junit.runners.Parameterized.Parameters
@SmallTest
-@RunWith(Parameterized::class)
+@RunWith(ParameterizedAndroidJunit4::class)
class EllipseOverlapDetectorTest(val testCase: TestCase) : SysuiTestCase() {
val underTest =
EllipseOverlapDetector(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/udfps/NormalizedTouchDataTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/udfps/NormalizedTouchDataTest.kt
index 3e5c43a..3863b3c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/udfps/NormalizedTouchDataTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/udfps/NormalizedTouchDataTest.kt
@@ -5,12 +5,13 @@
import com.android.systemui.SysuiTestCase
import com.google.common.truth.Truth.assertThat
import org.junit.Test
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4
+import platform.test.runner.parameterized.Parameters
+import platform.test.runner.parameterized.Parameter
import org.junit.runner.RunWith
-import org.junit.runners.Parameterized
-import org.junit.runners.Parameterized.Parameters
@SmallTest
-@RunWith(Parameterized::class)
+@RunWith(ParameterizedAndroidJunit4::class)
class NormalizedTouchDataTest(val testCase: TestCase) : SysuiTestCase() {
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/udfps/SinglePointerTouchProcessorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/udfps/SinglePointerTouchProcessorTest.kt
index aff93bd..a4653e7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/udfps/SinglePointerTouchProcessorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/udfps/SinglePointerTouchProcessorTest.kt
@@ -27,12 +27,13 @@
import com.android.systemui.biometrics.shared.model.UdfpsOverlayParams
import com.google.common.truth.Truth.assertThat
import org.junit.Test
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4
+import platform.test.runner.parameterized.Parameters
+import platform.test.runner.parameterized.Parameter
import org.junit.runner.RunWith
-import org.junit.runners.Parameterized
-import org.junit.runners.Parameterized.Parameters
@SmallTest
-@RunWith(Parameterized::class)
+@RunWith(ParameterizedAndroidJunit4::class)
class SinglePointerTouchProcessorTest(val testCase: TestCase) : SysuiTestCase() {
private val overlapDetector = FakeOverlapDetector()
private val underTest = SinglePointerTouchProcessor(overlapDetector)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/binder/SideFpsOverlayViewBinderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/binder/SideFpsOverlayViewBinderTest.kt
index ec2b104..4238254 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/binder/SideFpsOverlayViewBinderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/binder/SideFpsOverlayViewBinderTest.kt
@@ -32,6 +32,7 @@
import android.view.WindowMetrics
import android.view.layoutInflater
import android.view.windowManager
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.airbnb.lottie.LottieAnimationView
import com.android.keyguard.keyguardUpdateMonitor
@@ -61,7 +62,6 @@
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
import org.mockito.Mock
import org.mockito.Mockito
import org.mockito.Mockito.any
@@ -76,7 +76,7 @@
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
class SideFpsOverlayViewBinderTest : SysuiTestCase() {
private val kosmos = testKosmos()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/CredentialViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/CredentialViewModelTest.kt
index 9e804c1..e4c5cd4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/CredentialViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/CredentialViewModelTest.kt
@@ -1,5 +1,6 @@
package com.android.systemui.biometrics.ui.viewmodel
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.biometrics.data.repository.FakePromptRepository
@@ -19,7 +20,6 @@
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
private const val USER_ID = 9
private const val REQUEST_ID = 9L
@@ -27,7 +27,7 @@
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
class CredentialViewModelTest : SysuiTestCase() {
private val dispatcher = UnconfinedTestDispatcher()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/DeviceEntryUdfpsTouchOverlayViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/DeviceEntryUdfpsTouchOverlayViewModelTest.kt
index 1b6aaab..77ddd31 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/DeviceEntryUdfpsTouchOverlayViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/DeviceEntryUdfpsTouchOverlayViewModelTest.kt
@@ -16,6 +16,7 @@
package com.android.systemui.biometrics.ui.viewmodel
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.bouncer.data.repository.fakeKeyguardBouncerRepository
@@ -34,7 +35,6 @@
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
import org.mockito.ArgumentCaptor
import org.mockito.Captor
import org.mockito.Mockito.verify
@@ -42,7 +42,7 @@
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
class DeviceEntryUdfpsTouchOverlayViewModelTest : SysuiTestCase() {
private val kosmos =
testKosmos().apply {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptAuthStateTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptAuthStateTest.kt
index 278a43e..3eb2ff3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptAuthStateTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptAuthStateTest.kt
@@ -16,16 +16,16 @@
package com.android.systemui.biometrics.ui.viewmodel
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.biometrics.shared.model.BiometricModality
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
@SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
class PromptAuthStateTest : SysuiTestCase() {
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptHistoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptHistoryImplTest.kt
index f9b590f..81132d7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptHistoryImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptHistoryImplTest.kt
@@ -16,6 +16,7 @@
package com.android.systemui.biometrics.ui.viewmodel
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.biometrics.shared.model.BiometricModality
@@ -23,10 +24,9 @@
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
@SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
class PromptHistoryImplTest : SysuiTestCase() {
private lateinit var history: PromptHistoryImpl
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt
index 1167fce..db6aba3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt
@@ -86,10 +86,12 @@
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import org.junit.Before
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4
+import platform.test.runner.parameterized.Parameter
+import platform.test.runner.parameterized.Parameters
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import org.junit.runners.Parameterized
import org.mockito.ArgumentMatchers.anyInt
import org.mockito.ArgumentMatchers.eq
import org.mockito.Mock
@@ -105,7 +107,7 @@
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
-@RunWith(Parameterized::class)
+@RunWith(ParameterizedAndroidJunit4::class)
internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCase() {
@JvmField @Rule var mockitoRule = MockitoJUnit.rule()
@@ -1476,7 +1478,7 @@
companion object {
@JvmStatic
- @Parameterized.Parameters(name = "{0}")
+ @Parameters(name = "{0}")
fun data(): Collection<TestCase> = singleModalityTestCases + coexTestCases
private val singleModalityTestCases =
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/SideFpsOverlayViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/SideFpsOverlayViewModelTest.kt
index b065393..3b2cf61 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/SideFpsOverlayViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/SideFpsOverlayViewModelTest.kt
@@ -27,6 +27,7 @@
import android.view.WindowInsets
import android.view.WindowMetrics
import android.view.windowManager
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.airbnb.lottie.model.KeyPath
import com.android.keyguard.keyguardUpdateMonitor
@@ -62,7 +63,6 @@
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
import org.mockito.Mock
import org.mockito.Mockito.mock
import org.mockito.Mockito.spy
@@ -71,7 +71,7 @@
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
class SideFpsOverlayViewModelTest : SysuiTestCase() {
private val kosmos = testKosmos()
@JvmField @Rule var mockitoRule: MockitoRule = MockitoJUnit.rule()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/BroadcastDialogDelegateTest.java b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/BroadcastDialogDelegateTest.java
index 49f2043..7d4ee25 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/BroadcastDialogDelegateTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/BroadcastDialogDelegateTest.java
@@ -28,11 +28,11 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.widget.Button;
import android.widget.TextView;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.internal.logging.testing.UiEventLoggerFake;
@@ -58,7 +58,7 @@
import org.mockito.MockitoAnnotations;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
public class BroadcastDialogDelegateTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingInteractorTest.kt
index 8a1a082..4d7c499 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/AudioSharingInteractorTest.kt
@@ -16,8 +16,8 @@
package com.android.systemui.bluetooth.qsdialog
-import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession
import com.android.dx.mockito.inline.extended.StaticMockitoSession
@@ -44,7 +44,7 @@
@ExperimentalCoroutinesApi
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
class AudioSharingInteractorTest : SysuiTestCase() {
private val testDispatcher = UnconfinedTestDispatcher()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/BluetoothAutoOnInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/BluetoothAutoOnInteractorTest.kt
index 4949716..ac5ceb8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/BluetoothAutoOnInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/BluetoothAutoOnInteractorTest.kt
@@ -17,7 +17,7 @@
package com.android.systemui.bluetooth.qsdialog
import android.bluetooth.BluetoothAdapter
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.settingslib.bluetooth.LocalBluetoothManager
import com.android.systemui.SysuiTestCase
@@ -39,7 +39,7 @@
import org.mockito.junit.MockitoRule
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
class BluetoothAutoOnInteractorTest : SysuiTestCase() {
@get:Rule val mockitoRule: MockitoRule = MockitoJUnit.rule()
private val testDispatcher = StandardTestDispatcher()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/BluetoothAutoOnRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/BluetoothAutoOnRepositoryTest.kt
index 85e2a8d..b7b2be4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/BluetoothAutoOnRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/BluetoothAutoOnRepositoryTest.kt
@@ -17,7 +17,7 @@
package com.android.systemui.bluetooth.qsdialog
import android.bluetooth.BluetoothAdapter
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.settingslib.bluetooth.BluetoothEventManager
import com.android.settingslib.bluetooth.LocalBluetoothManager
@@ -38,7 +38,7 @@
import org.mockito.junit.MockitoRule
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
class BluetoothAutoOnRepositoryTest : SysuiTestCase() {
@get:Rule val mockitoRule: MockitoRule = MockitoJUnit.rule()
private val testDispatcher = StandardTestDispatcher()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/BluetoothStateInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/BluetoothStateInteractorTest.kt
index 6fe7d86..993cac7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/BluetoothStateInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/BluetoothStateInteractorTest.kt
@@ -16,8 +16,8 @@
package com.android.systemui.bluetooth.qsdialog
-import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.settingslib.bluetooth.LocalBluetoothAdapter
import com.android.settingslib.bluetooth.LocalBluetoothManager
@@ -38,7 +38,7 @@
import org.mockito.junit.MockitoRule
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
class BluetoothStateInteractorTest : SysuiTestCase() {
@get:Rule val mockitoRule: MockitoRule = MockitoJUnit.rule()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogDelegateTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogDelegateTest.kt
index 7215619..d01fac3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogDelegateTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogDelegateTest.kt
@@ -17,7 +17,6 @@
package com.android.systemui.bluetooth.qsdialog
import android.graphics.drawable.Drawable
-import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
import android.view.LayoutInflater
import android.view.View
@@ -27,6 +26,7 @@
import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.internal.logging.UiEventLogger
import com.android.settingslib.bluetooth.CachedBluetoothDevice
@@ -57,7 +57,7 @@
import org.mockito.junit.MockitoRule
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
class BluetoothTileDialogDelegateTest : SysuiTestCase() {
companion object {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogRepositoryTest.kt
index 4aa6209..1f3dcac 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogRepositoryTest.kt
@@ -17,8 +17,8 @@
package com.android.systemui.bluetooth.qsdialog
import android.bluetooth.BluetoothAdapter
-import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.settingslib.bluetooth.CachedBluetoothDevice
import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager
@@ -35,7 +35,7 @@
import org.mockito.junit.MockitoRule
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
class BluetoothTileDialogRepositoryTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogViewModelTest.kt
index 11f74c0..9abb85d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogViewModelTest.kt
@@ -18,11 +18,11 @@
import android.bluetooth.BluetoothAdapter
import android.platform.test.annotations.EnableFlags
-import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
import android.view.View
import android.view.View.GONE
import android.view.View.VISIBLE
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.internal.logging.UiEventLogger
import com.android.settingslib.bluetooth.CachedBluetoothDevice
@@ -62,7 +62,7 @@
import org.mockito.junit.MockitoRule
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
@EnableFlags(Flags.FLAG_BLUETOOTH_QS_TILE_DIALOG_AUTO_ON_TOGGLE)
class BluetoothTileDialogViewModelTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/DeviceItemActionInteractorImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/DeviceItemActionInteractorImplTest.kt
index 762137b..64bd742 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/DeviceItemActionInteractorImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/DeviceItemActionInteractorImplTest.kt
@@ -16,8 +16,8 @@
package com.android.systemui.bluetooth.qsdialog
import android.bluetooth.BluetoothDevice
-import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.settingslib.bluetooth.CachedBluetoothDevice
import com.android.systemui.SysuiTestCase
@@ -39,7 +39,7 @@
import org.mockito.junit.MockitoRule
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
@OptIn(ExperimentalCoroutinesApi::class)
class DeviceItemActionInteractorImplTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/DeviceItemFactoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/DeviceItemFactoryTest.kt
index 4bcd9a9..a27ccc6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/DeviceItemFactoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/DeviceItemFactoryTest.kt
@@ -22,8 +22,8 @@
import android.media.AudioManager
import android.platform.test.annotations.DisableFlags
import android.platform.test.annotations.EnableFlags
-import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.settingslib.bluetooth.CachedBluetoothDevice
import com.android.settingslib.flags.Flags
@@ -39,7 +39,7 @@
import org.mockito.junit.MockitoRule
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
class DeviceItemFactoryTest : SysuiTestCase() {
@get:Rule val mockitoRule: MockitoRule = MockitoJUnit.rule()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/DeviceItemInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/DeviceItemInteractorTest.kt
index 2b4f950..7f7abaf 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/DeviceItemInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/DeviceItemInteractorTest.kt
@@ -20,8 +20,8 @@
import android.bluetooth.BluetoothDevice
import android.content.Context
import android.media.AudioManager
-import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.settingslib.bluetooth.CachedBluetoothDevice
import com.android.settingslib.bluetooth.LocalBluetoothManager
@@ -43,7 +43,7 @@
import org.mockito.junit.MockitoRule
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
class DeviceItemInteractorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/helper/BouncerSceneLayoutTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/helper/BouncerSceneLayoutTest.kt
index ca95822..923687b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/helper/BouncerSceneLayoutTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/helper/BouncerSceneLayoutTest.kt
@@ -25,11 +25,13 @@
import com.google.common.truth.Truth.assertThat
import java.util.Locale
import org.junit.Test
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4
+import platform.test.runner.parameterized.Parameter
+import platform.test.runner.parameterized.Parameters
import org.junit.runner.RunWith
-import org.junit.runners.Parameterized
@SmallTest
-@RunWith(Parameterized::class)
+@RunWith(ParameterizedAndroidJunit4::class)
class BouncerSceneLayoutTest : SysuiTestCase() {
data object Phone :
@@ -79,7 +81,7 @@
companion object {
@JvmStatic
- @Parameterized.Parameters(name = "{0}")
+ @Parameters(name = "{0}")
fun testCases() =
listOf(
Phone to
@@ -158,7 +160,7 @@
}
}
- @Parameterized.Parameter @JvmField var testCase: TestCase? = null
+ @Parameter @JvmField var testCase: TestCase? = null
@Test
fun calculateLayout() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/broadcast/BroadcastSenderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/broadcast/BroadcastSenderTest.kt
index 8e81727..1e9f855 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/broadcast/BroadcastSenderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/broadcast/BroadcastSenderTest.kt
@@ -20,7 +20,7 @@
import android.content.Intent
import android.os.Bundle
import android.os.UserHandle
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.util.concurrency.FakeExecutor
@@ -34,7 +34,7 @@
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@SmallTest
class BroadcastSenderTest : SysuiTestCase() {
@@ -138,4 +138,4 @@
verification.invoke()
assertThat(wakeLock.isHeld).isFalse()
}
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/broadcast/PendingRemovalStoreTest.kt b/packages/SystemUI/tests/src/com/android/systemui/broadcast/PendingRemovalStoreTest.kt
index 43d2cb8..c693ecc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/broadcast/PendingRemovalStoreTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/broadcast/PendingRemovalStoreTest.kt
@@ -2,7 +2,7 @@
import android.content.BroadcastReceiver
import android.os.UserHandle
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.broadcast.logging.BroadcastDispatcherLogger
@@ -14,7 +14,7 @@
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@SmallTest
class PendingRemovalStoreTest : SysuiTestCase() {
@@ -78,4 +78,4 @@
assertThat(store.isPendingRemoval(receiverOne, user)).isTrue()
assertThat(store.isPendingRemoval(receiverTwo, user)).isFalse()
}
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/broadcast/UserBroadcastDispatcherTest.kt b/packages/SystemUI/tests/src/com/android/systemui/broadcast/UserBroadcastDispatcherTest.kt
index 582f301..d878352 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/broadcast/UserBroadcastDispatcherTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/broadcast/UserBroadcastDispatcherTest.kt
@@ -21,8 +21,8 @@
import android.content.IntentFilter
import android.os.Handler
import android.os.UserHandle
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
import com.android.systemui.SysuiTestCase
import com.android.systemui.broadcast.logging.BroadcastDispatcherLogger
@@ -43,7 +43,7 @@
import org.mockito.MockitoAnnotations
import java.util.concurrent.Executor
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@TestableLooper.RunWithLooper
@SmallTest
class UserBroadcastDispatcherTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/camera/CameraGestureHelperTest.kt b/packages/SystemUI/tests/src/com/android/systemui/camera/CameraGestureHelperTest.kt
index 669795b..bea0db6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/camera/CameraGestureHelperTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/camera/CameraGestureHelperTest.kt
@@ -24,6 +24,7 @@
import android.content.pm.ActivityInfo
import android.content.pm.PackageManager
import android.content.pm.ResolveInfo
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.ActivityIntentHelper
import com.android.systemui.SysuiTestCase
@@ -41,7 +42,6 @@
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
import org.mockito.Mock
import org.mockito.Mockito.any
import org.mockito.Mockito.anyInt
@@ -50,7 +50,7 @@
import org.mockito.Mockito.`when` as whenever
@SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
class CameraGestureHelperTest : SysuiTestCase() {
@Mock
diff --git a/packages/SystemUI/tests/src/com/android/systemui/camera/CameraIntentsTest.kt b/packages/SystemUI/tests/src/com/android/systemui/camera/CameraIntentsTest.kt
index 1e522fc..3494024 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/camera/CameraIntentsTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/camera/CameraIntentsTest.kt
@@ -17,8 +17,8 @@
package com.android.systemui.camera
import android.content.Intent
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import android.testing.AndroidTestingRunner
import com.android.systemui.SysuiTestCase
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
@@ -26,7 +26,7 @@
import org.junit.runner.RunWith
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
class CameraIntentsTest : SysuiTestCase() {
companion object {
val VALID_SECURE_INTENT = Intent(CameraIntents.DEFAULT_SECURE_CAMERA_INTENT_ACTION)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/charging/WiredChargingRippleControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/charging/WiredChargingRippleControllerTest.kt
index 11756d5..034bab8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/charging/WiredChargingRippleControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/charging/WiredChargingRippleControllerTest.kt
@@ -17,11 +17,11 @@
package com.android.systemui.charging
import android.graphics.Rect
-import android.testing.AndroidTestingRunner
import android.view.Surface
import android.view.View
import android.view.WindowManager
import android.view.WindowMetrics
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.internal.logging.UiEventLogger
import com.android.systemui.res.R
@@ -49,7 +49,7 @@
import org.mockito.MockitoAnnotations
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
class WiredChargingRippleControllerTest : SysuiTestCase() {
private lateinit var controller: WiredChargingRippleController
@Mock private lateinit var commandRegistry: CommandRegistry
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineClassifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineClassifierTest.java
index 6afbde0..88bfcf0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineClassifierTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineClassifierTest.java
@@ -29,10 +29,10 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-import android.testing.AndroidTestingRunner;
import android.view.MotionEvent;
import android.view.accessibility.AccessibilityManager;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.internal.logging.MetricsLogger;
@@ -58,7 +58,7 @@
import java.util.Set;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
public class BrightLineClassifierTest extends SysuiTestCase {
private BrightLineFalsingManager mBrightLineFalsingManager;
@Mock
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineFalsingManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineFalsingManagerTest.java
index 6e00b70..ec8cc4d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineFalsingManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineFalsingManagerTest.java
@@ -25,10 +25,10 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-import android.testing.AndroidTestingRunner;
import android.view.MotionEvent;
import android.view.accessibility.AccessibilityManager;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.internal.logging.MetricsLogger;
@@ -53,7 +53,7 @@
import java.util.Set;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
public class BrightLineFalsingManagerTest extends SysuiTestCase {
private BrightLineFalsingManager mBrightLineFalsingManager;
@Mock
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/DiagonalClassifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/DiagonalClassifierTest.java
index 14dcd58..8e1be41 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/DiagonalClassifierTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/DiagonalClassifierTest.java
@@ -24,8 +24,8 @@
import static org.mockito.Mockito.when;
-import android.testing.AndroidTestingRunner;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.util.DeviceConfigProxyFake;
@@ -38,7 +38,7 @@
import org.mockito.MockitoAnnotations;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
public class DiagonalClassifierTest extends ClassifierTest {
// Next variable is not actually five, but is very close. 5 degrees is currently the value
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/DistanceClassifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/DistanceClassifierTest.java
index ab6d5b7..cbfecee 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/DistanceClassifierTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/DistanceClassifierTest.java
@@ -21,8 +21,8 @@
import static com.google.common.truth.Truth.assertThat;
-import android.testing.AndroidTestingRunner;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.util.DeviceConfigProxyFake;
@@ -33,7 +33,7 @@
import org.junit.runner.RunWith;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
public class DistanceClassifierTest extends ClassifierTest {
private FalsingDataProvider mDataProvider;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/DoubleTapClassifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/DoubleTapClassifierTest.java
index 2ceee6d..9289867 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/DoubleTapClassifierTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/DoubleTapClassifierTest.java
@@ -22,9 +22,9 @@
import static org.mockito.ArgumentMatchers.anyList;
import static org.mockito.Mockito.when;
-import android.testing.AndroidTestingRunner;
import android.view.MotionEvent;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import org.junit.After;
@@ -38,7 +38,7 @@
import java.util.List;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
public class DoubleTapClassifierTest extends ClassifierTest {
private static final int TOUCH_SLOP = 100;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingA11yDelegateTest.kt b/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingA11yDelegateTest.kt
index 2c904e7..8e4bec3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingA11yDelegateTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingA11yDelegateTest.kt
@@ -16,10 +16,10 @@
package com.android.systemui.classifier
-import android.testing.AndroidTestingRunner
import android.view.View
import android.view.accessibility.AccessibilityNodeInfo.ACTION_CLICK
import android.view.accessibility.AccessibilityNodeInfo.ACTION_LONG_CLICK
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import org.junit.Before
@@ -31,7 +31,7 @@
import org.mockito.MockitoAnnotations
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
class FalsingA11yDelegateTest : SysuiTestCase() {
@Mock lateinit var falsingCollector: FalsingCollector
@Mock lateinit var view: View
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingCollectorImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingCollectorImplTest.java
index 5361cef..5d0bfd7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingCollectorImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingCollectorImplTest.java
@@ -25,11 +25,11 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.view.KeyEvent;
import android.view.MotionEvent;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.keyguard.KeyguardUpdateMonitor;
@@ -66,7 +66,7 @@
import org.mockito.MockitoAnnotations;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
public class FalsingCollectorImplTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingDataProviderTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingDataProviderTest.java
index 057b0a1..49c6239 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingDataProviderTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingDataProviderTest.java
@@ -25,11 +25,11 @@
import static org.mockito.Mockito.when;
import android.hardware.devicestate.DeviceStateManager.FoldStateListener;
-import android.testing.AndroidTestingRunner;
import android.util.DisplayMetrics;
import android.view.KeyEvent;
import android.view.MotionEvent;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.classifier.FalsingDataProvider.GestureFinalizedListener;
@@ -46,7 +46,7 @@
import java.util.List;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
public class FalsingDataProviderTest extends ClassifierTest {
private FalsingDataProvider mDataProvider;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/HistoryTrackerTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/HistoryTrackerTest.java
index 38355c7..8e19a1f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/HistoryTrackerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/HistoryTrackerTest.java
@@ -18,8 +18,8 @@
import static com.google.common.truth.Truth.assertThat;
-import android.testing.AndroidTestingRunner;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
@@ -33,7 +33,7 @@
import java.util.Collections;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
public class HistoryTrackerTest extends SysuiTestCase {
private FakeSystemClock mSystemClock = new FakeSystemClock();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/PointerCountClassifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/PointerCountClassifierTest.java
index b8ea062..352a25c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/PointerCountClassifierTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/PointerCountClassifierTest.java
@@ -23,9 +23,9 @@
import static org.mockito.ArgumentMatchers.anyDouble;
import static org.mockito.ArgumentMatchers.anyInt;
-import android.testing.AndroidTestingRunner;
import android.view.MotionEvent;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import org.junit.After;
@@ -34,7 +34,7 @@
import org.junit.runner.RunWith;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
public class PointerCountClassifierTest extends ClassifierTest {
private FalsingClassifier mClassifier;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/ProximityClassifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/ProximityClassifierTest.java
index 1c3922a..f965a11 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/ProximityClassifierTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/ProximityClassifierTest.java
@@ -24,9 +24,9 @@
import static org.mockito.Mockito.when;
-import android.testing.AndroidTestingRunner;
import android.view.MotionEvent;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.plugins.FalsingManager;
@@ -40,7 +40,7 @@
import org.mockito.MockitoAnnotations;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ProximityClassifierTest extends ClassifierTest {
private static final long NS_PER_MS = 1000000;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/SingleTapClassifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/SingleTapClassifierTest.java
index e3c800e..65e9088 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/SingleTapClassifierTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/SingleTapClassifierTest.java
@@ -20,9 +20,9 @@
import static org.mockito.Mockito.when;
-import android.testing.AndroidTestingRunner;
import android.view.MotionEvent;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import org.junit.After;
@@ -36,7 +36,7 @@
import java.util.List;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
public class SingleTapClassifierTest extends ClassifierTest {
private static final int TOUCH_SLOP = 100;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/TimeLimitedInputEventBufferTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/TimeLimitedInputEventBufferTest.java
index ad7afa3..9a27f38 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/TimeLimitedInputEventBufferTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/TimeLimitedInputEventBufferTest.java
@@ -19,11 +19,11 @@
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
-import android.testing.AndroidTestingRunner;
import android.view.InputEvent;
import android.view.KeyEvent;
import android.view.MotionEvent;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
@@ -35,7 +35,7 @@
import org.mockito.MockitoAnnotations;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
public class TimeLimitedInputEventBufferTest extends SysuiTestCase {
private static final long MAX_AGE_MS = 100;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/TypeClassifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/TypeClassifierTest.java
index 588edb7..80c44e2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/TypeClassifierTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/TypeClassifierTest.java
@@ -33,8 +33,8 @@
import static org.mockito.Mockito.when;
-import android.testing.AndroidTestingRunner;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import org.junit.Before;
@@ -44,7 +44,7 @@
import org.mockito.MockitoAnnotations;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
public class TypeClassifierTest extends ClassifierTest {
@Mock
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/ZigZagClassifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/ZigZagClassifierTest.java
index ae2b8bb..1fe7268 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/ZigZagClassifierTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/ZigZagClassifierTest.java
@@ -20,8 +20,8 @@
import static com.google.common.truth.Truth.assertThat;
-import android.testing.AndroidTestingRunner;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.util.DeviceConfigProxyFake;
@@ -34,7 +34,7 @@
import java.util.Random;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ZigZagClassifierTest extends ClassifierTest {
private FalsingClassifier mClassifier;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardModelTest.kt
index c0dada4..5d76e32 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardModelTest.kt
@@ -22,8 +22,8 @@
import android.graphics.Bitmap
import android.net.Uri
import android.os.PersistableBundle
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import androidx.test.runner.AndroidJUnit4
import com.android.systemui.SysuiTestCase
import com.android.systemui.util.mockito.whenever
import java.io.IOException
diff --git a/packages/SystemUI/tests/src/com/android/systemui/common/coroutine/CoroutineResultTest.kt b/packages/SystemUI/tests/src/com/android/systemui/common/coroutine/CoroutineResultTest.kt
index d552c9d..de07cda 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/common/coroutine/CoroutineResultTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/common/coroutine/CoroutineResultTest.kt
@@ -14,7 +14,7 @@
package com.android.systemui.common.coroutine
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.google.common.truth.Truth.assertThat
@@ -28,7 +28,7 @@
/** atest SystemUITests:CoroutineResultTest */
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
class CoroutineResultTest : SysuiTestCase() {
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/common/ui/view/LongPressHandlingViewInteractionHandlerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/common/ui/view/LongPressHandlingViewInteractionHandlerTest.kt
index 2f4fc96..bb400f2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/common/ui/view/LongPressHandlingViewInteractionHandlerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/common/ui/view/LongPressHandlingViewInteractionHandlerTest.kt
@@ -18,6 +18,7 @@
package com.android.systemui.common.ui.view
import android.view.ViewConfiguration
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.common.ui.view.LongPressHandlingViewInteractionHandler.MotionEventModel
@@ -33,7 +34,6 @@
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
import org.mockito.Mock
import org.mockito.Mockito.never
import org.mockito.Mockito.verify
@@ -41,7 +41,7 @@
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
class LongPressHandlingViewInteractionHandlerTest : SysuiTestCase() {
@Mock private lateinit var postDelayed: (Runnable, Long) -> DisposableHandle
diff --git a/packages/SystemUI/tests/src/com/android/systemui/common/ui/view/SeekBarWithIconButtonsViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/common/ui/view/SeekBarWithIconButtonsViewTest.java
index 4c4205e..cecb525 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/common/ui/view/SeekBarWithIconButtonsViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/common/ui/view/SeekBarWithIconButtonsViewTest.java
@@ -25,12 +25,12 @@
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.SeekBar;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
@@ -49,7 +49,7 @@
* Tests for {@link SeekBarWithIconButtonsView}
*/
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@TestableLooper.RunWithLooper
public class SeekBarWithIconButtonsViewTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/complication/ComplicationCollectionLiveDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/complication/ComplicationCollectionLiveDataTest.java
index 288f3b6..ed21474 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/complication/ComplicationCollectionLiveDataTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/complication/ComplicationCollectionLiveDataTest.java
@@ -21,10 +21,10 @@
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import androidx.lifecycle.Observer;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
@@ -48,7 +48,7 @@
import java.util.HashSet;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
public class ComplicationCollectionLiveDataTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/complication/ComplicationHostViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/complication/ComplicationHostViewControllerTest.java
index c43df17..dd3f991 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/complication/ComplicationHostViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/complication/ComplicationHostViewControllerTest.java
@@ -24,13 +24,13 @@
import android.os.UserHandle;
import android.provider.Settings;
-import android.testing.AndroidTestingRunner;
import android.view.View;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.Observer;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
@@ -51,7 +51,7 @@
import java.util.HashSet;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ComplicationHostViewControllerTest extends SysuiTestCase {
@Mock
ConstraintLayout mComplicationHostView;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/complication/ComplicationLayoutEngineTest.java b/packages/SystemUI/tests/src/com/android/systemui/complication/ComplicationLayoutEngineTest.java
index baaeee1..383e0fa 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/complication/ComplicationLayoutEngineTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/complication/ComplicationLayoutEngineTest.java
@@ -22,10 +22,10 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-import android.testing.AndroidTestingRunner;
import android.view.View;
import androidx.constraintlayout.widget.ConstraintLayout;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
@@ -48,7 +48,7 @@
import java.util.stream.Collectors;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ComplicationLayoutEngineTest extends SysuiTestCase {
@Mock
ConstraintLayout mLayout;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/complication/ComplicationLayoutParamsTest.java b/packages/SystemUI/tests/src/com/android/systemui/complication/ComplicationLayoutParamsTest.java
index a23e9e4..12cb8a6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/complication/ComplicationLayoutParamsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/complication/ComplicationLayoutParamsTest.java
@@ -21,8 +21,8 @@
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
-import android.testing.AndroidTestingRunner;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
@@ -36,7 +36,7 @@
import java.util.function.Consumer;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ComplicationLayoutParamsTest extends SysuiTestCase {
/**
* Ensures ComplicationLayoutParams cannot be constructed with improper position or direction.
diff --git a/packages/SystemUI/tests/src/com/android/systemui/complication/ComplicationTypesUpdaterTest.java b/packages/SystemUI/tests/src/com/android/systemui/complication/ComplicationTypesUpdaterTest.java
index 8cd23b2..d728517 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/complication/ComplicationTypesUpdaterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/complication/ComplicationTypesUpdaterTest.java
@@ -25,8 +25,8 @@
import android.database.ContentObserver;
import android.os.UserHandle;
import android.provider.Settings;
-import android.testing.AndroidTestingRunner;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.settingslib.dream.DreamBackend;
@@ -50,7 +50,7 @@
import java.util.HashSet;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ComplicationTypesUpdaterTest extends SysuiTestCase {
@Mock
private Context mContext;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/complication/ComplicationUtilsTest.java b/packages/SystemUI/tests/src/com/android/systemui/complication/ComplicationUtilsTest.java
index e23e1f4..1e80233 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/complication/ComplicationUtilsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/complication/ComplicationUtilsTest.java
@@ -29,8 +29,8 @@
import static com.google.common.truth.Truth.assertThat;
-import android.testing.AndroidTestingRunner;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.settingslib.dream.DreamBackend;
@@ -45,7 +45,7 @@
import java.util.Set;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ComplicationUtilsTest extends SysuiTestCase {
@Test
public void testConvertComplicationType() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/complication/ComplicationViewModelTransformerTest.java b/packages/SystemUI/tests/src/com/android/systemui/complication/ComplicationViewModelTransformerTest.java
index 09675e2..98b119a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/complication/ComplicationViewModelTransformerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/complication/ComplicationViewModelTransformerTest.java
@@ -21,9 +21,9 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-import android.testing.AndroidTestingRunner;
import androidx.lifecycle.ViewModel;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
@@ -38,7 +38,7 @@
import org.mockito.MockitoAnnotations;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
public class ComplicationViewModelTransformerTest extends SysuiTestCase {
@Mock
ComplicationViewModelComponent.Factory mFactory;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/complication/DreamClockTimeComplicationTest.java b/packages/SystemUI/tests/src/com/android/systemui/complication/DreamClockTimeComplicationTest.java
index b9aa4c6..22ab499 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/complication/DreamClockTimeComplicationTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/complication/DreamClockTimeComplicationTest.java
@@ -23,9 +23,9 @@
import static org.mockito.Mockito.when;
import android.content.Context;
-import android.testing.AndroidTestingRunner;
import android.view.View;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.internal.logging.UiEventLogger;
@@ -42,7 +42,7 @@
import org.mockito.MockitoAnnotations;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
public class DreamClockTimeComplicationTest extends SysuiTestCase {
@SuppressWarnings("HidingField")
@Mock
diff --git a/packages/SystemUI/tests/src/com/android/systemui/complication/DreamHomeControlsComplicationTest.java b/packages/SystemUI/tests/src/com/android/systemui/complication/DreamHomeControlsComplicationTest.java
index 18bd960b..ddf69b5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/complication/DreamHomeControlsComplicationTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/complication/DreamHomeControlsComplicationTest.java
@@ -29,9 +29,9 @@
import android.content.ComponentName;
import android.content.res.Resources;
-import android.testing.AndroidTestingRunner;
import android.view.View;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.internal.logging.UiEventLogger;
@@ -62,7 +62,7 @@
import java.util.Optional;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
public class DreamHomeControlsComplicationTest extends SysuiTestCase {
@Mock
private DreamHomeControlsComplication mComplication;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/complication/DreamMediaEntryComplicationTest.java b/packages/SystemUI/tests/src/com/android/systemui/complication/DreamMediaEntryComplicationTest.java
index 05b4a41..3a856a0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/complication/DreamMediaEntryComplicationTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/complication/DreamMediaEntryComplicationTest.java
@@ -26,10 +26,10 @@
import android.app.PendingIntent;
import android.content.Intent;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.view.View;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.ActivityIntentHelper;
@@ -51,7 +51,7 @@
import org.mockito.MockitoAnnotations;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@TestableLooper.RunWithLooper
public class DreamMediaEntryComplicationTest extends SysuiTestCase {
@Mock
diff --git a/packages/SystemUI/tests/src/com/android/systemui/complication/SmartSpaceComplicationTest.java b/packages/SystemUI/tests/src/com/android/systemui/complication/SmartSpaceComplicationTest.java
index 87de865..6c354ef 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/complication/SmartSpaceComplicationTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/complication/SmartSpaceComplicationTest.java
@@ -24,9 +24,9 @@
import static org.mockito.Mockito.when;
import android.app.smartspace.SmartspaceTarget;
-import android.testing.AndroidTestingRunner;
import android.view.View;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
@@ -52,7 +52,7 @@
import java.util.Set;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
public class SmartSpaceComplicationTest extends SysuiTestCase {
@Mock
diff --git a/packages/SystemUI/tests/src/com/android/systemui/compose/ComposeInitializerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/compose/ComposeInitializerTest.kt
index 03e4f9a..c2fe009 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/compose/ComposeInitializerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/compose/ComposeInitializerTest.kt
@@ -17,10 +17,10 @@
package com.android.systemui.compose
import android.content.Context
-import android.testing.AndroidTestingRunner
import android.testing.ViewUtils
import android.widget.FrameLayout
import androidx.compose.ui.platform.ComposeView
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.google.common.truth.Truth.assertThat
@@ -28,7 +28,7 @@
import org.junit.runner.RunWith
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
class ComposeInitializerTest : SysuiTestCase() {
@Test
fun testCanAddComposeViewInInitializedWindow() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/CustomIconCacheTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/CustomIconCacheTest.kt
index 4d0f2ed..28e0cff 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/CustomIconCacheTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/CustomIconCacheTest.kt
@@ -18,7 +18,7 @@
import android.content.ComponentName
import android.graphics.drawable.Icon
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import org.junit.Assert.assertNull
@@ -30,7 +30,7 @@
import org.mockito.MockitoAnnotations
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
class CustomIconCacheTest : SysuiTestCase() {
companion object {
@@ -98,4 +98,4 @@
assertNull(customIconCache.retrieve(TEST_COMPONENT1, CONTROL_ID_1))
}
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/controller/AuxiliaryPersistenceWrapperTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/controller/AuxiliaryPersistenceWrapperTest.kt
index 129fe9a..8d6e3a0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/controller/AuxiliaryPersistenceWrapperTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/controller/AuxiliaryPersistenceWrapperTest.kt
@@ -17,7 +17,7 @@
package com.android.systemui.controls.controller
import android.content.ComponentName
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import org.junit.Assert.assertEquals
@@ -37,7 +37,7 @@
import java.io.File
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
class AuxiliaryPersistenceWrapperTest : SysuiTestCase() {
companion object {
@@ -128,4 +128,4 @@
verify(persistenceWrapper, never()).storeFavorites(ArgumentMatchers.anyList())
}
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlActionCoordinatorImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlActionCoordinatorImplTest.kt
index 6cc3ef19..9285146 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlActionCoordinatorImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlActionCoordinatorImplTest.kt
@@ -16,8 +16,8 @@
package com.android.systemui.controls.ui
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import android.testing.AndroidTestingRunner
import android.view.HapticFeedbackConstants
import com.android.systemui.SysuiTestCase
import com.android.systemui.broadcast.BroadcastSender
@@ -48,7 +48,7 @@
import java.util.Optional
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
class ControlActionCoordinatorImplTest : SysuiTestCase() {
@Mock
private lateinit var vibratorHelper: VibratorHelper
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsBindingControllerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsBindingControllerImplTest.kt
index 724c9d1..ed0c7ee 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsBindingControllerImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsBindingControllerImplTest.kt
@@ -24,7 +24,7 @@
import android.service.controls.DeviceTypes
import android.service.controls.IControlsSubscriber
import android.service.controls.IControlsSubscription
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.settings.UserTracker
@@ -49,7 +49,7 @@
import org.mockito.MockitoAnnotations
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
class ControlsBindingControllerImplTest : SysuiTestCase() {
companion object {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsControllerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsControllerImplTest.kt
index de455f63..cf385e7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsControllerImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsControllerImplTest.kt
@@ -26,7 +26,7 @@
import android.service.controls.Control
import android.service.controls.DeviceTypes
import android.service.controls.actions.ControlAction
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.backup.BackupHelper
@@ -74,7 +74,7 @@
import java.util.function.Consumer
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
class ControlsControllerImplTest : SysuiTestCase() {
private val kosmos = testKosmos()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsFavoritePersistenceWrapperTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsFavoritePersistenceWrapperTest.kt
index 690b9a7..afa5cec 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsFavoritePersistenceWrapperTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsFavoritePersistenceWrapperTest.kt
@@ -18,7 +18,7 @@
import android.content.ComponentName
import android.service.controls.DeviceTypes
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.util.concurrency.FakeExecutor
@@ -32,7 +32,7 @@
import java.io.File
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
class ControlsFavoritePersistenceWrapperTest : SysuiTestCase() {
private lateinit var file: File
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsProviderLifecycleManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsProviderLifecycleManagerTest.kt
index b5d3476..f9c2c6b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsProviderLifecycleManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsProviderLifecycleManagerTest.kt
@@ -26,7 +26,7 @@
import android.service.controls.IControlsSubscriber
import android.service.controls.actions.ControlAction
import android.service.controls.actions.ControlActionWrapper
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.util.concurrency.FakeExecutor
@@ -57,7 +57,7 @@
import org.mockito.MockitoAnnotations
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
class ControlsProviderLifecycleManagerTest : SysuiTestCase() {
@Mock
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsTileResourceConfigurationImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsTileResourceConfigurationImplTest.kt
index 581e88b..e04ce45 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsTileResourceConfigurationImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsTileResourceConfigurationImplTest.kt
@@ -16,7 +16,7 @@
package com.android.systemui.controls.controller
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.res.R
import com.android.systemui.SysuiTestCase
@@ -25,7 +25,7 @@
import org.junit.Test
import org.junit.runner.RunWith
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@SmallTest
class ControlsTileResourceConfigurationImplTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/controller/DeletionJobServiceTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/controller/DeletionJobServiceTest.kt
index 2283746..b6ea62e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/controller/DeletionJobServiceTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/controller/DeletionJobServiceTest.kt
@@ -19,7 +19,7 @@
import android.app.job.JobParameters
import android.content.Context
import android.os.PersistableBundle
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.controls.controller.AuxiliaryPersistenceWrapper.DeletionJobService.Companion.USER
@@ -37,7 +37,7 @@
import org.mockito.MockitoAnnotations
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
class DeletionJobServiceTest : SysuiTestCase() {
@Mock private lateinit var context: Context
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/controller/PackageUpdateMonitorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/controller/PackageUpdateMonitorTest.kt
index 85d6211..282ea5c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/controller/PackageUpdateMonitorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/controller/PackageUpdateMonitorTest.kt
@@ -20,7 +20,7 @@
import android.content.pm.PackageManager
import android.os.Handler
import android.os.UserHandle
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.util.mockito.any
@@ -39,7 +39,7 @@
import org.mockito.MockitoAnnotations
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
class PackageUpdateMonitorTest : SysuiTestCase() {
@Mock private lateinit var context: Context
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ServiceWrapperTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ServiceWrapperTest.kt
index 789d6df..b5c6c53 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ServiceWrapperTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ServiceWrapperTest.kt
@@ -23,7 +23,7 @@
import android.service.controls.IControlsSubscription
import android.service.controls.actions.ControlAction
import android.service.controls.actions.ControlActionWrapper
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import org.junit.Assert.assertEquals
@@ -42,7 +42,7 @@
import org.mockito.MockitoAnnotations
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
class ServiceWrapperTest : SysuiTestCase() {
@Mock
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/controller/StatefulControlSubscriberTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/controller/StatefulControlSubscriberTest.kt
index 267520e..7d197f7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/controller/StatefulControlSubscriberTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/controller/StatefulControlSubscriberTest.kt
@@ -20,7 +20,7 @@
import android.os.Binder
import android.service.controls.Control
import android.service.controls.IControlsSubscription
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.util.concurrency.FakeExecutor
@@ -36,7 +36,7 @@
import org.mockito.MockitoAnnotations
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
class StatefulControlSubscriberTest : SysuiTestCase() {
@Mock
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/dagger/ControlsComponentTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/dagger/ControlsComponentTest.kt
index 54f66dc..844cc1f1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/dagger/ControlsComponentTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/dagger/ControlsComponentTest.kt
@@ -16,7 +16,7 @@
package com.android.systemui.controls.dagger
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.internal.widget.LockPatternUtils
import com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_NOT_REQUIRED
@@ -45,7 +45,7 @@
import org.mockito.MockitoAnnotations
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
class ControlsComponentTest : SysuiTestCase() {
@Mock private lateinit var controller: ControlsController
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/management/AllModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/management/AllModelTest.kt
index 4ea9616..5528f65 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/management/AllModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/management/AllModelTest.kt
@@ -19,7 +19,7 @@
import android.app.PendingIntent
import android.content.ComponentName
import android.service.controls.Control
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.controls.ControlStatus
@@ -37,7 +37,7 @@
import org.mockito.MockitoAnnotations
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
class AllModelTest : SysuiTestCase() {
companion object {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/management/AppAdapterTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/management/AppAdapterTest.kt
index 226ef3b..56c7c85 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/management/AppAdapterTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/management/AppAdapterTest.kt
@@ -18,10 +18,10 @@
import android.content.ComponentName
import android.content.res.Resources
-import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
import android.view.LayoutInflater
import android.view.View
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.settingslib.core.lifecycle.Lifecycle
import com.android.systemui.SysuiTestCase
@@ -45,7 +45,7 @@
import java.text.Collator
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
class AppAdapterTest : SysuiTestCase() {
private val fakeSystemClock = FakeSystemClock()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsEditingActivityTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsEditingActivityTest.kt
index 2a4524b..39e1e1d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsEditingActivityTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsEditingActivityTest.kt
@@ -3,12 +3,12 @@
import android.content.ComponentName
import android.content.Intent
import android.os.Bundle
-import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
import android.view.View
import android.widget.Button
import android.window.OnBackInvokedCallback
import android.window.OnBackInvokedDispatcher
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import androidx.test.rule.ActivityTestRule
import com.android.systemui.res.R
@@ -33,7 +33,7 @@
import org.mockito.MockitoAnnotations
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@TestableLooper.RunWithLooper
class ControlsEditingActivityTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsFavoritingActivityTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsFavoritingActivityTest.kt
index 88d36af..f5616d4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsFavoritingActivityTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsFavoritingActivityTest.kt
@@ -4,12 +4,12 @@
import android.content.Intent
import android.os.Bundle
import android.service.controls.Control
-import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
import android.view.View
import android.widget.Button
import android.window.OnBackInvokedCallback
import android.window.OnBackInvokedDispatcher
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.FlakyTest
import androidx.test.filters.SmallTest
import androidx.test.rule.ActivityTestRule
@@ -45,7 +45,7 @@
import org.mockito.MockitoAnnotations
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@TestableLooper.RunWithLooper
class ControlsFavoritingActivityTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsListingControllerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsListingControllerImplTest.kt
index 6361e94..e4f0910 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsListingControllerImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsListingControllerImplTest.kt
@@ -28,7 +28,7 @@
import android.os.Bundle
import android.os.UserHandle
import android.service.controls.ControlsProviderService
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.settingslib.applications.ServiceListing
import com.android.systemui.res.R
@@ -65,7 +65,7 @@
import org.mockito.MockitoAnnotations
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
class ControlsListingControllerImplTest : SysuiTestCase() {
companion object {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsProviderSelectorActivityTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsProviderSelectorActivityTest.kt
index d17495f..7698520 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsProviderSelectorActivityTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsProviderSelectorActivityTest.kt
@@ -23,10 +23,10 @@
import android.content.pm.ServiceInfo
import android.graphics.drawable.Drawable
import android.os.Bundle
-import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
import android.window.OnBackInvokedCallback
import android.window.OnBackInvokedDispatcher
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import androidx.test.rule.ActivityTestRule
import com.android.systemui.SysuiTestCase
@@ -65,7 +65,7 @@
import org.mockito.MockitoAnnotations
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@TestableLooper.RunWithLooper
class ControlsProviderSelectorActivityTest : SysuiTestCase() {
@Main private val executor: Executor = MoreExecutors.directExecutor()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsRequestDialogTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsRequestDialogTest.kt
index ca970bb..5008927 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsRequestDialogTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsRequestDialogTest.kt
@@ -25,9 +25,9 @@
import android.service.controls.Control
import android.service.controls.ControlsProviderService
import android.service.controls.DeviceTypes
-import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
import androidx.lifecycle.Lifecycle
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
import androidx.test.rule.ActivityTestRule
import com.android.systemui.SysuiTestCase
@@ -53,7 +53,7 @@
import java.util.concurrent.Executor
@MediumTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@TestableLooper.RunWithLooper
class ControlsRequestDialogTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsRequestReceiverTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsRequestReceiverTest.kt
index ae77d1f..c49867a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsRequestReceiverTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsRequestReceiverTest.kt
@@ -30,7 +30,7 @@
import android.os.UserHandle
import android.service.controls.Control
import android.service.controls.ControlsProviderService
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import org.junit.Assert.assertEquals
@@ -49,7 +49,7 @@
import org.mockito.MockitoAnnotations
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
class ControlsRequestReceiverTest : SysuiTestCase() {
@Mock
@@ -266,4 +266,4 @@
}
}
}
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/management/FavoritesModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/management/FavoritesModelTest.kt
index f0003ed..281addc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/management/FavoritesModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/management/FavoritesModelTest.kt
@@ -17,8 +17,8 @@
package com.android.systemui.controls.management
import android.content.ComponentName
-import android.testing.AndroidTestingRunner
import androidx.recyclerview.widget.RecyclerView
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.controls.ControlInterface
@@ -43,7 +43,7 @@
import org.mockito.MockitoAnnotations
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
class FavoritesModelTest : SysuiTestCase() {
companion object {
@@ -299,4 +299,4 @@
}
private fun getDividerPosition(): Int = model.elements.indexOf(dividerWrapper)
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/management/PanelConfirmationDialogFactoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/management/PanelConfirmationDialogFactoryTest.kt
index 7f0ea9a..d8aac10 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/management/PanelConfirmationDialogFactoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/management/PanelConfirmationDialogFactoryTest.kt
@@ -19,7 +19,7 @@
import android.content.Context
import android.content.DialogInterface
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.res.R
@@ -39,7 +39,7 @@
import org.mockito.Mockito.`when` as whenever
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
class PanelConfirmationDialogFactoryTest : SysuiTestCase() {
@Mock private lateinit var mockDialog : SystemUIDialog
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/panels/AuthorizedPanelsRepositoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/panels/AuthorizedPanelsRepositoryImplTest.kt
index 18ce4a8..fd4c681 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/panels/AuthorizedPanelsRepositoryImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/panels/AuthorizedPanelsRepositoryImplTest.kt
@@ -19,7 +19,7 @@
import android.content.SharedPreferences
import android.content.pm.UserInfo
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
@@ -37,7 +37,7 @@
import org.junit.Test
import org.junit.runner.RunWith
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@SmallTest
class AuthorizedPanelsRepositoryImplTest : SysuiTestCase() {
val kosmos = testKosmos()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/panels/SelectedComponentRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/panels/SelectedComponentRepositoryTest.kt
index a7e7ba9..86e3481 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/panels/SelectedComponentRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/panels/SelectedComponentRepositoryTest.kt
@@ -19,7 +19,7 @@
import android.content.ComponentName
import android.content.SharedPreferences
import android.os.UserHandle
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
@@ -43,7 +43,7 @@
import org.mockito.MockitoAnnotations
@ExperimentalCoroutinesApi
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@SmallTest
class SelectedComponentRepositoryTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/settings/ControlsSettingsDialogManagerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/settings/ControlsSettingsDialogManagerImplTest.kt
index 154c373..aee334f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/settings/ControlsSettingsDialogManagerImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/settings/ControlsSettingsDialogManagerImplTest.kt
@@ -22,8 +22,8 @@
import android.database.ContentObserver
import android.provider.Settings.Secure.LOCKSCREEN_ALLOW_TRIVIAL_CONTROLS
import android.provider.Settings.Secure.LOCKSCREEN_SHOW_CONTROLS
-import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.controls.settings.ControlsSettingsDialogManager.Companion.PREFS_SETTINGS_DIALOG_ATTEMPTS
@@ -52,7 +52,7 @@
import org.mockito.MockitoAnnotations
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@TestableLooper.RunWithLooper
class ControlsSettingsDialogManagerImplTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/settings/ControlsSettingsRepositoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/settings/ControlsSettingsRepositoryImplTest.kt
index b904ac1..3bdd5cf 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/settings/ControlsSettingsRepositoryImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/settings/ControlsSettingsRepositoryImplTest.kt
@@ -19,6 +19,7 @@
import android.content.pm.UserInfo
import android.provider.Settings
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.user.data.repository.FakeUserRepository
@@ -33,10 +34,9 @@
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
@SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
@OptIn(ExperimentalCoroutinesApi::class)
class ControlsSettingsRepositoryImplTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/start/ControlsStartableTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/start/ControlsStartableTest.kt
index c44429b..9e8914a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/start/ControlsStartableTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/start/ControlsStartableTest.kt
@@ -26,7 +26,7 @@
import android.content.pm.ServiceInfo
import android.os.UserHandle
import android.os.UserManager
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.broadcast.BroadcastDispatcher
@@ -75,7 +75,7 @@
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
class ControlsStartableTest : SysuiTestCase() {
private val kosmos = testKosmos()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/CanUseIconPredicateTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/CanUseIconPredicateTest.kt
index bfdb923..193ce21 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/CanUseIconPredicateTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/CanUseIconPredicateTest.kt
@@ -21,7 +21,7 @@
import android.graphics.drawable.Icon
import android.net.Uri
import android.os.UserHandle
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.google.common.truth.Truth.assertThat
@@ -29,7 +29,7 @@
import org.junit.runner.RunWith
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
class CanUseIconPredicateTest : SysuiTestCase() {
private companion object {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlViewHolderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlViewHolderTest.kt
index 101b8ed..4b30fa5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlViewHolderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlViewHolderTest.kt
@@ -24,11 +24,11 @@
import android.service.controls.Control
import android.service.controls.DeviceTypes
import android.service.controls.templates.ControlTemplate
-import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.res.R
import com.android.systemui.SysuiTestCase
@@ -44,7 +44,7 @@
import org.mockito.Mockito.mock
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@TestableLooper.RunWithLooper
class ControlViewHolderTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsActivityTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsActivityTest.kt
index e279d28..03aa622 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsActivityTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsActivityTest.kt
@@ -19,8 +19,8 @@
import android.content.Intent
import android.content.res.Configuration
import android.service.dreams.IDreamManager
-import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import androidx.test.rule.ActivityTestRule
import com.android.systemui.SysuiTestCase
@@ -39,7 +39,7 @@
import org.mockito.MockitoAnnotations
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@TestableLooper.RunWithLooper
class ControlsActivityTest : SysuiTestCase() {
@Mock private lateinit var uiController: ControlsUiController
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsDialogsFactoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsDialogsFactoryTest.kt
index 38c6a0e..ca33f16 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsDialogsFactoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsDialogsFactoryTest.kt
@@ -18,7 +18,7 @@
package com.android.systemui.controls.ui
import android.content.Context
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.res.R
import com.android.systemui.SysuiTestCase
@@ -36,7 +36,7 @@
import org.mockito.MockitoAnnotations
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
class ControlsDialogsFactoryTest : SysuiTestCase() {
private companion object {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsPopupMenuTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsPopupMenuTest.kt
index 48e3962..66303eb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsPopupMenuTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsPopupMenuTest.kt
@@ -19,12 +19,12 @@
import android.app.Activity
import android.graphics.Color
import android.graphics.drawable.ShapeDrawable
-import android.testing.AndroidTestingRunner
import android.util.DisplayMetrics
import android.view.View
import android.view.ViewGroup
import android.widget.PopupWindow.OnDismissListener
import androidx.test.ext.junit.rules.ActivityScenarioRule
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.res.R
import com.android.systemui.SysuiTestCase
@@ -43,7 +43,7 @@
import org.mockito.MockitoAnnotations
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
open class ControlsPopupMenuTest : SysuiTestCase() {
private companion object {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsUiControllerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsUiControllerImplTest.kt
index 8f3813d..20890a7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsUiControllerImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsUiControllerImplTest.kt
@@ -26,13 +26,13 @@
import android.os.UserHandle
import android.service.controls.ControlsProviderService
import android.service.controls.flags.Flags.FLAG_HOME_PANEL_DREAM
-import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.controls.ControlsMetricsLogger
@@ -83,7 +83,7 @@
import org.mockito.MockitoAnnotations
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@TestableLooper.RunWithLooper
class ControlsUiControllerImplTest : SysuiTestCase() {
private val kosmos = testKosmos()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/DetailDialogTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/DetailDialogTest.kt
index 677108c..10b3ce3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/DetailDialogTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/DetailDialogTest.kt
@@ -19,9 +19,9 @@
import android.app.ActivityOptions
import android.app.PendingIntent
import android.content.Context
-import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
import androidx.test.ext.junit.rules.ActivityScenarioRule
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.activity.EmptyTestActivity
@@ -44,7 +44,7 @@
import org.mockito.MockitoAnnotations
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@TestableLooper.RunWithLooper
class DetailDialogTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/OverflowMenuAdapterTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/OverflowMenuAdapterTest.kt
index 483ab3b..6092b8c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/OverflowMenuAdapterTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/OverflowMenuAdapterTest.kt
@@ -17,7 +17,7 @@
package com.android.systemui.controls.ui
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.google.common.truth.Truth.assertThat
@@ -25,7 +25,7 @@
import org.junit.runner.RunWith
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
class OverflowMenuAdapterTest : SysuiTestCase() {
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/PanelTaskViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/PanelTaskViewControllerTest.kt
index 021facc..de2d852 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/PanelTaskViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/PanelTaskViewControllerTest.kt
@@ -25,8 +25,8 @@
import android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK
import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
import android.graphics.Rect
-import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.util.boundsOnScreen
@@ -49,7 +49,7 @@
import org.mockito.MockitoAnnotations
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@TestableLooper.RunWithLooper
class PanelTaskViewControllerTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/SelectionItemTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/SelectionItemTest.kt
index 57176f0..4579807 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/SelectionItemTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/SelectionItemTest.kt
@@ -1,7 +1,7 @@
package com.android.systemui.controls.ui
import android.content.ComponentName
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.controls.controller.StructureInfo
@@ -11,7 +11,7 @@
import org.junit.runner.RunWith
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
class SelectionItemTest : SysuiTestCase() {
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ToggleRangeTemplateTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ToggleRangeTemplateTest.kt
index 31e0954..9f4836a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ToggleRangeTemplateTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ToggleRangeTemplateTest.kt
@@ -17,7 +17,7 @@
package com.android.systemui.controls.ui
import android.service.controls.templates.RangeTemplate
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import org.junit.Assert.assertEquals
@@ -25,7 +25,7 @@
import org.junit.runner.RunWith
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
class ToggleRangeTemplateTest : SysuiTestCase() {
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/coroutines/FlowTest.kt b/packages/SystemUI/tests/src/com/android/systemui/coroutines/FlowTest.kt
index 1e4753e..23da3f1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/coroutines/FlowTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/coroutines/FlowTest.kt
@@ -1,6 +1,6 @@
package com.android.systemui.coroutines
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.google.common.truth.Truth.assertThat
@@ -12,7 +12,7 @@
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
class FlowTest : SysuiTestCase() {
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/decor/CutoutDecorProviderFactoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/decor/CutoutDecorProviderFactoryTest.kt
index 1040ec4..f029847 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/decor/CutoutDecorProviderFactoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/decor/CutoutDecorProviderFactoryTest.kt
@@ -18,7 +18,6 @@
import android.graphics.Insets
import android.graphics.Rect
-import android.testing.AndroidTestingRunner
import android.testing.TestableResources
import android.util.RotationUtils
import android.util.Size
@@ -27,6 +26,7 @@
import android.view.DisplayCutout.BOUNDS_POSITION_LENGTH
import android.view.DisplayInfo
import android.view.Surface
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.util.mockito.any
@@ -38,7 +38,7 @@
import org.mockito.Mockito.doAnswer
import org.mockito.MockitoAnnotations
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@SmallTest
class CutoutDecorProviderFactoryTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/decor/OverlayWindowTest.kt b/packages/SystemUI/tests/src/com/android/systemui/decor/OverlayWindowTest.kt
index a1cffc1..69fab56 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/decor/OverlayWindowTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/decor/OverlayWindowTest.kt
@@ -17,11 +17,11 @@
package com.android.systemui.decor
import android.graphics.Color
-import android.testing.AndroidTestingRunner
import android.testing.TestableLooper.RunWithLooper
import android.view.DisplayCutout
import android.view.Surface
import android.view.View
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.res.R
import com.android.systemui.SysuiTestCase
@@ -34,7 +34,7 @@
import org.mockito.Mockito.times
import org.mockito.Mockito.verify
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@RunWithLooper(setAsMainLooper = true)
@SmallTest
class OverlayWindowTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/decor/PrivacyDotDecorProviderFactoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/decor/PrivacyDotDecorProviderFactoryTest.kt
index e4ddc37..6d6c6ef 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/decor/PrivacyDotDecorProviderFactoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/decor/PrivacyDotDecorProviderFactoryTest.kt
@@ -17,8 +17,8 @@
package com.android.systemui.decor
import android.content.res.Resources
-import android.testing.AndroidTestingRunner
import android.view.DisplayCutout
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.res.R
import com.android.systemui.SysuiTestCase
@@ -30,7 +30,7 @@
import org.mockito.Mockito.spy
import org.mockito.Mockito.`when` as whenever
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@SmallTest
class PrivacyDotDecorProviderFactoryTest : SysuiTestCase() {
private lateinit var mPrivacyDotDecorProviderFactory: PrivacyDotDecorProviderFactory
@@ -83,4 +83,4 @@
and it.alignedBounds.contains(DisplayCutout.BOUNDS_POSITION_RIGHT))
})
}
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/decor/RoundedCornerDecorProviderFactoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/decor/RoundedCornerDecorProviderFactoryTest.kt
index d1d4880..4da988a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/decor/RoundedCornerDecorProviderFactoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/decor/RoundedCornerDecorProviderFactoryTest.kt
@@ -16,9 +16,9 @@
package com.android.systemui.decor
-import android.testing.AndroidTestingRunner
import android.util.Size
import android.view.DisplayCutout
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.res.R
import com.android.systemui.SysuiTestCase
@@ -30,7 +30,7 @@
import org.mockito.Mockito
import org.mockito.Mockito.spy
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@SmallTest
class RoundedCornerDecorProviderFactoryTest : SysuiTestCase() {
@@ -139,4 +139,4 @@
})
}
}
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/decor/RoundedCornerResDelegateTest.kt b/packages/SystemUI/tests/src/com/android/systemui/decor/RoundedCornerResDelegateTest.kt
index 2bff7d2..9d440c3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/decor/RoundedCornerResDelegateTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/decor/RoundedCornerResDelegateTest.kt
@@ -18,9 +18,9 @@
import android.content.res.TypedArray
import android.graphics.drawable.Drawable
-import android.testing.AndroidTestingRunner
import android.util.Size
import androidx.annotation.DrawableRes
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.internal.R as InternalR
import com.android.systemui.res.R as SystemUIR
@@ -33,7 +33,7 @@
import org.mockito.Mock
import org.mockito.MockitoAnnotations
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@SmallTest
class RoundedCornerResDelegateTest : SysuiTestCase() {
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 6c2e136..4793a52f3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/demomode/DemoModeControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/demomode/DemoModeControllerTest.kt
@@ -18,8 +18,8 @@
import android.content.Intent
import android.os.Bundle
-import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.demomode.DemoMode.ACTION_DEMO
@@ -40,7 +40,7 @@
@Suppress("EXPERIMENTAL_IS_NOT_ENABLED")
@OptIn(ExperimentalCoroutinesApi::class)
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@TestableLooper.RunWithLooper
@SmallTest
class DemoModeControllerTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/deviceentry/data/repository/FaceWakeUpTriggersConfigTest.kt b/packages/SystemUI/tests/src/com/android/systemui/deviceentry/data/repository/FaceWakeUpTriggersConfigTest.kt
index e9b4bbb..6b0de92 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/deviceentry/data/repository/FaceWakeUpTriggersConfigTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/deviceentry/data/repository/FaceWakeUpTriggersConfigTest.kt
@@ -17,7 +17,7 @@
package com.android.systemui.deviceentry.data.repository
import android.os.PowerManager
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.dump.DumpManager
@@ -30,7 +30,7 @@
import org.mockito.Mock
import org.mockito.MockitoAnnotations
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@SmallTest
class FaceWakeUpTriggersConfigTest : SysuiTestCase() {
@Mock lateinit var globalSettings: GlobalSettings
diff --git a/packages/SystemUI/tests/src/com/android/systemui/devicepolicy/DevicePolicyManagerExtTest.kt b/packages/SystemUI/tests/src/com/android/systemui/devicepolicy/DevicePolicyManagerExtTest.kt
index 8203291..64ff5f7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/devicepolicy/DevicePolicyManagerExtTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/devicepolicy/DevicePolicyManagerExtTest.kt
@@ -22,6 +22,7 @@
import android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_NONE
import android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA
import android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_SHORTCUTS_ALL
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.settings.UserTracker
@@ -31,13 +32,12 @@
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
import org.mockito.ArgumentMatchers.anyInt
import org.mockito.Mock
import org.mockito.MockitoAnnotations
@SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
class DevicePolicyManagerExtTest : SysuiTestCase() {
@Mock lateinit var devicePolicyManager: DevicePolicyManager
diff --git a/packages/SystemUI/tests/src/com/android/systemui/display/data/repository/DeviceStateRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/display/data/repository/DeviceStateRepositoryTest.kt
index c79cbab..3f5b9a3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/display/data/repository/DeviceStateRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/display/data/repository/DeviceStateRepositoryTest.kt
@@ -17,8 +17,8 @@
package com.android.systemui.display.data.repository
import android.hardware.devicestate.DeviceStateManager
-import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.internal.R
import com.android.systemui.SysuiTestCase
@@ -41,7 +41,7 @@
import org.mockito.Mockito.never
import org.mockito.Mockito.verify
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@TestableLooper.RunWithLooper
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
diff --git a/packages/SystemUI/tests/src/com/android/systemui/display/data/repository/DisplayRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/display/data/repository/DisplayRepositoryTest.kt
index 68d49c7..01868ae 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/display/data/repository/DisplayRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/display/data/repository/DisplayRepositoryTest.kt
@@ -18,11 +18,11 @@
import android.hardware.display.DisplayManager
import android.os.Looper
-import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
import android.view.Display
import android.view.Display.TYPE_EXTERNAL
import android.view.Display.TYPE_INTERNAL
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.FlowValue
@@ -46,7 +46,7 @@
import org.mockito.Mockito.times
import org.mockito.Mockito.verify
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@TestableLooper.RunWithLooper
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
diff --git a/packages/SystemUI/tests/src/com/android/systemui/display/domain/interactor/ConnectedDisplayInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/display/domain/interactor/ConnectedDisplayInteractorTest.kt
index 37c7409..fd9964f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/display/domain/interactor/ConnectedDisplayInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/display/domain/interactor/ConnectedDisplayInteractorTest.kt
@@ -19,12 +19,12 @@
import android.companion.virtual.VirtualDeviceManager
import android.companion.virtual.flags.Flags.FLAG_INTERACTIVE_SCREEN_MIRROR
import android.platform.test.annotations.EnableFlags
-import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
import android.view.Display
import android.view.Display.TYPE_EXTERNAL
import android.view.Display.TYPE_INTERNAL
import android.view.Display.TYPE_VIRTUAL
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.FlowValue
@@ -53,7 +53,7 @@
import org.junit.runner.RunWith
import org.mockito.Mockito.anyInt
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@TestableLooper.RunWithLooper
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
diff --git a/packages/SystemUI/tests/src/com/android/systemui/display/ui/view/MirroringConfirmationDialogDelegateTest.kt b/packages/SystemUI/tests/src/com/android/systemui/display/ui/view/MirroringConfirmationDialogDelegateTest.kt
index d118cc7..8105bc8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/display/ui/view/MirroringConfirmationDialogDelegateTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/display/ui/view/MirroringConfirmationDialogDelegateTest.kt
@@ -18,13 +18,13 @@
import android.app.Dialog
import android.graphics.Insets
-import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
import android.view.LayoutInflater
import android.view.View
import android.view.Window
import android.view.WindowInsets
import android.view.WindowInsetsAnimation
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.app.animation.Interpolators
import com.android.systemui.SysuiTestCase
@@ -42,7 +42,7 @@
import org.mockito.Mockito.verify
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
class MirroringConfirmationDialogDelegateTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeDockHandlerTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeDockHandlerTest.java
index 6d2df19..8c125f8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeDockHandlerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeDockHandlerTest.java
@@ -28,9 +28,9 @@
import android.app.ActivityManager;
import android.hardware.display.AmbientDisplayConfiguration;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper.RunWithLooper;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
@@ -46,7 +46,7 @@
import org.mockito.MockitoAnnotations;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@RunWithLooper
public class DozeDockHandlerTest extends SysuiTestCase {
@Mock private DozeMachine mMachine;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenBrightnessTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenBrightnessTest.java
index 27fd3b1..aa5edae 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenBrightnessTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenBrightnessTest.java
@@ -45,8 +45,8 @@
import android.os.PowerManager;
import android.os.UserHandle;
import android.provider.Settings;
-import android.testing.AndroidTestingRunner;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
@@ -71,7 +71,7 @@
import java.util.Optional;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
public class DozeScreenBrightnessTest extends SysuiTestCase {
private static final int DEFAULT_BRIGHTNESS = 10;
@@ -583,4 +583,4 @@
private void waitForSensorManager() {
mFakeExecutor.runAllReady();
}
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java
index 3cc0451..9c127b8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java
@@ -42,10 +42,10 @@
import android.database.ContentObserver;
import android.hardware.Sensor;
import android.hardware.display.AmbientDisplayConfiguration;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.testing.TestableLooper.RunWithLooper;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
@@ -75,7 +75,7 @@
import java.util.List;
import java.util.function.Consumer;
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@RunWithLooper
@SmallTest
public class DozeSensorsTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSuppressorTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSuppressorTest.java
index 92941f9..fad52e0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSuppressorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSuppressorTest.java
@@ -38,9 +38,9 @@
import android.app.ActivityManager;
import android.hardware.display.AmbientDisplayConfiguration;
-import android.testing.AndroidTestingRunner;
import android.testing.UiThreadTest;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
@@ -60,7 +60,7 @@
import org.mockito.MockitoAnnotations;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@UiThreadTest
public class DozeSuppressorTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java
index 40b8fc7..3d1a0d0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java
@@ -38,10 +38,10 @@
import android.hardware.Sensor;
import android.hardware.display.AmbientDisplayConfiguration;
import android.platform.test.annotations.EnableFlags;
-import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper.RunWithLooper;
import android.view.Display;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.internal.logging.InstanceId;
@@ -80,7 +80,7 @@
import org.mockito.MockitoAnnotations;
@SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
@RunWithLooper(setAsMainLooper = true)
public class DozeTriggersTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeWallpaperStateTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeWallpaperStateTest.java
index f07edf3..4253c76 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeWallpaperStateTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeWallpaperStateTest.java
@@ -26,6 +26,7 @@
import android.app.IWallpaperManager;
import android.os.RemoteException;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
@@ -36,11 +37,10 @@
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-@RunWith(JUnit4.class)
+@RunWith(AndroidJUnit4.class)
@SmallTest
public class DozeWallpaperStateTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/flags/FakeFeatureFlagsTest.kt b/packages/SystemUI/tests/src/com/android/systemui/flags/FakeFeatureFlagsTest.kt
index 2bd2bff..771ecaf 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/flags/FakeFeatureFlagsTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/flags/FakeFeatureFlagsTest.kt
@@ -16,7 +16,7 @@
package com.android.systemui.flags
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.google.common.truth.Truth.assertThat
@@ -25,7 +25,7 @@
import org.junit.runner.RunWith
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
class FakeFeatureFlagsTest : SysuiTestCase() {
private val unreleasedFlag = UnreleasedFlag("-1000", "test")
diff --git a/packages/SystemUI/tests/src/com/android/systemui/flags/FlagDependenciesTest.kt b/packages/SystemUI/tests/src/com/android/systemui/flags/FlagDependenciesTest.kt
index 91da88e..0ae59bb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/flags/FlagDependenciesTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/flags/FlagDependenciesTest.kt
@@ -16,8 +16,8 @@
package com.android.systemui.flags
-import android.testing.AndroidTestingRunner
import android.util.Log
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import java.io.PrintWriter
@@ -25,7 +25,7 @@
import org.junit.Test
import org.junit.runner.RunWith
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
@SmallTest
class FlagDependenciesTest : SysuiTestCase() {
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/flags/ServerFlagReaderImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/flags/ServerFlagReaderImplTest.kt
index 2daa86b..d1082bd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/flags/ServerFlagReaderImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/flags/ServerFlagReaderImplTest.kt
@@ -16,7 +16,7 @@
package com.android.systemui.flags
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.util.DeviceConfigProxyFake
@@ -33,7 +33,7 @@
import org.mockito.MockitoAnnotations
@SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
class ServerFlagReaderImplTest : SysuiTestCase() {
private val NAMESPACE = "test"
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/muteawait/MediaMuteAwaitConnectionManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/muteawait/MediaMuteAwaitConnectionManagerTest.kt
index 53e9dc8..2a8967e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/muteawait/MediaMuteAwaitConnectionManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/muteawait/MediaMuteAwaitConnectionManagerTest.kt
@@ -62,7 +62,7 @@
MockitoAnnotations.initMocks(this)
context.addMockSystemService(Context.AUDIO_SERVICE, audioManager)
icon = context.getDrawable(R.drawable.ic_cake)!!
- whenever(deviceIconUtil.getIconFromAudioDeviceType(any(), any())).thenReturn(icon)
+ whenever(deviceIconUtil.getIconFromAudioDeviceType(any())).thenReturn(icon)
muteAwaitConnectionManager = MediaMuteAwaitConnectionManager(
FakeExecutor(FakeSystemClock()),
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/FakeCommunalSceneRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/FakeCommunalSceneRepository.kt
index a7bf87d..d280be2 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/FakeCommunalSceneRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/FakeCommunalSceneRepository.kt
@@ -6,6 +6,7 @@
import com.android.systemui.communal.shared.model.CommunalScenes
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
@@ -13,20 +14,25 @@
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.stateIn
+import kotlinx.coroutines.launch
/** Fake implementation of [CommunalSceneRepository]. */
@OptIn(ExperimentalCoroutinesApi::class)
class FakeCommunalSceneRepository(
- applicationScope: CoroutineScope,
+ private val applicationScope: CoroutineScope,
override val currentScene: MutableStateFlow<SceneKey> =
MutableStateFlow(CommunalScenes.Default),
) : CommunalSceneRepository {
- override fun changeScene(toScene: SceneKey, transitionKey: TransitionKey?) =
- snapToScene(toScene)
- override fun snapToScene(toScene: SceneKey) {
- this.currentScene.value = toScene
- this._transitionState.value = flowOf(ObservableTransitionState.Idle(toScene))
+ override fun changeScene(toScene: SceneKey, transitionKey: TransitionKey?) =
+ snapToScene(toScene, 0)
+
+ override fun snapToScene(toScene: SceneKey, delayMillis: Long) {
+ applicationScope.launch {
+ delay(delayMillis)
+ currentScene.value = toScene
+ _transitionState.value = flowOf(ObservableTransitionState.Idle(toScene))
+ }
}
private val defaultTransitionState = ObservableTransitionState.Idle(CommunalScenes.Default)
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/interactor/SceneInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/interactor/SceneInteractorKosmos.kt
index ef7aa63..d1fbb5e 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/interactor/SceneInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/interactor/SceneInteractorKosmos.kt
@@ -16,11 +16,16 @@
package com.android.systemui.scene.domain.interactor
+import com.android.compose.animation.scene.SceneKey
+import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
import com.android.systemui.deviceentry.domain.interactor.deviceUnlockedInteractor
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.applicationCoroutineScope
import com.android.systemui.scene.data.repository.sceneContainerRepository
+import com.android.systemui.scene.domain.resolver.HomeSceneFamilyResolver
+import com.android.systemui.scene.domain.resolver.SceneResolver
import com.android.systemui.scene.shared.logger.sceneLogger
+import com.android.systemui.scene.shared.model.SceneFamilies
val Kosmos.sceneInteractor by
Kosmos.Fixture {
@@ -28,6 +33,18 @@
applicationScope = applicationCoroutineScope,
repository = sceneContainerRepository,
logger = sceneLogger,
+ sceneFamilyResolvers = { sceneFamilyResolvers },
deviceUnlockedInteractor = deviceUnlockedInteractor,
)
}
+
+val Kosmos.sceneFamilyResolvers: Map<SceneKey, SceneResolver>
+ get() = mapOf(SceneFamilies.Home to homeSceneFamilyResolver)
+
+val Kosmos.homeSceneFamilyResolver by
+ Kosmos.Fixture {
+ HomeSceneFamilyResolver(
+ applicationScope = applicationCoroutineScope,
+ deviceEntryInteractor = deviceEntryInteractor,
+ )
+ }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ShadeControllerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ShadeControllerKosmos.kt
index d08855f..cc836ac 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ShadeControllerKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ShadeControllerKosmos.kt
@@ -20,8 +20,6 @@
import com.android.systemui.assist.AssistManager
import com.android.systemui.concurrency.fakeExecutor
-import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
-import com.android.systemui.deviceentry.domain.interactor.deviceUnlockedInteractor
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.applicationCoroutineScope
import com.android.systemui.kosmos.testDispatcher
@@ -52,15 +50,14 @@
shadeInteractor = shadeInteractor,
sceneInteractor = sceneInteractor,
notificationStackScrollLayout = mock<NotificationStackScrollLayout>(),
- deviceEntryInteractor = deviceEntryInteractor,
touchLog = mock<LogBuffer>(),
vibratorHelper = mock<VibratorHelper>(),
commandQueue = mock<CommandQueue>(),
statusBarKeyguardViewManager = mock<StatusBarKeyguardViewManager>(),
notificationShadeWindowController = mock<NotificationShadeWindowController>(),
- assistManagerLazy = { mock<AssistManager>() },
- deviceUnlockedInteractor = deviceUnlockedInteractor,
- )
+ ) {
+ mock<AssistManager>()
+ }
}
val Kosmos.shadeControllerImpl by
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/NotificationsShadeSceneViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/NotificationsShadeSceneViewModelKosmos.kt
index 872eba06..1ca3509 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/NotificationsShadeSceneViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/NotificationsShadeSceneViewModelKosmos.kt
@@ -17,13 +17,7 @@
package com.android.systemui.shade.ui.viewmodel
import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.kosmos.applicationCoroutineScope
import com.android.systemui.notifications.ui.viewmodel.NotificationsShadeSceneViewModel
val Kosmos.notificationsShadeSceneViewModel: NotificationsShadeSceneViewModel by
- Kosmos.Fixture {
- NotificationsShadeSceneViewModel(
- applicationScope = applicationCoroutineScope,
- overlayShadeViewModel = overlayShadeViewModel,
- )
- }
+ Kosmos.Fixture { NotificationsShadeSceneViewModel() }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/OverlayShadeViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/OverlayShadeViewModelKosmos.kt
index 45ec032..fec1028 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/OverlayShadeViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/OverlayShadeViewModelKosmos.kt
@@ -14,21 +14,16 @@
* limitations under the License.
*/
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
package com.android.systemui.shade.ui.viewmodel
-import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.applicationCoroutineScope
import com.android.systemui.scene.domain.interactor.sceneInteractor
-import kotlinx.coroutines.ExperimentalCoroutinesApi
val Kosmos.overlayShadeViewModel: OverlayShadeViewModel by
Kosmos.Fixture {
OverlayShadeViewModel(
applicationScope = applicationCoroutineScope,
sceneInteractor = sceneInteractor,
- deviceEntryInteractor = deviceEntryInteractor,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/QuickSettingsShadeSceneViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/QuickSettingsShadeSceneViewModelKosmos.kt
index c5625e4..4d81ea1 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/QuickSettingsShadeSceneViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/QuickSettingsShadeSceneViewModelKosmos.kt
@@ -18,7 +18,6 @@
import com.android.systemui.brightness.ui.viewmodel.brightnessSliderViewModel
import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.kosmos.applicationCoroutineScope
import com.android.systemui.qs.panels.ui.viewmodel.editModeViewModel
import com.android.systemui.qs.panels.ui.viewmodel.tileGridViewModel
import com.android.systemui.qs.ui.adapter.qsSceneAdapter
@@ -27,7 +26,6 @@
val Kosmos.quickSettingsShadeSceneViewModel: QuickSettingsShadeSceneViewModel by
Kosmos.Fixture {
QuickSettingsShadeSceneViewModel(
- applicationScope = applicationCoroutineScope,
overlayShadeViewModel = overlayShadeViewModel,
brightnessSliderViewModel = brightnessSliderViewModel,
tileGridViewModel = tileGridViewModel,
diff --git a/services/accessibility/java/com/android/server/accessibility/UiAutomationManager.java b/services/accessibility/java/com/android/server/accessibility/UiAutomationManager.java
index 63a183d..f85d786 100644
--- a/services/accessibility/java/com/android/server/accessibility/UiAutomationManager.java
+++ b/services/accessibility/java/com/android/server/accessibility/UiAutomationManager.java
@@ -101,8 +101,10 @@
SystemActionPerformer systemActionPerformer,
AccessibilityWindowManager awm, int flags) {
accessibilityServiceInfo.setComponentName(COMPONENT_NAME);
- Slogf.i(LOG_TAG, "Registering UiTestAutomationService (id=%s) when called by user %d",
- accessibilityServiceInfo.getId(), Binder.getCallingUserHandle().getIdentifier());
+ Slogf.i(LOG_TAG, "Registering UiTestAutomationService (id=%s, flags=0x%x) when"
+ + " called by user %d",
+ accessibilityServiceInfo.getId(), flags,
+ Binder.getCallingUserHandle().getIdentifier());
if (mUiAutomationService != null) {
throw new IllegalStateException(
"UiAutomationService " + mUiAutomationService.mServiceInterface
@@ -272,8 +274,10 @@
mMainHandler.post(() -> {
try {
final IAccessibilityServiceClient serviceInterface;
+ final UiAutomationService uiAutomationService;
synchronized (mLock) {
serviceInterface = mServiceInterface;
+ uiAutomationService = mUiAutomationService;
if (serviceInterface == null) {
mService = null;
} else {
@@ -283,8 +287,8 @@
}
// If the serviceInterface is null, the UiAutomation has been shut down on
// another thread.
- if (serviceInterface != null) {
- mUiAutomationService.addWindowTokensForAllDisplays();
+ if (serviceInterface != null && uiAutomationService != null) {
+ uiAutomationService.addWindowTokensForAllDisplays();
if (mTrace.isA11yTracingEnabledForTypes(
AccessibilityTrace.FLAGS_ACCESSIBILITY_SERVICE_CLIENT)) {
mTrace.logTrace("UiAutomationService.connectServiceUnknownThread",
diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
index 0d0c21d..c9cce15 100644
--- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
+++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
@@ -18,6 +18,7 @@
package com.android.server.companion;
import static android.Manifest.permission.ASSOCIATE_COMPANION_DEVICES;
+import static android.Manifest.permission.BLUETOOTH_CONNECT;
import static android.Manifest.permission.DELIVER_COMPANION_MESSAGES;
import static android.Manifest.permission.MANAGE_COMPANION_DEVICES;
import static android.Manifest.permission.REQUEST_COMPANION_SELF_MANAGED;
@@ -52,6 +53,9 @@
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.ecm.EnhancedConfirmationManager;
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothManager;
import android.companion.AssociationInfo;
import android.companion.AssociationRequest;
import android.companion.IAssociationRequestCallback;
@@ -541,6 +545,31 @@
}
@Override
+ @EnforcePermission(BLUETOOTH_CONNECT)
+ public boolean removeBond(int associationId, String packageName, int userId) {
+ removeBond_enforcePermission();
+
+ Slog.i(TAG, "removeBond() "
+ + "associationId=" + associationId + ", "
+ + "package=u" + userId + "/" + packageName);
+ enforceCallerCanManageAssociationsForPackage(getContext(), userId, packageName,
+ "remove bonds");
+
+ AssociationInfo association = mAssociationStore
+ .getAssociationWithCallerChecks(associationId);
+ MacAddress address = association.getDeviceMacAddress();
+ if (address == null) {
+ throw new IllegalArgumentException(
+ "Association id=[" + associationId + "] doesn't have a device address.");
+ }
+
+ BluetoothAdapter btAdapter = getContext().getSystemService(BluetoothManager.class)
+ .getAdapter();
+ BluetoothDevice btDevice = btAdapter.getRemoteDevice(address.toString().toUpperCase());
+ return btDevice.removeBond();
+ }
+
+ @Override
public PendingIntent buildPermissionTransferUserConsentIntent(String packageName,
int userId, int associationId) {
return mSystemDataTransferProcessor.buildPermissionTransferUserConsentIntent(
diff --git a/services/core/java/com/android/server/am/ActivityManagerConstants.java b/services/core/java/com/android/server/am/ActivityManagerConstants.java
index 95c0e0e..26aa053 100644
--- a/services/core/java/com/android/server/am/ActivityManagerConstants.java
+++ b/services/core/java/com/android/server/am/ActivityManagerConstants.java
@@ -169,6 +169,7 @@
*/
static final String KEY_ENABLE_NEW_OOMADJ = "enable_new_oom_adj";
+ private static final int DEFAULT_MAX_CACHED_PROCESSES = 1024;
private static final boolean DEFAULT_PRIORITIZE_ALARM_BROADCASTS = true;
private static final long DEFAULT_FGSERVICE_MIN_SHOWN_TIME = 2*1000;
private static final long DEFAULT_FGSERVICE_MIN_REPORT_TIME = 3*1000;
@@ -293,7 +294,12 @@
private static final long DEFAULT_SERVICE_BACKGROUND_TIMEOUT = DEFAULT_SERVICE_TIMEOUT * 10;
/**
- * Maximum number of phantom processes.
+ * Maximum number of cached processes.
+ */
+ private static final String KEY_MAX_CACHED_PROCESSES = "max_cached_processes";
+
+ /**
+ * Maximum number of cached processes.
*/
private static final String KEY_MAX_PHANTOM_PROCESSES = "max_phantom_processes";
@@ -440,6 +446,9 @@
volatile int mProcStateDebugSetProcStateDelay = 0;
volatile int mProcStateDebugSetUidStateDelay = 0;
+ // Maximum number of cached processes we will allow.
+ public int MAX_CACHED_PROCESSES = DEFAULT_MAX_CACHED_PROCESSES;
+
// This is the amount of time we allow an app to settle after it goes into the background,
// before we start restricting what it can do.
public long BACKGROUND_SETTLE_TIME = DEFAULT_BACKGROUND_SETTLE_TIME;
@@ -848,6 +857,24 @@
private ContentResolver mResolver;
private final KeyValueListParser mParser = new KeyValueListParser(',');
+ private int mOverrideMaxCachedProcesses = -1;
+ private final int mCustomizedMaxCachedProcesses;
+
+ // The maximum number of cached processes we will keep around before killing them.
+ // NOTE: this constant is *only* a control to not let us go too crazy with
+ // keeping around processes on devices with large amounts of RAM. For devices that
+ // are tighter on RAM, the out of memory killer is responsible for killing background
+ // processes as RAM is needed, and we should *never* be relying on this limit to
+ // kill them. Also note that this limit only applies to cached background processes;
+ // we have no limit on the number of service, visible, foreground, or other such
+ // processes and the number of those processes does not count against the cached
+ // process limit. This will be initialized in the constructor.
+ public int CUR_MAX_CACHED_PROCESSES;
+
+ // The maximum number of empty app processes we will let sit around. This will be
+ // initialized in the constructor.
+ public int CUR_MAX_EMPTY_PROCESSES;
+
/** @see #mNoKillCachedProcessesUntilBootCompleted */
private static final String KEY_NO_KILL_CACHED_PROCESSES_UNTIL_BOOT_COMPLETED =
"no_kill_cached_processes_until_boot_completed";
@@ -879,6 +906,15 @@
volatile long mNoKillCachedProcessesPostBootCompletedDurationMillis =
DEFAULT_NO_KILL_CACHED_PROCESSES_POST_BOOT_COMPLETED_DURATION_MILLIS;
+ // The number of empty apps at which we don't consider it necessary to do
+ // memory trimming.
+ public int CUR_TRIM_EMPTY_PROCESSES = computeEmptyProcessLimit(MAX_CACHED_PROCESSES) / 2;
+
+ // The number of cached at which we don't consider it necessary to do
+ // memory trimming.
+ public int CUR_TRIM_CACHED_PROCESSES =
+ (MAX_CACHED_PROCESSES - computeEmptyProcessLimit(MAX_CACHED_PROCESSES)) / 3;
+
/** @see #mNoKillCachedProcessesUntilBootCompleted */
private static final String KEY_MAX_EMPTY_TIME_MILLIS =
"max_empty_time_millis";
@@ -1129,6 +1165,9 @@
return;
}
switch (name) {
+ case KEY_MAX_CACHED_PROCESSES:
+ updateMaxCachedProcesses();
+ break;
case KEY_DEFAULT_BACKGROUND_ACTIVITY_STARTS_ENABLED:
updateBackgroundActivityStarts();
break;
@@ -1378,7 +1417,16 @@
context.getResources().getStringArray(
com.android.internal.R.array.config_keep_warming_services))
.map(ComponentName::unflattenFromString).collect(Collectors.toSet()));
+ mCustomizedMaxCachedProcesses = context.getResources().getInteger(
+ com.android.internal.R.integer.config_customizedMaxCachedProcesses);
+ CUR_MAX_CACHED_PROCESSES = mCustomizedMaxCachedProcesses;
+ CUR_MAX_EMPTY_PROCESSES = computeEmptyProcessLimit(CUR_MAX_CACHED_PROCESSES);
+ final int rawMaxEmptyProcesses = computeEmptyProcessLimit(
+ Integer.min(CUR_MAX_CACHED_PROCESSES, MAX_CACHED_PROCESSES));
+ CUR_TRIM_EMPTY_PROCESSES = rawMaxEmptyProcesses / 2;
+ CUR_TRIM_CACHED_PROCESSES = (Integer.min(CUR_MAX_CACHED_PROCESSES, MAX_CACHED_PROCESSES)
+ - rawMaxEmptyProcesses) / 3;
loadNativeBootDeviceConfigConstants();
mDefaultDisableAppProfilerPssProfiling = context.getResources().getBoolean(
R.bool.config_am_disablePssProfiling);
@@ -1433,6 +1481,19 @@
DEFAULT_ENABLE_NEW_OOM_ADJ);
}
+ public void setOverrideMaxCachedProcesses(int value) {
+ mOverrideMaxCachedProcesses = value;
+ updateMaxCachedProcesses();
+ }
+
+ public int getOverrideMaxCachedProcesses() {
+ return mOverrideMaxCachedProcesses;
+ }
+
+ public static int computeEmptyProcessLimit(int totalProcessLimit) {
+ return totalProcessLimit/2;
+ }
+
@Override
public void onChange(boolean selfChange, Uri uri) {
if (uri == null) return;
@@ -1933,6 +1994,29 @@
mSystemServerAutomaticHeapDumpPackageName);
}
+ private void updateMaxCachedProcesses() {
+ String maxCachedProcessesFlag = DeviceConfig.getProperty(
+ DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, KEY_MAX_CACHED_PROCESSES);
+ try {
+ CUR_MAX_CACHED_PROCESSES = mOverrideMaxCachedProcesses < 0
+ ? (TextUtils.isEmpty(maxCachedProcessesFlag)
+ ? mCustomizedMaxCachedProcesses : Integer.parseInt(maxCachedProcessesFlag))
+ : mOverrideMaxCachedProcesses;
+ } catch (NumberFormatException e) {
+ // Bad flag value from Phenotype, revert to default.
+ Slog.e(TAG,
+ "Unable to parse flag for max_cached_processes: " + maxCachedProcessesFlag, e);
+ CUR_MAX_CACHED_PROCESSES = mCustomizedMaxCachedProcesses;
+ }
+ CUR_MAX_EMPTY_PROCESSES = computeEmptyProcessLimit(CUR_MAX_CACHED_PROCESSES);
+
+ final int rawMaxEmptyProcesses = computeEmptyProcessLimit(
+ Integer.min(CUR_MAX_CACHED_PROCESSES, MAX_CACHED_PROCESSES));
+ CUR_TRIM_EMPTY_PROCESSES = rawMaxEmptyProcesses / 2;
+ CUR_TRIM_CACHED_PROCESSES = (Integer.min(CUR_MAX_CACHED_PROCESSES, MAX_CACHED_PROCESSES)
+ - rawMaxEmptyProcesses) / 3;
+ }
+
private void updateProactiveKillsEnabled() {
PROACTIVE_KILLS_ENABLED = DeviceConfig.getBoolean(
DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
@@ -2191,6 +2275,8 @@
pw.println("ACTIVITY MANAGER SETTINGS (dumpsys activity settings) "
+ Settings.Global.ACTIVITY_MANAGER_CONSTANTS + ":");
+ pw.print(" "); pw.print(KEY_MAX_CACHED_PROCESSES); pw.print("=");
+ pw.println(MAX_CACHED_PROCESSES);
pw.print(" "); pw.print(KEY_BACKGROUND_SETTLE_TIME); pw.print("=");
pw.println(BACKGROUND_SETTLE_TIME);
pw.print(" "); pw.print(KEY_FGSERVICE_MIN_SHOWN_TIME); pw.print("=");
@@ -2391,6 +2477,14 @@
pw.print("="); pw.println(MAX_PREVIOUS_TIME);
pw.println();
+ if (mOverrideMaxCachedProcesses >= 0) {
+ pw.print(" mOverrideMaxCachedProcesses="); pw.println(mOverrideMaxCachedProcesses);
+ }
+ pw.print(" mCustomizedMaxCachedProcesses="); pw.println(mCustomizedMaxCachedProcesses);
+ pw.print(" CUR_MAX_CACHED_PROCESSES="); pw.println(CUR_MAX_CACHED_PROCESSES);
+ pw.print(" CUR_MAX_EMPTY_PROCESSES="); pw.println(CUR_MAX_EMPTY_PROCESSES);
+ pw.print(" CUR_TRIM_EMPTY_PROCESSES="); pw.println(CUR_TRIM_EMPTY_PROCESSES);
+ pw.print(" CUR_TRIM_CACHED_PROCESSES="); pw.println(CUR_TRIM_CACHED_PROCESSES);
pw.print(" OOMADJ_UPDATE_QUICK="); pw.println(OOMADJ_UPDATE_QUICK);
pw.print(" ENABLE_WAIT_FOR_FINISH_ATTACH_APPLICATION=");
pw.println(mEnableWaitForFinishAttachApplication);
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index e0ec171..d79d198 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -5846,13 +5846,19 @@
@Override
public void setProcessLimit(int max) {
- // Process limits are deprecated since b/253908413
+ enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
+ "setProcessLimit()");
+ synchronized (this) {
+ mConstants.setOverrideMaxCachedProcesses(max);
+ trimApplicationsLocked(true, OOM_ADJ_REASON_PROCESS_END);
+ }
}
@Override
public int getProcessLimit() {
- // Process limits are deprecated since b/253908413
- return Integer.MAX_VALUE;
+ synchronized (this) {
+ return mConstants.getOverrideMaxCachedProcesses();
+ }
}
void importanceTokenDied(ImportanceToken token) {
@@ -10201,6 +10207,19 @@
addStartInfoTimestampInternal(key, timestampNs, userId, callingUid);
}
+ @Override
+ public void reportStartInfoViewTimestamps(long renderThreadDrawStartTimeNs,
+ long framePresentedTimeNs) {
+ int callingUid = Binder.getCallingUid();
+ int userId = UserHandle.getUserId(callingUid);
+ addStartInfoTimestampInternal(
+ ApplicationStartInfo.START_TIMESTAMP_INITIAL_RENDERTHREAD_FRAME,
+ renderThreadDrawStartTimeNs, userId, callingUid);
+ addStartInfoTimestampInternal(
+ ApplicationStartInfo.START_TIMESTAMP_SURFACEFLINGER_COMPOSITION_COMPLETE,
+ framePresentedTimeNs, userId, callingUid);
+ }
+
private void addStartInfoTimestampInternal(int key, long timestampNs, int userId, int uid) {
mProcessList.getAppStartInfoTracker().addTimestampToStart(
Settings.getPackageNameForUid(mContext, uid),
@@ -15255,15 +15274,50 @@
BackgroundStartPrivileges backgroundStartPrivileges,
@Nullable int[] broadcastAllowList,
@Nullable BiFunction<Integer, Bundle, Bundle> filterExtrasForReceiver) {
- final int cookie = BroadcastQueue.traceBegin("broadcastIntentLockedTraced");
- final int res = broadcastIntentLockedTraced(callerApp, callerPackage, callerFeatureId,
- intent, resolvedType, resultToApp, resultTo, resultCode, resultData, resultExtras,
- requiredPermissions, excludedPermissions, excludedPackages, appOp,
- BroadcastOptions.fromBundleNullable(bOptions), ordered, sticky,
- callingPid, callingUid, realCallingUid, realCallingPid, userId,
- backgroundStartPrivileges, broadcastAllowList, filterExtrasForReceiver);
- BroadcastQueue.traceEnd(cookie);
- return res;
+ final int cookie = traceBroadcastIntentBegin(intent, resultTo, ordered, sticky,
+ callingUid, realCallingUid, userId);
+ try {
+ final int res = broadcastIntentLockedTraced(callerApp, callerPackage, callerFeatureId,
+ intent, resolvedType, resultToApp, resultTo, resultCode, resultData,
+ resultExtras, requiredPermissions, excludedPermissions, excludedPackages,
+ appOp, BroadcastOptions.fromBundleNullable(bOptions), ordered, sticky,
+ callingPid, callingUid, realCallingUid, realCallingPid, userId,
+ backgroundStartPrivileges, broadcastAllowList, filterExtrasForReceiver);
+ return res;
+ } finally {
+ traceBroadcastIntentEnd(cookie);
+ }
+ }
+
+ private static int traceBroadcastIntentBegin(Intent intent, IIntentReceiver resultTo,
+ boolean ordered, boolean sticky, int callingUid, int realCallingUid, int userId) {
+ if (!Flags.traceReceiverRegistration()) {
+ return BroadcastQueue.traceBegin("broadcastIntentLockedTraced");
+ }
+ if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
+ final StringBuilder sb = new StringBuilder("broadcastIntent: ");
+ sb.append(callingUid); sb.append('/');
+ final String action = intent.getAction();
+ sb.append(action == null ? null : action); sb.append('/');
+ sb.append("0x"); sb.append(Integer.toHexString(intent.getFlags())); sb.append('/');
+ sb.append(ordered ? "O" : "_");
+ sb.append(sticky ? "S" : "_");
+ sb.append(resultTo != null ? "C" : "_");
+ sb.append('/');
+ sb.append('u'); sb.append(userId);
+ if (callingUid != realCallingUid) {
+ sb.append('/');
+ sb.append("sender="); sb.append(realCallingUid);
+ }
+ return BroadcastQueue.traceBegin(sb.toString());
+ }
+ return 0;
+ }
+
+ private static void traceBroadcastIntentEnd(int cookie) {
+ if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
+ BroadcastQueue.traceEnd(cookie);
+ }
}
@GuardedBy("this")
diff --git a/services/core/java/com/android/server/am/AppProfiler.java b/services/core/java/com/android/server/am/AppProfiler.java
index 3ed60fc..dda48ad 100644
--- a/services/core/java/com/android/server/am/AppProfiler.java
+++ b/services/core/java/com/android/server/am/AppProfiler.java
@@ -507,7 +507,8 @@
final int lruSize = mService.mProcessList.getLruSizeLOSP();
if (mCachedAppFrozenDurations == null
|| mCachedAppFrozenDurations.length < lruSize) {
- mCachedAppFrozenDurations = new long[lruSize];
+ mCachedAppFrozenDurations = new long[Math.max(
+ lruSize, mService.mConstants.CUR_MAX_CACHED_PROCESSES)];
}
mService.mProcessList.forEachLruProcessesLOSP(true, app -> {
if (app.mOptRecord.isFrozen()) {
@@ -1369,13 +1370,18 @@
// are managing to keep around is less than half the maximum we desire;
// if we are keeping a good number around, we'll let them use whatever
// memory they want.
- final int numCachedAndEmpty = numCached + numEmpty;
- if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
- memFactor = ADJ_MEM_FACTOR_CRITICAL;
- } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
- memFactor = ADJ_MEM_FACTOR_LOW;
+ if (numCached <= mService.mConstants.CUR_TRIM_CACHED_PROCESSES
+ && numEmpty <= mService.mConstants.CUR_TRIM_EMPTY_PROCESSES) {
+ final int numCachedAndEmpty = numCached + numEmpty;
+ if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
+ memFactor = ADJ_MEM_FACTOR_CRITICAL;
+ } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
+ memFactor = ADJ_MEM_FACTOR_LOW;
+ } else {
+ memFactor = ADJ_MEM_FACTOR_MODERATE;
+ }
} else {
- memFactor = ADJ_MEM_FACTOR_MODERATE;
+ memFactor = ADJ_MEM_FACTOR_NORMAL;
}
}
// We always allow the memory level to go up (better). We only allow it to go
diff --git a/services/core/java/com/android/server/am/AppStartInfoTracker.java b/services/core/java/com/android/server/am/AppStartInfoTracker.java
index a8227fa..dc6e2fa3 100644
--- a/services/core/java/com/android/server/am/AppStartInfoTracker.java
+++ b/services/core/java/com/android/server/am/AppStartInfoTracker.java
@@ -1128,21 +1128,8 @@
// Records are sorted newest to oldest, grab record at index 0.
ApplicationStartInfo startInfo = mInfos.get(0);
- int startupState = startInfo.getStartupState();
- // If startup state is error then don't accept any further timestamps.
- if (startupState == ApplicationStartInfo.STARTUP_STATE_ERROR) {
- if (DEBUG) Slog.d(TAG, "Startup state is error, not accepting new timestamps.");
- return;
- }
-
- // If startup state is first frame drawn then only accept fully drawn timestamp.
- if (startupState == ApplicationStartInfo.STARTUP_STATE_FIRST_FRAME_DRAWN
- && key != ApplicationStartInfo.START_TIMESTAMP_FULLY_DRAWN) {
- if (DEBUG) {
- Slog.d(TAG, "Startup state is first frame drawn and timestamp is not fully "
- + "drawn, not accepting new timestamps.");
- }
+ if (!isAddTimestampAllowed(startInfo, key, timestampNs)) {
return;
}
@@ -1155,6 +1142,55 @@
}
}
+ private boolean isAddTimestampAllowed(ApplicationStartInfo startInfo, int key,
+ long timestampNs) {
+ int startupState = startInfo.getStartupState();
+
+ // If startup state is error then don't accept any further timestamps.
+ if (startupState == ApplicationStartInfo.STARTUP_STATE_ERROR) {
+ if (DEBUG) Slog.d(TAG, "Startup state is error, not accepting new timestamps.");
+ return false;
+ }
+
+ Map<Integer, Long> timestamps = startInfo.getStartupTimestamps();
+
+ if (startupState == ApplicationStartInfo.STARTUP_STATE_FIRST_FRAME_DRAWN) {
+ switch (key) {
+ case ApplicationStartInfo.START_TIMESTAMP_FULLY_DRAWN:
+ // Allowed, continue to confirm it's not already added.
+ break;
+ case ApplicationStartInfo.START_TIMESTAMP_INITIAL_RENDERTHREAD_FRAME:
+ Long firstFrameTimeNs = timestamps
+ .get(ApplicationStartInfo.START_TIMESTAMP_FIRST_FRAME);
+ if (firstFrameTimeNs == null) {
+ // This should never happen. State can't be first frame drawn if first
+ // frame timestamp was not provided.
+ return false;
+ }
+
+ if (timestampNs > firstFrameTimeNs) {
+ // Initial renderthread frame has to occur before first frame.
+ return false;
+ }
+
+ // Allowed, continue to confirm it's not already added.
+ break;
+ case ApplicationStartInfo.START_TIMESTAMP_SURFACEFLINGER_COMPOSITION_COMPLETE:
+ // Allowed, continue to confirm it's not already added.
+ break;
+ default:
+ return false;
+ }
+ }
+
+ if (timestamps.get(key) != null) {
+ // Timestamp should not occur more than once for a given start.
+ return false;
+ }
+
+ return true;
+ }
+
@GuardedBy("mLock")
void dumpLocked(PrintWriter pw, String prefix, SimpleDateFormat sdf) {
if (mMonitoringModeEnabled) {
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index d642b02..29e0f7a 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -122,12 +122,14 @@
import com.android.server.pm.UserManagerInternal;
import com.android.server.power.optimization.Flags;
import com.android.server.power.stats.AggregatedPowerStatsConfig;
+import com.android.server.power.stats.AudioPowerStatsProcessor;
import com.android.server.power.stats.BatteryExternalStatsWorker;
import com.android.server.power.stats.BatteryStatsDumpHelperImpl;
import com.android.server.power.stats.BatteryStatsImpl;
import com.android.server.power.stats.BatteryUsageStatsProvider;
import com.android.server.power.stats.BluetoothPowerStatsProcessor;
import com.android.server.power.stats.CpuPowerStatsProcessor;
+import com.android.server.power.stats.FlashlightPowerStatsProcessor;
import com.android.server.power.stats.MobileRadioPowerStatsProcessor;
import com.android.server.power.stats.PhoneCallPowerStatsProcessor;
import com.android.server.power.stats.PowerStatsAggregator;
@@ -136,6 +138,7 @@
import com.android.server.power.stats.PowerStatsStore;
import com.android.server.power.stats.PowerStatsUidResolver;
import com.android.server.power.stats.SystemServerCpuThreadReader.SystemServiceCpuThreadTimes;
+import com.android.server.power.stats.VideoPowerStatsProcessor;
import com.android.server.power.stats.WifiPowerStatsProcessor;
import com.android.server.power.stats.wakeups.CpuWakeupStats;
@@ -194,7 +197,7 @@
private final BatteryUsageStatsProvider mBatteryUsageStatsProvider;
private final AtomicFile mConfigFile;
private final BatteryStats.BatteryStatsDumpHelper mDumpHelper;
- private final PowerStatsUidResolver mPowerStatsUidResolver;
+ private final PowerStatsUidResolver mPowerStatsUidResolver = new PowerStatsUidResolver();
private final AggregatedPowerStatsConfig mAggregatedPowerStatsConfig;
private volatile boolean mMonitorEnabled = true;
@@ -422,7 +425,6 @@
setPowerStatsThrottlePeriods(batteryStatsConfigBuilder, context.getResources().getString(
com.android.internal.R.string.config_powerStatsThrottlePeriods));
mBatteryStatsConfig = batteryStatsConfigBuilder.build();
- mPowerStatsUidResolver = new PowerStatsUidResolver();
mStats = new BatteryStatsImpl(mBatteryStatsConfig, Clock.SYSTEM_CLOCK, mMonotonicClock,
systemDir, mHandler, this, this, mUserManagerUserInfoProvider, mPowerProfile,
mCpuScalingPolicies, mPowerStatsUidResolver);
@@ -516,6 +518,42 @@
AggregatedPowerStatsConfig.STATE_PROCESS_STATE)
.setProcessor(
new BluetoothPowerStatsProcessor(mPowerProfile));
+
+ config.trackPowerComponent(BatteryConsumer.POWER_COMPONENT_AUDIO)
+ .trackDeviceStates(
+ AggregatedPowerStatsConfig.STATE_POWER,
+ AggregatedPowerStatsConfig.STATE_SCREEN)
+ .trackUidStates(
+ AggregatedPowerStatsConfig.STATE_POWER,
+ AggregatedPowerStatsConfig.STATE_SCREEN,
+ AggregatedPowerStatsConfig.STATE_PROCESS_STATE)
+ .setProcessor(
+ new AudioPowerStatsProcessor(mPowerProfile,
+ mPowerStatsUidResolver));
+
+ config.trackPowerComponent(BatteryConsumer.POWER_COMPONENT_VIDEO)
+ .trackDeviceStates(
+ AggregatedPowerStatsConfig.STATE_POWER,
+ AggregatedPowerStatsConfig.STATE_SCREEN)
+ .trackUidStates(
+ AggregatedPowerStatsConfig.STATE_POWER,
+ AggregatedPowerStatsConfig.STATE_SCREEN,
+ AggregatedPowerStatsConfig.STATE_PROCESS_STATE)
+ .setProcessor(
+ new VideoPowerStatsProcessor(mPowerProfile,
+ mPowerStatsUidResolver));
+
+ config.trackPowerComponent(BatteryConsumer.POWER_COMPONENT_FLASHLIGHT)
+ .trackDeviceStates(
+ AggregatedPowerStatsConfig.STATE_POWER,
+ AggregatedPowerStatsConfig.STATE_SCREEN)
+ .trackUidStates(
+ AggregatedPowerStatsConfig.STATE_POWER,
+ AggregatedPowerStatsConfig.STATE_SCREEN,
+ AggregatedPowerStatsConfig.STATE_PROCESS_STATE)
+ .setProcessor(
+ new FlashlightPowerStatsProcessor(mPowerProfile,
+ mPowerStatsUidResolver));
return config;
}
@@ -583,6 +621,24 @@
BatteryConsumer.POWER_COMPONENT_BLUETOOTH,
Flags.streamlinedConnectivityBatteryStats());
+ mStats.setPowerStatsCollectorEnabled(BatteryConsumer.POWER_COMPONENT_AUDIO,
+ Flags.streamlinedMiscBatteryStats());
+ mBatteryUsageStatsProvider.setPowerStatsExporterEnabled(
+ BatteryConsumer.POWER_COMPONENT_AUDIO,
+ Flags.streamlinedMiscBatteryStats());
+
+ mStats.setPowerStatsCollectorEnabled(BatteryConsumer.POWER_COMPONENT_VIDEO,
+ Flags.streamlinedMiscBatteryStats());
+ mBatteryUsageStatsProvider.setPowerStatsExporterEnabled(
+ BatteryConsumer.POWER_COMPONENT_VIDEO,
+ Flags.streamlinedMiscBatteryStats());
+
+ mStats.setPowerStatsCollectorEnabled(BatteryConsumer.POWER_COMPONENT_FLASHLIGHT,
+ Flags.streamlinedMiscBatteryStats());
+ mBatteryUsageStatsProvider.setPowerStatsExporterEnabled(
+ BatteryConsumer.POWER_COMPONENT_FLASHLIGHT,
+ Flags.streamlinedMiscBatteryStats());
+
mWorker.systemServicesReady();
mStats.systemServicesReady(mContext);
mCpuWakeupStats.systemServicesReady();
diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java
index 105e201..ab34dd4 100644
--- a/services/core/java/com/android/server/am/OomAdjuster.java
+++ b/services/core/java/com/android/server/am/OomAdjuster.java
@@ -470,7 +470,7 @@
return true;
});
mTmpUidRecords = new ActiveUids(service, false);
- mTmpQueue = new ArrayDeque<ProcessRecord>();
+ mTmpQueue = new ArrayDeque<ProcessRecord>(mConstants.CUR_MAX_CACHED_PROCESSES << 1);
mNumSlots = ((CACHED_APP_MAX_ADJ - CACHED_APP_MIN_ADJ + 1) >> 1)
/ CACHED_APP_IMPORTANCE_LEVELS;
}
@@ -1079,11 +1079,23 @@
int curEmptyAdj = CACHED_APP_MIN_ADJ + CACHED_APP_IMPORTANCE_LEVELS;
int nextEmptyAdj = curEmptyAdj + (CACHED_APP_IMPORTANCE_LEVELS * 2);
+ final int emptyProcessLimit = mConstants.CUR_MAX_EMPTY_PROCESSES;
+ final int cachedProcessLimit = mConstants.CUR_MAX_CACHED_PROCESSES
+ - emptyProcessLimit;
// Let's determine how many processes we have running vs.
// how many slots we have for background processes; we may want
// to put multiple processes in a slot of there are enough of
// them.
int numEmptyProcs = numLru - mNumNonCachedProcs - mNumCachedHiddenProcs;
+ if (numEmptyProcs > cachedProcessLimit) {
+ // If there are more empty processes than our limit on cached
+ // processes, then use the cached process limit for the factor.
+ // This ensures that the really old empty processes get pushed
+ // down to the bottom, so if we are running low on memory we will
+ // have a better chance at keeping around more cached processes
+ // instead of a gazillion empty processes.
+ numEmptyProcs = cachedProcessLimit;
+ }
int cachedFactor = (mNumCachedHiddenProcs > 0
? (mNumCachedHiddenProcs + mNumSlots - 1) : 1)
/ mNumSlots;
@@ -1205,6 +1217,17 @@
ArrayList<ProcessRecord> lruList = mProcessList.getLruProcessesLOSP();
final int numLru = lruList.size();
+ final boolean doKillExcessiveProcesses = shouldKillExcessiveProcesses(now);
+ if (!doKillExcessiveProcesses) {
+ if (mNextNoKillDebugMessageTime < now) {
+ Slog.d(TAG, "Not killing cached processes"); // STOPSHIP Remove it b/222365734
+ mNextNoKillDebugMessageTime = now + 5000; // Every 5 seconds
+ }
+ }
+ final int emptyProcessLimit = doKillExcessiveProcesses
+ ? mConstants.CUR_MAX_EMPTY_PROCESSES : Integer.MAX_VALUE;
+ final int cachedProcessLimit = doKillExcessiveProcesses
+ ? (mConstants.CUR_MAX_CACHED_PROCESSES - emptyProcessLimit) : Integer.MAX_VALUE;
int lastCachedGroup = 0;
int lastCachedGroupUid = 0;
int numCached = 0;
@@ -1256,14 +1279,36 @@
} else {
lastCachedGroupUid = lastCachedGroup = 0;
}
- if (proactiveKillsEnabled) {
+ if ((numCached - numCachedExtraGroup) > cachedProcessLimit) {
+ app.killLocked("cached #" + numCached,
+ "too many cached",
+ ApplicationExitInfo.REASON_OTHER,
+ ApplicationExitInfo.SUBREASON_TOO_MANY_CACHED,
+ true);
+ } else if (proactiveKillsEnabled) {
lruCachedApp = app;
}
break;
case PROCESS_STATE_CACHED_EMPTY:
- numEmpty++;
- if (proactiveKillsEnabled) {
- lruCachedApp = app;
+ if (numEmpty > mConstants.CUR_TRIM_EMPTY_PROCESSES
+ && app.getLastActivityTime() < oldTime) {
+ app.killLocked("empty for " + ((now
+ - app.getLastActivityTime()) / 1000) + "s",
+ "empty for too long",
+ ApplicationExitInfo.REASON_OTHER,
+ ApplicationExitInfo.SUBREASON_TRIM_EMPTY,
+ true);
+ } else {
+ numEmpty++;
+ if (numEmpty > emptyProcessLimit) {
+ app.killLocked("empty #" + numEmpty,
+ "too many empty",
+ ApplicationExitInfo.REASON_OTHER,
+ ApplicationExitInfo.SUBREASON_TOO_MANY_EMPTY,
+ true);
+ } else if (proactiveKillsEnabled) {
+ lruCachedApp = app;
+ }
}
break;
default:
@@ -1304,6 +1349,7 @@
}
if (proactiveKillsEnabled // Proactive kills enabled?
+ && doKillExcessiveProcesses // Should kill excessive processes?
&& freeSwapPercent < lowSwapThresholdPercent // Swap below threshold?
&& lruCachedApp != null // If no cached app, let LMKD decide
// If swap is non-decreasing, give reclaim a chance to catch up
@@ -1498,6 +1544,25 @@
}
}
+ /**
+ * Return true if we should kill excessive cached/empty processes.
+ */
+ private boolean shouldKillExcessiveProcesses(long nowUptime) {
+ final long lastUserUnlockingUptime = mService.mUserController.getLastUserUnlockingUptime();
+
+ if (lastUserUnlockingUptime == 0) {
+ // No users have been unlocked.
+ return !mConstants.mNoKillCachedProcessesUntilBootCompleted;
+ }
+ final long noKillCachedProcessesPostBootCompletedDurationMillis =
+ mConstants.mNoKillCachedProcessesPostBootCompletedDurationMillis;
+ if ((lastUserUnlockingUptime + noKillCachedProcessesPostBootCompletedDurationMillis)
+ > nowUptime) {
+ return false;
+ }
+ return true;
+ }
+
protected final ComputeOomAdjWindowCallback mTmpComputeOomAdjWindowCallback =
new ComputeOomAdjWindowCallback();
diff --git a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
index 9a3b575..3df5687 100644
--- a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
+++ b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
@@ -172,6 +172,7 @@
"haptics",
"hardware_backed_security_mainline",
"input",
+ "llvm_and_toolchains",
"lse_desktop_experience",
"machine_learning",
"mainline_modularization",
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index c7ddccc..5dd1480 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -10331,7 +10331,7 @@
try {
if (!permissionOverridesCheck && mHardeningEnforcer.blockFocusMethod(uid,
HardeningEnforcer.METHOD_AUDIO_MANAGER_REQUEST_AUDIO_FOCUS,
- clientId, durationHint, callingPackageName)) {
+ clientId, durationHint, callingPackageName, attributionTag, sdk)) {
final String reason = "Audio focus request blocked by hardening";
Log.w(TAG, reason);
mmi.set(MediaMetrics.Property.EARLY_RETURN, reason).record();
@@ -10343,7 +10343,7 @@
mmi.record();
return mMediaFocusControl.requestAudioFocus(aa, durationHint, cb, fd,
- clientId, callingPackageName, attributionTag, flags, sdk,
+ clientId, callingPackageName, flags, sdk,
forceFocusDuckingForAccessibility(aa, durationHint, uid), -1 /*testUid, ignored*/,
permissionOverridesCheck);
}
@@ -10361,7 +10361,7 @@
return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
}
return mMediaFocusControl.requestAudioFocus(aa, durationHint, cb, fd,
- clientId, callingPackageName, null, flags,
+ clientId, callingPackageName, flags,
sdk, false /*forceDuck*/, fakeUid, true /*permissionOverridesCheck*/);
}
diff --git a/services/core/java/com/android/server/audio/HardeningEnforcer.java b/services/core/java/com/android/server/audio/HardeningEnforcer.java
index 409ed17..8ae04ac 100644
--- a/services/core/java/com/android/server/audio/HardeningEnforcer.java
+++ b/services/core/java/com/android/server/audio/HardeningEnforcer.java
@@ -19,6 +19,7 @@
import android.Manifest;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.AppOpsManager;
import android.content.Context;
@@ -26,6 +27,7 @@
import android.media.AudioFocusRequest;
import android.media.AudioManager;
import android.os.Binder;
+import android.os.Build;
import android.os.UserHandle;
import android.text.TextUtils;
import android.util.Slog;
@@ -128,19 +130,28 @@
* @param focusMethod name of the method to check, for logging purposes
* @param clientId id of the requester
* @param durationHint focus type being requested
+ * @param attributionTag attribution of the caller
+ * @param targetSdk target SDK of the caller
* @return false if the method call is allowed, true if it should be a no-op
*/
+ @SuppressWarnings("AndroidFrameworkCompatChange")
protected boolean blockFocusMethod(int callingUid, int focusMethod, @NonNull String clientId,
- int durationHint, @NonNull String packageName) {
+ int durationHint, @NonNull String packageName, String attributionTag, int targetSdk) {
if (packageName.isEmpty()) {
packageName = getPackNameForUid(callingUid);
}
- if (checkAppOp(AppOpsManager.OP_TAKE_AUDIO_FOCUS, callingUid, packageName)) {
+ if (noteOp(AppOpsManager.OP_TAKE_AUDIO_FOCUS, callingUid, packageName, attributionTag)) {
if (DEBUG) {
Slog.i(TAG, "blockFocusMethod pack:" + packageName + " NOT blocking");
}
return false;
+ } else if (targetSdk < Build.VERSION_CODES.VANILLA_ICE_CREAM) {
+ if (DEBUG) {
+ Slog.i(TAG, "blockFocusMethod pack:" + packageName + " NOT blocking due to sdk="
+ + targetSdk);
+ }
+ return false;
}
String errorMssg = "Focus request DENIED for uid:" + callingUid
@@ -169,14 +180,17 @@
}
/**
- * Checks the given op without throwing
+ * Notes the given op without throwing
* @param op the appOp code
* @param uid the calling uid
* @param packageName the package name of the caller
+ * @param attributionTag attribution of the caller
* @return return false if the operation is not allowed
*/
- private boolean checkAppOp(int op, int uid, @NonNull String packageName) {
- if (mAppOps.checkOpNoThrow(op, uid, packageName) != AppOpsManager.MODE_ALLOWED) {
+ private boolean noteOp(int op, int uid, @NonNull String packageName,
+ @Nullable String attributionTag) {
+ if (mAppOps.noteOpNoThrow(op, uid, packageName, attributionTag, null)
+ != AppOpsManager.MODE_ALLOWED) {
return false;
}
return true;
diff --git a/services/core/java/com/android/server/audio/MediaFocusControl.java b/services/core/java/com/android/server/audio/MediaFocusControl.java
index 35d38e2..70f3193 100644
--- a/services/core/java/com/android/server/audio/MediaFocusControl.java
+++ b/services/core/java/com/android/server/audio/MediaFocusControl.java
@@ -1082,7 +1082,6 @@
* @param fd
* @param clientId
* @param callingPackageName
- * @param attributionTag
* @param flags
* @param sdk
* @param forceDuck only true if
@@ -1096,7 +1095,7 @@
*/
protected int requestAudioFocus(@NonNull AudioAttributes aa, int focusChangeHint, IBinder cb,
IAudioFocusDispatcher fd, @NonNull String clientId, @NonNull String callingPackageName,
- String attributionTag, int flags, int sdk, boolean forceDuck, int testUid,
+ int flags, int sdk, boolean forceDuck, int testUid,
boolean permissionOverridesCheck) {
new MediaMetrics.Item(mMetricsId)
.setUid(Binder.getCallingUid())
@@ -1129,12 +1128,6 @@
return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
}
- final int res = mAppOps.noteOp(AppOpsManager.OP_TAKE_AUDIO_FOCUS, Binder.getCallingUid(),
- callingPackageName, attributionTag, null);
- if (!permissionOverridesCheck && res != AppOpsManager.MODE_ALLOWED) {
- return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
- }
-
synchronized(mAudioFocusLock) {
// check whether a focus freeze is in place and filter
if (isFocusFrozenForTest()) {
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java
index f9f56ee..2660932 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java
@@ -316,6 +316,8 @@
if (getBiometricContext().isAwake()) {
mALSProbeCallback.getProbe().enable();
+ } else {
+ mALSProbeCallback.getProbe().disable();
}
} catch (RemoteException e) {
Slog.e(TAG, "Remote exception", e);
diff --git a/services/core/java/com/android/server/display/DisplayDeviceConfig.java b/services/core/java/com/android/server/display/DisplayDeviceConfig.java
index eeacc53..e4db634 100644
--- a/services/core/java/com/android/server/display/DisplayDeviceConfig.java
+++ b/services/core/java/com/android/server/display/DisplayDeviceConfig.java
@@ -230,6 +230,16 @@
* <nits>55.2</nits>
* </displayBrightnessPoint>
* </blockingZoneThreshold>
+ * <supportedModes>
+ * <point>
+ * <first>60</first> // refresh rate
+ * <second>60</second> // vsync
+ * </point>
+ * <point>
+ * <first>120</first> // refresh rate
+ * <second>120</second> // vsync
+ * </point>
+ * </supportedModes>
* </lowerBlockingZoneConfigs>
* <higherBlockingZoneConfigs>
* <defaultRefreshRate>90</defaultRefreshRate>
@@ -244,6 +254,16 @@
* </displayBrightnessPoint>
* </blockingZoneThreshold>
* </higherBlockingZoneConfigs>
+ * <lowPowerSupportedModes>
+ * <point>
+ * <first>60</first> // refresh rate
+ * <second>60</second> // vsync
+ * </point>
+ * <point>
+ * <first>60</first> // refresh rate
+ * <second>240</second> // vsync
+ * </point>
+ * </lowPowerSupportedModes>
* </refreshRate>
*
* <highBrightnessMode enabled="true">
diff --git a/services/core/java/com/android/server/display/config/RefreshRateData.java b/services/core/java/com/android/server/display/config/RefreshRateData.java
index d7ed904..f769a89 100644
--- a/services/core/java/com/android/server/display/config/RefreshRateData.java
+++ b/services/core/java/com/android/server/display/config/RefreshRateData.java
@@ -64,18 +64,22 @@
public final List<SupportedModeData> lowPowerSupportedModes;
+ public final List<SupportedModeData> lowLightBlockingZoneSupportedModes;
+
@VisibleForTesting
public RefreshRateData(int defaultRefreshRate, int defaultPeakRefreshRate,
int defaultRefreshRateInHbmHdr, int defaultRefreshRateInHbmSunlight,
- List<SupportedModeData> lowPowerSupportedModes) {
+ List<SupportedModeData> lowPowerSupportedModes,
+ List<SupportedModeData> lowLightBlockingZoneSupportedModes) {
this.defaultRefreshRate = defaultRefreshRate;
this.defaultPeakRefreshRate = defaultPeakRefreshRate;
this.defaultRefreshRateInHbmHdr = defaultRefreshRateInHbmHdr;
this.defaultRefreshRateInHbmSunlight = defaultRefreshRateInHbmSunlight;
this.lowPowerSupportedModes = Collections.unmodifiableList(lowPowerSupportedModes);
+ this.lowLightBlockingZoneSupportedModes =
+ Collections.unmodifiableList(lowLightBlockingZoneSupportedModes);
}
-
@Override
public String toString() {
return "RefreshRateData {"
@@ -84,6 +88,7 @@
+ ", defaultRefreshRateInHbmHdr: " + defaultRefreshRateInHbmHdr
+ ", defaultRefreshRateInHbmSunlight: " + defaultRefreshRateInHbmSunlight
+ ", lowPowerSupportedModes=" + lowPowerSupportedModes
+ + ", lowLightBlockingZoneSupportedModes=" + lowLightBlockingZoneSupportedModes
+ "} ";
}
@@ -100,13 +105,19 @@
int defaultRefreshRateInHbmSunlight = loadDefaultRefreshRateInHbmSunlight(
refreshRateConfigs, resources);
- NonNegativeFloatToFloatMap modes =
+ NonNegativeFloatToFloatMap lowPowerModes =
refreshRateConfigs == null ? null : refreshRateConfigs.getLowPowerSupportedModes();
- List<SupportedModeData> lowPowerSupportedModes = SupportedModeData.load(modes);
+ List<SupportedModeData> lowPowerSupportedModes = SupportedModeData.load(lowPowerModes);
+
+ BlockingZoneConfig lowerZoneConfig = refreshRateConfigs == null ? null
+ : refreshRateConfigs.getLowerBlockingZoneConfigs();
+ NonNegativeFloatToFloatMap lowerZoneModes =
+ lowerZoneConfig == null ? null : lowerZoneConfig.getSupportedModes();
+ List<SupportedModeData> lowLightSupportedModes = SupportedModeData.load(lowerZoneModes);
return new RefreshRateData(defaultRefreshRate, defaultPeakRefreshRate,
defaultRefreshRateInHbmHdr, defaultRefreshRateInHbmSunlight,
- lowPowerSupportedModes);
+ lowPowerSupportedModes, lowLightSupportedModes);
}
private static int loadDefaultRefreshRate(
diff --git a/services/core/java/com/android/server/display/mode/DisplayModeDirector.java b/services/core/java/com/android/server/display/mode/DisplayModeDirector.java
index d519748..d610f08 100644
--- a/services/core/java/com/android/server/display/mode/DisplayModeDirector.java
+++ b/services/core/java/com/android/server/display/mode/DisplayModeDirector.java
@@ -2157,8 +2157,19 @@
}
}
+ private boolean hasLowLightVrrConfig() {
+ DisplayDeviceConfig config;
+ synchronized (mLock) {
+ config = mDefaultDisplayDeviceConfig;
+ }
+ return mVsyncLowLightBlockingVoteEnabled
+ && config != null
+ && config.isVrrSupportEnabled()
+ && !config.getRefreshRateData().lowLightBlockingZoneSupportedModes.isEmpty();
+ }
+
private void restartObserver() {
- if (mRefreshRateInLowZone > 0) {
+ if (mRefreshRateInLowZone > 0 || hasLowLightVrrConfig()) {
mShouldObserveDisplayLowChange = hasValidThreshold(
mLowDisplayBrightnessThresholds);
mShouldObserveAmbientLowChange = hasValidThreshold(
@@ -2300,6 +2311,7 @@
return false;
}
+ @GuardedBy("mLock")
private void onBrightnessChangedLocked() {
if (!mRefreshRateChangeable || mLowPowerModeEnabled) {
return;
@@ -2315,8 +2327,14 @@
boolean insideLowZone = hasValidLowZone() && isInsideLowZone(mBrightness, mAmbientLux);
if (insideLowZone) {
- refreshRateVote =
- Vote.forPhysicalRefreshRates(mRefreshRateInLowZone, mRefreshRateInLowZone);
+ if (hasLowLightVrrConfig()) {
+ refreshRateVote = Vote.forSupportedRefreshRates(mDefaultDisplayDeviceConfig
+ .getRefreshRateData().lowLightBlockingZoneSupportedModes);
+ } else {
+ refreshRateVote = Vote.forPhysicalRefreshRates(
+ mRefreshRateInLowZone, mRefreshRateInLowZone);
+ refreshRateSwitchingVote = Vote.forDisableRefreshRateSwitching();
+ }
if (mLowZoneRefreshRateForThermals != null) {
RefreshRateRange range = SkinThermalStatusObserver
.findBestMatchingRefreshRateRange(mThermalStatus,
@@ -2326,18 +2344,6 @@
Vote.forPhysicalRefreshRates(range.min, range.max);
}
}
-
- if (mVsyncLowLightBlockingVoteEnabled
- && isVrrSupportedLocked(Display.DEFAULT_DISPLAY)) {
- refreshRateSwitchingVote = Vote.forSupportedRefreshRatesAndDisableSwitching(
- List.of(
- new SupportedRefreshRatesVote.RefreshRates(
- /* peakRefreshRate= */ 60f, /* vsyncRate= */ 60f),
- new SupportedRefreshRatesVote.RefreshRates(
- /* peakRefreshRate= */120f, /* vsyncRate= */ 120f)));
- } else {
- refreshRateSwitchingVote = Vote.forDisableRefreshRateSwitching();
- }
}
boolean insideHighZone = hasValidHighZone()
@@ -2368,7 +2374,7 @@
}
private boolean hasValidLowZone() {
- return mRefreshRateInLowZone > 0
+ return (mRefreshRateInLowZone > 0 || hasLowLightVrrConfig())
&& (mShouldObserveDisplayLowChange || mShouldObserveAmbientLowChange);
}
diff --git a/services/core/java/com/android/server/display/mode/Vote.java b/services/core/java/com/android/server/display/mode/Vote.java
index cacc8b4..7cbdd13 100644
--- a/services/core/java/com/android/server/display/mode/Vote.java
+++ b/services/core/java/com/android/server/display/mode/Vote.java
@@ -233,13 +233,6 @@
return new SupportedModesVote(modeIds);
}
- static Vote forSupportedRefreshRatesAndDisableSwitching(
- List<SupportedRefreshRatesVote.RefreshRates> supportedRefreshRates) {
- return new CombinedVote(
- List.of(forDisableRefreshRateSwitching(),
- new SupportedRefreshRatesVote(supportedRefreshRates)));
- }
-
static String priorityToString(int priority) {
switch (priority) {
case PRIORITY_APP_REQUEST_BASE_MODE_REFRESH_RATE:
diff --git a/services/core/java/com/android/server/locksettings/BiometricDeferredQueue.java b/services/core/java/com/android/server/locksettings/BiometricDeferredQueue.java
index f572845..966be53 100644
--- a/services/core/java/com/android/server/locksettings/BiometricDeferredQueue.java
+++ b/services/core/java/com/android/server/locksettings/BiometricDeferredQueue.java
@@ -32,6 +32,7 @@
import android.util.Slog;
import com.android.internal.widget.VerifyCredentialResponse;
+import com.android.server.biometrics.BiometricHandlerProvider;
import java.util.ArrayList;
import java.util.List;
@@ -132,9 +133,11 @@
mFaceResetLockoutTask = null;
};
- BiometricDeferredQueue(@NonNull SyntheticPasswordManager spManager, @NonNull Handler handler) {
+ BiometricDeferredQueue(@NonNull SyntheticPasswordManager spManager) {
mSpManager = spManager;
- mHandler = handler;
+
+ //Using a higher priority thread to avoid any delays and interruption of clients
+ mHandler = BiometricHandlerProvider.getInstance().getBiometricCallbackHandler();
mPendingResetLockoutsForFingerprint = new ArrayList<>();
mPendingResetLockoutsForFace = new ArrayList<>();
mPendingResetLockouts = new ArrayList<>();
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index ae3d36a..22b33dd 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -687,7 +687,7 @@
mSpManager = injector.getSyntheticPasswordManager(mStorage);
mUnifiedProfilePasswordCache = injector.getUnifiedProfilePasswordCache(mKeyStore);
- mBiometricDeferredQueue = new BiometricDeferredQueue(mSpManager, mHandler);
+ mBiometricDeferredQueue = new BiometricDeferredQueue(mSpManager);
mRebootEscrowManager = injector.getRebootEscrowManager(new RebootEscrowCallbacks(),
mStorage);
diff --git a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
index c03497e..ba7d3b8 100644
--- a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
+++ b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
@@ -70,6 +70,7 @@
import com.android.media.flags.Flags;
import com.android.server.LocalServices;
import com.android.server.pm.UserManagerInternal;
+import com.android.server.statusbar.StatusBarManagerInternal;
import java.io.PrintWriter;
import java.lang.ref.WeakReference;
@@ -118,6 +119,7 @@
private final UserManagerInternal mUserManagerInternal;
private final Object mLock = new Object();
private final AppOpsManager mAppOpsManager;
+ private final StatusBarManagerInternal mStatusBarManagerInternal;
final AtomicInteger mNextRouterOrManagerId = new AtomicInteger(1);
final ActivityManager mActivityManager;
final PowerManager mPowerManager;
@@ -188,6 +190,7 @@
mPowerManager = mContext.getSystemService(PowerManager.class);
mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
mAppOpsManager = mContext.getSystemService(AppOpsManager.class);
+ mStatusBarManagerInternal = LocalServices.getService(StatusBarManagerInternal.class);
IntentFilter screenOnOffIntentFilter = new IntentFilter();
screenOnOffIntentFilter.addAction(ACTION_SCREEN_ON);
@@ -260,6 +263,17 @@
}
}
+ @RequiresPermission(Manifest.permission.PACKAGE_USAGE_STATS)
+ public boolean showMediaOutputSwitcherWithRouter2(@NonNull String packageName) {
+ UserHandle userHandle = Binder.getCallingUserHandle();
+ final long token = Binder.clearCallingIdentity();
+ try {
+ return showOutputSwitcher(packageName, userHandle);
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+
public void registerRouter2(@NonNull IMediaRouter2 router, @NonNull String packageName) {
Objects.requireNonNull(router, "router must not be null");
if (TextUtils.isEmpty(packageName)) {
@@ -778,6 +792,31 @@
}
}
+ @RequiresPermission(Manifest.permission.PACKAGE_USAGE_STATS)
+ public boolean showMediaOutputSwitcherWithProxyRouter(
+ @NonNull IMediaRouter2Manager proxyRouter) {
+ Objects.requireNonNull(proxyRouter, "Proxy router must not be null");
+
+ final long token = Binder.clearCallingIdentity();
+ try {
+ synchronized (mLock) {
+ final IBinder binder = proxyRouter.asBinder();
+ ManagerRecord proxyRouterRecord = mAllManagerRecords.get(binder);
+
+ if (proxyRouterRecord.mTargetPackageName == null) {
+ throw new UnsupportedOperationException(
+ "Only proxy routers can show the Output Switcher.");
+ }
+
+ return showOutputSwitcher(
+ proxyRouterRecord.mTargetPackageName,
+ UserHandle.of(proxyRouterRecord.mUserRecord.mUserId));
+ }
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+
// End of methods that implement MediaRouter2Manager operations.
// Start of methods that implements operations for both MediaRouter2 and MediaRouter2Manager.
@@ -934,6 +973,19 @@
}
}
+ @RequiresPermission(Manifest.permission.PACKAGE_USAGE_STATS)
+ private boolean showOutputSwitcher(
+ @NonNull String packageName, @NonNull UserHandle userHandle) {
+ if (mActivityManager.getPackageImportance(packageName) > IMPORTANCE_FOREGROUND) {
+ Slog.w(TAG, "showMediaOutputSwitcher only works when called from foreground");
+ return false;
+ }
+ synchronized (mLock) {
+ mStatusBarManagerInternal.showMediaOutputSwitcher(packageName, userHandle);
+ }
+ return true;
+ }
+
// End of methods that implements operations for both MediaRouter2 and MediaRouter2Manager.
public void dump(@NonNull PrintWriter pw, @NonNull String prefix) {
diff --git a/services/core/java/com/android/server/media/MediaRouterService.java b/services/core/java/com/android/server/media/MediaRouterService.java
index 192ac62..1188a07 100644
--- a/services/core/java/com/android/server/media/MediaRouterService.java
+++ b/services/core/java/com/android/server/media/MediaRouterService.java
@@ -16,7 +16,6 @@
package com.android.server.media;
-import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
import android.Manifest;
import android.annotation.NonNull;
@@ -75,7 +74,6 @@
import com.android.server.LocalServices;
import com.android.server.Watchdog;
import com.android.server.pm.UserManagerInternal;
-import com.android.server.statusbar.StatusBarManagerInternal;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -266,32 +264,6 @@
// Binder call
@Override
- public boolean showMediaOutputSwitcher(String packageName) {
- int uid = Binder.getCallingUid();
- if (!validatePackageName(uid, packageName)) {
- throw new SecurityException("packageName must match the calling identity");
- }
- UserHandle userHandle = UserHandle.getUserHandleForUid(uid);
- final long token = Binder.clearCallingIdentity();
- try {
- if (mContext.getSystemService(ActivityManager.class).getPackageImportance(packageName)
- > IMPORTANCE_FOREGROUND) {
- Slog.w(TAG, "showMediaOutputSwitcher only works when called from foreground");
- return false;
- }
- synchronized (mLock) {
- StatusBarManagerInternal statusBar =
- LocalServices.getService(StatusBarManagerInternal.class);
- statusBar.showMediaOutputSwitcher(packageName, userHandle);
- }
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- return true;
- }
-
- // Binder call
- @Override
public MediaRouterClientState getState(IMediaRouterClient client) {
final long token = Binder.clearCallingIdentity();
try {
@@ -443,6 +415,17 @@
}
// Binder call
+ @RequiresPermission(Manifest.permission.PACKAGE_USAGE_STATS)
+ @Override
+ public boolean showMediaOutputSwitcherWithRouter2(@NonNull String packageName) {
+ int uid = Binder.getCallingUid();
+ if (!validatePackageName(uid, packageName)) {
+ throw new SecurityException("packageName must match the calling identity");
+ }
+ return mService2.showMediaOutputSwitcherWithRouter2(packageName);
+ }
+
+ // Binder call
@Override
public void registerRouter2(IMediaRouter2 router, String packageName) {
final int uid = Binder.getCallingUid();
@@ -676,6 +659,13 @@
mService2.releaseSessionWithManager(manager, requestId, sessionId);
}
+ @RequiresPermission(Manifest.permission.PACKAGE_USAGE_STATS)
+ @Override
+ public boolean showMediaOutputSwitcherWithProxyRouter(
+ @NonNull IMediaRouter2Manager proxyRouter) {
+ return mService2.showMediaOutputSwitcherWithProxyRouter(proxyRouter);
+ }
+
void restoreBluetoothA2dp() {
try {
boolean a2dpOn;
diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java
index f02a3ff..1ebc856 100644
--- a/services/core/java/com/android/server/media/MediaSessionService.java
+++ b/services/core/java/com/android/server/media/MediaSessionService.java
@@ -197,6 +197,16 @@
@GuardedBy("mLock")
private final Map<Integer, Set<Notification>> mMediaNotifications = new HashMap<>();
+ /**
+ * Holds all {@link MediaSessionRecordImpl} which we've reported as being {@link
+ * ActivityManagerInternal#startForegroundServiceDelegate user engaged}.
+ *
+ * <p>This map simply prevents invoking {@link
+ * ActivityManagerInternal#startForegroundServiceDelegate} more than once per session.
+ */
+ @GuardedBy("mLock")
+ private final Set<MediaSessionRecordImpl> mFgsAllowedMediaSessionRecords = new HashSet<>();
+
// The FullUserRecord of the current users. (i.e. The foreground user that isn't a profile)
// It's always not null after the MediaSessionService is started.
private FullUserRecord mCurrentFullUserRecord;
@@ -704,15 +714,23 @@
int uid = mediaSessionRecord.getUid();
for (Notification mediaNotification : mMediaNotifications.getOrDefault(uid, Set.of())) {
if (mediaSessionRecord.isLinkedToNotification(mediaNotification)) {
- startFgsDelegate(mediaSessionRecord.getForegroundServiceDelegationOptions());
+ startFgsDelegateLocked(mediaSessionRecord);
return;
}
}
}
}
- private void startFgsDelegate(
- ForegroundServiceDelegationOptions foregroundServiceDelegationOptions) {
+ @GuardedBy("mLock")
+ private void startFgsDelegateLocked(MediaSessionRecordImpl mediaSessionRecord) {
+ ForegroundServiceDelegationOptions foregroundServiceDelegationOptions =
+ mediaSessionRecord.getForegroundServiceDelegationOptions();
+ if (foregroundServiceDelegationOptions == null) {
+ return; // This record doesn't support FGS. Typically a MediaSession2 record.
+ }
+ if (!mFgsAllowedMediaSessionRecords.add(mediaSessionRecord)) {
+ return; // This record is already FGS-started.
+ }
final long token = Binder.clearCallingIdentity();
try {
Log.i(
@@ -754,12 +772,21 @@
}
}
- stopFgsDelegate(foregroundServiceDelegationOptions);
+ stopFgsDelegateLocked(mediaSessionRecord);
}
}
- private void stopFgsDelegate(
- ForegroundServiceDelegationOptions foregroundServiceDelegationOptions) {
+ @GuardedBy("mLock")
+ private void stopFgsDelegateLocked(MediaSessionRecordImpl mediaSessionRecord) {
+ ForegroundServiceDelegationOptions foregroundServiceDelegationOptions =
+ mediaSessionRecord.getForegroundServiceDelegationOptions();
+ if (foregroundServiceDelegationOptions == null) {
+ return; // This record doesn't support FGS. Typically a MediaSession2 record.
+ }
+ if (!mFgsAllowedMediaSessionRecords.remove(mediaSessionRecord)) {
+ return; // This record is not FGS-started. No need to stop it.
+ }
+
final long token = Binder.clearCallingIdentity();
try {
Log.i(
@@ -3209,11 +3236,8 @@
mMediaNotifications.get(uid).add(postedNotification);
for (MediaSessionRecordImpl mediaSessionRecord :
mUserEngagedSessionsForFgs.getOrDefault(uid, Set.of())) {
- ForegroundServiceDelegationOptions foregroundServiceDelegationOptions =
- mediaSessionRecord.getForegroundServiceDelegationOptions();
- if (foregroundServiceDelegationOptions != null
- && mediaSessionRecord.isLinkedToNotification(postedNotification)) {
- startFgsDelegate(foregroundServiceDelegationOptions);
+ if (mediaSessionRecord.isLinkedToNotification(postedNotification)) {
+ startFgsDelegateLocked(mediaSessionRecord);
return;
}
}
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index c60ac3a..f03c639 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -3965,8 +3965,8 @@
// allow override without having plans defined.
synchronized (mNetworkPoliciesSecondLock) {
final SubscriptionPlan plan = getPrimarySubscriptionPlanLocked(subId);
- if (overrideMask != SUBSCRIPTION_OVERRIDE_UNMETERED && plan == null
- || plan.getDataLimitBehavior() == SubscriptionPlan.LIMIT_BEHAVIOR_UNKNOWN) {
+ if (overrideMask != SUBSCRIPTION_OVERRIDE_UNMETERED && (plan == null
+ || plan.getDataLimitBehavior() == SubscriptionPlan.LIMIT_BEHAVIOR_UNKNOWN)) {
throw new IllegalStateException(
"Must provide valid SubscriptionPlan to enable overriding");
}
diff --git a/services/core/java/com/android/server/net/OWNERS b/services/core/java/com/android/server/net/OWNERS
index 669cdaa..bbc7c01 100644
--- a/services/core/java/com/android/server/net/OWNERS
+++ b/services/core/java/com/android/server/net/OWNERS
@@ -1,5 +1,6 @@
set noparent
file:platform/packages/modules/Connectivity:main:/OWNERS_core_networking
+per-file NetworkPolicyManagerService.java=jackyu@google.com, sarahchin@google.com
jsharkey@android.com
sudheersai@google.com
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index 050d44e..b93dcdc 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -1423,7 +1423,9 @@
DevicePolicyManagerInternal dpmi =
LocalServices.getService(DevicePolicyManagerInternal.class);
final boolean canSilentlyInstallPackage =
- dpmi != null && dpmi.canSilentlyInstallPackage(callerPackageName, callingUid);
+ (dpmi != null && dpmi.canSilentlyInstallPackage(callerPackageName, callingUid))
+ || PackageInstallerSession.isEmergencyInstallerEnabled(
+ versionedPackage.getPackageName(), snapshot, userId, callingUid);
final PackageDeleteObserverAdapter adapter = new PackageDeleteObserverAdapter(mContext,
statusReceiver, versionedPackage.getPackageName(),
@@ -1445,15 +1447,6 @@
.createEvent(DevicePolicyEnums.UNINSTALL_PACKAGE)
.setAdmin(callerPackageName)
.write();
- } else if (PackageInstallerSession.isEmergencyInstallerEnabled(callerPackageName, snapshot,
- userId, callingUid)) {
- // Need to clear the calling identity to get DELETE_PACKAGES permission
- final long ident = Binder.clearCallingIdentity();
- try {
- mPm.deletePackageVersioned(versionedPackage, adapter.getBinder(), userId, flags);
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
} else {
ApplicationInfo appInfo = snapshot.getApplicationInfo(callerPackageName, 0, userId);
if (appInfo.targetSdkVersion >= Build.VERSION_CODES.P) {
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 8d6d774..3956552 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -934,6 +934,7 @@
ret.setTargetSdkVersion(p.getTargetSdkVersion());
ret.setRestrictUpdateHash(p.getRestrictUpdateHash());
ret.setScannedAsStoppedSystemApp(p.isScannedAsStoppedSystemApp());
+ ret.setInstallSource(p.getInstallSource());
}
mDisabledSysPackages.remove(name);
return ret;
diff --git a/services/core/java/com/android/server/policy/TalkbackShortcutController.java b/services/core/java/com/android/server/policy/TalkbackShortcutController.java
index b05a421..e544ae6 100644
--- a/services/core/java/com/android/server/policy/TalkbackShortcutController.java
+++ b/services/core/java/com/android/server/policy/TalkbackShortcutController.java
@@ -117,6 +117,7 @@
}
private boolean isTalkback(ServiceInfo info) {
- return TALKBACK_LABEL.equals(info.loadLabel(mPackageManager).toString());
+ return TALKBACK_LABEL.equals(info.loadLabel(mPackageManager).toString())
+ && (info.applicationInfo.isSystemApp() || info.applicationInfo.isUpdatedSystemApp());
}
}
diff --git a/services/core/java/com/android/server/power/stats/AudioPowerStatsProcessor.java b/services/core/java/com/android/server/power/stats/AudioPowerStatsProcessor.java
new file mode 100644
index 0000000..a48f162
--- /dev/null
+++ b/services/core/java/com/android/server/power/stats/AudioPowerStatsProcessor.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.power.stats;
+
+import android.os.BatteryConsumer;
+import android.os.BatteryStats;
+
+import com.android.internal.os.PowerProfile;
+
+public class AudioPowerStatsProcessor extends BinaryStatePowerStatsProcessor {
+ public AudioPowerStatsProcessor(PowerProfile powerProfile,
+ PowerStatsUidResolver uidResolver) {
+ super(BatteryConsumer.POWER_COMPONENT_AUDIO, uidResolver,
+ powerProfile.getAveragePower(PowerProfile.POWER_AUDIO));
+ }
+
+ @Override
+ protected @BinaryState int getBinaryState(BatteryStats.HistoryItem item) {
+ return (item.states & BatteryStats.HistoryItem.STATE_AUDIO_ON_FLAG) != 0
+ ? STATE_ON
+ : STATE_OFF;
+ }
+}
diff --git a/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java b/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java
index efaa7a8..5bae5a4 100644
--- a/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java
+++ b/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java
@@ -6490,12 +6490,14 @@
uid = mapUid(uid);
if (mAudioOnNesting == 0) {
mHistory.recordStateStartEvent(elapsedRealtimeMs, uptimeMs,
- HistoryItem.STATE_AUDIO_ON_FLAG);
+ HistoryItem.STATE_AUDIO_ON_FLAG, uid, "audio");
mAudioOnTimer.startRunningLocked(elapsedRealtimeMs);
}
mAudioOnNesting++;
- getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
- .noteAudioTurnedOnLocked(elapsedRealtimeMs);
+ if (!mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_AUDIO)) {
+ getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
+ .noteAudioTurnedOnLocked(elapsedRealtimeMs);
+ }
}
@GuardedBy("this")
@@ -6506,11 +6508,13 @@
uid = mapUid(uid);
if (--mAudioOnNesting == 0) {
mHistory.recordStateStopEvent(elapsedRealtimeMs, uptimeMs,
- HistoryItem.STATE_AUDIO_ON_FLAG);
+ HistoryItem.STATE_AUDIO_ON_FLAG, uid, "audio");
mAudioOnTimer.stopRunningLocked(elapsedRealtimeMs);
}
- getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
- .noteAudioTurnedOffLocked(elapsedRealtimeMs);
+ if (!mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_AUDIO)) {
+ getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
+ .noteAudioTurnedOffLocked(elapsedRealtimeMs);
+ }
}
@GuardedBy("this")
@@ -6518,12 +6522,14 @@
uid = mapUid(uid);
if (mVideoOnNesting == 0) {
mHistory.recordState2StartEvent(elapsedRealtimeMs, uptimeMs,
- HistoryItem.STATE2_VIDEO_ON_FLAG);
+ HistoryItem.STATE2_VIDEO_ON_FLAG, uid, "video");
mVideoOnTimer.startRunningLocked(elapsedRealtimeMs);
}
mVideoOnNesting++;
- getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
- .noteVideoTurnedOnLocked(elapsedRealtimeMs);
+ if (!mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_VIDEO)) {
+ getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
+ .noteVideoTurnedOnLocked(elapsedRealtimeMs);
+ }
}
@GuardedBy("this")
@@ -6534,11 +6540,13 @@
uid = mapUid(uid);
if (--mVideoOnNesting == 0) {
mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs,
- HistoryItem.STATE2_VIDEO_ON_FLAG);
+ HistoryItem.STATE2_VIDEO_ON_FLAG, uid, "video");
mVideoOnTimer.stopRunningLocked(elapsedRealtimeMs);
}
- getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
- .noteVideoTurnedOffLocked(elapsedRealtimeMs);
+ if (!mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_VIDEO)) {
+ getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
+ .noteVideoTurnedOffLocked(elapsedRealtimeMs);
+ }
}
@GuardedBy("this")
@@ -6613,11 +6621,13 @@
uid = mapUid(uid);
if (mFlashlightOnNesting++ == 0) {
mHistory.recordState2StartEvent(elapsedRealtimeMs, uptimeMs,
- HistoryItem.STATE2_FLASHLIGHT_FLAG);
+ HistoryItem.STATE2_FLASHLIGHT_FLAG, uid, "flashlight");
mFlashlightOnTimer.startRunningLocked(elapsedRealtimeMs);
}
- getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
- .noteFlashlightTurnedOnLocked(elapsedRealtimeMs);
+ if (!mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_FLASHLIGHT)) {
+ getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
+ .noteFlashlightTurnedOnLocked(elapsedRealtimeMs);
+ }
}
@GuardedBy("this")
@@ -6628,11 +6638,13 @@
uid = mapUid(uid);
if (--mFlashlightOnNesting == 0) {
mHistory.recordState2StopEvent(elapsedRealtimeMs, uptimeMs,
- HistoryItem.STATE2_FLASHLIGHT_FLAG);
+ HistoryItem.STATE2_FLASHLIGHT_FLAG, uid, "flashlight");
mFlashlightOnTimer.stopRunningLocked(elapsedRealtimeMs);
}
- getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
- .noteFlashlightTurnedOffLocked(elapsedRealtimeMs);
+ if (!mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_FLASHLIGHT)) {
+ getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
+ .noteFlashlightTurnedOffLocked(elapsedRealtimeMs);
+ }
}
@GuardedBy("this")
diff --git a/services/core/java/com/android/server/power/stats/BatteryUsageStatsProvider.java b/services/core/java/com/android/server/power/stats/BatteryUsageStatsProvider.java
index b252395..ba6e4a9 100644
--- a/services/core/java/com/android/server/power/stats/BatteryUsageStatsProvider.java
+++ b/services/core/java/com/android/server/power/stats/BatteryUsageStatsProvider.java
@@ -97,9 +97,15 @@
mContext.getSystemService(SensorManager.class)));
mPowerCalculators.add(new GnssPowerCalculator(mPowerProfile));
mPowerCalculators.add(new CameraPowerCalculator(mPowerProfile));
- mPowerCalculators.add(new FlashlightPowerCalculator(mPowerProfile));
- mPowerCalculators.add(new AudioPowerCalculator(mPowerProfile));
- mPowerCalculators.add(new VideoPowerCalculator(mPowerProfile));
+ if (!mPowerStatsExporterEnabled.get(BatteryConsumer.POWER_COMPONENT_FLASHLIGHT)) {
+ mPowerCalculators.add(new FlashlightPowerCalculator(mPowerProfile));
+ }
+ if (!mPowerStatsExporterEnabled.get(BatteryConsumer.POWER_COMPONENT_AUDIO)) {
+ mPowerCalculators.add(new AudioPowerCalculator(mPowerProfile));
+ }
+ if (!mPowerStatsExporterEnabled.get(BatteryConsumer.POWER_COMPONENT_VIDEO)) {
+ mPowerCalculators.add(new VideoPowerCalculator(mPowerProfile));
+ }
mPowerCalculators.add(new ScreenPowerCalculator(mPowerProfile));
mPowerCalculators.add(new AmbientDisplayPowerCalculator(mPowerProfile));
mPowerCalculators.add(new IdlePowerCalculator(mPowerProfile));
diff --git a/services/core/java/com/android/server/power/stats/FlashlightPowerStatsProcessor.java b/services/core/java/com/android/server/power/stats/FlashlightPowerStatsProcessor.java
new file mode 100644
index 0000000..f7216c9
--- /dev/null
+++ b/services/core/java/com/android/server/power/stats/FlashlightPowerStatsProcessor.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.power.stats;
+
+import android.os.BatteryConsumer;
+import android.os.BatteryStats;
+
+import com.android.internal.os.PowerProfile;
+
+public class FlashlightPowerStatsProcessor extends BinaryStatePowerStatsProcessor {
+ public FlashlightPowerStatsProcessor(PowerProfile powerProfile,
+ PowerStatsUidResolver uidResolver) {
+ super(BatteryConsumer.POWER_COMPONENT_FLASHLIGHT, uidResolver,
+ powerProfile.getAveragePower(PowerProfile.POWER_FLASHLIGHT));
+ }
+
+ @Override
+ protected @BinaryState int getBinaryState(BatteryStats.HistoryItem item) {
+ return (item.states2 & BatteryStats.HistoryItem.STATE2_FLASHLIGHT_FLAG) != 0
+ ? STATE_ON
+ : STATE_OFF;
+ }
+}
diff --git a/services/core/java/com/android/server/power/stats/VideoPowerStatsProcessor.java b/services/core/java/com/android/server/power/stats/VideoPowerStatsProcessor.java
new file mode 100644
index 0000000..48dac8a
--- /dev/null
+++ b/services/core/java/com/android/server/power/stats/VideoPowerStatsProcessor.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.power.stats;
+
+import android.os.BatteryConsumer;
+import android.os.BatteryStats;
+
+import com.android.internal.os.PowerProfile;
+
+public class VideoPowerStatsProcessor extends BinaryStatePowerStatsProcessor {
+ public VideoPowerStatsProcessor(PowerProfile powerProfile,
+ PowerStatsUidResolver uidResolver) {
+ super(BatteryConsumer.POWER_COMPONENT_VIDEO, uidResolver,
+ powerProfile.getAveragePower(PowerProfile.POWER_VIDEO));
+ }
+
+ @Override
+ protected @BinaryState int getBinaryState(BatteryStats.HistoryItem item) {
+ return (item.states2 & BatteryStats.HistoryItem.STATE2_VIDEO_ON_FLAG) != 0
+ ? STATE_ON
+ : STATE_OFF;
+ }
+}
diff --git a/services/core/java/com/android/server/vibrator/VibratorController.java b/services/core/java/com/android/server/vibrator/VibratorController.java
index 6710d02..988e8fe 100644
--- a/services/core/java/com/android/server/vibrator/VibratorController.java
+++ b/services/core/java/com/android/server/vibrator/VibratorController.java
@@ -56,10 +56,17 @@
private volatile boolean mIsUnderExternalControl;
private volatile float mCurrentAmplitude;
- /** Listener for vibration completion callbacks from native. */
+ /**
+ * Listener for vibration completion callbacks from native.
+ *
+ * <p>Only the latest active native call to {@link VibratorController#on} will ever trigger this
+ * completion callback, to avoid race conditions during a vibration playback. If a new call to
+ * {@link #on} or {@link #off} happens before a previous callback was triggered then the
+ * previous callback will be disabled, even if the new command fails.
+ */
public interface OnVibrationCompleteListener {
- /** Callback triggered when vibration is complete. */
+ /** Callback triggered when an active vibration command is complete. */
void onComplete(int vibratorId, long vibrationId);
}
@@ -235,7 +242,7 @@
}
/**
- * Turn on the vibrator for {@code milliseconds} time, using {@code vibrationId} or completion
+ * Turn on the vibrator for {@code milliseconds} time, using {@code vibrationId} for completion
* callback to {@link OnVibrationCompleteListener}.
*
* <p>This will affect the state of {@link #isVibrating()}.
@@ -255,7 +262,7 @@
}
/**
- * Plays predefined vibration effect, using {@code vibrationId} or completion callback to
+ * Plays predefined vibration effect, using {@code vibrationId} for completion callback to
* {@link OnVibrationCompleteListener}.
*
* <p>This will affect the state of {@link #isVibrating()}.
@@ -276,8 +283,8 @@
}
/**
- * Plays a composition of vibration primitives, using {@code vibrationId} or completion callback
- * to {@link OnVibrationCompleteListener}.
+ * Plays a composition of vibration primitives, using {@code vibrationId} for completion
+ * callback to {@link OnVibrationCompleteListener}.
*
* <p>This will affect the state of {@link #isVibrating()}.
*
@@ -299,7 +306,7 @@
}
/**
- * Plays a composition of pwle primitives, using {@code vibrationId} or completion callback
+ * Plays a composition of pwle primitives, using {@code vibrationId} for completion callback
* to {@link OnVibrationCompleteListener}.
*
* <p>This will affect the state of {@link #isVibrating()}.
@@ -321,7 +328,11 @@
}
}
- /** Turns off the vibrator. This will affect the state of {@link #isVibrating()}. */
+ /**
+ * Turns off the vibrator and disables completion callback to any pending vibration.
+ *
+ * <p>This will affect the state of {@link #isVibrating()}.
+ */
public void off() {
synchronized (mLock) {
mNativeWrapper.off();
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperCropper.java b/services/core/java/com/android/server/wallpaper/WallpaperCropper.java
index 80f1125..f70a3ba 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperCropper.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperCropper.java
@@ -150,7 +150,7 @@
Rect landscapeCrop = getCrop(rotatedDisplaySize, bitmapSize, suggestedCrops, rtl);
landscapeCrop = noParallax(landscapeCrop, rotatedDisplaySize, bitmapSize, rtl);
// compute the crop on portrait at the center of the landscape crop
- crop = getAdjustedCrop(landscapeCrop, bitmapSize, displaySize, false, ADD);
+ crop = getAdjustedCrop(landscapeCrop, bitmapSize, displaySize, false, rtl, ADD);
// add some parallax (until the border of the landscape crop without parallax)
if (rtl) {
@@ -160,7 +160,7 @@
}
}
- return getAdjustedCrop(crop, bitmapSize, displaySize, true, ADD);
+ return getAdjustedCrop(crop, bitmapSize, displaySize, true, rtl, ADD);
}
// If any suggested crop is invalid, fallback to case 1
@@ -176,7 +176,7 @@
// Case 2: if the orientation exists in the suggested crops, adjust the suggested crop
Rect suggestedCrop = suggestedCrops.get(orientation);
if (suggestedCrop != null) {
- return getAdjustedCrop(suggestedCrop, bitmapSize, displaySize, true, ADD);
+ return getAdjustedCrop(suggestedCrop, bitmapSize, displaySize, true, rtl, ADD);
}
// Case 3: if we have the 90° rotated orientation in the suggested crops, reuse it and
@@ -188,7 +188,7 @@
if (suggestedCrop != null) {
// only keep the visible part (without parallax)
Rect adjustedCrop = noParallax(suggestedCrop, suggestedDisplaySize, bitmapSize, rtl);
- return getAdjustedCrop(adjustedCrop, bitmapSize, displaySize, false, BALANCE);
+ return getAdjustedCrop(adjustedCrop, bitmapSize, displaySize, false, rtl, BALANCE);
}
// Case 4: if the device is a foldable, if we're looking for a folded orientation and have
@@ -200,13 +200,13 @@
// compute the visible part (without parallax) of the unfolded screen
Rect adjustedCrop = noParallax(suggestedCrop, suggestedDisplaySize, bitmapSize, rtl);
// compute the folded crop, at the center of the crop of the unfolded screen
- Rect res = getAdjustedCrop(adjustedCrop, bitmapSize, displaySize, false, REMOVE);
+ Rect res = getAdjustedCrop(adjustedCrop, bitmapSize, displaySize, false, rtl, REMOVE);
// if we removed some width, add it back to add a parallax effect
if (res.width() < adjustedCrop.width()) {
if (rtl) res.left = Math.min(res.left, adjustedCrop.left);
else res.right = Math.max(res.right, adjustedCrop.right);
// use getAdjustedCrop(parallax=true) to make sure we don't exceed MAX_PARALLAX
- res = getAdjustedCrop(res, bitmapSize, displaySize, true, ADD);
+ res = getAdjustedCrop(res, bitmapSize, displaySize, true, rtl, ADD);
}
return res;
}
@@ -220,7 +220,7 @@
if (suggestedCrop != null) {
// only keep the visible part (without parallax)
Rect adjustedCrop = noParallax(suggestedCrop, suggestedDisplaySize, bitmapSize, rtl);
- return getAdjustedCrop(adjustedCrop, bitmapSize, displaySize, false, ADD);
+ return getAdjustedCrop(adjustedCrop, bitmapSize, displaySize, false, rtl, ADD);
}
// Case 6: for a foldable device, try to combine case 3 + case 4 or 5:
@@ -255,7 +255,7 @@
@VisibleForTesting
static Rect noParallax(Rect crop, Point displaySize, Point bitmapSize, boolean rtl) {
if (displaySize == null) return crop;
- Rect adjustedCrop = getAdjustedCrop(crop, bitmapSize, displaySize, true, ADD);
+ Rect adjustedCrop = getAdjustedCrop(crop, bitmapSize, displaySize, true, rtl, ADD);
// only keep the visible part (without parallax)
float suggestedDisplayRatio = 1f * displaySize.x / displaySize.y;
int widthToRemove = (int) (adjustedCrop.width()
@@ -272,7 +272,7 @@
* Adjust a given crop:
* <ul>
* <li>If parallax = true, make sure we have a parallax of at most {@link #MAX_PARALLAX},
- * by removing content from both sides if necessary.
+ * by removing content from the right (or left if RTL) if necessary.
* <li>If parallax = false, make sure we do not have additional width for parallax. If we
* have additional width for parallax, remove half of the additional width on both sides.
* <li>Make sure the crop fills the screen, i.e. that the width/height ratio of the crop
@@ -282,7 +282,7 @@
*/
@VisibleForTesting
static Rect getAdjustedCrop(Rect crop, Point bitmapSize, Point screenSize,
- boolean parallax, int mode) {
+ boolean parallax, boolean rtl, int mode) {
Rect adjustedCrop = new Rect(crop);
float cropRatio = ((float) crop.width()) / crop.height();
float screenRatio = ((float) screenSize.x) / screenSize.y;
@@ -297,7 +297,8 @@
Rect rotatedCrop = new Rect(newLeft, newTop, newRight, newBottom);
Point rotatedBitmap = new Point(bitmapSize.y, bitmapSize.x);
Point rotatedScreen = new Point(screenSize.y, screenSize.x);
- Rect rect = getAdjustedCrop(rotatedCrop, rotatedBitmap, rotatedScreen, false, mode);
+ Rect rect = getAdjustedCrop(
+ rotatedCrop, rotatedBitmap, rotatedScreen, false, rtl, mode);
int resultLeft = rect.top;
int resultRight = resultLeft + rect.height();
int resultTop = rotatedBitmap.x - rect.right;
@@ -308,8 +309,11 @@
if (additionalWidthForParallax > MAX_PARALLAX) {
int widthToRemove = (int) Math.ceil(
(additionalWidthForParallax - MAX_PARALLAX) * screenRatio * crop.height());
- adjustedCrop.left += widthToRemove / 2;
- adjustedCrop.right -= widthToRemove / 2 + widthToRemove % 2;
+ if (rtl) {
+ adjustedCrop.left += widthToRemove;
+ } else {
+ adjustedCrop.right -= widthToRemove;
+ }
}
} else {
// Note: the third case when MODE == BALANCE, -W + sqrt(W * H * R), is the width to add
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index fec1af4..d9e14340 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -661,7 +661,8 @@
*/
private CompatDisplayInsets mCompatDisplayInsets;
- private final TaskFragment.ConfigOverrideHint mResolveConfigHint;
+ @VisibleForTesting
+ final TaskFragment.ConfigOverrideHint mResolveConfigHint;
private final boolean mOptOutEdgeToEdge;
@@ -8533,6 +8534,8 @@
mIsEligibleForFixedOrientationLetterbox = false;
mLetterboxBoundsForFixedOrientationAndAspectRatio = null;
mLetterboxBoundsForAspectRatio = null;
+ mResolveConfigHint.resolveTmpOverrides(mDisplayContent, newParentConfiguration,
+ isFixedRotationTransforming());
// Can't use resolvedConfig.windowConfiguration.getWindowingMode() because it can be
// different from windowing mode of the task (PiP) during transition from fullscreen to PiP
@@ -8647,10 +8650,15 @@
}
applySizeOverrideIfNeeded(newParentConfiguration, parentWindowingMode, resolvedConfig);
+ mResolveConfigHint.resetTmpOverrides();
logAppCompatState();
}
+ @Nullable Rect getParentAppBoundsOverride() {
+ return Rect.copyOrNull(mResolveConfigHint.mTmpParentAppBoundsOverride);
+ }
+
/**
* If necessary, override configuration fields related to app bounds.
* This will happen when the app is targeting SDK earlier than 35.
@@ -8674,8 +8682,8 @@
rotation = mDisplayContent.getRotation();
}
if (!mOptOutEdgeToEdge && (!mResolveConfigHint.mUseOverrideInsetsForConfig
- || getCompatDisplayInsets() != null || shouldCreateCompatDisplayInsets()
- || isFloating(parentWindowingMode) || rotation == ROTATION_UNDEFINED)) {
+ || getCompatDisplayInsets() != null || isFloating(parentWindowingMode)
+ || rotation == ROTATION_UNDEFINED)) {
// If the insets configuration decoupled logic is not enabled for the app, or the app
// already has a compat override, or the context doesn't contain enough info to
// calculate the override, skip the override.
@@ -8697,7 +8705,7 @@
: mDisplayContent.mBaseDisplayWidth;
final int dh = rotated ? mDisplayContent.mBaseDisplayWidth
: mDisplayContent.mBaseDisplayHeight;
- final Rect nonDecorInsets = mDisplayContent.getDisplayPolicy()
+ final Rect nonDecorInsets = mDisplayContent.getDisplayPolicy()
.getDecorInsetsInfo(rotation, dw, dh).mOverrideNonDecorInsets;
// This should be the only place override the configuration for ActivityRecord. Override
// the value if not calculated yet.
@@ -8713,12 +8721,10 @@
}
density *= DisplayMetrics.DENSITY_DEFAULT_SCALE;
if (inOutConfig.screenWidthDp == Configuration.SCREEN_WIDTH_DP_UNDEFINED) {
- final int overrideScreenWidthDp = (int) (outAppBounds.width() / density + 0.5f);
- inOutConfig.screenWidthDp = overrideScreenWidthDp;
+ inOutConfig.screenWidthDp = (int) (outAppBounds.width() / density + 0.5f);
}
if (inOutConfig.screenHeightDp == Configuration.SCREEN_HEIGHT_DP_UNDEFINED) {
- final int overrideScreenHeightDp = (int) (outAppBounds.height() / density + 0.5f);
- inOutConfig.screenHeightDp = overrideScreenHeightDp;
+ inOutConfig.screenHeightDp = (int) (outAppBounds.height() / density + 0.5f);
}
if (inOutConfig.smallestScreenWidthDp
== Configuration.SMALLEST_SCREEN_WIDTH_DP_UNDEFINED
@@ -8829,7 +8835,7 @@
}
final Rect screenResolvedBounds =
mSizeCompatBounds != null ? mSizeCompatBounds : resolvedBounds;
- final Rect parentAppBounds = newParentConfiguration.windowConfiguration.getAppBounds();
+ final Rect parentAppBounds = mResolveConfigHint.mTmpParentAppBoundsOverride;
final Rect parentBounds = newParentConfiguration.windowConfiguration.getBounds();
final float screenResolvedBoundsWidth = screenResolvedBounds.width();
final float parentAppBoundsWidth = parentAppBounds.width();
@@ -9238,7 +9244,7 @@
*/
private void resolveAspectRatioRestriction(Configuration newParentConfiguration) {
final Configuration resolvedConfig = getResolvedOverrideConfiguration();
- final Rect parentAppBounds = newParentConfiguration.windowConfiguration.getAppBounds();
+ final Rect parentAppBounds = mResolveConfigHint.mTmpParentAppBoundsOverride;
final Rect parentBounds = newParentConfiguration.windowConfiguration.getBounds();
final Rect resolvedBounds = resolvedConfig.windowConfiguration.getBounds();
// Use tmp bounds to calculate aspect ratio so we can know whether the activity should use
@@ -9267,19 +9273,6 @@
@NonNull CompatDisplayInsets compatDisplayInsets) {
final Configuration resolvedConfig = getResolvedOverrideConfiguration();
final Rect resolvedBounds = resolvedConfig.windowConfiguration.getBounds();
- final Insets insets;
- if (mResolveConfigHint.mUseOverrideInsetsForConfig) {
- // TODO(b/343197837): Add test to verify SCM behaviour with new bound configuration
- // Insets are decoupled from configuration by default from V+, use legacy
- // compatibility behaviour for apps targeting SDK earlier than 35
- // (see applySizeOverrideIfNeeded).
- insets = Insets.of(mDisplayContent.getDisplayPolicy()
- .getDecorInsetsInfo(mDisplayContent.mDisplayFrames.mRotation,
- mDisplayContent.mDisplayFrames.mWidth,
- mDisplayContent.mDisplayFrames.mHeight).mOverrideNonDecorInsets);
- } else {
- insets = Insets.NONE;
- }
// When an activity needs to be letterboxed because of fixed orientation, use fixed
// orientation bounds (stored in resolved bounds) instead of parent bounds since the
@@ -9290,22 +9283,22 @@
final Rect containerBounds = useResolvedBounds
? new Rect(resolvedBounds)
: newParentConfiguration.windowConfiguration.getBounds();
- final Rect parentAppBounds =
- newParentConfiguration.windowConfiguration.getAppBounds();
- parentAppBounds.inset(insets);
final Rect containerAppBounds = useResolvedBounds
? new Rect(resolvedConfig.windowConfiguration.getAppBounds())
- : parentAppBounds;
+ : mResolveConfigHint.mTmpParentAppBoundsOverride;
final int requestedOrientation = getRequestedConfigurationOrientation();
final boolean orientationRequested = requestedOrientation != ORIENTATION_UNDEFINED;
+ final int parentOrientation = mResolveConfigHint.mUseOverrideInsetsForConfig
+ ? mResolveConfigHint.mTmpOverrideConfigOrientation
+ : newParentConfiguration.orientation;
final int orientation = orientationRequested
? requestedOrientation
// We should use the original orientation of the activity when possible to avoid
// forcing the activity in the opposite orientation.
: compatDisplayInsets.mOriginalRequestedOrientation != ORIENTATION_UNDEFINED
? compatDisplayInsets.mOriginalRequestedOrientation
- : newParentConfiguration.orientation;
+ : parentOrientation;
int rotation = newParentConfiguration.windowConfiguration.getRotation();
final boolean isFixedToUserRotation = mDisplayContent == null
|| mDisplayContent.getDisplayRotation().isFixedToUserRotation();
@@ -9347,7 +9340,7 @@
// Use parent orientation if it cannot be decided by bounds, so the activity can fit inside
// the parent bounds appropriately.
if (resolvedConfig.screenWidthDp == resolvedConfig.screenHeightDp) {
- resolvedConfig.orientation = newParentConfiguration.orientation;
+ resolvedConfig.orientation = parentOrientation;
}
// Below figure is an example that puts an activity which was launched in a larger container
diff --git a/services/core/java/com/android/server/wm/BackgroundActivityStartController.java b/services/core/java/com/android/server/wm/BackgroundActivityStartController.java
index 19d7a3c..a4fb959 100644
--- a/services/core/java/com/android/server/wm/BackgroundActivityStartController.java
+++ b/services/core/java/com/android/server/wm/BackgroundActivityStartController.java
@@ -427,19 +427,6 @@
return name + "[debugOnly]";
}
- /** @return valid targetSdk or <code>-1</code> */
- private int getTargetSdk(String packageName) {
- if (packageName == null) {
- return -1;
- }
- try {
- PackageManager pm = mService.mContext.getPackageManager();
- return pm.getTargetSdkVersion(packageName);
- } catch (Exception e) {
- return -1;
- }
- }
-
private boolean hasRealCaller() {
return mRealCallingUid != NO_PROCESS_UID;
}
@@ -1730,7 +1717,9 @@
state.mResultForRealCaller == null ? BAL_BLOCK
: state.mResultForRealCaller.getRawCode(),
state.mBalAllowedByPiSender.allowsBackgroundActivityStarts(),
- state.realCallerExplicitOptInOrOut()
+ state.realCallerExplicitOptInOrOut(),
+ getTargetSdk(state.mCallingPackage),
+ getTargetSdk(state.mRealCallingPackage)
);
}
@@ -1811,6 +1800,19 @@
+ ", taskFragment=" + ar.getTaskFragment();
}
+ /** @return valid targetSdk or <code>-1</code> */
+ private int getTargetSdk(String packageName) {
+ if (packageName == null) {
+ return -1;
+ }
+ try {
+ PackageManager pm = mService.mContext.getPackageManager();
+ return pm.getTargetSdkVersion(packageName);
+ } catch (Exception e) {
+ return -1;
+ }
+ }
+
private class FinishedActivityEntry {
int mUid;
int mTaskId;
diff --git a/services/core/java/com/android/server/wm/LetterboxUiController.java b/services/core/java/com/android/server/wm/LetterboxUiController.java
index 194771f..5e93e89 100644
--- a/services/core/java/com/android/server/wm/LetterboxUiController.java
+++ b/services/core/java/com/android/server/wm/LetterboxUiController.java
@@ -1288,6 +1288,9 @@
if (!allowHorizontalReachabilityForThinLetterbox()) {
return false;
}
+ final Rect parentAppBoundsOverride = mActivityRecord.getParentAppBoundsOverride();
+ final Rect parentAppBounds = parentAppBoundsOverride != null
+ ? parentAppBoundsOverride : parentConfiguration.windowConfiguration.getAppBounds();
// Use screen resolved bounds which uses resolved bounds or size compat bounds
// as activity bounds can sometimes be empty
final Rect opaqueActivityBounds = mActivityRecord.mTransparentPolicy
@@ -1297,10 +1300,8 @@
&& parentConfiguration.windowConfiguration.getWindowingMode()
== WINDOWING_MODE_FULLSCREEN
// Check whether the activity fills the parent vertically.
- && parentConfiguration.windowConfiguration.getAppBounds().height()
- <= opaqueActivityBounds.height()
- && parentConfiguration.windowConfiguration.getAppBounds().width()
- > opaqueActivityBounds.width();
+ && parentAppBounds.height() <= opaqueActivityBounds.height()
+ && parentAppBounds.width() > opaqueActivityBounds.width();
}
@VisibleForTesting
@@ -1326,6 +1327,9 @@
if (!allowVerticalReachabilityForThinLetterbox()) {
return false;
}
+ final Rect parentAppBoundsOverride = mActivityRecord.getParentAppBoundsOverride();
+ final Rect parentAppBounds = parentAppBoundsOverride != null
+ ? parentAppBoundsOverride : parentConfiguration.windowConfiguration.getAppBounds();
// Use screen resolved bounds which uses resolved bounds or size compat bounds
// as activity bounds can sometimes be empty.
final Rect opaqueActivityBounds = mActivityRecord.mTransparentPolicy
@@ -1335,10 +1339,8 @@
&& parentConfiguration.windowConfiguration.getWindowingMode()
== WINDOWING_MODE_FULLSCREEN
// Check whether the activity fills the parent horizontally.
- && parentConfiguration.windowConfiguration.getAppBounds().width()
- <= opaqueActivityBounds.width()
- && parentConfiguration.windowConfiguration.getAppBounds().height()
- > opaqueActivityBounds.height();
+ && parentAppBounds.width() <= opaqueActivityBounds.width()
+ && parentAppBounds.height() > opaqueActivityBounds.height();
}
@VisibleForTesting
diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java
index b8b746a..187b105 100644
--- a/services/core/java/com/android/server/wm/TaskFragment.java
+++ b/services/core/java/com/android/server/wm/TaskFragment.java
@@ -40,6 +40,8 @@
import static android.os.Process.SYSTEM_UID;
import static android.os.UserHandle.USER_NULL;
import static android.view.Display.INVALID_DISPLAY;
+import static android.view.Surface.ROTATION_270;
+import static android.view.Surface.ROTATION_90;
import static android.view.WindowManager.LayoutParams.FLAG_DIM_BEHIND;
import static android.view.WindowManager.TRANSIT_CLOSE;
import static android.view.WindowManager.TRANSIT_FLAG_OPEN_BEHIND;
@@ -87,6 +89,7 @@
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
+import android.graphics.Insets;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.IBinder;
@@ -2225,7 +2228,43 @@
static class ConfigOverrideHint {
@Nullable DisplayInfo mTmpOverrideDisplayInfo;
@Nullable ActivityRecord.CompatDisplayInsets mTmpCompatInsets;
+ @Nullable Rect mTmpParentAppBoundsOverride;
+ int mTmpOverrideConfigOrientation;
boolean mUseOverrideInsetsForConfig;
+
+ void resolveTmpOverrides(DisplayContent dc, Configuration parentConfig,
+ boolean isFixedRotationTransforming) {
+ mTmpParentAppBoundsOverride = new Rect(parentConfig.windowConfiguration.getAppBounds());
+ final Insets insets;
+ if (mUseOverrideInsetsForConfig && dc != null) {
+ // Insets are decoupled from configuration by default from V+, use legacy
+ // compatibility behaviour for apps targeting SDK earlier than 35
+ // (see applySizeOverrideIfNeeded).
+ int rotation = parentConfig.windowConfiguration.getRotation();
+ if (rotation == ROTATION_UNDEFINED && !isFixedRotationTransforming) {
+ rotation = dc.getRotation();
+ }
+ final boolean rotated = (rotation == ROTATION_90 || rotation == ROTATION_270);
+ final int dw = rotated ? dc.mBaseDisplayHeight : dc.mBaseDisplayWidth;
+ final int dh = rotated ? dc.mBaseDisplayWidth : dc.mBaseDisplayHeight;
+ DisplayPolicy.DecorInsets.Info decorInsets = dc.getDisplayPolicy()
+ .getDecorInsetsInfo(rotation, dw, dh);
+ final Rect stableBounds = decorInsets.mOverrideConfigFrame;
+ mTmpOverrideConfigOrientation = stableBounds.width() > stableBounds.height()
+ ? ORIENTATION_LANDSCAPE : ORIENTATION_PORTRAIT;
+ insets = Insets.of(decorInsets.mOverrideNonDecorInsets);
+ } else {
+ insets = Insets.NONE;
+ }
+ mTmpParentAppBoundsOverride.inset(insets);
+ }
+
+ void resetTmpOverrides() {
+ mTmpOverrideDisplayInfo = null;
+ mTmpCompatInsets = null;
+ mTmpParentAppBoundsOverride = null;
+ mTmpOverrideConfigOrientation = ORIENTATION_UNDEFINED;
+ }
}
void computeConfigResourceOverrides(@NonNull Configuration inOutConfig,
@@ -2311,7 +2350,9 @@
if (!customContainerPolicy && windowingMode != WINDOWING_MODE_FREEFORM) {
final Rect containingAppBounds;
if (insideParentBounds) {
- containingAppBounds = parentConfig.windowConfiguration.getAppBounds();
+ containingAppBounds = useOverrideInsetsForConfig
+ ? overrideHint.mTmpParentAppBoundsOverride
+ : parentConfig.windowConfiguration.getAppBounds();
} else {
// Restrict appBounds to display non-decor rather than parent because the
// override bounds are beyond the parent. Otherwise, it won't match the
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index edbba92..70143ba 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -1077,9 +1077,6 @@
if (dc != null && dc != this) {
dc.getPendingTransaction().merge(mPendingTransaction);
}
- if (dc != this && mLocalInsetsSources != null) {
- mLocalInsetsSources.clear();
- }
for (int i = mChildren.size() - 1; i >= 0; --i) {
final WindowContainer child = mChildren.get(i);
child.onDisplayChanged(dc);
diff --git a/services/core/jni/com_android_server_vibrator_VibratorController.cpp b/services/core/jni/com_android_server_vibrator_VibratorController.cpp
index f47a59d..4be21d8 100644
--- a/services/core/jni/com_android_server_vibrator_VibratorController.cpp
+++ b/services/core/jni/com_android_server_vibrator_VibratorController.cpp
@@ -131,17 +131,28 @@
}
std::function<void()> createCallback(jlong vibrationId) {
- return [vibrationId, this]() {
+ auto callbackId = ++mCallbackId;
+ return [vibrationId, callbackId, this]() {
+ auto currentCallbackId = mCallbackId.load();
+ if (currentCallbackId != callbackId) {
+ // This callback is from an older HAL call that is no longer relevant to the service
+ return;
+ }
auto jniEnv = GetOrAttachJNIEnvironment(sJvm);
jniEnv->CallVoidMethod(mCallbackListener, sMethodIdOnComplete, mVibratorId,
vibrationId);
};
}
+ void disableOldCallbacks() {
+ mCallbackId++;
+ }
+
private:
const std::shared_ptr<vibrator::HalController> mHal;
const int32_t mVibratorId;
const jobject mCallbackListener;
+ std::atomic<int64_t> mCallbackId;
};
static aidl::BrakingPwle brakingPwle(aidl::Braking braking, int32_t duration) {
@@ -236,6 +247,7 @@
}
auto offFn = [](vibrator::HalWrapper* hal) { return hal->off(); };
wrapper->halCall<void>(offFn, "off");
+ wrapper->disableOldCallbacks();
}
static void vibratorSetAmplitude(JNIEnv* env, jclass /* clazz */, jlong ptr, jfloat amplitude) {
diff --git a/services/core/xsd/display-device-config/display-device-config.xsd b/services/core/xsd/display-device-config/display-device-config.xsd
index 610b502..eeb8b9b 100644
--- a/services/core/xsd/display-device-config/display-device-config.xsd
+++ b/services/core/xsd/display-device-config/display-device-config.xsd
@@ -779,6 +779,21 @@
</xs:complexType>
<xs:complexType name="blockingZoneConfig">
+ <!-- list of supported modes for blocking zone . Each point corresponds to one mode.
+ Supported only for lowerBlockingZoneConfigs
+ Mode format is : first = refreshRate, second = vsyncRate. E.g. :
+ <supportedModes>
+ <point>
+ <first>60</first> // refreshRate
+ <second>60</second> //vsyncRate
+ </point>
+ ....
+ </supportedModes>
+ -->
+ <xs:element type="nonNegativeFloatToFloatMap" name="supportedModes" minOccurs="0">
+ <xs:annotation name="nullable"/>
+ <xs:annotation name="final"/>
+ </xs:element>
<xs:element name="defaultRefreshRate" type="xs:nonNegativeInteger"
minOccurs="1" maxOccurs="1">
<xs:annotation name="final"/>
diff --git a/services/core/xsd/display-device-config/schema/current.txt b/services/core/xsd/display-device-config/schema/current.txt
index 203a6d9..757b23a 100644
--- a/services/core/xsd/display-device-config/schema/current.txt
+++ b/services/core/xsd/display-device-config/schema/current.txt
@@ -35,9 +35,11 @@
method public final com.android.server.display.config.BlockingZoneThreshold getBlockingZoneThreshold();
method public final java.math.BigInteger getDefaultRefreshRate();
method @Nullable public final String getRefreshRateThermalThrottlingId();
+ method @Nullable public final com.android.server.display.config.NonNegativeFloatToFloatMap getSupportedModes();
method public final void setBlockingZoneThreshold(com.android.server.display.config.BlockingZoneThreshold);
method public final void setDefaultRefreshRate(java.math.BigInteger);
method public final void setRefreshRateThermalThrottlingId(@Nullable String);
+ method public final void setSupportedModes(@Nullable com.android.server.display.config.NonNegativeFloatToFloatMap);
}
public class BlockingZoneThreshold {
diff --git a/services/permission/java/com/android/server/permission/access/appop/AppOpService.kt b/services/permission/java/com/android/server/permission/access/appop/AppOpService.kt
index 3bdcd9b..161a816 100644
--- a/services/permission/java/com/android/server/permission/access/appop/AppOpService.kt
+++ b/services/permission/java/com/android/server/permission/access/appop/AppOpService.kt
@@ -246,24 +246,32 @@
}
override fun setUidMode(uid: Int, deviceId: String, code: Int, mode: Int): Boolean {
- if (
- Flags.runtimePermissionAppopsMappingEnabled() && code in runtimeAppOpToPermissionNames
- ) {
- Slog.w(
- LOG_TAG,
- "Cannot set UID mode for runtime permission app op, " +
- " callingUid = ${Binder.getCallingUid()}, " +
- " uid = $uid," +
- " code = ${AppOpsManager.opToName(code)}," +
- " mode = ${AppOpsManager.modeToName(mode)}",
- RuntimeException()
- )
- return false
- }
-
val appId = UserHandle.getAppId(uid)
val userId = UserHandle.getUserId(uid)
val appOpName = AppOpsManager.opToPublicName(code)
+
+ if (
+ Flags.runtimePermissionAppopsMappingEnabled() && code in runtimeAppOpToPermissionNames
+ ) {
+ val oldMode =
+ service.getState { with(appIdPolicy) { getAppOpMode(appId, userId, appOpName) } }
+ val wouldHaveChanged = oldMode != mode
+ val logMessage =
+ (if (wouldHaveChanged) "Blocked" else "Ignored") +
+ " setUidMode call for runtime permission app op:" +
+ " uid = $uid," +
+ " code = ${AppOpsManager.opToName(code)}," +
+ " mode = ${AppOpsManager.modeToName(mode)}," +
+ " callingUid = ${Binder.getCallingUid()}," +
+ " oldMode = ${AppOpsManager.modeToName(oldMode)}"
+ if (wouldHaveChanged) {
+ Slog.e(LOG_TAG, logMessage, RuntimeException())
+ } else {
+ Slog.w(LOG_TAG, logMessage)
+ }
+ return false
+ }
+
var wasChanged: Boolean
service.mutateState {
wasChanged = with(appIdPolicy) { setAppOpMode(appId, userId, appOpName, mode) }
diff --git a/services/tests/InputMethodSystemServerTests/src/com/android/inputmethodservice/AndroidTest.xml b/services/tests/InputMethodSystemServerTests/src/com/android/inputmethodservice/AndroidTest.xml
index 820628c..8e6954b 100644
--- a/services/tests/InputMethodSystemServerTests/src/com/android/inputmethodservice/AndroidTest.xml
+++ b/services/tests/InputMethodSystemServerTests/src/com/android/inputmethodservice/AndroidTest.xml
@@ -25,6 +25,12 @@
<option name="test-file-name" value="FrameworksImeTests.apk" />
</target_preparer>
+ <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
+ <option name="run-command" value="input keyevent KEYCODE_WAKEUP" />
+ <option name="run-command" value="wm dismiss-keyguard" />
+ <option name="run-command" value="settings put secure immersive_mode_confirmations confirmed" />
+ </target_preparer>
+
<option name="test-tag" value="FrameworksImeTests" />
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
diff --git a/services/tests/InputMethodSystemServerTests/src/com/android/inputmethodservice/InputMethodServiceTest.java b/services/tests/InputMethodSystemServerTests/src/com/android/inputmethodservice/InputMethodServiceTest.java
index 1535298..2029b71 100644
--- a/services/tests/InputMethodSystemServerTests/src/com/android/inputmethodservice/InputMethodServiceTest.java
+++ b/services/tests/InputMethodSystemServerTests/src/com/android/inputmethodservice/InputMethodServiceTest.java
@@ -48,6 +48,7 @@
import com.android.apps.inputmethod.simpleime.ims.InputMethodServiceWrapper;
import com.android.apps.inputmethod.simpleime.testing.TestActivity;
+import com.android.compatibility.common.util.SystemUtil;
import com.android.internal.inputmethod.InputMethodNavButtonFlags;
import org.junit.After;
@@ -834,8 +835,7 @@
private String executeShellCommand(String cmd) throws IOException {
Log.i(TAG, "Run command: " + cmd);
- return UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
- .executeShellCommand(cmd);
+ return SystemUtil.runShellCommandOrThrow(cmd);
}
private void clickOnEditorText() {
diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceConfigTest.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceConfigTest.java
index 46d08b0..9a25b1a 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceConfigTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceConfigTest.java
@@ -948,6 +948,22 @@
assertThat(supportedModeData.vsyncRate).isEqualTo(120);
}
+ @Test
+ public void testLowLightBlockingZoneSupportedModesFromConfigFile() throws IOException {
+ setupDisplayDeviceConfigFromDisplayConfigFile();
+
+ RefreshRateData refreshRateData = mDisplayDeviceConfig.getRefreshRateData();
+ assertNotNull(refreshRateData);
+ assertThat(refreshRateData.lowLightBlockingZoneSupportedModes).hasSize(2);
+ SupportedModeData supportedModeData =
+ refreshRateData.lowLightBlockingZoneSupportedModes.get(0);
+ assertThat(supportedModeData.refreshRate).isEqualTo(60);
+ assertThat(supportedModeData.vsyncRate).isEqualTo(60);
+ supportedModeData = refreshRateData.lowLightBlockingZoneSupportedModes.get(1);
+ assertThat(supportedModeData.refreshRate).isEqualTo(240);
+ assertThat(supportedModeData.vsyncRate).isEqualTo(240);
+ }
+
private String getValidLuxThrottling() {
return "<luxThrottling>\n"
+ " <brightnessLimitMap>\n"
@@ -1117,6 +1133,19 @@
+ "</lowPowerSupportedModes>\n";
}
+ private String getLowLightVrrSupportedModesConfig() {
+ return "<supportedModes>\n"
+ + " <point>\n"
+ + " <first>60</first>\n"
+ + " <second>60</second>\n"
+ + " </point>\n"
+ + " <point>\n"
+ + " <first>240</first>\n"
+ + " <second>240</second>\n"
+ + " </point>\n"
+ + "</supportedModes>\n";
+ }
+
private String getHdrBrightnessConfig() {
return "<hdrBrightnessConfig>\n"
+ " <brightnessMap>\n"
@@ -1624,6 +1653,7 @@
+ "<nits>-1</nits>\n"
+ "</displayBrightnessPoint>\n"
+ "</blockingZoneThreshold>\n"
+ + getLowLightVrrSupportedModesConfig()
+ "</lowerBlockingZoneConfigs>\n"
+ "<higherBlockingZoneConfigs>\n"
+ "<defaultRefreshRate>90</defaultRefreshRate>\n"
diff --git a/services/tests/displayservicetests/src/com/android/server/display/mode/BrightnessObserverTest.kt b/services/tests/displayservicetests/src/com/android/server/display/mode/BrightnessObserverTest.kt
index 88c0daa..95702aa 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/mode/BrightnessObserverTest.kt
+++ b/services/tests/displayservicetests/src/com/android/server/display/mode/BrightnessObserverTest.kt
@@ -19,11 +19,12 @@
import android.content.Context
import android.content.ContextWrapper
import android.hardware.display.BrightnessInfo
-import android.util.SparseArray
import android.view.Display
import androidx.test.core.app.ApplicationProvider
import androidx.test.filters.SmallTest
import com.android.server.display.DisplayDeviceConfig
+import com.android.server.display.config.RefreshRateData
+import com.android.server.display.config.SupportedModeData
import com.android.server.display.feature.DisplayManagerFlags
import com.android.server.display.mode.DisplayModeDirector.DisplayDeviceConfigProvider
import com.android.server.testutils.TestHandler
@@ -39,6 +40,13 @@
import org.mockito.kotlin.mock
import org.mockito.kotlin.whenever
+private val LOW_LIGHT_REFRESH_RATE_DATA = createRefreshRateData(
+ lowLightBlockingZoneSupportedModes = listOf(
+ SupportedModeData(60f, 60f), SupportedModeData(240f, 240f)))
+private val EXPECTED_SUPPORTED_MODES_VOTE = SupportedRefreshRatesVote(
+ listOf(SupportedRefreshRatesVote.RefreshRates(60f, 60f),
+ SupportedRefreshRatesVote.RefreshRates(240f, 240f)))
+
@SmallTest
@RunWith(TestParameterInjector::class)
class BrightnessObserverTest {
@@ -65,21 +73,25 @@
whenever(mockFlags.isVsyncLowLightVoteEnabled).thenReturn(testCase.vsyncLowLightVoteEnabled)
val displayModeDirector = DisplayModeDirector(
spyContext, testHandler, mockInjector, mockFlags, mockDisplayDeviceConfigProvider)
- val ddcByDisplay = SparseArray<DisplayDeviceConfig>()
whenever(mockDeviceConfig.isVrrSupportEnabled).thenReturn(testCase.vrrSupported)
- ddcByDisplay.put(Display.DEFAULT_DISPLAY, mockDeviceConfig)
- displayModeDirector.injectDisplayDeviceConfigByDisplay(ddcByDisplay)
+ whenever(mockDeviceConfig.refreshRateData).thenReturn(testCase.refreshRateData)
+ whenever(mockDeviceConfig.defaultLowBlockingZoneRefreshRate).thenReturn(-1)
+
+ displayModeDirector.defaultDisplayDeviceUpdated(mockDeviceConfig)
+
val brightnessObserver = displayModeDirector.BrightnessObserver(
spyContext, testHandler, mockInjector, mockFlags)
-
+ // set mRefreshRateChangeable to true
brightnessObserver.onRefreshRateSettingChangedLocked(0.0f, 120.0f)
brightnessObserver.updateBlockingZoneThresholds(mockDeviceConfig, false)
- brightnessObserver.onDeviceConfigRefreshRateInLowZoneChanged(60)
+ brightnessObserver.onDeviceConfigRefreshRateInLowZoneChanged(testCase.refreshRateInLowZone)
brightnessObserver.onDisplayChanged(Display.DEFAULT_DISPLAY)
assertThat(displayModeDirector.getVote(VotesStorage.GLOBAL_ID,
- Vote.PRIORITY_FLICKER_REFRESH_RATE_SWITCH)).isEqualTo(testCase.expectedVote)
+ Vote.PRIORITY_FLICKER_REFRESH_RATE)).isEqualTo(testCase.expectedRefreshRateVote)
+ assertThat(displayModeDirector.getVote(VotesStorage.GLOBAL_ID,
+ Vote.PRIORITY_FLICKER_REFRESH_RATE_SWITCH)).isEqualTo(testCase.expectedSwitchVote)
}
private fun setUpLowBrightnessZone() {
@@ -98,14 +110,20 @@
enum class LowLightTestCase(
val vrrSupported: Boolean,
val vsyncLowLightVoteEnabled: Boolean,
- internal val expectedVote: Vote
+ val refreshRateData: RefreshRateData,
+ val refreshRateInLowZone: Int,
+ internal val expectedRefreshRateVote: Vote,
+ internal val expectedSwitchVote: Vote?,
) {
- ALL_ENABLED(true, true, CombinedVote(
- listOf(DisableRefreshRateSwitchingVote(true),
- SupportedRefreshRatesVote(
- listOf(SupportedRefreshRatesVote.RefreshRates(60f, 60f),
- SupportedRefreshRatesVote.RefreshRates(120f, 120f)))))),
- VRR_NOT_SUPPORTED(false, true, DisableRefreshRateSwitchingVote(true)),
- VSYNC_VOTE_DISABLED(true, false, DisableRefreshRateSwitchingVote(true))
+ ALL_ENABLED(true, true, LOW_LIGHT_REFRESH_RATE_DATA, 60,
+ EXPECTED_SUPPORTED_MODES_VOTE, null),
+ ALL_ENABLED_NO_RR_IN_LOW_ZONE(true, true, LOW_LIGHT_REFRESH_RATE_DATA, 0,
+ EXPECTED_SUPPORTED_MODES_VOTE, null),
+ VRR_NOT_SUPPORTED(false, true, LOW_LIGHT_REFRESH_RATE_DATA, 60,
+ Vote.forPhysicalRefreshRates(60f, 60f), DisableRefreshRateSwitchingVote(true)),
+ VSYNC_VOTE_DISABLED(true, false, LOW_LIGHT_REFRESH_RATE_DATA, 50,
+ Vote.forPhysicalRefreshRates(50f, 50f), DisableRefreshRateSwitchingVote(true)),
+ NO_LOW_LIGHT_CONFIG(true, true, createRefreshRateData(), 40,
+ Vote.forPhysicalRefreshRates(40f, 40f), DisableRefreshRateSwitchingVote(true)),
}
}
\ No newline at end of file
diff --git a/services/tests/displayservicetests/src/com/android/server/display/mode/DisplayModeDirectorTest.java b/services/tests/displayservicetests/src/com/android/server/display/mode/DisplayModeDirectorTest.java
index 714b423..242d559 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/mode/DisplayModeDirectorTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/mode/DisplayModeDirectorTest.java
@@ -132,7 +132,8 @@
/* defaultPeakRefreshRate= */ 0,
/* defaultRefreshRateInHbmHdr= */ 0,
/* defaultRefreshRateInHbmSunlight= */ 0,
- /* lowPowerSupportedModes =*/ List.of());
+ /* lowPowerSupportedModes= */ List.of(),
+ /* lowLightBlockingZoneSupportedModes= */ List.of());
public static Collection<Object[]> getAppRequestedSizeTestCases() {
var appRequestedSizeTestCases = Arrays.asList(new Object[][] {
@@ -3170,7 +3171,8 @@
/* defaultPeakRefreshRate= */ 65,
/* defaultRefreshRateInHbmHdr= */ 65,
/* defaultRefreshRateInHbmSunlight= */ 75,
- /* lowPowerSupportedModes= */ List.of());
+ /* lowPowerSupportedModes= */ List.of(),
+ /* lowLightBlockingZoneSupportedModes= */ List.of());
when(displayDeviceConfig.getRefreshRateData()).thenReturn(refreshRateData);
when(displayDeviceConfig.getDefaultLowBlockingZoneRefreshRate()).thenReturn(50);
when(displayDeviceConfig.getDefaultHighBlockingZoneRefreshRate()).thenReturn(55);
diff --git a/services/tests/displayservicetests/src/com/android/server/display/mode/TestUtils.kt b/services/tests/displayservicetests/src/com/android/server/display/mode/TestUtils.kt
index 1206e30..5b07166 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/mode/TestUtils.kt
+++ b/services/tests/displayservicetests/src/com/android/server/display/mode/TestUtils.kt
@@ -34,9 +34,10 @@
defaultPeakRefreshRate: Int = 60,
defaultRefreshRateInHbmHdr: Int = 60,
defaultRefreshRateInHbmSunlight: Int = 60,
- lowPowerSupportedModes: List<SupportedModeData> = emptyList()
+ lowPowerSupportedModes: List<SupportedModeData> = emptyList(),
+ lowLightBlockingZoneSupportedModes: List<SupportedModeData> = emptyList()
): RefreshRateData {
return RefreshRateData(defaultRefreshRate, defaultPeakRefreshRate,
defaultRefreshRateInHbmHdr, defaultRefreshRateInHbmSunlight,
- lowPowerSupportedModes)
+ lowPowerSupportedModes, lowLightBlockingZoneSupportedModes)
}
diff --git a/services/tests/mockingservicestests/src/com/android/server/wallpaper/WallpaperCropperTest.java b/services/tests/mockingservicestests/src/com/android/server/wallpaper/WallpaperCropperTest.java
index 1b0a8d2..f1bf86f 100644
--- a/services/tests/mockingservicestests/src/com/android/server/wallpaper/WallpaperCropperTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/wallpaper/WallpaperCropperTest.java
@@ -211,9 +211,11 @@
new Rect(100, 200, bitmapSize.x - 100, bitmapSize.y))) {
for (int mode: ALL_MODES) {
for (boolean parallax: List.of(true, false)) {
- assertThat(WallpaperCropper.getAdjustedCrop(
- crop, bitmapSize, displaySize, parallax, mode))
- .isEqualTo(crop);
+ for (boolean rtl: List.of(true, false)) {
+ assertThat(WallpaperCropper.getAdjustedCrop(
+ crop, bitmapSize, displaySize, parallax, rtl, mode))
+ .isEqualTo(crop);
+ }
}
}
}
@@ -234,8 +236,11 @@
Point expectedCropSize = new Point(expectedWidth, 1000);
for (int mode: ALL_MODES) {
assertThat(WallpaperCropper.getAdjustedCrop(
- crop, bitmapSize, displaySize, true, mode))
- .isEqualTo(centerOf(crop, expectedCropSize));
+ crop, bitmapSize, displaySize, true, false, mode))
+ .isEqualTo(leftOf(crop, expectedCropSize));
+ assertThat(WallpaperCropper.getAdjustedCrop(
+ crop, bitmapSize, displaySize, true, true, mode))
+ .isEqualTo(rightOf(crop, expectedCropSize));
}
}
@@ -254,9 +259,11 @@
Point bitmapSize = new Point(acceptableWidth, 1000);
Rect crop = new Rect(0, 0, bitmapSize.x, bitmapSize.y);
for (int mode : ALL_MODES) {
- assertThat(WallpaperCropper.getAdjustedCrop(
- crop, bitmapSize, displaySize, true, mode))
- .isEqualTo(crop);
+ for (boolean rtl : List.of(false, true)) {
+ assertThat(WallpaperCropper.getAdjustedCrop(
+ crop, bitmapSize, displaySize, true, rtl, mode))
+ .isEqualTo(crop);
+ }
}
}
}
@@ -286,9 +293,11 @@
for (int i = 0; i < crops.size(); i++) {
Rect crop = crops.get(i);
Rect expectedCrop = expectedAdjustedCrops.get(i);
- assertThat(WallpaperCropper.getAdjustedCrop(
- crop, bitmapSize, displaySize, false, WallpaperCropper.ADD))
- .isEqualTo(expectedCrop);
+ for (boolean rtl: List.of(false, true)) {
+ assertThat(WallpaperCropper.getAdjustedCrop(
+ crop, bitmapSize, displaySize, false, rtl, WallpaperCropper.ADD))
+ .isEqualTo(expectedCrop);
+ }
}
}
@@ -309,9 +318,11 @@
Point expectedCropSize = new Point(1000, 1000);
for (Rect crop: crops) {
- assertThat(WallpaperCropper.getAdjustedCrop(
- crop, bitmapSize, displaySize, false, WallpaperCropper.REMOVE))
- .isEqualTo(centerOf(crop, expectedCropSize));
+ for (boolean rtl : List.of(false, true)) {
+ assertThat(WallpaperCropper.getAdjustedCrop(
+ crop, bitmapSize, displaySize, false, rtl, WallpaperCropper.REMOVE))
+ .isEqualTo(centerOf(crop, expectedCropSize));
+ }
}
}
@@ -338,14 +349,14 @@
Rect crop = crops.get(i);
Rect expected = expectedAdjustedCrops.get(i);
assertThat(WallpaperCropper.getAdjustedCrop(
- crop, bitmapSize, displaySize, false, WallpaperCropper.BALANCE))
+ crop, bitmapSize, displaySize, false, false, WallpaperCropper.BALANCE))
.isEqualTo(expected);
Rect transposedCrop = new Rect(crop.top, crop.left, crop.bottom, crop.right);
Rect expectedTransposed = new Rect(
expected.top, expected.left, expected.bottom, expected.right);
assertThat(WallpaperCropper.getAdjustedCrop(transposedCrop, bitmapSize,
- transposedDisplaySize, false, WallpaperCropper.BALANCE))
+ transposedDisplaySize, false, false, WallpaperCropper.BALANCE))
.isEqualTo(expectedTransposed);
}
}
@@ -376,9 +387,11 @@
Point displaySize = displaySizes.get(i);
Point expectedCropSize = expectedCropSizes.get(i);
for (boolean rtl : List.of(false, true)) {
+ Rect expectedCrop = rtl ? rightOf(bitmapRect, expectedCropSize)
+ : leftOf(bitmapRect, expectedCropSize);
assertThat(mWallpaperCropper.getCrop(
displaySize, bitmapSize, suggestedCrops, rtl))
- .isEqualTo(centerOf(bitmapRect, expectedCropSize));
+ .isEqualTo(expectedCrop);
}
}
}
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsTest.java
index 851cf4a..976cc18 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsTest.java
@@ -91,7 +91,7 @@
final Parcel parcel = Parcel.obtain();
parcel.writeParcelable(outBatteryUsageStats, 0);
- assertThat(parcel.dataSize()).isLessThan(8000);
+ assertThat(parcel.dataSize()).isLessThan(10000);
parcel.setDataPosition(0);
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClientTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClientTest.java
index 40de1b2..182d603 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClientTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClientTest.java
@@ -320,7 +320,7 @@
}
@Test
- public void luxProbeNotEnabledOnStartWhenNotWake() throws RemoteException {
+ public void luxProbeDisabledOnStartWhenNotWake() throws RemoteException {
luxProbeEnabledOnStart(false /* isAwake */);
}
@@ -337,6 +337,7 @@
.getValue().toAidlContext());
verify(mLuxProbe, isAwake ? times(1) : never()).enable();
+ verify(mLuxProbe, isAwake ? never() : times(1)).disable();
}
@Test
diff --git a/services/tests/vibrator/src/com/android/server/vibrator/VibrationThreadTest.java b/services/tests/vibrator/src/com/android/server/vibrator/VibrationThreadTest.java
index 19ce217..9dac23f 100644
--- a/services/tests/vibrator/src/com/android/server/vibrator/VibrationThreadTest.java
+++ b/services/tests/vibrator/src/com/android/server/vibrator/VibrationThreadTest.java
@@ -1681,7 +1681,7 @@
.addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK)
.compose();
VibrationEffect effect4 = VibrationEffect.createOneShot(8000, 100);
- VibrationEffect effect5 = VibrationEffect.createOneShot(20, 222);
+ VibrationEffect effect5 = VibrationEffect.get(VibrationEffect.EFFECT_CLICK);
long vibrationId1 = startThreadAndDispatcher(effect1);
waitForCompletion();
@@ -1745,13 +1745,12 @@
verifyCallbacksTriggered(vibrationId4, Vibration.Status.CANCELLED_BY_SCREEN_OFF);
assertTrue("Tested duration=" + duration4, duration4 < 2000);
- // Effect5: normal oneshot. Don't worry about amplitude, as effect4 may or may not have
- // started.
+ // Effect5: played normally after effect4, which may or may not have played.
verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibrationId5));
verifyCallbacksTriggered(vibrationId5, Vibration.Status.FINISHED);
- assertEquals(Arrays.asList(expectedOneShot(20)),
+ assertEquals(Arrays.asList(expectedPrebaked(VibrationEffect.EFFECT_CLICK)),
fakeVibrator.getEffectSegments(vibrationId5));
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java
index c67d1ec..a39a1a8 100644
--- a/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java
@@ -550,7 +550,7 @@
}).when(appWindow.mSession).setOnBackInvokedCallbackInfo(eq(appWindow.mClient), any());
addToWindowMap(appWindow, true);
- dispatcher.attachToWindow(appWindow.mSession, appWindow.mClient, null, null);
+ dispatcher.attachToWindow(appWindow.mSession, appWindow.mClient, null);
OnBackInvokedCallback appCallback = createBackCallback(appLatch);
diff --git a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
index 7adac5b..1a366b3 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
@@ -105,7 +105,6 @@
import android.os.UserHandle;
import android.platform.test.annotations.EnableFlags;
import android.platform.test.annotations.Presubmit;
-import android.platform.test.annotations.RequiresFlagsDisabled;
import android.provider.DeviceConfig;
import android.provider.DeviceConfig.Properties;
import android.view.InsetsFrameProvider;
@@ -339,10 +338,9 @@
}
}
- // TODO(b/333663877): Enable test after fix
@Test
- @RequiresFlagsDisabled({Flags.FLAG_INSETS_DECOUPLED_CONFIGURATION})
@EnableFlags(Flags.FLAG_IMMERSIVE_APP_REPOSITIONING)
+ @DisableCompatChanges({ActivityInfo.INSETS_DECOUPLED_CONFIGURATION_ENFORCED})
public void testRepositionLandscapeImmersiveAppWithDisplayCutout() {
final int dw = 2100;
final int dh = 2000;
@@ -356,11 +354,14 @@
mWm.mLetterboxConfiguration.setLetterboxVerticalPositionMultiplier(0.5f);
mWm.mLetterboxConfiguration.setIsVerticalReachabilityEnabled(true);
- doReturn(true).when(mActivity).isImmersiveMode(any());
- prepareMinAspectRatio(mActivity, OVERRIDE_MIN_ASPECT_RATIO_LARGE_VALUE,
- SCREEN_ORIENTATION_LANDSCAPE);
- addWindowToActivity(mActivity);
- mActivity.mRootWindowContainer.performSurfacePlacement();
+ final ActivityRecord activity = getActivityBuilderOnSameTask()
+ .setScreenOrientation(SCREEN_ORIENTATION_LANDSCAPE)
+ .setMinAspectRatio(OVERRIDE_MIN_ASPECT_RATIO_LARGE_VALUE)
+ .build();
+
+ doReturn(true).when(activity).isImmersiveMode(any());
+ addWindowToActivity(activity);
+ activity.mRootWindowContainer.performSurfacePlacement();
final Function<ActivityRecord, Rect> innerBoundsOf =
(ActivityRecord a) -> {
@@ -371,22 +372,22 @@
final Consumer<Integer> doubleClick =
(Integer y) -> {
- mActivity.mLetterboxUiController.handleVerticalDoubleTap(y);
- mActivity.mRootWindowContainer.performSurfacePlacement();
+ activity.mLetterboxUiController.handleVerticalDoubleTap(y);
+ activity.mRootWindowContainer.performSurfacePlacement();
};
- final Rect bounds = mActivity.getBounds();
+ final Rect bounds = activity.getBounds();
assertTrue(bounds.top > cutoutHeight && bounds.bottom < dh);
assertEquals(dw, bounds.width());
// Double click bottom.
doubleClick.accept(dh - 10);
- assertEquals(dh, innerBoundsOf.apply(mActivity).bottom);
+ assertEquals(dh, innerBoundsOf.apply(activity).bottom);
// Double click top.
doubleClick.accept(10);
doubleClick.accept(10);
- assertEquals(cutoutHeight, innerBoundsOf.apply(mActivity).top);
+ assertEquals(cutoutHeight, innerBoundsOf.apply(activity).top);
}
@Test
@@ -417,26 +418,25 @@
}
@Test
+ @DisableCompatChanges({ActivityInfo.INSETS_DECOUPLED_CONFIGURATION_ENFORCED})
public void testFixedAspectRatioBoundsWithDecorInSquareDisplay() {
- if (Flags.insetsDecoupledConfiguration()) {
- // TODO (b/151861875): Re-enable it. This is disabled temporarily because the config
- // bounds no longer contains display cutout.
- return;
- }
final int notchHeight = 100;
setUpApp(new TestDisplayContent.Builder(mAtm, 600, 800).setNotch(notchHeight).build());
final Rect displayBounds = mActivity.mDisplayContent.getWindowConfiguration().getBounds();
final float aspectRatio = 1.2f;
- mActivity.info.setMaxAspectRatio(aspectRatio);
- mActivity.info.setMinAspectRatio(aspectRatio);
- prepareUnresizable(mActivity, -1f, SCREEN_ORIENTATION_UNSPECIFIED);
- final Rect appBounds = mActivity.getWindowConfiguration().getAppBounds();
+ final ActivityRecord activity = getActivityBuilderOnSameTask()
+ .setScreenOrientation(SCREEN_ORIENTATION_UNSPECIFIED)
+ .setMinAspectRatio(aspectRatio)
+ .setMaxAspectRatio(aspectRatio)
+ .setResizeMode(RESIZE_MODE_UNRESIZEABLE)
+ .build();
+ final Rect appBounds = activity.getWindowConfiguration().getAppBounds();
// The parent configuration doesn't change since the first resolved configuration, so the
// activity should fit in the parent naturally (size=583x700, appBounds=[9, 100 - 592, 800],
// horizontal offset = round((600 - 583) / 2) = 9)).
- assertFitted();
+ assertFitted(activity);
final int offsetX = (int) ((1f + displayBounds.width() - appBounds.width()) / 2);
// The bounds must be horizontal centered.
assertEquals(offsetX, appBounds.left);
@@ -444,30 +444,30 @@
// Ensure the app bounds keep the declared aspect ratio.
assertEquals(appBounds.height(), appBounds.width() * aspectRatio, 0.5f /* delta */);
// The decor height should be a part of the effective bounds.
- assertEquals(mActivity.getBounds().height(), appBounds.height() + notchHeight);
+ assertEquals(activity.getBounds().height(), appBounds.height() + notchHeight);
// Activity max bounds should be sandboxed; activity is letterboxed due to aspect ratio.
- assertActivityMaxBoundsSandboxed();
+ assertActivityMaxBoundsSandboxed(activity);
// Activity max bounds ignore notch, since an app can be shown past the notch (although app
// is currently limited by the notch).
- assertThat(mActivity.getWindowConfiguration().getMaxBounds().height())
+ assertThat(activity.getWindowConfiguration().getMaxBounds().height())
.isEqualTo(displayBounds.height());
- mActivity.setRequestedOrientation(SCREEN_ORIENTATION_LANDSCAPE);
- assertFitted();
+ activity.setRequestedOrientation(SCREEN_ORIENTATION_LANDSCAPE);
+ assertFitted(activity);
// After the orientation of activity is changed, the display is rotated, the aspect
// ratio should be the same (bounds=[0, 0 - 800, 583], appBounds=[100, 0 - 800, 583]).
assertEquals(appBounds.width(), appBounds.height() * aspectRatio, 0.5f /* delta */);
// Activity max bounds are sandboxed.
- assertActivityMaxBoundsSandboxed();
+ assertActivityMaxBoundsSandboxed(activity);
- mActivity.setRequestedOrientation(SCREEN_ORIENTATION_PORTRAIT);
- assertFitted();
+ activity.setRequestedOrientation(SCREEN_ORIENTATION_PORTRAIT);
+ assertFitted(activity);
// Activity max bounds should be sandboxed; activity is letterboxed due to aspect ratio.
- assertActivityMaxBoundsSandboxed();
+ assertActivityMaxBoundsSandboxed(activity);
// Activity max bounds ignore notch, since an app can be shown past the notch (although app
// is currently limited by the notch).
- assertThat(mActivity.getWindowConfiguration().getMaxBounds().height())
+ assertThat(activity.getWindowConfiguration().getMaxBounds().height())
.isEqualTo(displayBounds.height());
}
@@ -674,12 +674,8 @@
@Test
public void testMoveToDifferentOrientationDisplay() {
- if (Flags.insetsDecoupledConfiguration()) {
- // TODO (b/151861875): Re-enable it. This is disabled temporarily because the config
- // bounds no longer contains display cutout.
- return;
- }
setUpDisplaySizeWithApp(1000, 2500);
+ mActivity.mResolveConfigHint.mUseOverrideInsetsForConfig = true;
prepareUnresizable(mActivity, -1.f /* maxAspect */, SCREEN_ORIENTATION_PORTRAIT);
assertFitted();
@@ -726,16 +722,12 @@
@Test
public void testFixedOrientationRotateCutoutDisplay() {
- if (Flags.insetsDecoupledConfiguration()) {
- // TODO (b/151861875): Re-enable it. This is disabled temporarily because the config
- // bounds no longer contains display cutout.
- return;
- }
// Create a display with a notch/cutout
final int notchHeight = 60;
final int width = 1000;
setUpApp(new TestDisplayContent.Builder(mAtm, width, 2500)
.setNotch(notchHeight).build());
+ mActivity.mResolveConfigHint.mUseOverrideInsetsForConfig = true;
// Bounds=[0, 0 - 1000, 1400], AppBounds=[0, 60 - 1000, 1460].
final float maxAspect = 1.4f;
prepareUnresizable(mActivity, 1.4f /* maxAspect */, SCREEN_ORIENTATION_PORTRAIT);
@@ -1328,12 +1320,8 @@
setUpDisplaySizeWithApp(1000, 1200);
// Create a size compat activity on the same task.
- final ActivityRecord activity = new ActivityBuilder(mAtm)
- .setTask(mTask)
+ final ActivityRecord activity = getActivityBuilderOnSameTask()
.setScreenOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT)
- .setComponent(ComponentName.createRelative(mContext,
- SizeCompatTests.class.getName()))
- .setUid(android.os.Process.myUid())
.build();
// The per-package override forces the activity into a 3:2 aspect ratio
@@ -1345,24 +1333,18 @@
@Test
@EnableCompatChanges({ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO,
ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO_MEDIUM})
+ @DisableCompatChanges({ActivityInfo.INSETS_DECOUPLED_CONFIGURATION_ENFORCED})
public void testOverrideMinAspectRatioLowerThanManifest() {
- if (Flags.insetsDecoupledConfiguration()) {
- // TODO (b/151861875): Re-enable it. This is disabled temporarily because the config
- // bounds no longer contains display cutout.
- return;
- }
- final DisplayContent display = new TestDisplayContent.Builder(mAtm, 1400, 1800)
- .setNotch(200).setSystemDecorations(true).build();
+ final int dh = 1800;
+ final int notchHeight = 200;
+ final DisplayContent display = new TestDisplayContent.Builder(mAtm, 1400, dh)
+ .setNotch(notchHeight).setSystemDecorations(true).build();
mTask = new TaskBuilder(mSupervisor).setDisplay(display).build();
// Create a size compat activity on the same task.
- final ActivityRecord activity = new ActivityBuilder(mAtm)
- .setTask(mTask)
+ final ActivityRecord activity = getActivityBuilderOnSameTask()
.setScreenOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT)
- .setComponent(ComponentName.createRelative(mContext,
- SizeCompatTests.class.getName()))
.setMinAspectRatio(2f)
- .setUid(android.os.Process.myUid())
.build();
// The per-package override should have no effect, because the manifest aspect ratio is
@@ -1371,7 +1353,7 @@
assertEquals("App bounds must have min aspect ratio", 2f,
(float) appBounds.height() / appBounds.width(), 0.0001f /* delta */);
assertEquals("Long side must fit task",
- mTask.getWindowConfiguration().getAppBounds().height(), appBounds.height());
+ dh - notchHeight, appBounds.height());
assertEquals("Bounds can include insets", mTask.getBounds().height(),
activity.getBounds().height());
}
@@ -1383,13 +1365,9 @@
setUpDisplaySizeWithApp(1400, 1600);
// Create a size compat activity on the same task.
- final ActivityRecord activity = new ActivityBuilder(mAtm)
- .setTask(mTask)
+ final ActivityRecord activity = getActivityBuilderOnSameTask()
.setScreenOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT)
- .setComponent(ComponentName.createRelative(mContext,
- SizeCompatTests.class.getName()))
.setMinAspectRatio(1.1f)
- .setUid(android.os.Process.myUid())
.build();
// The per-package override should have no effect, because the manifest aspect ratio is
@@ -1406,12 +1384,8 @@
setUpDisplaySizeWithApp(1500, 1600);
// Create a size compat activity on the same task.
- final ActivityRecord activity = new ActivityBuilder(mAtm)
- .setTask(mTask)
+ final ActivityRecord activity = getActivityBuilderOnSameTask()
.setScreenOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT)
- .setComponent(ComponentName.createRelative(mContext,
- SizeCompatTests.class.getName()))
- .setUid(android.os.Process.myUid())
.build();
// The per-package override forces the activity into a 16:9 aspect ratio
@@ -1430,12 +1404,8 @@
setUpDisplaySizeWithApp(1400, 1600);
// Create a size compat activity on the same task.
- final ActivityRecord activity = new ActivityBuilder(mAtm)
- .setTask(mTask)
+ final ActivityRecord activity = getActivityBuilderOnSameTask()
.setScreenOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT)
- .setComponent(ComponentName.createRelative(mContext,
- SizeCompatTests.class.getName()))
- .setUid(android.os.Process.myUid())
.build();
// The per-package override forces the activity into a 16:9 aspect ratio
@@ -1455,12 +1425,7 @@
setUpDisplaySizeWithApp(1000, 1200);
// Create a size compat activity on the same task.
- final ActivityRecord activity = new ActivityBuilder(mAtm)
- .setTask(mTask)
- .setComponent(ComponentName.createRelative(mContext,
- SizeCompatTests.class.getName()))
- .setUid(android.os.Process.myUid())
- .build();
+ final ActivityRecord activity = getActivityBuilderOnSameTask().build();
// The per-package override should have no effect
assertEquals(1200, activity.getBounds().height());
@@ -1487,12 +1452,8 @@
setUpDisplaySizeWithApp(1000, 1200);
// Create a size compat activity on the same task.
- final ActivityRecord activity = new ActivityBuilder(mAtm)
- .setTask(mTask)
+ final ActivityRecord activity = getActivityBuilderOnSameTask()
.setScreenOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE)
- .setComponent(ComponentName.createRelative(mContext,
- SizeCompatTests.class.getName()))
- .setUid(android.os.Process.myUid())
.build();
// The per-package override should have no effect
@@ -1517,12 +1478,8 @@
setUpDisplaySizeWithApp(1000, 1200);
// Create a size compat activity on the same task.
- final ActivityRecord activity = new ActivityBuilder(mAtm)
- .setTask(mTask)
+ final ActivityRecord activity = getActivityBuilderOnSameTask()
.setScreenOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT)
- .setComponent(ComponentName.createRelative(mContext,
- SizeCompatTests.class.getName()))
- .setUid(android.os.Process.myUid())
.build();
// The per-package override forces the activity into a 3:2 aspect ratio
@@ -1547,12 +1504,7 @@
setUpDisplaySizeWithApp(1000, 1200);
// Create a size compat activity on the same task.
- final ActivityRecord activity = new ActivityBuilder(mAtm)
- .setTask(mTask)
- .setComponent(ComponentName.createRelative(mContext,
- SizeCompatTests.class.getName()))
- .setUid(android.os.Process.myUid())
- .build();
+ final ActivityRecord activity = getActivityBuilderOnSameTask().build();
// The per-package override forces the activity into a 3:2 aspect ratio
assertEquals(1200, activity.getBounds().height());
@@ -1571,12 +1523,8 @@
setUpDisplaySizeWithApp(1000, 1200);
// Create a size compat activity on the same task.
- final ActivityRecord activity = new ActivityBuilder(mAtm)
- .setTask(mTask)
+ final ActivityRecord activity = getActivityBuilderOnSameTask()
.setScreenOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE)
- .setComponent(ComponentName.createRelative(mContext,
- SizeCompatTests.class.getName()))
- .setUid(android.os.Process.myUid())
.build();
// The per-package override forces the activity into a 3:2 aspect ratio
@@ -1594,12 +1542,8 @@
setUpDisplaySizeWithApp(1000, 1200);
// Create a size compat activity on the same task.
- final ActivityRecord activity = new ActivityBuilder(mAtm)
- .setTask(mTask)
+ final ActivityRecord activity = getActivityBuilderOnSameTask()
.setScreenOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT)
- .setComponent(ComponentName.createRelative(mContext,
- SizeCompatTests.class.getName()))
- .setUid(android.os.Process.myUid())
.build();
// The per-package override should have no effect
@@ -1614,12 +1558,8 @@
setUpDisplaySizeWithApp(/* dw= */ 1000, /* dh= */ 2800);
// Create a size compat activity on the same task.
- final ActivityRecord activity = new ActivityBuilder(mAtm)
- .setTask(mTask)
+ final ActivityRecord activity = getActivityBuilderOnSameTask()
.setScreenOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT)
- .setComponent(ComponentName.createRelative(mContext,
- SizeCompatTests.class.getName()))
- .setUid(android.os.Process.myUid())
.build();
final TestSplitOrganizer organizer =
@@ -1697,15 +1637,11 @@
@Test
public void testLaunchWithFixedRotationTransform() {
- if (Flags.insetsDecoupledConfiguration()) {
- // TODO (b/151861875): Re-enable it. This is disabled temporarily because the config
- // bounds no longer contains display cutout.
- return;
- }
final int dw = 1000;
final int dh = 2500;
final int notchHeight = 200;
setUpApp(new TestDisplayContent.Builder(mAtm, dw, dh).setNotch(notchHeight).build());
+ mActivity.mResolveConfigHint.mUseOverrideInsetsForConfig = true;
// The test assumes the notch will be at left side when the orientation is landscape.
if (mContext.getResources().getBoolean(
com.android.internal.R.bool.config_reverseDefaultRotation)) {
@@ -2315,12 +2251,7 @@
private void testUserOverrideAspectRatio(boolean isUnresizable, int screenOrientation,
float expectedAspectRatio, @PackageManager.UserMinAspectRatio int aspectRatio,
boolean enabled) {
- final ActivityRecord activity = new ActivityBuilder(mAtm)
- .setTask(mTask)
- .setComponent(ComponentName.createRelative(mContext,
- SizeCompatTests.class.getName()))
- .setUid(android.os.Process.myUid())
- .build();
+ final ActivityRecord activity = getActivityBuilderOnSameTask().build();
activity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
spyOn(activity.mWmService.mLetterboxConfiguration);
doReturn(enabled).when(activity.mWmService.mLetterboxConfiguration)
@@ -2351,12 +2282,8 @@
final int displayWidth = 1400;
final int displayHeight = 1600;
setUpDisplaySizeWithApp(displayWidth, displayHeight);
- final ActivityRecord activity = new ActivityBuilder(mAtm)
- .setTask(mTask)
- .setComponent(ComponentName.createRelative(mContext,
- SizeCompatTests.class.getName()))
+ final ActivityRecord activity = getActivityBuilderOnSameTask()
.setMinAspectRatio(1.1f)
- .setUid(android.os.Process.myUid())
.build();
// Setup Letterbox Configuration
activity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
@@ -2376,12 +2303,8 @@
final int displayWidth = 1600;
final int displayHeight = 1400;
setUpDisplaySizeWithApp(displayWidth, displayHeight);
- final ActivityRecord activity = new ActivityBuilder(mAtm)
- .setTask(mTask)
- .setComponent(ComponentName.createRelative(mContext,
- SizeCompatTests.class.getName()))
+ final ActivityRecord activity = getActivityBuilderOnSameTask()
.setMinAspectRatio(1.1f)
- .setUid(android.os.Process.myUid())
.build();
// Setup Letterbox Configuration
activity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
@@ -2402,12 +2325,8 @@
final int displayWidth = 1400;
final int displayHeight = 1600;
setUpDisplaySizeWithApp(displayWidth, displayHeight);
- final ActivityRecord activity = new ActivityBuilder(mAtm)
- .setTask(mTask)
- .setComponent(ComponentName.createRelative(mContext,
- SizeCompatTests.class.getName()))
+ final ActivityRecord activity = getActivityBuilderOnSameTask()
.setMinAspectRatio(1.1f)
- .setUid(android.os.Process.myUid())
.build();
// Setup Letterbox Configuration
activity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
@@ -2428,12 +2347,8 @@
final int displayWidth = 1600;
final int displayHeight = 1400;
setUpDisplaySizeWithApp(displayWidth, displayHeight);
- final ActivityRecord activity = new ActivityBuilder(mAtm)
- .setTask(mTask)
- .setComponent(ComponentName.createRelative(mContext,
- SizeCompatTests.class.getName()))
+ final ActivityRecord activity = getActivityBuilderOnSameTask()
.setMinAspectRatio(1.1f)
- .setUid(android.os.Process.myUid())
.build();
// Setup Letterbox Configuration
activity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
@@ -2454,12 +2369,7 @@
final int screenWidth = 1800;
final int screenHeight = 1000;
setUpDisplaySizeWithApp(screenWidth, screenHeight);
- final ActivityRecord activity = new ActivityBuilder(mAtm)
- .setTask(mTask)
- .setComponent(ComponentName.createRelative(mContext,
- SizeCompatTests.class.getName()))
- .setUid(android.os.Process.myUid())
- .build();
+ final ActivityRecord activity = getActivityBuilderOnSameTask().build();
activity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
// Simulate real display with top insets.
@@ -2495,12 +2405,7 @@
final int screenWidth = 1000;
final int screenHeight = 1800;
setUpDisplaySizeWithApp(screenWidth, screenHeight);
- final ActivityRecord activity = new ActivityBuilder(mAtm)
- .setTask(mTask)
- .setComponent(ComponentName.createRelative(mContext,
- SizeCompatTests.class.getName()))
- .setUid(android.os.Process.myUid())
- .build();
+ final ActivityRecord activity = getActivityBuilderOnSameTask().build();
activity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
// Simulate real display with top insets.
@@ -2538,12 +2443,7 @@
mActivity.mWmService.mLetterboxConfiguration.setFixedOrientationLetterboxAspectRatio(1.33f);
// Create a size compat activity on the same task.
- final ActivityRecord activity = new ActivityBuilder(mAtm)
- .setTask(mTask)
- .setComponent(ComponentName.createRelative(mContext,
- SizeCompatTests.class.getName()))
- .setUid(android.os.Process.myUid())
- .build();
+ final ActivityRecord activity = getActivityBuilderOnSameTask().build();
// Non-resizable portrait activity
prepareUnresizable(activity, 0f, ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
@@ -2573,12 +2473,7 @@
mActivity.mWmService.mLetterboxConfiguration.setFixedOrientationLetterboxAspectRatio(1.33f);
// Create a size compat activity on the same task.
- final ActivityRecord activity = new ActivityBuilder(mAtm)
- .setTask(mTask)
- .setComponent(ComponentName.createRelative(mContext,
- SizeCompatTests.class.getName()))
- .setUid(android.os.Process.myUid())
- .build();
+ final ActivityRecord activity = getActivityBuilderOnSameTask().build();
final TestSplitOrganizer organizer =
new TestSplitOrganizer(mAtm, activity.getDisplayContent());
@@ -3636,17 +3531,13 @@
@Test
public void testLetterboxDetailsForStatusBar_letterboxNotOverlappingStatusBar() {
- if (Flags.insetsDecoupledConfiguration()) {
- // TODO (b/151861875): Re-enable it. This is disabled temporarily because the config
- // bounds no longer contains display cutout.
- return;
- }
// Align to center so that we don't overlap with the status bar
mAtm.mWindowManager.mLetterboxConfiguration.setLetterboxVerticalPositionMultiplier(0.5f);
final DisplayContent display = new TestDisplayContent.Builder(mAtm, 1000, 2800)
.setNotch(100)
.build();
setUpApp(display);
+ mActivity.mResolveConfigHint.mUseOverrideInsetsForConfig = true;
TestWindowState statusBar = addStatusBar(mActivity.mDisplayContent);
spyOn(statusBar);
doReturn(new Rect(0, 0, statusBar.mRequestedWidth, statusBar.mRequestedHeight))
@@ -3658,12 +3549,12 @@
// Refresh the letterbox
mActivity.mRootWindowContainer.performSurfacePlacement();
- Rect mBounds = new Rect(mActivity.getWindowConfiguration().getBounds());
- assertEquals(mBounds, new Rect(0, 900, 1000, 2000));
+ Rect bounds = new Rect(mActivity.getWindowConfiguration().getBounds());
+ assertEquals(new Rect(0, 900, 1000, 2000), bounds);
DisplayPolicy displayPolicy = mActivity.getDisplayContent().getDisplayPolicy();
LetterboxDetails[] expectedLetterboxDetails = {new LetterboxDetails(
- mBounds,
+ bounds,
mActivity.getDisplayContent().getBounds(),
mActivity.findMainWindow().mAttrs.insetsFlags.appearance
)};
@@ -3952,12 +3843,8 @@
assertTrue(display.getDisplayPolicy().updateDecorInsetsInfo());
display.sendNewConfiguration();
- final ActivityRecord activity = new ActivityBuilder(mAtm)
- .setTask(mTask)
+ final ActivityRecord activity = getActivityBuilderOnSameTask()
.setScreenOrientation(SCREEN_ORIENTATION_PORTRAIT)
- .setComponent(ComponentName.createRelative(mContext,
- SizeCompatTests.class.getName()))
- .setUid(android.os.Process.myUid())
.build();
// Activity should not be letterboxed and should have portrait app bounds even though
@@ -3989,12 +3876,8 @@
assertTrue(display.getDisplayPolicy().updateDecorInsetsInfo());
display.sendNewConfiguration();
- final ActivityRecord activity = new ActivityBuilder(mAtm)
- .setTask(mTask)
+ final ActivityRecord activity = getActivityBuilderOnSameTask()
.setScreenOrientation(SCREEN_ORIENTATION_PORTRAIT)
- .setComponent(ComponentName.createRelative(mContext,
- SizeCompatTests.class.getName()))
- .setUid(android.os.Process.myUid())
.build();
final Rect bounds = activity.getBounds();
@@ -4021,14 +3904,11 @@
assertTrue(dc.getDisplayPolicy().updateDecorInsetsInfo());
dc.sendNewConfiguration();
- final ActivityRecord activity = new ActivityBuilder(mAtm)
- .setTask(mTask)
- .setComponent(ComponentName.createRelative(mContext,
- SizeCompatTests.class.getName()))
- .setUid(android.os.Process.myUid())
+ final ActivityRecord activity = getActivityBuilderOnSameTask()
+ .setResizeMode(RESIZE_MODE_UNRESIZEABLE)
+ .setScreenOrientation(SCREEN_ORIENTATION_LANDSCAPE)
+ .setMinAspectRatio(OVERRIDE_MIN_ASPECT_RATIO_LARGE_VALUE)
.build();
- prepareMinAspectRatio(activity, OVERRIDE_MIN_ASPECT_RATIO_LARGE_VALUE,
- SCREEN_ORIENTATION_LANDSCAPE);
// To force config to update again but with the same landscape orientation.
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
@@ -4042,11 +3922,6 @@
@Test
public void testApplyAspectRatio_activityAlignWithParentAppVertical() {
- if (Flags.insetsDecoupledConfiguration()) {
- // TODO (b/151861875): Re-enable it. This is disabled temporarily because the config
- // bounds no longer contains display cutout.
- return;
- }
// The display's app bounds will be (0, 100, 1000, 2350)
final DisplayContent display = new TestDisplayContent.Builder(mAtm, 1000, 2500)
.setCanRotate(false)
@@ -4054,19 +3929,16 @@
.build();
setUpApp(display);
- prepareUnresizable(mActivity, 2.1f /* maxAspect */, SCREEN_ORIENTATION_UNSPECIFIED);
+ mActivity.mResolveConfigHint.mUseOverrideInsetsForConfig = true;
+ prepareUnresizable(mActivity, 2.1f, SCREEN_ORIENTATION_UNSPECIFIED);
// The activity height is 2100 and the display's app bounds height is 2250, so the activity
// can be aligned inside parentAppBounds
- assertEquals(mActivity.getBounds(), new Rect(0, 0, 1000, 2200));
+ assertEquals(new Rect(0, 0, 1000, 2200), mActivity.getBounds());
}
@Test
+ @DisableCompatChanges({ActivityInfo.INSETS_DECOUPLED_CONFIGURATION_ENFORCED})
public void testApplyAspectRatio_activityCannotAlignWithParentAppVertical() {
- if (Flags.insetsDecoupledConfiguration()) {
- // TODO (b/151861875): Re-enable it. This is disabled temporarily because the config
- // bounds no longer contains display cutout.
- return;
- }
// The display's app bounds will be (0, 100, 1000, 2150)
final DisplayContent display = new TestDisplayContent.Builder(mAtm, 1000, 2300)
.setCanRotate(false)
@@ -4074,19 +3946,21 @@
.build();
setUpApp(display);
- prepareUnresizable(mActivity, 2.1f /* maxAspect */, SCREEN_ORIENTATION_UNSPECIFIED);
+
+ final ActivityRecord activity = getActivityBuilderOnSameTask()
+ .setResizeMode(RESIZE_MODE_UNRESIZEABLE)
+ .setMaxAspectRatio(2.1f)
+ .setScreenOrientation(SCREEN_ORIENTATION_UNSPECIFIED)
+ .build();
+
// The activity height is 2100 and the display's app bounds height is 2050, so the activity
// cannot be aligned inside parentAppBounds and it will fill the parentBounds of the display
- assertEquals(mActivity.getBounds(), display.getBounds());
+ assertEquals(activity.getBounds(), display.getBounds());
}
@Test
+ @DisableCompatChanges({ActivityInfo.INSETS_DECOUPLED_CONFIGURATION_ENFORCED})
public void testApplyAspectRatio_activityAlignWithParentAppHorizontal() {
- if (Flags.insetsDecoupledConfiguration()) {
- // TODO (b/151861875): Re-enable it. This is disabled temporarily because the config
- // bounds no longer contains display cutout.
- return;
- }
// The display's app bounds will be (100, 0, 2350, 1000)
final DisplayContent display = new TestDisplayContent.Builder(mAtm, 2500, 1000)
.setCanRotate(false)
@@ -4094,18 +3968,19 @@
.build();
setUpApp(display);
- prepareUnresizable(mActivity, 2.1f /* maxAspect */, SCREEN_ORIENTATION_UNSPECIFIED);
+
+ final ActivityRecord activity = getActivityBuilderOnSameTask()
+ .setResizeMode(RESIZE_MODE_UNRESIZEABLE)
+ .setMaxAspectRatio(2.1f)
+ .setScreenOrientation(SCREEN_ORIENTATION_UNSPECIFIED)
+ .build();
// The activity width is 2100 and the display's app bounds width is 2250, so the activity
// can be aligned inside parentAppBounds
- assertEquals(mActivity.getBounds(), new Rect(175, 0, 2275, 1000));
+ assertEquals(activity.getBounds(), new Rect(175, 0, 2275, 1000));
}
@Test
+ @DisableCompatChanges({ActivityInfo.INSETS_DECOUPLED_CONFIGURATION_ENFORCED})
public void testApplyAspectRatio_activityCannotAlignWithParentAppHorizontal() {
- if (Flags.insetsDecoupledConfiguration()) {
- // TODO (b/151861875): Re-enable it. This is disabled temporarily because the config
- // bounds no longer contains display cutout.
- return;
- }
// The display's app bounds will be (100, 0, 2150, 1000)
final DisplayContent display = new TestDisplayContent.Builder(mAtm, 2300, 1000)
.setCanRotate(false)
@@ -4113,10 +3988,14 @@
.build();
setUpApp(display);
- prepareUnresizable(mActivity, 2.1f /* maxAspect */, SCREEN_ORIENTATION_UNSPECIFIED);
+ final ActivityRecord activity = getActivityBuilderOnSameTask()
+ .setResizeMode(RESIZE_MODE_UNRESIZEABLE)
+ .setMaxAspectRatio(2.1f)
+ .setScreenOrientation(SCREEN_ORIENTATION_UNSPECIFIED)
+ .build();
// The activity width is 2100 and the display's app bounds width is 2050, so the activity
// cannot be aligned inside parentAppBounds and it will fill the parentBounds of the display
- assertEquals(mActivity.getBounds(), display.getBounds());
+ assertEquals(activity.getBounds(), display.getBounds());
}
@Test
@@ -4344,26 +4223,23 @@
@Test
public void testUpdateResolvedBoundsPosition_alignToTop() {
- if (Flags.insetsDecoupledConfiguration()) {
- // TODO (b/151861875): Re-enable it. This is disabled temporarily because the config
- // bounds no longer contains display cutout.
- return;
- }
final int notchHeight = 100;
final DisplayContent display = new TestDisplayContent.Builder(mAtm, 1000, 2800)
.setNotch(notchHeight)
.build();
setUpApp(display);
+ mActivity.mResolveConfigHint.mUseOverrideInsetsForConfig = true;
// Prepare unresizable activity with max aspect ratio
- prepareUnresizable(mActivity, /* maxAspect */ 1.1f, SCREEN_ORIENTATION_UNSPECIFIED);
+ prepareUnresizable(mActivity, 1.1f, SCREEN_ORIENTATION_UNSPECIFIED);
- Rect mBounds = new Rect(mActivity.getWindowConfiguration().getBounds());
+ Rect bounds = new Rect(mActivity.getWindowConfiguration().getBounds());
Rect appBounds = new Rect(mActivity.getWindowConfiguration().getAppBounds());
// The insets should be cut for aspect ratio and then added back because the appBounds
// are aligned to the top of the parentAppBounds
- assertEquals(mBounds, new Rect(0, 0, 1000, 1200));
- assertEquals(appBounds, new Rect(0, notchHeight, 1000, 1200));
+ assertEquals(new Rect(0, notchHeight, 1000, 1200), appBounds);
+ assertEquals(new Rect(0, 0, 1000, 1200), bounds);
+
}
private void assertVerticalPositionForDifferentDisplayConfigsForLandscapeActivity(
@@ -4859,15 +4735,19 @@
*/
private ActivityRecord buildActivityRecord(boolean supportsSizeChanges, int resizeMode,
@ScreenOrientation int screenOrientation) {
- return new ActivityBuilder(mAtm)
- .setTask(mTask)
+ return getActivityBuilderOnSameTask()
.setResizeMode(resizeMode)
.setSupportsSizeChanges(supportsSizeChanges)
.setScreenOrientation(screenOrientation)
+ .build();
+ }
+
+ private ActivityBuilder getActivityBuilderOnSameTask() {
+ return new ActivityBuilder(mAtm)
+ .setTask(mTask)
.setComponent(ComponentName.createRelative(mContext,
SizeCompatTests.class.getName()))
- .setUid(android.os.Process.myUid())
- .build();
+ .setUid(android.os.Process.myUid());
}
static void prepareMinAspectRatio(ActivityRecord activity, float minAspect,
@@ -4931,21 +4811,29 @@
}
}
- /** Asserts that the size of activity is larger than its parent so it is scaling. */
private void assertScaled() {
- assertTrue(mActivity.inSizeCompatMode());
- assertNotEquals(1f, mActivity.getCompatScale(), 0.0001f /* delta */);
+ assertScaled(mActivity);
+ }
+
+ /** Asserts that the size of activity is larger than its parent so it is scaling. */
+ private void assertScaled(ActivityRecord activity) {
+ assertTrue(activity.inSizeCompatMode());
+ assertNotEquals(1f, activity.getCompatScale(), 0.0001f /* delta */);
+ }
+
+ private void assertFitted() {
+ assertFitted(mActivity);
}
/** Asserts that the activity is best fitted in the parent. */
- private void assertFitted() {
- final boolean inSizeCompatMode = mActivity.inSizeCompatMode();
+ private void assertFitted(ActivityRecord activity) {
+ final boolean inSizeCompatMode = activity.inSizeCompatMode();
final String failedConfigInfo = inSizeCompatMode
- ? ("ParentConfig=" + mActivity.getParent().getConfiguration()
- + " ActivityConfig=" + mActivity.getConfiguration())
+ ? ("ParentConfig=" + activity.getParent().getConfiguration()
+ + " ActivityConfig=" + activity.getConfiguration())
: "";
assertFalse(failedConfigInfo, inSizeCompatMode);
- assertFalse(mActivity.hasSizeCompatBounds());
+ assertFalse(activity.hasSizeCompatBounds());
}
/** Asserts the activity max bounds inherit from the TaskDisplayArea. */
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
index 9f85acb..4ebbf49 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
@@ -960,10 +960,20 @@
assertTrue(child.handlesOrientationChangeFromDescendant(orientation));
}
+ private static void addLocalInsets(WindowContainer wc) {
+ final Binder owner = new Binder();
+ Rect genericOverlayInsetsRect1 = new Rect(0, 200, 1080, 700);
+ final InsetsFrameProvider provider1 =
+ new InsetsFrameProvider(owner, 1, WindowInsets.Type.systemOverlays())
+ .setArbitraryRectangle(genericOverlayInsetsRect1);
+ wc.addLocalInsetsFrameProvider(provider1, owner);
+ }
+
@Test
public void testOnDisplayChanged() {
final Task rootTask = createTask(mDisplayContent);
final Task task = createTaskInRootTask(rootTask, 0 /* userId */);
+ addLocalInsets(task);
final ActivityRecord activity = createActivityRecord(mDisplayContent, task);
final DisplayContent newDc = createNewDisplay();
@@ -972,6 +982,7 @@
verify(rootTask).onDisplayChanged(newDc);
verify(task).onDisplayChanged(newDc);
+ assertTrue(task.mLocalInsetsSources.size() == 1);
verify(activity).onDisplayChanged(newDc);
assertEquals(newDc, rootTask.mDisplayContent);
assertEquals(newDc, task.mDisplayContent);
@@ -981,6 +992,7 @@
@Test
public void testOnDisplayChanged_cleanupChanging() {
final Task task = createTask(mDisplayContent);
+ addLocalInsets(task);
spyOn(task.mSurfaceFreezer);
mDisplayContent.mChangingContainers.add(task);
@@ -988,6 +1000,7 @@
// This happens on display info changed.
task.onDisplayChanged(mDisplayContent);
+ assertTrue(task.mLocalInsetsSources.size() == 1);
assertTrue(mDisplayContent.mChangingContainers.contains(task));
verify(task.mSurfaceFreezer, never()).unfreeze(any());
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index bc8f65e..09cb464 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -9842,6 +9842,43 @@
public static final String KEY_REMOVE_SATELLITE_PLMN_IN_MANUAL_NETWORK_SCAN_BOOL =
"remove_satellite_plmn_in_manual_network_scan_bool";
+
+ /** @hide */
+ @IntDef({
+ SATELLITE_DATA_SUPPORT_ONLY_RESTRICTED,
+ SATELLITE_DATA_SUPPORT_BANDWIDTH_CONSTRAINED,
+ SATELLITE_DATA_SUPPORT_ALL,
+ })
+ public @interface SATELLITE_DATA_SUPPORT_MODE {}
+
+ /**
+ * Doesn't support unrestricted traffic on satellite network.
+ * @hide
+ */
+ public static final int SATELLITE_DATA_SUPPORT_ONLY_RESTRICTED = 0;
+ /**
+ * Support unrestricted but bandwidth_constrained traffic on satellite network.
+ * @hide
+ */
+ public static final int SATELLITE_DATA_SUPPORT_BANDWIDTH_CONSTRAINED = 1;
+ /**
+ * Support unrestricted satellite network that serves all traffic.
+ * @hide
+ */
+ public static final int SATELLITE_DATA_SUPPORT_ALL = 2;
+ /**
+ * Indicates what kind of traffic an {@link NetworkCapabilities#NET_CAPABILITY_NOT_RESTRICTED}
+ * satellite network can possibly support. The network may subject to further
+ * restrictions such as entitlement etc.
+ * If no data is allowed on satellite network, exclude
+ * {@link ApnSetting#INFRASTRUCTURE_SATELLITE} from APN infrastructure_bitmask, and this
+ * configuration is ignored.
+ * By default it only supports restricted data.
+ * @hide
+ */
+ public static final String KEY_SATELLITE_DATA_SUPPORT_MODE_INT =
+ "satellite_data_support_mode_int";
+
/**
* Determine whether to override roaming Wi-Fi Calling preference when device is connected to
* non-terrestrial network.
@@ -11084,6 +11121,8 @@
sDefaults.putInt(KEY_PARAMETERS_USED_FOR_NTN_LTE_SIGNAL_BAR_INT,
CellSignalStrengthLte.USE_RSRP);
sDefaults.putBoolean(KEY_REMOVE_SATELLITE_PLMN_IN_MANUAL_NETWORK_SCAN_BOOL, true);
+ sDefaults.putInt(KEY_SATELLITE_DATA_SUPPORT_MODE_INT,
+ CarrierConfigManager.SATELLITE_DATA_SUPPORT_ONLY_RESTRICTED);
sDefaults.putBoolean(KEY_OVERRIDE_WFC_ROAMING_MODE_WHILE_USING_NTN_BOOL, true);
sDefaults.putInt(KEY_SATELLITE_ENTITLEMENT_STATUS_REFRESH_DAYS_INT, 7);
sDefaults.putBoolean(KEY_SATELLITE_ENTITLEMENT_SUPPORTED_BOOL, false);