diff options
404 files changed, 4148 insertions, 2065 deletions
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg index e8571757c6f7..c4ffa340dccd 100644 --- a/PREUPLOAD.cfg +++ b/PREUPLOAD.cfg @@ -30,7 +30,7 @@ hidden_api_txt_exclude_hook = ${REPO_ROOT}/frameworks/base/tools/hiddenapi/exclu 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 c0bc6d96f7ef..a819b6e27152 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -9801,6 +9801,7 @@ package android.companion { 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 76c1ed619510..b384326201fc 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -7500,7 +7500,7 @@ public final class ActivityThread extends ClientTransactionHandler + 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 15b13dc97554..ffb920b907ab 100644 --- a/core/java/android/app/IActivityManager.aidl +++ b/core/java/android/app/IActivityManager.aidl @@ -757,6 +757,15 @@ interface IActivityManager { 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 8fe5ae09a36d..b4ad1c8fff12 100644 --- a/core/java/android/companion/CompanionDeviceManager.java +++ b/core/java/android/companion/CompanionDeviceManager.java @@ -1149,6 +1149,32 @@ public final class CompanionDeviceManager { } } + /** + * 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 1b00f90e1fb3..de3ddec05d27 100644 --- a/core/java/android/companion/ICompanionDeviceManager.aidl +++ b/core/java/android/companion/ICompanionDeviceManager.aidl @@ -141,4 +141,7 @@ interface ICompanionDeviceManager { 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 36d0e081af2a..fd4ba83b02e3 100644 --- a/core/java/android/companion/flags.aconfig +++ b/core/java/android/companion/flags.aconfig @@ -46,4 +46,11 @@ flag { 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 bad73fc68f3a..4fcf6b66895c 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -7188,9 +7188,10 @@ public abstract class Context { * 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 6168b6800adc..93cc71b34e47 100644 --- a/core/java/android/content/pm/LauncherApps.java +++ b/core/java/android/content/pm/LauncherApps.java @@ -695,13 +695,13 @@ public class LauncherApps { * <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 @@ public class LauncherApps { * 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 @@ public class LauncherApps { * 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 @@ public class LauncherApps { * </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 @@ public class LauncherApps { * <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 @@ public class LauncherApps { /** * 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 @@ public class LauncherApps { * 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 @@ public class LauncherApps { /** * 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 @@ public class LauncherApps { * 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 @@ public class LauncherApps { /** * 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 @@ public class LauncherApps { * <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 @@ public class LauncherApps { * 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 @@ public class LauncherApps { /** * 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 @@ public class LauncherApps { * <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 @@ public class LauncherApps { /** * 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 @@ public class LauncherApps { /** * 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 @@ public class LauncherApps { * 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 3cc87ea9d359..6fffb822c9ca 100644 --- a/core/java/android/hardware/camera2/CameraCharacteristics.java +++ b/core/java/android/hardware/camera2/CameraCharacteristics.java @@ -1472,9 +1472,9 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri 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 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri 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 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri 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 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri 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 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri /** * <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 938636f7e8e5..6968f279dbc0 100644 --- a/core/java/android/hardware/camera2/CaptureRequest.java +++ b/core/java/android/hardware/camera2/CaptureRequest.java @@ -2683,27 +2683,27 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>> /** * <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 4406a419c317..ef83f9a1e4c6 100644 --- a/core/java/android/hardware/camera2/CaptureResult.java +++ b/core/java/android/hardware/camera2/CaptureResult.java @@ -2976,27 +2976,27 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> { /** * <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 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> { * 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 278e8631622c..4d694372efaf 100644 --- a/core/java/android/inputmethodservice/InputMethodService.java +++ b/core/java/android/inputmethodservice/InputMethodService.java @@ -720,6 +720,7 @@ public class InputMethodService extends AbstractInputMethodService { 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 9c55b0ee0623..de67e06ddda7 100644 --- a/core/java/android/inputmethodservice/NavigationBarController.java +++ b/core/java/android/inputmethodservice/NavigationBarController.java @@ -58,6 +58,10 @@ import java.util.Objects; 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 @@ final class NavigationBarController { ? 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 @@ final class NavigationBarController { } @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 b41753413baf..7bdd53d00215 100644 --- a/core/java/android/os/BatteryConsumer.java +++ b/core/java/android/os/BatteryConsumer.java @@ -197,6 +197,9 @@ public abstract class BatteryConsumer { 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 000000000000..25a3b9f13d3b --- /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 000000000000..8b12a1cb997e --- /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 000000000000..e3e72e19e418 --- /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 beb1a5d4ee15..54ee37519546 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -177,6 +177,7 @@ import android.graphics.Region; 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.util.proto.ProtoOutputStream; 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.OptionalInt; 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 @@ public final class ViewRootImpl implements ViewParent, 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 @@ public final class ViewRootImpl implements ViewParent, } else { mSensitiveContentProtectionService = null; } + + mAppStartInfoTimestampsFlagValue = android.app.Flags.appStartInfoTimestamps(); } public static void addFirstDrawHandler(Runnable callback) { @@ -2576,6 +2588,12 @@ public final class ViewRootImpl implements ViewParent, notifySurfaceDestroyed(); } destroySurface(); + + // Reset so they can be sent again for warm starts. + mAppStartTimestampsSent = false; + mAppStartTrackingStarted = false; + mRenderThreadDrawStartTimeNs = -1; + mFirstFramePresentedTimeNs = -1; } } } @@ -4374,6 +4392,30 @@ public final class ViewRootImpl implements ViewParent, 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 @@ public final class ViewRootImpl implements ViewParent, 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 @@ public final class ViewRootImpl implements ViewParent, 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 @@ public final class ViewRootImpl implements ViewParent, 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 final class ViewRootImpl implements ViewParent, 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 final class ViewRootImpl implements ViewParent, 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 @@ public final class ViewRootImpl implements ViewParent, 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 @@ public final class ViewRootImpl implements ViewParent, } @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 @@ public final class ViewRootImpl implements ViewParent, } else { scheduleProcessInputEvents(); } - return q; } private void scheduleProcessInputEvents() { @@ -12374,45 +12449,29 @@ public final class ViewRootImpl implements ViewParent, + "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 46b41aead027..950dfeeacc8b 100644 --- a/core/java/android/view/autofill/AutofillFeatureFlags.java +++ b/core/java/android/view/autofill/AutofillFeatureFlags.java @@ -548,7 +548,7 @@ public class AutofillFeatureFlags { 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 4099e88f1c17..15f9cff87458 100644 --- a/core/java/android/widget/RemoteViews.java +++ b/core/java/android/widget/RemoteViews.java @@ -1424,6 +1424,10 @@ public class RemoteViews implements Parcelable, Filter { 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 4c993c2544ce..b7f6f363dd04 100644 --- a/core/java/android/window/WindowOnBackInvokedDispatcher.java +++ b/core/java/android/window/WindowOnBackInvokedDispatcher.java @@ -37,7 +37,6 @@ import android.view.IWindow; 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.ArrayList; 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 @@ import java.util.function.Supplier; 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 @@ public class WindowOnBackInvokedDispatcher implements OnBackInvokedDispatcher { * 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 @@ public class WindowOnBackInvokedDispatcher implements OnBackInvokedDispatcher { clear(); mWindow = null; mWindowSession = null; - mViewRoot = null; mImeBackAnimationController = null; } } @@ -182,6 +176,8 @@ public class WindowOnBackInvokedDispatcher implements OnBackInvokedDispatcher { 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 @@ public class WindowOnBackInvokedDispatcher implements OnBackInvokedDispatcher { } } - 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 @@ public class WindowOnBackInvokedDispatcher implements OnBackInvokedDispatcher { 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 @@ public class WindowOnBackInvokedDispatcher implements OnBackInvokedDispatcher { 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 class WindowOnBackInvokedDispatcher implements OnBackInvokedDispatcher { 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 @@ public class WindowOnBackInvokedDispatcher implements OnBackInvokedDispatcher { }); } - 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 daf2fe345ffd..b91f2d628359 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 @@ flag { 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 98d6ec6897a6..920981e2b8fe 100644 --- a/core/java/com/android/internal/app/ResolverActivity.java +++ b/core/java/com/android/internal/app/ResolverActivity.java @@ -923,7 +923,7 @@ public class ResolverActivity extends Activity implements mSystemWindowInsets = insets.getSystemWindowInsets(); mResolverDrawerLayout.setPadding(mSystemWindowInsets.left, mSystemWindowInsets.top, - mSystemWindowInsets.right, mSystemWindowInsets.bottom); + mSystemWindowInsets.right, 0); resetButtonBar(); @@ -952,7 +952,7 @@ public class ResolverActivity extends Activity implements 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 244165f5e814..5c270e0e874c 100644 --- a/core/java/com/android/internal/os/BatteryStatsHistory.java +++ b/core/java/com/android/internal/os/BatteryStatsHistory.java @@ -1514,6 +1514,36 @@ public class BatteryStatsHistory { } /** + * 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 index c4b44484d046..99acedf06e2d 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 767140d9d5c1..000000000000 --- 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 776a35d15ef0..96f0909eea10 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 e4c2a34b1af8..0b3861cad252 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 12e200088286..a51836b35057 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 34e7bc8af8da..d6e1e9d61743 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 575573cb0ffb..df5cbb1fbc92 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 c74bc9ba6e75..9846b710300f 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 c6d4f3ad771d..4dfe000659ff 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 dcda5d8669a4..fba95a5e41b4 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 4442b5e4c044..cc74d023ee5e 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 bdbf96b97c1e..c3d304dc35e1 100644 --- a/core/res/res/values/themes.xml +++ b/core/res/res/values/themes.xml @@ -391,11 +391,9 @@ please see themes_device_defaults.xml. <!-- 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 @@ please see themes_device_defaults.xml. <!-- 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 d4482f243939..b0190a5c8218 100644 --- a/core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java +++ b/core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java @@ -112,7 +112,7 @@ public class WindowOnBackInvokedDispatcherTest { 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 @@ public class WindowOnBackInvokedDispatcherTest { @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 d92d24d9e22d..94c281fa9fac 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 @@ class DividerPresenter implements View.OnTouchListener { ? 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 (Math.abs(velocity) < minFlingVelocityPxPerSecond) { - if (dividerPosition >= minPosition && dividerPosition <= maxPosition) { - return dividerPosition; - } - final int[] snapPositions = {0, minPosition, maxPosition, fullyExpandedPosition}; - return snap(dividerPosition, snapPositions); + if (dividerPosition >= minPosition && dividerPosition <= maxPosition) { + return dividerPosition; } - 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 af3c4dac5d67..4f51815ed05d 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 @@ public class DividerPresenterTest { // 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 0efdbdc9376c..327e2059557c 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 @@ class BubbleStackViewTest { 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 4a1da4daf1ad..644907361cd7 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 @@ public class BubbleController implements ConfigurationChangeListener, * 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 b0d3cc4a5d5c..3d9bf032c1b0 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 @@ interface BubbleExpandedViewManager { fun setAppBubbleTaskId(key: String, taskId: Int) fun isStackExpanded(): Boolean fun isShowingAsBubbleBar(): Boolean + fun hideCurrentInputMethod() companion object { /** @@ -73,6 +74,10 @@ interface BubbleExpandedViewManager { 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 fac9bf6e2a4b..ed904e2ff766 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 @@ public class BubbleStackView extends FrameLayout * 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 271fb9abce6a..a7da07d013c1 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 @@ public class BubbleBarExpandedView extends FrameLayout implements BubbleTaskView 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 @@ public class BubbleBarExpandedView extends FrameLayout implements BubbleTaskView boolean isOverflow, @Nullable BubbleTaskView bubbleTaskView) { mManager = expandedViewManager; + mPositioner = positioner; mIsOverflow = isOverflow; if (mIsOverflow) { @@ -290,15 +292,27 @@ public class BubbleBarExpandedView extends FrameLayout implements BubbleTaskView } /** - * 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 123cc7e9d488..badc40997902 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 @@ public class BubbleBarLayerView extends FrameLayout } }); - setOnClickListener(view -> hideMenuOrCollapse()); + setOnClickListener(view -> hideModalOrCollapse()); } @Override @@ -217,7 +217,7 @@ public class BubbleBarLayerView extends FrameLayout @Override public void onBackPressed() { - hideMenuOrCollapse(); + hideModalOrCollapse(); } }); @@ -344,15 +344,23 @@ public class BubbleBarLayerView extends FrameLayout 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 e1657f99639d..04dd0eff5d68 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 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, // 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 07e97f85d588..a88139d6b5d6 100644 --- a/libs/hwui/jni/Graphics.cpp +++ b/libs/hwui/jni/Graphics.cpp @@ -583,6 +583,16 @@ jobject GraphicsJNI::getColorSpace(JNIEnv* env, SkColorSpace* decodeColorSpace, 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 efbf8da6d17c..eeb4853afadc 100644 --- a/media/java/android/media/IMediaRouterService.aidl +++ b/media/java/android/media/IMediaRouterService.aidl @@ -52,6 +52,7 @@ interface IMediaRouterService { // 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 @@ interface IMediaRouterService { 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 5672cd54e369..0667bfda7596 100644 --- a/media/java/android/media/MediaRouter2.java +++ b/media/java/android/media/MediaRouter2.java @@ -2666,8 +2666,11 @@ public final class MediaRouter2 { @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 final class MediaRouter2 { 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 02d72ad7d693..44fa677b59f7 100644 --- a/native/android/performance_hint.cpp +++ b/native/android/performance_hint.cpp @@ -51,6 +51,9 @@ struct APerformanceHintSession; 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 @@ APerformanceHintSession* APerformanceHintManager::createSession( } 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 @@ APerformanceHintSession::APerformanceHintSession(std::shared_ptr<IHintManager> h 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 @@ int APerformanceHintSession::updateTargetWorkDuration(int64_t targetDurationNano 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::reportActualWorkDuration(int64_t actualDurationNano } 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 @@ int APerformanceHintSession::setThreads(const int32_t* threadIds, size_t size) { return EPIPE; } + std::scoped_lock lock(sHintMutex); traceThreads(tids); return 0; @@ -343,6 +351,7 @@ int APerformanceHintSession::setPreferPowerEfficiency(bool enabled) { ret.getMessage()); return EPIPE; } + std::scoped_lock lock(sHintMutex); tracePowerEfficient(enabled); return OK; } @@ -355,6 +364,7 @@ int APerformanceHintSession::reportActualWorkDurationInternal(AWorkDuration* wor 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 38ad560d1bf0..5a4d3ce5661b 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 927aa6930ec3..363045ec1d83 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 3de49336f427..f3ff0fe84a30 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)); - } - - 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 final Context mContext; + public DeviceIconUtil(@NonNull Context context) { + mContext = Objects.requireNonNull(context); + mIsTv = + mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_LEANBACK) + && Flags.enableTvMediaOutputDialog(); } - 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; - - @MediaRoute2Info.Type - private final int mMediaRouteType; + @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. + }; + } - @DrawableRes - private final int mIconDrawableRes; + @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; + }; + } - 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 c2c334bf896a..1e79bb7b8cc8 100644 --- a/packages/SystemUI/Android.bp +++ b/packages/SystemUI/Android.bp @@ -78,10 +78,50 @@ filegroup { 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 @@ filegroup { ], } -// 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 @@ android_robolectric_test { 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 2e9af7e3a763..afcd8a9624c8 100644 --- a/packages/SystemUI/aconfig/communal.aconfig +++ b/packages/SystemUI/aconfig/communal.aconfig @@ -7,3 +7,13 @@ flag { 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 4311e7968e91..29b57c95ee45 100644 --- a/packages/SystemUI/aconfig/systemui.aconfig +++ b/packages/SystemUI/aconfig/systemui.aconfig @@ -1039,6 +1039,16 @@ flag { } 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 c32938497147..a1f8f1b32f77 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.foundation.shape.RoundedCornerShape 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 @@ private fun SceneScope.CommunalScene( CommunalBackgroundType.DEFAULT -> DefaultBackground(colors = colors) CommunalBackgroundType.STATIC_GRADIENT -> StaticLinearGradient() CommunalBackgroundType.ANIMATED -> AnimatedLinearGradient() + CommunalBackgroundType.NONE -> BackgroundTopScrim() } } with(content) { Content(modifier = modifier) } @@ -252,7 +251,8 @@ private fun BoxScope.AnimatedLinearGradient() { 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 @@ private fun BoxScope.BackgroundTopScrim() { 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 776651558e48..60b6f62dfa46 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 androidx.compose.ui.unit.IntRect 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 @@ class CommunalContent @Inject constructor( private val viewModel: CommunalViewModel, + private val interactionHandler: WidgetInteractionHandler, private val dialogFactory: SystemUIDialogFactory, private val lockSection: LockSection, ) { @@ -45,6 +47,7 @@ constructor( 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 1f7f07bb072d..eccb0724a8d4 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.modifiers.thenIf 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.BaseCommunalViewModel 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 @@ import kotlinx.coroutines.launch fun CommunalHub( modifier: Modifier = Modifier, viewModel: BaseCommunalViewModel, + interactionHandler: RemoteViews.InteractionHandler? = null, dialogFactory: SystemUIDialogFactory? = null, widgetConfigurator: WidgetConfigurator? = null, onOpenWidgetPicker: (() -> Unit)? = null, @@ -262,6 +265,7 @@ fun CommunalHub( contentListState = contentListState, selectedKey = selectedKey, widgetConfigurator = widgetConfigurator, + interactionHandler = interactionHandler, ) } } @@ -391,6 +395,7 @@ private fun BoxScope.CommunalHubLazyGrid( 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 @@ private fun BoxScope.CommunalHubLazyGrid( selected = selected && !isDragging, widgetConfigurator = widgetConfigurator, index = index, - contentListState = contentListState + contentListState = contentListState, + interactionHandler = interactionHandler, ) } } else { @@ -479,7 +485,8 @@ private fun BoxScope.CommunalHubLazyGrid( size = size, selected = false, index = index, - contentListState = contentListState + contentListState = contentListState, + interactionHandler = interactionHandler, ) } } @@ -759,6 +766,7 @@ private fun CommunalContent( widgetConfigurator: WidgetConfigurator? = null, index: Int, contentListState: ContentListState, + interactionHandler: RemoteViews.InteractionHandler?, ) { when (model) { is CommunalContentModel.WidgetContent.Widget -> @@ -778,7 +786,7 @@ private fun CommunalContent( 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 @@ fun PendingWidgetPlaceholder( @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 9e905ac11b1e..94018bbdbd22 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.SwipeDirection 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 @@ class CommunalScene constructor( private val viewModel: CommunalViewModel, private val dialogFactory: SystemUIDialogFactory, + private val interactionHandler: WidgetInteractionHandler, ) : ComposableScene { override val key = Scenes.Communal @@ -53,6 +55,6 @@ constructor( @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 48a348b9d1c5..c2dd80375d5a 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 @@ internal fun CoroutineScope.animateToScene( layoutState.transitions.interruptionHandler.onInterruption( transitionState, target, - ) - ?: DefaultInterruptionHandler.onInterruption(transitionState, target) + ) ?: DefaultInterruptionHandler.onInterruption(transitionState, target) val animateFrom = interruptionResult.animateFrom if ( @@ -159,6 +158,7 @@ private fun CoroutineScope.animate( val transition = if (reversed) { OneOffTransition( + key = transitionKey, fromScene = targetScene, toScene = fromScene, currentScene = targetScene, @@ -167,6 +167,7 @@ private fun CoroutineScope.animate( ) } else { OneOffTransition( + key = transitionKey, fromScene = fromScene, toScene = targetScene, currentScene = targetScene, @@ -178,7 +179,7 @@ private fun CoroutineScope.animate( // 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 fun CoroutineScope.animate( } 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 e9633c2f6603..60d78feec8c2 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 @@ private class DragControllerImpl( fun updateTransition(newTransition: SwipeTransition, force: Boolean = false) { if (isDrivingTransition || force) { - layoutState.startTransition(newTransition, newTransition.key) + layoutState.startTransition(newTransition) } swipeTransition = newTransition @@ -555,7 +555,7 @@ private class SwipeTransition( 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 edf8943509df..980982a30926 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 @@ internal class ElementNode( 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 @@ internal class ElementNode( 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 @@ internal class ElementNode( 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 @@ internal class ElementNode( 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 @@ internal class ElementNode( } 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 @@ internal class ElementNode( 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 @@ internal class ElementNode( * its scenes contains the element. */ private fun elementTransition( + layoutImpl: SceneTransitionLayoutImpl, element: Element, transitions: List<TransitionState.Transition>, ): TransitionState.Transition? { @@ -448,7 +460,7 @@ private fun elementTransition( 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 elementTransition( } 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 @@ private inline fun <T> computeInterruptedValue( } } +/** + * 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 @@ private fun shouldPlaceElement( // 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 @@ private fun shouldPlaceElement( return shouldPlaceOrComposeSharedElement( layoutImpl, - scene.key, + scene, element.key, transition, ) @@ -740,13 +806,14 @@ private fun elementAlpha( 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 @@ private fun interruptedAlpha( 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 @@ private fun ContentDrawScope.getDrawScale( 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 44affd968513..6a178c8b0c25 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 @@ sealed interface TransitionState { 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 @@ internal abstract class BaseSceneTransitionLayoutState( * * 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 @@ internal abstract class BaseSceneTransitionLayoutState( // 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 @@ internal abstract class BaseSceneTransitionLayoutState( 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 79f126d24561..ed9888560f05 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 @@ internal class LinkedTransition( 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 47c9b9cbfd10..41cacb4c71fc 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.Modifier 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 @@ class ElementTest { // 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 @@ class ElementTest { 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 @@ class ElementTest { 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 @@ class ElementTest { 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 @@ class ElementTest { 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 @@ class ElementTest { to = SceneB, progress = { -1f }, orientation = Orientation.Horizontal - ), - transitionKey = null, + ) ) } } @@ -1513,8 +1508,7 @@ class ElementTest { to = SceneB, progress = { 0.6f }, interruptionProgress = { interruptionProgress }, - ), - transitionKey = null + ) ) } rule.waitForIdle() @@ -1632,4 +1626,97 @@ class ElementTest { 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 85d4165b4bf6..09d1a827d0c7 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 @@ class InterruptionHandlerTest { val state = MutableSceneTransitionLayoutState( SceneA, - transitions { /* default interruption handler */}, + transitions { /* default interruption handler */ }, ) state.setTargetScene(SceneB, coroutineScope = this) @@ -160,7 +160,7 @@ class InterruptionHandlerTest { 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 @@ class InterruptionHandlerTest { 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 2a75e13066df..55431354b693 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 @@ class ObservableTransitionStateTest { 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 d2c8bd6928ee..de6f1cc518f4 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 @@ class SceneTransitionLayoutStateTest { @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 @@ class SceneTransitionLayoutStateTest { 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 @@ class SceneTransitionLayoutStateTest { 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 @@ class SceneTransitionLayoutStateTest { 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 @@ class SceneTransitionLayoutStateTest { 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 @@ class SceneTransitionLayoutStateTest { 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 @@ class SceneTransitionLayoutStateTest { 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 @@ class SceneTransitionLayoutStateTest { 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 @@ class SceneTransitionLayoutStateTest { @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 @@ class SceneTransitionLayoutStateTest { @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 @@ class SceneTransitionLayoutStateTest { 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 @@ class SceneTransitionLayoutStateTest { 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 @@ class SceneTransitionLayoutStateTest { 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 @@ class SceneTransitionLayoutStateTest { 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 @@ class SceneTransitionLayoutStateTest { to = SceneB, progress = progress, orientation = Orientation.Vertical, - ), - transitionKey = null + ) ) assertThat(state.isTransitioning()).isTrue() return state @@ -583,19 +576,19 @@ class SceneTransitionLayoutStateTest { 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 @@ class SceneTransitionLayoutStateTest { 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 95a25c58bc67..d78ef5a5f1bf 100755 --- a/packages/SystemUI/flag_check.py +++ b/packages/SystemUI/flag_check.py @@ -52,7 +52,7 @@ def main(): 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 @@ def main(): 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 ab551256cfc3..29a6e56891af 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 @@ class UdfpsKeyguardViewLegacyControllerWithCoroutinesTest : job.cancel() } + @Test fun fadeFromDialogSuggestedAlpha() = testScope.runTest { @@ -511,9 +512,10 @@ class UdfpsKeyguardViewLegacyControllerWithCoroutinesTest : 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 @@ class UdfpsKeyguardViewLegacyControllerWithCoroutinesTest : // 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 @@ class UdfpsKeyguardViewLegacyControllerWithCoroutinesTest : 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 bfed33c54019..fe683e07a93d 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.ext.junit.runners.AndroidJUnit4 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 @@ class CommunalDreamStartableTest : SysuiTestCase() { 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 aad2e6001f1c..a0e7781a07b0 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.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.compose.animation.scene.ObservableTransitionState import com.android.systemui.SysuiTestCase +import com.android.systemui.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.coroutines.collectLastValue 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 @@ class CommunalSceneInteractorTest : SysuiTestCase() { 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 420b11c4bde3..df7b291c4bab 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.ext.junit.runners.AndroidJUnit4 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 @@ class WidgetInteractionHandlerTest : SysuiTestCase() { ) 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 @@ class WidgetInteractionHandlerTest : SysuiTestCase() { } @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 5756bca49cb2..0f061de5226c 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 @@ class KeyguardTransitionInteractorTest : SysuiTestCase() { } @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 49df345397d4..194f362d984c 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.KeyguardState import com.android.systemui.keyguard.shared.model.TransitionState import com.android.systemui.keyguard.shared.model.TransitionStep import com.android.systemui.kosmos.testScope +import com.android.systemui.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 @@ class KeyguardRootViewModelTest(flags: FlagsParameterization) : SysuiTestCase() 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 @@ class KeyguardRootViewModelTest(flags: FlagsParameterization) : SysuiTestCase() 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 9d8ec951dfe7..6b1794e28237 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.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.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 @@ class NotificationsShadeSceneViewModelTest : SysuiTestCase() { 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 @@ class NotificationsShadeSceneViewModelTest : SysuiTestCase() { 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 @@ class NotificationsShadeSceneViewModelTest : SysuiTestCase() { ) 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 @@ class NotificationsShadeSceneViewModelTest : SysuiTestCase() { 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 0b55befce932..7ee20e587059 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.data.repository.fakeAuthenticationRep 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.data.repository.fakeDeviceEntryFingerprintA 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.any 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 @@ class QuickSettingsSceneViewModelTest : SysuiTestCase() { 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 @@ class QuickSettingsSceneViewModelTest : SysuiTestCase() { underTest = QuickSettingsSceneViewModel( applicationScope = testScope.backgroundScope, - deviceEntryInteractor = kosmos.deviceEntryInteractor, brightnessMirrorViewModel = kosmos.brightnessMirrorViewModel, shadeHeaderViewModel = kosmos.shadeHeaderViewModel, qsSceneAdapter = qsFlexiglassAdapter, @@ -112,6 +107,7 @@ class QuickSettingsSceneViewModelTest : SysuiTestCase() { 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 @@ class QuickSettingsSceneViewModelTest : SysuiTestCase() { 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 @@ class QuickSettingsSceneViewModelTest : SysuiTestCase() { 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 @@ class QuickSettingsSceneViewModelTest : SysuiTestCase() { 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 @@ class QuickSettingsSceneViewModelTest : SysuiTestCase() { 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 @@ class QuickSettingsSceneViewModelTest : SysuiTestCase() { 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 @@ class QuickSettingsSceneViewModelTest : SysuiTestCase() { 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 @@ class QuickSettingsSceneViewModelTest : SysuiTestCase() { 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 034c2e9b6789..f28ddebb6e9d 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.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.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 @@ class QuickSettingsShadeSceneViewModelTest : SysuiTestCase() { 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 @@ class QuickSettingsShadeSceneViewModelTest : SysuiTestCase() { 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 9e7e766cb820..f8a62cb65309 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.flags.fakeFeatureFlagsClassic 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.power.domain.interactor.powerInteractor import com.android.systemui.qs.footerActionsController import com.android.systemui.qs.footerActionsViewModelFactory import com.android.systemui.qs.ui.adapter.FakeQSSceneAdapter +import com.android.systemui.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 kotlinx.coroutines.test.runTest 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 @@ class SceneFrameworkIntegrationTest : SysuiTestCase() { 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 @@ class SceneFrameworkIntegrationTest : SysuiTestCase() { shadeSceneViewModel = ShadeSceneViewModel( applicationScope = testScope.backgroundScope, - deviceEntryInteractor = deviceEntryInteractor, shadeHeaderViewModel = kosmos.shadeHeaderViewModel, qsSceneAdapter = qsFlexiglassAdapter, notifications = kosmos.notificationsPlaceholderViewModel, @@ -280,6 +277,7 @@ class SceneFrameworkIntegrationTest : SysuiTestCase() { 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 @@ class SceneFrameworkIntegrationTest : SysuiTestCase() { 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 @@ class SceneFrameworkIntegrationTest : SysuiTestCase() { 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 @@ class SceneFrameworkIntegrationTest : SysuiTestCase() { 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 229a711d637d..92e6b16e5001 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 @@ package com.android.systemui.scene.domain.interactor 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 com.google.common.truth.Truth.assertThat 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 @@ class SceneInteractorTest : SysuiTestCase() { 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 @@ class SceneInteractorTest : SysuiTestCase() { @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 @@ class SceneInteractorTest : SysuiTestCase() { @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 @@ class SceneInteractorTest : SysuiTestCase() { } @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 @@ class SceneInteractorTest : SysuiTestCase() { @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 @@ class SceneInteractorTest : SysuiTestCase() { @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 @@ class SceneInteractorTest : SysuiTestCase() { @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 @@ class SceneInteractorTest : SysuiTestCase() { 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 @@ class SceneInteractorTest : SysuiTestCase() { @Test fun transitioningTo() = testScope.runTest { - underTest = kosmos.sceneInteractor val transitionState = MutableStateFlow<ObservableTransitionState>( ObservableTransitionState.Idle(underTest.currentScene.value) @@ -306,7 +279,6 @@ class SceneInteractorTest : SysuiTestCase() { @Test fun isTransitionUserInputOngoing_idle_false() = testScope.runTest { - underTest = kosmos.sceneInteractor val transitionState = MutableStateFlow<ObservableTransitionState>( ObservableTransitionState.Idle(Scenes.Shade) @@ -321,7 +293,6 @@ class SceneInteractorTest : SysuiTestCase() { @Test fun isTransitionUserInputOngoing_transition_true() = testScope.runTest { - underTest = kosmos.sceneInteractor val transitionState = MutableStateFlow<ObservableTransitionState>( ObservableTransitionState.Transition( @@ -343,7 +314,6 @@ class SceneInteractorTest : SysuiTestCase() { @Test fun isTransitionUserInputOngoing_updateMidTransition_false() = testScope.runTest { - underTest = kosmos.sceneInteractor val transitionState = MutableStateFlow<ObservableTransitionState>( ObservableTransitionState.Transition( @@ -377,7 +347,6 @@ class SceneInteractorTest : SysuiTestCase() { @Test fun isTransitionUserInputOngoing_updateOnIdle_false() = testScope.runTest { - underTest = kosmos.sceneInteractor val transitionState = MutableStateFlow<ObservableTransitionState>( ObservableTransitionState.Transition( @@ -403,7 +372,6 @@ class SceneInteractorTest : SysuiTestCase() { @Test fun isVisible() = testScope.runTest { - underTest = kosmos.sceneInteractor val isVisible by collectLastValue(underTest.isVisible) assertThat(isVisible).isTrue() @@ -417,7 +385,6 @@ class SceneInteractorTest : SysuiTestCase() { @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 @@ class SceneInteractorTest : SysuiTestCase() { 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 468c39daa282..3a5ff009c4fd 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.flags.EnableSceneContainer 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.android.systemui.testKosmos 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 @@ class ShadeBackActionInteractorImplTest : SysuiTestCase() { @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 482dc5d992f0..f88d10242e04 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.authentication.shared.model.AuthenticationMethodMode 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.footerActionsController 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 @@ class ShadeSceneViewModelTest : SysuiTestCase() { 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 @@ class ShadeSceneViewModelTest : SysuiTestCase() { underTest = ShadeSceneViewModel( applicationScope = testScope.backgroundScope, - deviceEntryInteractor = deviceEntryInteractor, shadeHeaderViewModel = kosmos.shadeHeaderViewModel, qsSceneAdapter = qsSceneAdapter, notifications = kosmos.notificationsPlaceholderViewModel, @@ -109,18 +108,21 @@ class ShadeSceneViewModelTest : SysuiTestCase() { 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 @@ class ShadeSceneViewModelTest : SysuiTestCase() { ) 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 @@ class ShadeSceneViewModelTest : SysuiTestCase() { 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 @@ class ShadeSceneViewModelTest : SysuiTestCase() { 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 88bef91d043f..206b39c28da3 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 @@ public class BaseHeadsUpManagerTest extends SysuiTestCase { 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 5ce2601d407d..08edf59000b8 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 2a1ce1fc5ec6..cc5a27d60ec1 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 1d9307ba20ed..17c0222ef69e 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 77172ca8f90e..d512e7c3a433 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 d308c3d89507..d979abbe0af9 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 1e0adec4e84f..73b7586f1210 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 86c807bf9d07..5dcf1618ed6b 100644 --- a/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt +++ b/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt @@ -178,6 +178,7 @@ constructor( 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 @@ constructor( 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 @@ constructor( 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 @@ constructor( 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 @@ constructor( 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 @@ constructor( 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 a9fd34015e73..03b13fe47c10 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.KeyguardBottomAreaRefactor; 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 @@ public class LegacyLockIconViewController implements Dumpable, LockIconViewContr 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 @@ public class LegacyLockIconViewController implements Dumpable, LockIconViewContr 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 177aad9a40fc..430ff0716ee0 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 @@ public class AuthContainerView extends LinearLayout } 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 298b87d05f39..c3d9240c40a1 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.DREAMING 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 java.io.PrintWriter 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 @@ open class UdfpsKeyguardViewControllerLegacy( @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 8993a3be058b..38f51daca2a4 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 @@ package com.android.systemui.communal 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 @@ constructor( 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 @@ constructor( // 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 260dcbad6201..7a4006d515f7 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 com.android.systemui.scene.shared.model.SceneDataSource 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 @@ interface CommunalSceneRepository { 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 @@ constructor( } } - 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 fdb40fb01d79..3e513f829831 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.Application 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 @@ constructor( /** 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 5cfe9798420d..0dab67c98761 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 @@ constructor( } /** 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 8b816db53970..4eaba065e078 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 @@ enum class CommunalBackgroundType(val value: Int) { 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 bc65ccb9ed5a..5312aec16b1b 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.content.res.Resources 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.core.Logger 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 @@ constructor( 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 @@ constructor( 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 9114aabae2e9..7a20ebcd2624 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.domain.interactor.CommunalInteractor 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 @@ constructor( // 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 @@ constructor( 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 @@ constructor( 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 000000000000..7f1146399f4e --- /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 51a3a6d827dd..e88a8b5b7cdb 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 @@ package com.android.systemui.communal.widgets 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.component1 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 @@ constructor( 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 7aab37e12b8c..9f0fc51abdd2 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.display.ui.viewmodel.ConnectingDisplayViewModel; 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 @@ import javax.inject.Named; 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 fc9406bd27d8..c6fb4f9d6956 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 @@ package com.android.systemui.keyboard 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 d09b9f68ea60..5d541260b05f 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 @@ constructor( ) : 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 @@ constructor( } } + 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 8ec460a7088f..1b201ceda310 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.AnimatorListenerAdapter 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 @@ class KeyguardTransitionRepositoryImpl 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 756c6c20e58d..118ea16bff40 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.Background 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.merge 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 @@ constructor( 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 a540d761c38f..f5b12a2ecfcf 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 @@ constructor( 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 @@ constructor( 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 8cf4b53618b4..aaf935f179b7 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.dagger.qualifiers.Main 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 @@ constructor( 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 73835a3c1c96..48660f25907a 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.shade.data.repository.ShadeRepository 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.map 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 @@ constructor( 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 @@ constructor( 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 2766b71fae02..37272dca911f 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 @@ constructor( } } + 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 @@ constructor( 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 @@ constructor( .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 @@ constructor( /** 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 @@ constructor( 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 3baeb7682e12..9b3ba7d8feb0 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 @@ constructor( 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 @@ constructor( 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 @@ constructor( } 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 c1e8d2214282..1306b2690c05 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 @@ sealed class Edge { 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 2b4c4af98ccd..0a8c1909937c 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 @@ constructor( 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 1f4bc61fb003..ecdc21cf3bb5 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.GlanceableHubToDreamingTransit 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 class DeviceEntryIconTransitionModule { 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 c05a1b732a50..d9a6d6401d64 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.KeyguardInteractor 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 @@ constructor( 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 000000000000..8eab406a1273 --- /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 ee52ad024e24..5027524e7a4b 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 @@ constructor( 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 8e985e11732f..37dffd1955d6 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.CoroutineDispatcher 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 @@ class MediaDataProcessor( .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 f47954a23890..3a292e7a6ddd 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 @@ class MediaMuteAwaitConnectionManager constructor( } 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 f677ec1b31bb..d0c7fbcac189 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 6cf2e52ff3d9..79cdfec182ae 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.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.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 com.android.systemui.statusbar.notification.stack.ui.viewmodel.Notificati 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 @@ class QuickSettingsSceneViewModel @Inject constructor( @Application private val applicationScope: CoroutineScope, - deviceEntryInteractor: DeviceEntryInteractor, val brightnessMirrorViewModel: BrightnessMirrorViewModel, val shadeHeaderViewModel: ShadeHeaderViewModel, val qsSceneAdapter: QSSceneAdapter, @@ -77,25 +73,15 @@ constructor( 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 @@ constructor( 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 @@ constructor( 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 c1a56465064f..bd748d5c2174 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 @@ constructor( 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 7a9d09ad815a..da239360a644 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 @@ package com.android.systemui.scene 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 @@ import dagger.multibindings.IntoMap 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 7e6dfb8762cd..a0cf82a28406 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 @@ package com.android.systemui.scene 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 @@ import dagger.multibindings.IntoMap 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 b918277bd3a4..a326ec1b53b3 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 @@ import dagger.Provides 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 000000000000..9b2a6dd9dcc2 --- /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 b1700e377725..998537c98f8d 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.SysUISingleton 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 @@ constructor( @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 @@ constructor( ) /** + * 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 @@ constructor( 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 @@ constructor( 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 @@ constructor( 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 @@ constructor( logger.logSceneChangeRequested( from = currentSceneKey, - to = toScene, + to = resolvedScene, reason = loggingReason, isInstant = true, ) - repository.snapToScene(toScene) + repository.snapToScene(resolvedScene) } /** @@ -288,6 +316,13 @@ constructor( 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 000000000000..f19929cc51a3 --- /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 000000000000..837252995e7d --- /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 09c80b09a388..ab24e0bbb690 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.CoroutineScope import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.stateIn /** Models UI state for the scene container. */ @@ -61,7 +63,9 @@ constructor( 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 @@ constructor( 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 c01b7b6f4883..1df085b24cdc 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 @@ public class NotificationShadeWindowViewController implements Dumpable { 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 884ccef3a080..ac1f97172c0e 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 @@ constructor( @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 @@ constructor( override fun instantCollapseShade() { sceneInteractor.snapToScene( - getCollapseDestinationScene(), + SceneFamilies.Home, "hide shade", ) } @@ -140,24 +136,12 @@ constructor( 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 55bd8c6c0834..3a483f460db7 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 @@ package com.android.systemui.shade.domain.interactor 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 @@ constructor( 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 b8dd62897587..0314091e792e 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 @@ package com.android.systemui.shade.ui.viewmodel 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 e4a2424e1ead..b0100b9642c2 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.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.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.domain.interactor.ShadeInteractor import com.android.systemui.shade.shared.model.ShadeMode import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationsPlaceholderViewModel import com.android.systemui.unfold.domain.interactor.UnfoldTransitionInteractor +import com.android.systemui.utils.coroutines.flow.flatMapLatestConflated import java.util.concurrent.atomic.AtomicBoolean import javax.inject.Inject import kotlinx.coroutines.CoroutineScope @@ -47,6 +48,7 @@ import kotlinx.coroutines.flow.Flow 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 @@ class ShadeSceneViewModel @Inject constructor( @Application private val applicationScope: CoroutineScope, - deviceEntryInteractor: DeviceEntryInteractor, val qsSceneAdapter: QSSceneAdapter, val shadeHeaderViewModel: ShadeHeaderViewModel, val notifications: NotificationsPlaceholderViewModel, @@ -70,16 +71,12 @@ constructor( ) { 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 @@ constructor( 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 @@ constructor( /** 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 @@ constructor( } 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 c29d700396af..a8fd082dd1e1 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 android.util.Log 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 @@ import javax.inject.Inject 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 @@ constructor( } 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 f84b5f48c864..367aaadf2942 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 @@ class AvalancheSuppressor( } 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 = "HUN allowed during avalanche because it is a calendar notification.") - ALLOW_CATEGORY_REMINDER(1807), + @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_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 @@ class AvalancheSuppressor( 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 fe22cc628b5f..b77321bbe46a 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 @@ public class NotificationStackScrollLayout 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 @@ public class NotificationStackScrollLayout } if (isUpOrCancel) { + mScrollViewFields.sendCurrentGestureOverscroll(false); setIsBeingDragged(false); } return false; @@ -3606,7 +3624,6 @@ public class NotificationStackScrollLayout 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 6dfaec9d8830..6a8c43a077a6 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 @@ constructor( 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 fc29eaba4b46..e5fc4e2968cf 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 @@ constructor( 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 @@ constructor( // 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 db4f0af5ba9f..b40bf56ee66e 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.KeyguardSurfaceBehindInte 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 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb 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 a97298527e11..32774e0b270a 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 @@ import javax.inject.Inject @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 @@ constructor( @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 @@ constructor( 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 @@ constructor( // 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 @@ constructor( 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 @@ constructor( 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 @@ constructor( 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 @@ constructor( // 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 405b57a1a04d..d9a2e956cc86 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 @@ package com.android.systemui.util.kotlin 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 @@ class Utils { ) /** + * 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 5702a8c61e7a..69a6f2aed4c4 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 @@ class ClockEventControllerTest : SysuiTestCase() { 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 @@ class ClockEventControllerTest : SysuiTestCase() { 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 @@ class ClockEventControllerTest : SysuiTestCase() { 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 @@ class ClockEventControllerTest : SysuiTestCase() { 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 @@ class ClockEventControllerTest : SysuiTestCase() { 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 25a87b8aaf60..958013908e44 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 androidx.test.filters.SmallTest 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 @@ class LegacyLockIconViewControllerWithCoroutinesTest : LegacyLockIconViewControl // 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 @@ class LegacyLockIconViewControllerWithCoroutinesTest : LegacyLockIconViewControl // 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 deacac39b587..1ce21e77f7f3 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.Mockito.verify 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 9cb4fb319fa2..cb8cfc2f5dd6 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.assertNotEquals; 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.Test; 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 3164f8e11593..5bfb3cf71c70 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.annotations.RequiresFlagsEnabled; 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.IMagnificationConnection; 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 @@ import org.mockito.MockitoAnnotations; * {@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 ad0217980e92..7b06dd65e7b3 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 static org.mockito.Mockito.verify; 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.Mockito; 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 1a885453eccb..5be1180d3bdb 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.Insets; 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.AccessibilityManager; 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 org.mockito.MockitoAnnotations; 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 9eead6a422ac..d0f8e7863537 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.ArgumentMatchers.eq; 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.Mock; 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 bbdd8050a142..ffba25cfa9f8 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.content.Context; 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.Mock; 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 e81613edc7ca..8f9b7c8cbc45 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 static org.mockito.Mockito.verify; 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.Mock; 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 3c974232990a..6e942979e0ed 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 static org.mockito.Mockito.verify; 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.Mockito; 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 9c601a8670c0..9222fc2222be 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 static com.google.common.truth.Truth.assertThat; 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.junit.runner.RunWith; 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 c67429492180..f46b2f905f5b 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.hardware.input.InputManager; 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 @@ import java.util.Optional; @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 cb42078460c2..f57003e37117 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.annotations.RequiresFlagsDisabled; 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.AccessibilityNodeInfo; 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 @@ import java.util.concurrent.atomic.AtomicInteger; @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 @@ public class WindowMagnificationControllerTest extends SysuiTestCase { }); } } -}
\ 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 01e4d58b68c2..e27268292763 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.annotations.RequiresFlagsEnabled; 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.widget.FrameLayout; 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 @@ import java.util.function.Supplier; @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 93c0eeaac488..ad9053a7edda 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.ArgumentMatchers.eq; 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.Test; 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 138fed298ef1..003f7e4479ba 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.Insets; 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.CompoundButton; 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.Mock; 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 aff52f511171..c4a92bf18283 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.Mockito.verify 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 095c945ba77b..b71739ac6434 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.content.ContextWrapper; 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.MockitoJUnit; 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 630db629bf76..b08f97a646b9 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 com.google.common.truth.Truth.assertThat; 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 @@ import java.util.List; /** 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 4b8758889fd4..5b2afe7443dd 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 com.google.common.truth.Truth.assertThat; 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 @@ import java.util.concurrent.atomic.AtomicBoolean; /** 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 abc95bc23f87..19b27003ebd1 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 static org.mockito.Mockito.verify; 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 @@ import org.mockito.junit.MockitoRule; /** 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 34a2e8719f0b..b59773700ed5 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 @@ package com.android.systemui.accessibility.floatingmenu; 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 @@ import org.junit.runner.RunWith; /** 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 1faa8aca74c7..24f3a29e64ee 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 static org.mockito.Mockito.verify; 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.List; 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 1f7d0336c590..c5509ac44046 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 static org.mockito.Mockito.verify; 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 android.view.accessibility.AccessibilityNodeInfo; 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 @@ import java.util.concurrent.atomic.AtomicBoolean; /** 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 9e8c6b3395e2..4373c880d999 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 static org.mockito.Mockito.verify; 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 android.view.accessibility.AccessibilityManager; 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.Collections; 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 9dd337e43b6a..2746fef42704 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 @@ package com.android.systemui.accessibility.floatingmenu; 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.Before; 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 31824ecaa432..bd1a7f072832 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 static org.mockito.Mockito.when; 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.WindowManager; 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.MockitoJUnit; 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 05d75606fd10..38095c83367d 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.os.UserHandle; 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 android.view.accessibility.AccessibilityManager; 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.ArrayList; 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 f6288b633ac8..103449b6b0f7 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.app.UiModeManager; 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.MockitoJUnit; 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 05f306b1e8b3..8fb71faf71a9 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 @@ package com.android.systemui.accessibility.floatingmenu; 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 @@ import org.junit.runner.RunWith; /** 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 d77a80a3318d..f67e8d068203 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 static com.google.common.truth.Truth.assertThat; 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 @@ import java.util.concurrent.atomic.AtomicBoolean; /** 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 e371b39faab4..0bd00fb0a0e9 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 @@ package com.android.systemui.accessibility.fontscaling 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 @@ private const val OFF: Int = 0 /** 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 0db0de2bcd7e..8f7dc7cf109b 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.media.AudioManager; 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.ArrayList; 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 cb9c26c7a4b6..09aa286874b9 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.ArgumentMatchers.eq; 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.MockitoJUnit; 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 d16db65334d3..9359adf96f80 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 com.google.common.truth.Truth.assertThat; 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.ArrayList; 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 717292378913..17ce1ddee87a 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.ComponentName; 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 @@ import java.util.List; /** * 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 2f4999b1b326..8fca557c7832 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.verify; 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 @@ import org.mockito.MockitoAnnotations; * 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 358e8cbd4a3c..4118c90a80a0 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.graphics.Region; 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.Lifecycle; 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.Collectors; 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 70a544ca6d2c..9aaf2958031a 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.Point 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.FrameLayout 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.Spy 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 e3be3822fb94..37f549a0c675 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.Rule 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 e14762cd8792..a60fb764215e 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.content.Context 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.ViewGroup.LayoutParams.MATCH_PARENT 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.MockitoJUnit 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 5e1a8e1432dd..ec42b7fc4713 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.Paint 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 070cad7302b2..b0f81c012cca 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_WDTH = "wdth" 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 42fcd547408a..e492c63d095c 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.Test 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 263d3750c657..6ba171525bd1 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 @@ package com.android.systemui.animation 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.times 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 f6fcd16cfd00..cca5f3525ef6 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.Color 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 @@ private val END_PAINT = TextPaint(PAINT).apply { 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 @@ private fun Layout.toBitmap(width: Int, height: Int) = 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 c2e6db362035..a8c3af9488f0 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.Test 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 0ed84ea2d183..4809d0e4838f 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 @@ package com.android.systemui.animation.back 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 com.google.common.truth.Truth.assertThat 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 44a546704953..d898d1cc0f8e 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 com.google.common.truth.Truth.assertThat 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 314abda66401..9548e297e7c5 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 @@ package com.android.systemui.animation.back 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.android.systemui.util.mockito.mock 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 0d464cfd71f7..476d6e373df3 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.AudioManager; 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.List; 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 4d582ab02fc4..828d36741aeb 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 static org.mockito.Mockito.when; 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.Mock; 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 3c073d5e7a3b..2bd0976f30dc 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 @@ package com.android.systemui.battery 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.junit.runner.RunWith 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 7c03d7899398..6dc4b10a57da 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 @@ package com.android.systemui.biometrics 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 @@ import javax.inject.Provider @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 d2c695739ea9..197cb843ba5f 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.biometrics.BiometricSourceType; 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 org.mockito.junit.MockitoRule; 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 a279d3ee67e4..20d9433effe2 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.face.FaceManager; 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 org.mockito.junit.MockitoRule; 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 5b6aee697fec..d26ccbcd12e0 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.graphics.Rect; 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.Before; 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 b3e845f00005..d2150471744e 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.BiometricSourceType 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.Before 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 @@ import org.mockito.junit.MockitoRule @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 eae953e2031e..d9b71619992f 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 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 kotlinx.coroutines.test.runTest 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 f5e96c93271a..9c114054bcfb 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.camera2.CameraManager 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.Before 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 @@ import org.mockito.junit.MockitoRule @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 63919865d8ab..0209ab803368 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 @@ package com.android.systemui.biometrics.data.repository 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.Before 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 @@ private const val USER_ID = 8 @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 7808c414de00..ff5a419faf35 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.FingerprintManager 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.Before 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 @@ import org.mockito.junit.MockitoJUnit @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 2682633f5dfd..22971bcf799e 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.Before 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 @@ private const val OP_PACKAGE_NAME = "biometric.testapp" @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 4cff3e6bfd23..5d2d20ce88e9 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 @@ package com.android.systemui.biometrics.domain.interactor 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 kotlinx.coroutines.test.runTest 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 8690d4eb1f3e..4856f156c4c7 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.DevicePolicyManager 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.Before 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 @@ private const val MAX_ATTEMPTS = 5 @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 31bdde2bc895..f40b6b046187 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.Before 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 3f83ce371ffe..a58efd3224a4 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 @@ package com.android.systemui.biometrics.domain.interactor 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.Before 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 c4d0d23ce9f3..5a3637668cfe 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 @@ package com.android.systemui.biometrics.domain.interactor 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.Before 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 @@ private const val OP_PACKAGE_NAME = "biometric.testapp" @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 6e78e334891b..720f2071ac73 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.BiometricManager.Authenticators 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.Before 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 5e7adb7671f7..3d63c5b6d0f8 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 @@ package com.android.systemui.biometrics.domain.interactor 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.Before 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.Mockito.`when` as whenever 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 d10b93534f3c..1f6a8b8aa6c2 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.graphics.Bitmap 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.truth.Truth.assertThat 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 74c43131b955..4d8fafc2111a 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.android.systemui.biometrics.fingerprintSensorPropertiesInternal 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 95b72d554896..f9bedc93e193 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 androidx.test.filters.SmallTest 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 317141ba42dd..33ddbf1989b3 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.SysuiTestCase 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 3e5c43a33474..3863b3ccdaee 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 androidx.test.filters.SmallTest 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 aff93bd339ad..a4653e736745 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.SysuiTestCase 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 ec2b10455b90..42382540d401 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.WindowManager 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.Before 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 @@ import org.mockito.junit.MockitoRule @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 9e804c123520..e4c5cd456f03 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 kotlinx.coroutines.test.runTest 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 @@ private const val OPERATION_ID = 10L @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 1b6aaabd4fd6..77ddd3183b00 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 kotlinx.coroutines.test.runTest 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 @@ import org.mockito.MockitoAnnotations @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 278a43ea1bf1..3eb2ff301212 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 f9b590f8e018..81132d72f86c 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 com.google.common.truth.Truth.assertThat 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 1167fce7524b..db6aba374ef3 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.TestScope 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 @@ private const val OP_PACKAGE_NAME_CAN_NOT_BE_FOUND = "can.not.be.found" @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 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa 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 b065393de1f6..3b2cf61dde68 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.DisplayInfo 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.Before 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 @@ import org.mockito.junit.MockitoRule @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 49f204372730..7d4ee25ef0a5 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.mock; 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.Mock; 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 8a1a08249856..4d7c49973605 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 @@ import org.mockito.Mock @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 4949716ad129..ac5ceb8ed266 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.MockitoJUnit 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 85e2a8d4b48e..b7b2be48bb61 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.MockitoJUnit 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 6fe7d86faab8..993cac721f48 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.MockitoJUnit 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 72156194b0e1..d01fac36230e 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.MATCH_PARENT 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.MockitoJUnit 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 4aa6209fab3c..1f3dcac24726 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.MockitoJUnit 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 11f74c0b98cb..9abb85d249eb 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 @@ package com.android.systemui.bluetooth.qsdialog 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.MockitoJUnit 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 762137bede27..64bd742d3af1 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.MockitoJUnit 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 4bcd9a9b3f1c..a27ccc67d584 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.content.pm.PackageManager 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.MockitoJUnit 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 2b4f9503f371..7f7abaf9b689 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.BluetoothAdapter 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.MockitoJUnit 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 ca9582240b93..923687b9375d 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.android.systemui.bouncer.ui.helper.BouncerSceneLayout.STANDARD_BOUNCE 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 @@ class BouncerSceneLayoutTest : SysuiTestCase() { companion object { @JvmStatic - @Parameterized.Parameters(name = "{0}") + @Parameters(name = "{0}") fun testCases() = listOf( Phone to @@ -158,7 +160,7 @@ class BouncerSceneLayoutTest : SysuiTestCase() { } } - @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 8e8172757cbe..1e9f8558d73c 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.Context 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.Mock import org.mockito.Mockito.verify import org.mockito.MockitoAnnotations -@RunWith(AndroidTestingRunner::class) +@RunWith(AndroidJUnit4::class) @SmallTest class BroadcastSenderTest : SysuiTestCase() { @@ -138,4 +138,4 @@ class BroadcastSenderTest : SysuiTestCase() { 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 43d2cb8be2d6..c693ecc7252f 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 @@ package com.android.systemui.broadcast 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.Mock import org.mockito.Mockito.verify import org.mockito.MockitoAnnotations -@RunWith(AndroidTestingRunner::class) +@RunWith(AndroidJUnit4::class) @SmallTest class PendingRemovalStoreTest : SysuiTestCase() { @@ -78,4 +78,4 @@ class PendingRemovalStoreTest : SysuiTestCase() { 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 582f30110a5f..d878352183bd 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.Context 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.Mockito.verify 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 669795bc91a8..bea0db66555d 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.Intent 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 com.google.common.util.concurrent.MoreExecutors 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.MockitoAnnotations 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 1e522fc9941a..34940246a7cb 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.Test 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 11756d5b8ea2..034bab855faf 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.Mockito.verify 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 6afbde09610e..88bfcf00423f 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.ArgumentMatchers.eq; 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.List; 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 6e00b70b5410..ec8cc4d493d0 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.never; 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.List; 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 14dcd58e40a2..8e1be4160498 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 com.google.common.truth.Truth.assertThat; 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.Mock; 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 ab6d5b771d5a..cbfeceeb88d3 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.android.systemui.classifier.Classifier.QS_SWIPE_SIDE; 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.Test; 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 2ceee6dc56d8..9289867cbfe2 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.anyDouble; 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.ArrayList; 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 2c904e7e3735..8e4bec3f2e50 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.Mockito.verify 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 5361cef2ac64..5d0bfd7d3d87 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.times; 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.Mock; 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 057b0a158cab..49c6239d2541 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.verify; 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 org.mockito.MockitoAnnotations; 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 38355c74a4a7..8e19a1f84d72 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 @@ package com.android.systemui.classifier; 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 org.mockito.MockitoAnnotations; 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 b8ea062eedc8..352a25c49e8b 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 com.google.common.truth.Truth.assertThat; 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.Test; 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 1c3922a57368..f965a11c2aa9 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 com.google.common.truth.Truth.assertThat; 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.Mock; 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 e3c800e441e0..65e90888ecb2 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 com.google.common.truth.Truth.assertThat; 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.ArrayList; 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 ad7afa3c593f..9a27f386d519 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 @@ package com.android.systemui.classifier; 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.junit.runner.RunWith; 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 588edb770047..80c44e2537ec 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 com.google.common.truth.Truth.assertThat; 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.Mock; 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 ae2b8bbb4ce6..1fe726863f7f 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.android.systemui.classifier.Classifier.BRIGHTNESS_SLIDER; 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 org.junit.runner.RunWith; 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 c0dada4725b8..5d76e325bd3a 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.content.Context 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 d552c9d922ff..de07cda21e75 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 @@ import org.junit.runner.RunWith /** 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 2f4fc96ebf6c..bb400f274fbe 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 kotlinx.coroutines.test.runTest 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 @@ import org.mockito.MockitoAnnotations @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 4c4205eaa8bb..cecb5251b6e2 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.never; 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 @@ import org.mockito.MockitoAnnotations; * 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 288f3b651a3c..ed214749d6a7 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 com.google.common.truth.Truth.assertThat; 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.Collection; 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 c43df17f498c..dd3f991e60b7 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 static org.mockito.Mockito.when; 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.Collections; 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 baaeee1c3bd2..383e0fab73ff 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.never; 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.function.Consumer; 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 a23e9e40959a..12cb8a61e0d8 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.mock; 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.HashSet; 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 8cd23b27e4eb..d728517e2000 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.content.Context; 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.Arrays; 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 e23e1f4c0578..1e802337a9e7 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.android.systemui.complication.ComplicationUtils.convertComplic 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.HashSet; 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 09675e28f5da..98b119ae75c4 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.junit.Assert.assertNotEquals; 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.Mockito; 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 b9aa4c65be92..22ab4994f026 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.verify; 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.Mock; 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 18bd960b30a5..ddf69b5b964c 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 static org.mockito.Mockito.when; 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.List; 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 05b4a41d1b40..3a856a05ac02 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 static org.mockito.Mockito.when; 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.Mock; 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 87de8657f593..6c354ef0966c 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.verify; 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.HashSet; 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 03e4f9ae1685..c2fe009c13bb 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.Test 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 4d0f2ed47495..28e0cffc4f78 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 @@ package com.android.systemui.controls 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.Mock import org.mockito.MockitoAnnotations @SmallTest -@RunWith(AndroidTestingRunner::class) +@RunWith(AndroidJUnit4::class) class CustomIconCacheTest : SysuiTestCase() { companion object { @@ -98,4 +98,4 @@ class CustomIconCacheTest : SysuiTestCase() { 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 129fe9a36a0d..8d6e3a04ee50 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 org.mockito.MockitoAnnotations import java.io.File @SmallTest -@RunWith(AndroidTestingRunner::class) +@RunWith(AndroidJUnit4::class) class AuxiliaryPersistenceWrapperTest : SysuiTestCase() { companion object { @@ -128,4 +128,4 @@ class AuxiliaryPersistenceWrapperTest : SysuiTestCase() { 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 6cc3ef19ef3b..928514657257 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 org.mockito.MockitoAnnotations 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 724c9d1dfc42..ed0c7ee54f13 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.Control 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.Mockito.`when` 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 de455f6374f1..cf385e79483b 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.os.UserHandle 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.Optional 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 690b9a7248be..afa5ceccb6cb 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 @@ package com.android.systemui.controls.controller 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 org.junit.runner.RunWith 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 b5d34768dc9f..f9c2c6b791f1 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.IControlsProvider 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.Mockito.`when` 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 581e88b52c0f..e04ce45592b1 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.Assert.assertEquals 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 228374671ad4..b6ea62e48f0f 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 @@ package com.android.systemui.controls.controller 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.Mockito.verify 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 85d6211bdb8c..282ea5ccb5c2 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.Context 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.Mockito.`when` as whenever 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 789d6dfebf72..b5c6c538ec9e 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.IControlsSubscriber 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.Mockito.verify 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 267520ef7f1d..7d197f75b5f9 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.content.ComponentName 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.Mockito.verify 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 54f66dc957d9..844cc1f1f8fa 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.Mockito.`when` 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 4ea96169e8a5..5528f6523111 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 @@ package com.android.systemui.controls.management 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.Mockito.verify 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 226ef3b85706..56c7c854b69d 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 @@ package com.android.systemui.controls.management 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 org.mockito.MockitoAnnotations 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 2a4524b971a4..39e1e1d8bb57 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 @@ package com.android.systemui.controls.management 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.Mockito.verify 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 88d36af71958..f5616d45a3da 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.ComponentName 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.Mockito.verify 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 6361e94bd0ef..e4f0910f99fd 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.content.pm.ServiceInfo 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.Mockito.verify 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 d17495f21a68..7698520cdf2c 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.ApplicationInfo 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.Mockito.verifyNoMoreInteractions 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 ca970bb41d56..5008927fc939 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.os.UserHandle 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 org.mockito.MockitoAnnotations 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 ae77d1f590e3..c49867a30dc9 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.Parcelable 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.Mockito.`when` import org.mockito.MockitoAnnotations @SmallTest -@RunWith(AndroidTestingRunner::class) +@RunWith(AndroidJUnit4::class) class ControlsRequestReceiverTest : SysuiTestCase() { @Mock @@ -266,4 +266,4 @@ class ControlsRequestReceiverTest : SysuiTestCase() { } } } -}
\ 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 f0003ed603ab..281addc053f9 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.Mockito.verifyNoMoreInteractions import org.mockito.MockitoAnnotations @SmallTest -@RunWith(AndroidTestingRunner::class) +@RunWith(AndroidJUnit4::class) class FavoritesModelTest : SysuiTestCase() { companion object { @@ -299,4 +299,4 @@ class FavoritesModelTest : SysuiTestCase() { } 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 7f0ea9a7a6d0..d8aac101e84f 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 @@ package com.android.systemui.controls.management 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.MockitoAnnotations 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 18ce4a8e1b7a..fd4c6810a7fc 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 @@ package com.android.systemui.controls.panels 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.Before 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 a7e7ba97b5e5..86e3481ff263 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 @@ package com.android.systemui.controls.panels 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.Mock 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 154c3734558d..aee334f82f63 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.content.SharedPreferences 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.Mockito.`when` 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 b904ac14e707..3bdd5cf8cfe7 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 @@ package com.android.systemui.controls.settings 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 kotlinx.coroutines.test.runTest 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 c44429bbbf9e..9e8914a1119f 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.ApplicationInfo 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 @@ import org.mockito.MockitoAnnotations @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 bfdb9231a9f8..193ce21dcfa0 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.Bitmap 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.Test 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 101b8ed4f6f0..4b30fa5dd161 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.graphics.drawable.Icon 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.junit.runner.RunWith 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 e279d28de499..03aa622977be 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 @@ package com.android.systemui.controls.ui 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.Mockito.verify 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 38c6a0e236ed..ca33f16b10ac 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.Mockito.verify 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 48e3962717c1..66303ebb0def 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 @@ package com.android.systemui.controls.ui 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.Mockito.verify 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 8f3813d49b8f..20890a7780c8 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.graphics.drawable.Drawable 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.Mockito.`when` 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 677108cab291..10b3ce31a895 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 @@ package com.android.systemui.controls.ui 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.Mockito.verify 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 483ab3bae6f1..6092b8c5eb65 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.Test 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 021facc51dba..de2d8529adff 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 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.Mockito.verify 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 57176f0eabe0..45798072ed73 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.Test 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 31e09549a2b5..9f4836ad1d9b 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.Test 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 1e4753e5b4a5..23da3f1d3ac0 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 @@ import org.junit.runner.RunWith @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 1040ec453a7c..f029847161d1 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 @@ package com.android.systemui.decor 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 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.Mock 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 a1cffc1419d5..69fab5675e7f 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.spy 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 e4ddc37c4f3c..6d6c6efff13a 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.Mock 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 @@ class PrivacyDotDecorProviderFactoryTest : SysuiTestCase() { 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 d1d48803c486..4da988a27cd5 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.Mock import org.mockito.Mockito import org.mockito.Mockito.spy -@RunWith(AndroidTestingRunner::class) +@RunWith(AndroidJUnit4::class) @SmallTest class RoundedCornerDecorProviderFactoryTest : SysuiTestCase() { @@ -139,4 +139,4 @@ class RoundedCornerDecorProviderFactoryTest : SysuiTestCase() { }) } } -}
\ 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 2bff7d22785a..9d440c353d04 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 @@ package com.android.systemui.decor 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.junit.runner.RunWith 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 6c2e13691fba..4793a52f3497 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 @@ package com.android.systemui.demomode 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 @@ import org.mockito.MockitoAnnotations @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 e9b4bbb5bb1a..6b0de92711b9 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.junit.runner.RunWith 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 820329119f8d..64ff5f73bd4d 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_ALL 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 com.google.common.truth.Truth.assertThat 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 c79cbab87576..3f5b9a35d3a5 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.junit.runner.RunWith 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 68d49c78c567..01868ae3e5da 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 @@ package com.android.systemui.display.data.repository 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.never 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 37c740968261..fd9964f938c8 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 @@ package com.android.systemui.display.domain.interactor 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.Test 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 d118cc718aed..8105bc8ae6a0 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 @@ package com.android.systemui.display.ui.view 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.never 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 6d2df19b997d..8c125f833b41 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 static org.mockito.Mockito.when; 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.Mock; 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 27fd3b13d55a..aa5edae72684 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.content.Intent; 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 org.mockito.MockitoAnnotations; 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 @@ public class DozeScreenBrightnessTest extends SysuiTestCase { 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 3cc04511d57b..9c127b85b38e 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.content.res.Resources; 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.ArrayList; 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 92941f946286..fad52e090c69 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 static org.mockito.Mockito.when; 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.Mock; 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 40b8fc77b50f..3d1a0d0cef3c 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.app.StatusBarManager; 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.Mock; 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 f07edf331f13..4253c766e62f 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 static org.mockito.Mockito.when; 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 com.android.systemui.statusbar.phone.DozeParameters; 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 2bd2bff80951..771ecaf967a2 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.Test 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 91da88e480d4..0ae59bbf47fe 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 kotlin.test.fail 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 2daa86bf5c14..d1082bdca76b 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.Mockito.verify 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 53e9dc814161..2a8967edf13d 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 @@ class MediaMuteAwaitConnectionManagerTest : SysuiTestCase() { 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 a7bf87def5be..d280be216f5e 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.compose.animation.scene.TransitionKey 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.StateFlow 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) + snapToScene(toScene, 0) - override fun snapToScene(toScene: SceneKey) { - this.currentScene.value = toScene - this._transitionState.value = flowOf(ObservableTransitionState.Idle(toScene)) + 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 ef7aa6308491..d1fbb5e95ee6 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 @@ val Kosmos.sceneInteractor by 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 d08855f190ed..cc836acac37d 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 @@ package com.android.systemui.shade 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 @@ val Kosmos.shadeControllerSceneImpl by 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 872eba06961e..1ca3509cbd79 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 45ec03241495..fec102857619 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 c5625e47040a..4d81ea16220c 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 @@ package com.android.systemui.shade.ui.viewmodel 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 @@ import com.android.systemui.qs.ui.viewmodel.QuickSettingsShadeSceneViewModel 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 63a183d506f8..f85d786f89c5 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 @@ class UiAutomationManager { 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 @@ class UiAutomationManager { 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 @@ class UiAutomationManager { } // 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 0d0c21dcf49c..c9cce1568335 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.AppOpsManager; 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 @@ public class CompanionDeviceManagerService extends SystemService { } @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 95c0e0ee5272..26aa0535d43e 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 @@ final class ActivityManagerConstants extends ContentObserver { */ 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 @@ final class ActivityManagerConstants extends ContentObserver { 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 @@ final class ActivityManagerConstants extends ContentObserver { 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 @@ final class ActivityManagerConstants extends ContentObserver { 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 @@ final class ActivityManagerConstants extends ContentObserver { 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 @@ final class ActivityManagerConstants extends ContentObserver { return; } switch (name) { + case KEY_MAX_CACHED_PROCESSES: + updateMaxCachedProcesses(); + break; case KEY_DEFAULT_BACKGROUND_ACTIVITY_STARTS_ENABLED: updateBackgroundActivityStarts(); break; @@ -1378,7 +1417,16 @@ final class ActivityManagerConstants extends ContentObserver { 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 @@ final class ActivityManagerConstants extends ContentObserver { 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 @@ final class ActivityManagerConstants extends ContentObserver { 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 @@ final class ActivityManagerConstants extends ContentObserver { 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 @@ final class ActivityManagerConstants extends ContentObserver { 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 e0ec17124318..d79d198b554e 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 @@ public class ActivityManagerService extends IActivityManager.Stub @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 @@ public class ActivityManagerService extends IActivityManager.Stub 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 @@ public class ActivityManagerService extends IActivityManager.Stub 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 3ed60fcae5e4..dda48adbf732 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 @@ public class AppProfiler { 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 @@ public class AppProfiler { // 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 a8227fa8e38b..dc6e2fa39b65 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 @@ public final class AppStartInfoTracker { // 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 @@ public final class AppStartInfoTracker { } } + 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 d642b02e23ea..29e0f7ae6f01 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.net.BaseNetworkObserver; 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.PowerStatsScheduler; 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 @@ public final class BatteryStatsService extends IBatteryStats.Stub 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 @@ public final class BatteryStatsService extends IBatteryStats.Stub 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 @@ public final class BatteryStatsService extends IBatteryStats.Stub 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 @@ public final class BatteryStatsService extends IBatteryStats.Stub 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 105e201add52..ab34dd4477fd 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 @@ public class OomAdjuster { 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 @@ public class OomAdjuster { 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 @@ public class OomAdjuster { 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 @@ public class OomAdjuster { } 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 @@ public class OomAdjuster { } 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 @@ public class OomAdjuster { } } + /** + * 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 9a3b575bbaaf..3df56877cbd6 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 @@ public class SettingsToPropertiesMapper { "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 c7ddccc2964e..5dd1480c2052 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 @@ public class AudioService extends IAudioService.Stub 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 @@ public class AudioService extends IAudioService.Stub 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 @@ public class AudioService extends IAudioService.Stub 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 409ed17001b7..8ae04accb62f 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 static android.media.audio.Flags.autoPublicVolumeApiHardening; 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.content.pm.PackageManager; 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 @@ public class HardeningEnforcer { * @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 @@ public class HardeningEnforcer { } /** - * 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 35d38e2373f5..70f319321d30 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 @@ public class MediaFocusControl implements PlayerFocusEnforcer { * @param fd * @param clientId * @param callingPackageName - * @param attributionTag * @param flags * @param sdk * @param forceDuck only true if @@ -1096,7 +1095,7 @@ public class MediaFocusControl implements PlayerFocusEnforcer { */ 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 @@ public class MediaFocusControl implements PlayerFocusEnforcer { 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 f9f56ee4d134..266093229186 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 @@ public class FingerprintAuthenticationClient 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 eeacc53f0fd4..e4db634c0e26 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 @@ import javax.xml.datatype.DatatypeConfigurationException; * <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 @@ import javax.xml.datatype.DatatypeConfigurationException; * </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 d7ed904e398d..f769a89551c7 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 class RefreshRateData { 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 @@ public class RefreshRateData { + ", defaultRefreshRateInHbmHdr: " + defaultRefreshRateInHbmHdr + ", defaultRefreshRateInHbmSunlight: " + defaultRefreshRateInHbmSunlight + ", lowPowerSupportedModes=" + lowPowerSupportedModes + + ", lowLightBlockingZoneSupportedModes=" + lowLightBlockingZoneSupportedModes + "} "; } @@ -100,13 +105,19 @@ public class RefreshRateData { 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 d519748929bf..d610f086b3b5 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 @@ public class DisplayModeDirector { } } + 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 @@ public class DisplayModeDirector { return false; } + @GuardedBy("mLock") private void onBrightnessChangedLocked() { if (!mRefreshRateChangeable || mLowPowerModeEnabled) { return; @@ -2315,8 +2327,14 @@ public class DisplayModeDirector { 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 @@ public class DisplayModeDirector { 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 @@ public class DisplayModeDirector { } 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 cacc8b4ab50a..7cbdd13152b5 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 @@ interface Vote { 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 f572845dc214..966be5318973 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.ArraySet; 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 @@ public class BiometricDeferredQueue { 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 ae3d36acdb7f..22b33ddcfa2b 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 @@ public class LockSettingsService extends ILockSettings.Stub { 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 c03497e629f0..ba7d3b8c76d2 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.internal.util.function.pooled.PooledLambda; 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 @@ class MediaRouter2ServiceImpl { 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 @@ class MediaRouter2ServiceImpl { 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 @@ class MediaRouter2ServiceImpl { } } + @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 @@ class MediaRouter2ServiceImpl { } } + @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 @@ class MediaRouter2ServiceImpl { } } + @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 192ac6287884..1188a0764051 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.media.flags.Flags; 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 @@ public final class MediaRouterService extends IMediaRouterService.Stub // 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 @@ public final class MediaRouterService extends IMediaRouterService.Stub } // 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 @@ public final class MediaRouterService extends IMediaRouterService.Stub 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 f02a3fff12f5..1ebc856af2d8 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 @@ public class MediaSessionService extends SystemService implements Monitor { @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 @@ public class MediaSessionService extends SystemService implements Monitor { 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 @@ public class MediaSessionService extends SystemService implements Monitor { } } - 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 @@ public class MediaSessionService extends SystemService implements Monitor { 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 c60ac3a74ebd..f03c639c103c 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 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { // 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 669cdaaf3ab5..bbc7c013f170 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 050d44eed2ea..b93dcdc93a82 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 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements 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 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements .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 8d6d774a9959..39565526f33e 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 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile 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 b05a421e6e87..e544ae64521c 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 @@ class TalkbackShortcutController { } 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 000000000000..a48f162321dd --- /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 efaa7a8598c0..5bae5a42d484 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 @@ public class BatteryStatsImpl extends BatteryStats { 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 @@ public class BatteryStatsImpl extends BatteryStats { 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 @@ public class BatteryStatsImpl extends BatteryStats { 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 @@ public class BatteryStatsImpl extends BatteryStats { 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 @@ public class BatteryStatsImpl extends BatteryStats { 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 @@ public class BatteryStatsImpl extends BatteryStats { 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 b25239574071..ba6e4a96ddc4 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 @@ public class BatteryUsageStatsProvider { 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 000000000000..f7216c9af9d6 --- /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 000000000000..48dac8a8a970 --- /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 6710d02bee90..988e8fea70b9 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 @@ final class VibratorController { 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 @@ final class VibratorController { } /** - * 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 @@ final class VibratorController { } /** - * 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 @@ final class VibratorController { } /** - * 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 @@ final class VibratorController { } /** - * 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 @@ final class VibratorController { } } - /** 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 80f1125a4ecf..f70a3ba107e1 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 @@ public class WallpaperCropper { 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 @@ public class WallpaperCropper { } } - 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 @@ public class WallpaperCropper { // 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 @@ public class WallpaperCropper { 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 @@ public class WallpaperCropper { // 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 @@ public class WallpaperCropper { 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 @@ public class WallpaperCropper { @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 @@ public class WallpaperCropper { * 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 @@ public class WallpaperCropper { */ @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 @@ public class WallpaperCropper { 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 @@ public class WallpaperCropper { 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 fec1af47d6e6..d9e143403e2d 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 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A */ private CompatDisplayInsets mCompatDisplayInsets; - private final TaskFragment.ConfigOverrideHint mResolveConfigHint; + @VisibleForTesting + final TaskFragment.ConfigOverrideHint mResolveConfigHint; private final boolean mOptOutEdgeToEdge; @@ -8533,6 +8534,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A 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 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } 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 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A 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 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A : 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 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } 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 class ActivityRecord extends WindowToken implements WindowManagerService.A } 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 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A */ 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 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A @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 class ActivityRecord extends WindowToken implements WindowManagerService.A 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 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A // 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 19d7a3c8d86c..a4fb95964a5c 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 @@ public class BackgroundActivityStartController { 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 @@ public class BackgroundActivityStartController { 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 @@ public class BackgroundActivityStartController { + ", 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 194771f6b387..5e93e8930bab 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 @@ final class LetterboxUiController { 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 @@ final class LetterboxUiController { && 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 @@ final class LetterboxUiController { 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 @@ final class LetterboxUiController { && 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 b8b746a3de7f..187b1057b6fc 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.INVALID_UID; 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.PermissionChecker; 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 @@ class TaskFragment extends WindowContainer<WindowContainer> { 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 @@ class TaskFragment extends WindowContainer<WindowContainer> { 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 edbba9244738..70143bae9fb0 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 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< 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 f47a59d6cec9..4be21d872383 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 @@ public: } 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 @@ static void vibratorOff(JNIEnv* env, jclass /* clazz */, jlong ptr) { } 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 610b502f2a07..eeb8b9b0b469 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 203a6d99dba1..757b23a2df7e 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 @@ package com.android.server.display.config { 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 3bdcd9b0fdcd..161a8168d993 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 @@ class AppOpService(private val service: AccessCheckingService) : AppOpsCheckingS } override fun setUidMode(uid: Int, deviceId: String, code: Int, mode: Int): Boolean { + val appId = UserHandle.getAppId(uid) + val userId = UserHandle.getUserId(uid) + val appOpName = AppOpsManager.opToPublicName(code) + if ( Flags.runtimePermissionAppopsMappingEnabled() && code in runtimeAppOpToPermissionNames ) { - Slog.w( - LOG_TAG, - "Cannot set UID mode for runtime permission app op, " + - " callingUid = ${Binder.getCallingUid()}, " + + 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)}", - RuntimeException() - ) + " 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 } - val appId = UserHandle.getAppId(uid) - val userId = UserHandle.getUserId(uid) - val appOpName = AppOpsManager.opToPublicName(code) 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 820628c98dee..8e6954b474cb 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 1535298f74e3..2029b71034eb 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 androidx.test.platform.app.InstrumentationRegistry; 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 @@ public class InputMethodServiceTest { 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 46d08b0ce018..9a25b1acfaae 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 @@ public final class DisplayDeviceConfigTest { 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 @@ public final class DisplayDeviceConfigTest { + "</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 @@ public final class DisplayDeviceConfigTest { + "<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 88c0daaffcd2..95702aa1bce1 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 @@ package com.android.server.display.mode 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.junit.MockitoJUnit 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 @@ class BrightnessObserverTest { 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 @@ class BrightnessObserverTest { 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 714b423fae70..242d5593c3c8 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 @@ public class DisplayModeDirectorTest { /* 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 @@ public class DisplayModeDirectorTest { /* 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 1206e30b9e88..5b07166d63e4 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 @@ fun createRefreshRateData( 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 1b0a8d2222b9..f1bf86f2f57c 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 @@ public class WallpaperCropperTest { 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 @@ public class WallpaperCropperTest { 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 @@ public class WallpaperCropperTest { 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 @@ public class WallpaperCropperTest { 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 @@ public class WallpaperCropperTest { 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 @@ public class WallpaperCropperTest { 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 @@ public class WallpaperCropperTest { 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 851cf4a535a2..976cc18127f0 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 @@ public class BatteryUsageStatsTest { 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 40de1b253dea..182d60328440 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 @@ public class FingerprintAuthenticationClientTest { } @Test - public void luxProbeNotEnabledOnStartWhenNotWake() throws RemoteException { + public void luxProbeDisabledOnStartWhenNotWake() throws RemoteException { luxProbeEnabledOnStart(false /* isAwake */); } @@ -337,6 +337,7 @@ public class FingerprintAuthenticationClientTest { .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 19ce217e581c..9dac23f075e6 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 @@ public class VibrationThreadTest { .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 @@ public class VibrationThreadTest { 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 c67d1ec63827..a39a1a8637df 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 @@ public class BackNavigationControllerTests extends WindowTestsBase { }).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 7adac5b283c5..1a366b3e3a4f 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.RemoteException; 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 @@ public class SizeCompatTests extends WindowTestsBase { } } - // 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 @@ public class SizeCompatTests extends WindowTestsBase { 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 @@ public class SizeCompatTests extends WindowTestsBase { 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 @@ public class SizeCompatTests extends WindowTestsBase { } @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 @@ public class SizeCompatTests extends WindowTestsBase { // 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 @@ public class SizeCompatTests extends WindowTestsBase { @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 @@ public class SizeCompatTests extends WindowTestsBase { @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 @@ public class SizeCompatTests extends WindowTestsBase { 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 @@ public class SizeCompatTests extends WindowTestsBase { @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 @@ public class SizeCompatTests extends WindowTestsBase { 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 @@ public class SizeCompatTests extends WindowTestsBase { 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 @@ public class SizeCompatTests extends WindowTestsBase { 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 @@ public class SizeCompatTests extends WindowTestsBase { 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 @@ public class SizeCompatTests extends WindowTestsBase { 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 @@ public class SizeCompatTests extends WindowTestsBase { 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 @@ public class SizeCompatTests extends WindowTestsBase { 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 @@ public class SizeCompatTests extends WindowTestsBase { 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 @@ public class SizeCompatTests extends WindowTestsBase { 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 @@ public class SizeCompatTests extends WindowTestsBase { 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 @@ public class SizeCompatTests extends WindowTestsBase { 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 @@ public class SizeCompatTests extends WindowTestsBase { @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 @@ public class SizeCompatTests extends WindowTestsBase { 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 @@ public class SizeCompatTests extends WindowTestsBase { 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 @@ public class SizeCompatTests extends WindowTestsBase { 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 @@ public class SizeCompatTests extends WindowTestsBase { 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 @@ public class SizeCompatTests extends WindowTestsBase { 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 @@ public class SizeCompatTests extends WindowTestsBase { 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 @@ public class SizeCompatTests extends WindowTestsBase { 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 @@ public class SizeCompatTests extends WindowTestsBase { 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 @@ public class SizeCompatTests extends WindowTestsBase { 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 @@ public class SizeCompatTests extends WindowTestsBase { @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 @@ public class SizeCompatTests extends WindowTestsBase { // 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 @@ public class SizeCompatTests extends WindowTestsBase { 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 @@ public class SizeCompatTests extends WindowTestsBase { 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 @@ public class SizeCompatTests extends WindowTestsBase { 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 @@ public class SizeCompatTests extends WindowTestsBase { @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 @@ public class SizeCompatTests extends WindowTestsBase { .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 @@ public class SizeCompatTests extends WindowTestsBase { .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 @@ public class SizeCompatTests extends WindowTestsBase { .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 @@ public class SizeCompatTests extends WindowTestsBase { .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 @@ public class SizeCompatTests extends WindowTestsBase { @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 @@ public class SizeCompatTests extends WindowTestsBase { */ 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 @@ public class SizeCompatTests extends WindowTestsBase { } } - /** 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 */); } - /** Asserts that the activity is best fitted in the parent. */ private void assertFitted() { - final boolean inSizeCompatMode = mActivity.inSizeCompatMode(); + assertFitted(mActivity); + } + + /** Asserts that the activity is best fitted in the parent. */ + 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 9f85acb98817..4ebbf496b2a4 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 @@ public class WindowContainerTests extends WindowTestsBase { 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 @@ public class WindowContainerTests extends WindowTestsBase { 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 @@ public class WindowContainerTests extends WindowTestsBase { @Test public void testOnDisplayChanged_cleanupChanging() { final Task task = createTask(mDisplayContent); + addLocalInsets(task); spyOn(task.mSurfaceFreezer); mDisplayContent.mChangingContainers.add(task); @@ -988,6 +1000,7 @@ public class WindowContainerTests extends WindowTestsBase { // 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 bc8f65edaa12..09cb464198b5 100644 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -9842,6 +9842,43 @@ public class CarrierConfigManager { 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 @@ public class CarrierConfigManager { 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); |