diff --git a/AconfigFlags.bp b/AconfigFlags.bp index c30164c065af5edfc4240cf2ed56f5cf9160502f..003b7f87fa23fe365d98dca25d6d4cc85539bfc9 100644 --- a/AconfigFlags.bp +++ b/AconfigFlags.bp @@ -42,6 +42,7 @@ aconfig_srcjars = [ ":android.credentials.flags-aconfig-java{.generated_srcjars}", ":android.view.contentprotection.flags-aconfig-java{.generated_srcjars}", ":android.service.voice.flags-aconfig-java{.generated_srcjars}", + ":android.service.autofill.flags-aconfig-java{.generated_srcjars}", ] filegroup { @@ -416,3 +417,19 @@ java_aconfig_library { aconfig_declarations: "android.service.voice.flags-aconfig", defaults: ["framework-minus-apex-aconfig-java-defaults"], } + +// Autofill +aconfig_declarations { + name: "android.service.autofill.flags-aconfig", + package: "android.service.autofill", + srcs: [ + "services/autofill/bugfixes.aconfig", + "services/autofill/features.aconfig" + ], +} + +java_aconfig_library { + name: "android.service.autofill.flags-aconfig-java", + aconfig_declarations: "android.service.autofill.flags-aconfig", + defaults: ["framework-minus-apex-aconfig-java-defaults"], +} diff --git a/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java b/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java index f252a0ba48cf7d35c1a5d48393d1135e28adfbce..158d914575c6c6c94fff049404cfd2efd5afdff9 100644 --- a/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java +++ b/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java @@ -1030,6 +1030,12 @@ public class DeviceIdleController extends SystemService "light_idle_to_initial_flex"; private static final String KEY_LIGHT_IDLE_TIMEOUT_MAX_FLEX = "light_max_idle_to_flex"; private static final String KEY_LIGHT_IDLE_FACTOR = "light_idle_factor"; + private static final String KEY_LIGHT_IDLE_INCREASE_LINEARLY = + "light_idle_increase_linearly"; + private static final String KEY_LIGHT_IDLE_LINEAR_INCREASE_FACTOR_MS = + "light_idle_linear_increase_factor_ms"; + private static final String KEY_LIGHT_IDLE_FLEX_LINEAR_INCREASE_FACTOR_MS = + "light_idle_flex_linear_increase_factor_ms"; private static final String KEY_LIGHT_MAX_IDLE_TIMEOUT = "light_max_idle_to"; private static final String KEY_LIGHT_IDLE_MAINTENANCE_MIN_BUDGET = "light_idle_maintenance_min_budget"; @@ -1079,6 +1085,10 @@ public class DeviceIdleController extends SystemService private long mDefaultLightIdleTimeoutMaxFlex = !COMPRESS_TIME ? 15 * 60 * 1000L : 60 * 1000L; private float mDefaultLightIdleFactor = 2f; + private boolean mDefaultLightIdleIncreaseLinearly; + private long mDefaultLightIdleLinearIncreaseFactorMs = mDefaultLightIdleTimeout; + private long mDefaultLightIdleFlexLinearIncreaseFactorMs = + mDefaultLightIdleTimeoutInitialFlex; private long mDefaultLightMaxIdleTimeout = !COMPRESS_TIME ? 15 * 60 * 1000L : 60 * 1000L; private long mDefaultLightIdleMaintenanceMinBudget = @@ -1173,6 +1183,37 @@ public class DeviceIdleController extends SystemService */ public float LIGHT_IDLE_FACTOR = mDefaultLightIdleFactor; + /** + * Whether to increase the light idle mode time linearly or exponentially. + * If true, will increase linearly + * (i.e. {@link #LIGHT_IDLE_TIMEOUT} + x * {@link #LIGHT_IDLE_LINEAR_INCREASE_FACTOR_MS}). + * If false, will increase by exponentially + * (i.e. {@link #LIGHT_IDLE_TIMEOUT} * ({@link #LIGHT_IDLE_FACTOR} ^ x)). + * This will also impact how the light idle flex value + * ({@link #LIGHT_IDLE_TIMEOUT_INITIAL_FLEX}) is increased (using + * {@link #LIGHT_IDLE_FLEX_LINEAR_INCREASE_FACTOR_MS} for the linear increase).. + * + * @see #KEY_LIGHT_IDLE_INCREASE_LINEARLY + */ + public boolean LIGHT_IDLE_INCREASE_LINEARLY = mDefaultLightIdleIncreaseLinearly; + + /** + * Amount of time to increase the light idle time by, if increasing it linearly. + * + * @see #KEY_LIGHT_IDLE_LINEAR_INCREASE_FACTOR_MS + * @see #LIGHT_IDLE_INCREASE_LINEARLY + */ + public long LIGHT_IDLE_LINEAR_INCREASE_FACTOR_MS = mDefaultLightIdleLinearIncreaseFactorMs; + + /** + * Amount of time to increase the light idle flex time by, if increasing it linearly. + * + * @see #KEY_LIGHT_IDLE_LINEAR_INCREASE_FACTOR_MS + * @see #LIGHT_IDLE_INCREASE_LINEARLY + */ + public long LIGHT_IDLE_FLEX_LINEAR_INCREASE_FACTOR_MS = + mDefaultLightIdleFlexLinearIncreaseFactorMs; + /** * This is the maximum time we will stay in light idle mode. * @@ -1409,6 +1450,16 @@ public class DeviceIdleController extends SystemService mDefaultLightIdleTimeoutMaxFlex); mDefaultLightIdleFactor = res.getFloat( com.android.internal.R.integer.device_idle_light_idle_factor); + mDefaultLightIdleIncreaseLinearly = res.getBoolean( + com.android.internal.R.bool.device_idle_light_idle_increase_linearly); + mDefaultLightIdleLinearIncreaseFactorMs = getTimeout(res.getInteger( + com.android.internal.R.integer + .device_idle_light_idle_linear_increase_factor_ms), + mDefaultLightIdleLinearIncreaseFactorMs); + mDefaultLightIdleFlexLinearIncreaseFactorMs = getTimeout(res.getInteger( + com.android.internal.R.integer + .device_idle_light_idle_flex_linear_increase_factor_ms), + mDefaultLightIdleFlexLinearIncreaseFactorMs); mDefaultLightMaxIdleTimeout = getTimeout( res.getInteger(com.android.internal.R.integer.device_idle_light_max_idle_to_ms), mDefaultLightMaxIdleTimeout); @@ -1487,6 +1538,9 @@ public class DeviceIdleController extends SystemService LIGHT_IDLE_TIMEOUT_INITIAL_FLEX = mDefaultLightIdleTimeoutInitialFlex; LIGHT_IDLE_TIMEOUT_MAX_FLEX = mDefaultLightIdleTimeoutMaxFlex; LIGHT_IDLE_FACTOR = mDefaultLightIdleFactor; + LIGHT_IDLE_INCREASE_LINEARLY = mDefaultLightIdleIncreaseLinearly; + LIGHT_IDLE_LINEAR_INCREASE_FACTOR_MS = mDefaultLightIdleLinearIncreaseFactorMs; + LIGHT_IDLE_FLEX_LINEAR_INCREASE_FACTOR_MS = mDefaultLightIdleFlexLinearIncreaseFactorMs; LIGHT_MAX_IDLE_TIMEOUT = mDefaultLightMaxIdleTimeout; LIGHT_IDLE_MAINTENANCE_MIN_BUDGET = mDefaultLightIdleMaintenanceMinBudget; LIGHT_IDLE_MAINTENANCE_MAX_BUDGET = mDefaultLightIdleMaintenanceMaxBudget; @@ -1556,6 +1610,21 @@ public class DeviceIdleController extends SystemService LIGHT_IDLE_FACTOR = Math.max(1, properties.getFloat( KEY_LIGHT_IDLE_FACTOR, mDefaultLightIdleFactor)); break; + case KEY_LIGHT_IDLE_INCREASE_LINEARLY: + LIGHT_IDLE_INCREASE_LINEARLY = properties.getBoolean( + KEY_LIGHT_IDLE_INCREASE_LINEARLY, + mDefaultLightIdleIncreaseLinearly); + break; + case KEY_LIGHT_IDLE_LINEAR_INCREASE_FACTOR_MS: + LIGHT_IDLE_LINEAR_INCREASE_FACTOR_MS = properties.getLong( + KEY_LIGHT_IDLE_LINEAR_INCREASE_FACTOR_MS, + mDefaultLightIdleLinearIncreaseFactorMs); + break; + case KEY_LIGHT_IDLE_FLEX_LINEAR_INCREASE_FACTOR_MS: + LIGHT_IDLE_FLEX_LINEAR_INCREASE_FACTOR_MS = properties.getLong( + KEY_LIGHT_IDLE_FLEX_LINEAR_INCREASE_FACTOR_MS, + mDefaultLightIdleFlexLinearIncreaseFactorMs); + break; case KEY_LIGHT_MAX_IDLE_TIMEOUT: LIGHT_MAX_IDLE_TIMEOUT = properties.getLong( KEY_LIGHT_MAX_IDLE_TIMEOUT, mDefaultLightMaxIdleTimeout); @@ -1716,6 +1785,20 @@ public class DeviceIdleController extends SystemService pw.print(LIGHT_IDLE_FACTOR); pw.println(); + pw.print(" "); pw.print(KEY_LIGHT_IDLE_INCREASE_LINEARLY); pw.print("="); + pw.print(LIGHT_IDLE_INCREASE_LINEARLY); + pw.println(); + + pw.print(" "); pw.print(KEY_LIGHT_IDLE_LINEAR_INCREASE_FACTOR_MS); + pw.print("="); + pw.print(LIGHT_IDLE_LINEAR_INCREASE_FACTOR_MS); + pw.println(); + + pw.print(" "); pw.print(KEY_LIGHT_IDLE_FLEX_LINEAR_INCREASE_FACTOR_MS); + pw.print("="); + pw.print(LIGHT_IDLE_FLEX_LINEAR_INCREASE_FACTOR_MS); + pw.println(); + pw.print(" "); pw.print(KEY_LIGHT_MAX_IDLE_TIMEOUT); pw.print("="); TimeUtils.formatDuration(LIGHT_MAX_IDLE_TIMEOUT, pw); pw.println(); @@ -3694,10 +3777,18 @@ public class DeviceIdleController extends SystemService } mMaintenanceStartTime = 0; scheduleLightAlarmLocked(mNextLightIdleDelay, mNextLightIdleDelayFlex, true); - mNextLightIdleDelay = Math.min(mConstants.LIGHT_MAX_IDLE_TIMEOUT, - (long) (mNextLightIdleDelay * mConstants.LIGHT_IDLE_FACTOR)); - mNextLightIdleDelayFlex = Math.min(mConstants.LIGHT_IDLE_TIMEOUT_MAX_FLEX, - (long) (mNextLightIdleDelayFlex * mConstants.LIGHT_IDLE_FACTOR)); + if (!mConstants.LIGHT_IDLE_INCREASE_LINEARLY) { + mNextLightIdleDelay = Math.min(mConstants.LIGHT_MAX_IDLE_TIMEOUT, + (long) (mNextLightIdleDelay * mConstants.LIGHT_IDLE_FACTOR)); + mNextLightIdleDelayFlex = Math.min(mConstants.LIGHT_IDLE_TIMEOUT_MAX_FLEX, + (long) (mNextLightIdleDelayFlex * mConstants.LIGHT_IDLE_FACTOR)); + } else { + mNextLightIdleDelay = Math.min(mConstants.LIGHT_MAX_IDLE_TIMEOUT, + mNextLightIdleDelay + mConstants.LIGHT_IDLE_LINEAR_INCREASE_FACTOR_MS); + mNextLightIdleDelayFlex = Math.min(mConstants.LIGHT_IDLE_TIMEOUT_MAX_FLEX, + mNextLightIdleDelayFlex + + mConstants.LIGHT_IDLE_FLEX_LINEAR_INCREASE_FACTOR_MS); + } moveToLightStateLocked(LIGHT_STATE_IDLE, reason); addEvent(EVENT_LIGHT_IDLE, null); mGoingIdleWakeLock.acquire(); diff --git a/core/api/system-current.txt b/core/api/system-current.txt index 358c8e72064b3f7c0a5724214291ad6eddbd3058..a99eeb0c36d830e1528e8b676829d954617cb33b 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -3946,7 +3946,7 @@ package android.content.pm { field public static final int DELETE_FAILED_OWNER_BLOCKED = -4; // 0xfffffffc field public static final int DELETE_KEEP_DATA = 1; // 0x1 field public static final int DELETE_SUCCEEDED = 1; // 0x1 - field public static final String EXTRA_REQUEST_PERMISSIONS_DEVICE_ID = "android.content.pm.extra.REQUEST_PERMISSIONS_DEVICE_ID"; + field @FlaggedApi("android.permission.flags.device_aware_permission_apis") public static final String EXTRA_REQUEST_PERMISSIONS_DEVICE_ID = "android.content.pm.extra.REQUEST_PERMISSIONS_DEVICE_ID"; field public static final String EXTRA_REQUEST_PERMISSIONS_LEGACY_ACCESS_PERMISSION_NAMES = "android.content.pm.extra.REQUEST_PERMISSIONS_LEGACY_ACCESS_PERMISSION_NAMES"; field public static final String EXTRA_REQUEST_PERMISSIONS_NAMES = "android.content.pm.extra.REQUEST_PERMISSIONS_NAMES"; field public static final String EXTRA_REQUEST_PERMISSIONS_RESULTS = "android.content.pm.extra.REQUEST_PERMISSIONS_RESULTS"; diff --git a/core/java/android/companion/CompanionDeviceManager.java b/core/java/android/companion/CompanionDeviceManager.java index 2fb428b3e0b47421cd0f7d5fa76d2e595886daae..a84845a15a79217b2404d5a174f043d28d10bba6 100644 --- a/core/java/android/companion/CompanionDeviceManager.java +++ b/core/java/android/companion/CompanionDeviceManager.java @@ -239,6 +239,12 @@ public final class CompanionDeviceManager { @SystemApi(client = MODULE_LIBRARIES) public static final int MESSAGE_REQUEST_PERMISSION_RESTORE = 0x63826983; // ?RES + /** + * The length limit of Association tag. + * @hide + */ + private static final int ASSOCIATION_TAG_LENGTH_LIMIT = 100; + /** * Callback for applications to receive updates about and the outcome of * {@link AssociationRequest} issued via {@code associate()} call. @@ -1409,7 +1415,7 @@ public final class CompanionDeviceManager { /** * Sets the {@link AssociationInfo#getTag() tag} for this association. * - * <p>The length of the tag must be at most 20 characters. + * <p>The length of the tag must be at most 100 characters to save disk space. * * <p>This allows to store useful information about the associated devices. * @@ -1421,8 +1427,8 @@ public final class CompanionDeviceManager { public void setAssociationTag(int associationId, @NonNull String tag) { Objects.requireNonNull(tag, "tag cannot be null"); - if (tag.length() > 20) { - throw new IllegalArgumentException("Length of the tag must be at most 20 characters"); + if (tag.length() > ASSOCIATION_TAG_LENGTH_LIMIT) { + throw new IllegalArgumentException("Length of the tag must be at most 100 characters"); } try { diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index 3fc515d3d37d2a52778badd6759b7f0eef4e6f34..8fbe50c3288164889ff907e5582e6b763b9d184b 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -4802,6 +4802,7 @@ public abstract class PackageManager { * @hide */ @SystemApi + @FlaggedApi(android.permission.flags.Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS) public static final String EXTRA_REQUEST_PERMISSIONS_DEVICE_ID = "android.content.pm.extra.REQUEST_PERMISSIONS_DEVICE_ID"; diff --git a/core/java/android/view/IRecentsAnimationController.aidl b/core/java/android/view/IRecentsAnimationController.aidl index c4d307073d122fe0e5b694f782f07a38b9b4dd8b..a150187bbc6c5ef0de3f33b49516382695911cfc 100644 --- a/core/java/android/view/IRecentsAnimationController.aidl +++ b/core/java/android/view/IRecentsAnimationController.aidl @@ -23,6 +23,8 @@ import android.graphics.GraphicBuffer; import android.window.PictureInPictureSurfaceTransaction; import android.window.TaskSnapshot; +import com.android.internal.os.IResultReceiver; + /** * Passed to the {@link IRecentsAnimationRunner} in order for the runner to control to let the * runner control certain aspects of the recents animation, and to notify window manager when the @@ -58,7 +60,7 @@ interface IRecentsAnimationController { * top resumed app, false otherwise. */ @UnsupportedAppUsage - void finish(boolean moveHomeToTop, boolean sendUserLeaveHint); + void finish(boolean moveHomeToTop, boolean sendUserLeaveHint, in IResultReceiver finishCb); /** * Called by the handler to indicate that the recents animation input consumer should be diff --git a/core/java/android/view/InputWindowHandle.java b/core/java/android/view/InputWindowHandle.java index 2761aaeb4a7d7f7473560951267910a3706a6c63..45b3fdd7e5bc57f18cef6563d84656d5be241533 100644 --- a/core/java/android/view/InputWindowHandle.java +++ b/core/java/android/view/InputWindowHandle.java @@ -16,6 +16,8 @@ package android.view; +import static com.android.window.flags.Flags.surfaceTrustedOverlay; + import android.annotation.IntDef; import android.annotation.Nullable; import android.graphics.Matrix; @@ -35,7 +37,6 @@ import java.lang.ref.WeakReference; * @hide */ public final class InputWindowHandle { - /** * An internal annotation for all the {@link android.os.InputConfig} flags that can be * specified to {@link #inputConfig} to control the behavior of an input window. Only the @@ -59,7 +60,6 @@ public final class InputWindowHandle { InputConfig.DUPLICATE_TOUCH_TO_WALLPAPER, InputConfig.IS_WALLPAPER, InputConfig.PAUSE_DISPATCHING, - InputConfig.TRUSTED_OVERLAY, InputConfig.WATCH_OUTSIDE_TOUCH, InputConfig.SLIPPERY, InputConfig.DISABLE_USER_ACTIVITY, @@ -272,4 +272,13 @@ public final class InputWindowHandle { } this.inputConfig &= ~inputConfig; } + + public void setTrustedOverlay(SurfaceControl.Transaction t, SurfaceControl sc, + boolean isTrusted) { + if (surfaceTrustedOverlay()) { + t.setTrustedOverlay(sc, isTrusted); + } else if (isTrusted) { + inputConfig |= InputConfig.TRUSTED_OVERLAY; + } + } } diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java index e64274ec38925f69b35f5758762c0ad3dcc36aa5..2f4bea0270c1819a1291e1823448af2ed0738f2d 100644 --- a/core/java/android/view/WindowManager.java +++ b/core/java/android/view/WindowManager.java @@ -1850,6 +1850,8 @@ public interface WindowManager extends ViewManager { to = "PHONE"), @ViewDebug.IntToString(from = TYPE_SYSTEM_ALERT, to = "SYSTEM_ALERT"), + @ViewDebug.IntToString(from = TYPE_KEYGUARD, + to = "KEYGUARD"), @ViewDebug.IntToString(from = TYPE_TOAST, to = "TOAST"), @ViewDebug.IntToString(from = TYPE_SYSTEM_OVERLAY, @@ -1898,6 +1900,8 @@ public interface WindowManager extends ViewManager { to = "PRIVATE_PRESENTATION"), @ViewDebug.IntToString(from = TYPE_VOICE_INTERACTION, to = "VOICE_INTERACTION"), + @ViewDebug.IntToString(from = TYPE_ACCESSIBILITY_OVERLAY, + to = "ACCESSIBILITY_OVERLAY"), @ViewDebug.IntToString(from = TYPE_VOICE_INTERACTION_STARTING, to = "VOICE_INTERACTION_STARTING"), @ViewDebug.IntToString(from = TYPE_DOCK_DIVIDER, @@ -1907,7 +1911,13 @@ public interface WindowManager extends ViewManager { @ViewDebug.IntToString(from = TYPE_SCREENSHOT, to = "SCREENSHOT"), @ViewDebug.IntToString(from = TYPE_APPLICATION_OVERLAY, - to = "APPLICATION_OVERLAY") + to = "APPLICATION_OVERLAY"), + @ViewDebug.IntToString(from = TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY, + to = "ACCESSIBILITY_MAGNIFICATION_OVERLAY"), + @ViewDebug.IntToString(from = TYPE_NOTIFICATION_SHADE, + to = "NOTIFICATION_SHADE"), + @ViewDebug.IntToString(from = TYPE_STATUS_BAR_ADDITIONAL, + to = "STATUS_BAR_ADDITIONAL") }) @WindowType public int type; diff --git a/core/java/android/view/accessibility/flags/accessibility_flags.aconfig b/core/java/android/view/accessibility/flags/accessibility_flags.aconfig index a0d58001a30d1f8d8e4f1ab23fe8125ee08fc802..e31ad82d3f5577738cb3f619a2dbac5637a86286 100644 --- a/core/java/android/view/accessibility/flags/accessibility_flags.aconfig +++ b/core/java/android/view/accessibility/flags/accessibility_flags.aconfig @@ -4,5 +4,5 @@ flag { namespace: "accessibility" name: "force_invert_color" description: "Enable force force-dark for smart inversion and dark theme everywhere" - bug: "239594271" + bug: "282821643" } \ No newline at end of file diff --git a/core/java/android/window/flags/window_surfaces.aconfig b/core/java/android/window/flags/window_surfaces.aconfig new file mode 100644 index 0000000000000000000000000000000000000000..1b98806a0f01535696e42740ee3df7158e60c2b9 --- /dev/null +++ b/core/java/android/window/flags/window_surfaces.aconfig @@ -0,0 +1,11 @@ +package: "com.android.window.flags" + +# Project link: https://gantry.corp.google.com/projects/android_platform_window_surfaces/changes + +flag { + namespace: "window_surfaces" + name: "surface_trusted_overlay" + description: "Whether to add trusted overlay flag on the SurfaceControl or the InputWindow" + is_fixed_read_only: true + bug: "292032926" +} diff --git a/core/java/com/android/internal/jank/InteractionJankMonitor.java b/core/java/com/android/internal/jank/InteractionJankMonitor.java index 1bfb51cc4b82148169643cfcb6d16c0ca8cc30a2..6e836e077e4446e1f3c84a8276cb66dd1692e870 100644 --- a/core/java/com/android/internal/jank/InteractionJankMonitor.java +++ b/core/java/com/android/internal/jank/InteractionJankMonitor.java @@ -837,25 +837,41 @@ public class InteractionJankMonitor { @WorkerThread private void updateProperties(DeviceConfig.Properties properties) { - mSamplingInterval = properties.getInt(SETTINGS_SAMPLING_INTERVAL_KEY, - DEFAULT_SAMPLING_INTERVAL); - mTraceThresholdMissedFrames = properties.getInt(SETTINGS_THRESHOLD_MISSED_FRAMES_KEY, - DEFAULT_TRACE_THRESHOLD_MISSED_FRAMES); - mTraceThresholdFrameTimeMillis = properties.getInt( - SETTINGS_THRESHOLD_FRAME_TIME_MILLIS_KEY, - DEFAULT_TRACE_THRESHOLD_FRAME_TIME_MILLIS); - // Never allow the debug overlay to be used on user builds - boolean debugOverlayEnabled = Build.IS_DEBUGGABLE && properties.getBoolean( - SETTINGS_DEBUG_OVERLAY_ENABLED_KEY, - DEFAULT_DEBUG_OVERLAY_ENABLED); - if (debugOverlayEnabled && mDebugOverlay == null) { - mDebugOverlay = new InteractionMonitorDebugOverlay(mLock, mDebugBgColor, mDebugYOffset); - } else if (!debugOverlayEnabled && mDebugOverlay != null) { - mDebugOverlay.dispose(); - mDebugOverlay = null; + for (String property : properties.getKeyset()) { + switch (property) { + case SETTINGS_SAMPLING_INTERVAL_KEY: + mSamplingInterval = properties.getInt(property, DEFAULT_SAMPLING_INTERVAL); + break; + case SETTINGS_THRESHOLD_MISSED_FRAMES_KEY: + mTraceThresholdMissedFrames = + properties.getInt(property, DEFAULT_TRACE_THRESHOLD_MISSED_FRAMES); + break; + case SETTINGS_THRESHOLD_FRAME_TIME_MILLIS_KEY: + mTraceThresholdFrameTimeMillis = + properties.getInt(property, DEFAULT_TRACE_THRESHOLD_FRAME_TIME_MILLIS); + break; + case SETTINGS_ENABLED_KEY: + mEnabled = properties.getBoolean(property, DEFAULT_ENABLED); + break; + case SETTINGS_DEBUG_OVERLAY_ENABLED_KEY: + // Never allow the debug overlay to be used on user builds + boolean debugOverlayEnabled = Build.IS_DEBUGGABLE + && properties.getBoolean(property, DEFAULT_DEBUG_OVERLAY_ENABLED); + if (debugOverlayEnabled && mDebugOverlay == null) { + mDebugOverlay = new InteractionMonitorDebugOverlay( + mLock, mDebugBgColor, mDebugYOffset); + } else if (!debugOverlayEnabled && mDebugOverlay != null) { + mDebugOverlay.dispose(); + mDebugOverlay = null; + } + break; + default: + if (DEBUG) { + Log.d(TAG, "Got a change event for an unknown property: " + + property + " => " + properties.getString(property, "")); + } + } } - // The memory visibility is powered by the volatile field, mEnabled. - mEnabled = properties.getBoolean(SETTINGS_ENABLED_KEY, DEFAULT_ENABLED); } @VisibleForTesting diff --git a/core/java/com/android/internal/view/FloatingActionMode.java b/core/java/com/android/internal/view/FloatingActionMode.java index 06e69f2d985956155168b7a01af63ebf2e5a6006..fd435d0595c21aeaa796821fae467a35a217a2fb 100644 --- a/core/java/com/android/internal/view/FloatingActionMode.java +++ b/core/java/com/android/internal/view/FloatingActionMode.java @@ -222,6 +222,7 @@ public final class FloatingActionMode extends ActionMode { private boolean isContentRectWithinBounds() { mContext.getDisplayNoVerify().getRealSize(mDisplaySize); mScreenRect.set(0, 0, mDisplaySize.x, mDisplaySize.y); + mScreenRect.offset(mRootViewPositionOnScreen[0], mRootViewPositionOnScreen[1]); return intersectsClosed(mContentRectOnScreen, mScreenRect) && intersectsClosed(mContentRectOnScreen, mViewRectOnScreen); diff --git a/core/res/res/layout/autofill_save.xml b/core/res/res/layout/autofill_save.xml index 8b6c90141bb76c95d47853111de2b46280fb34c0..27f8138ac5e371f3aa8bacac7a5fb4cbead0b5c7 100644 --- a/core/res/res/layout/autofill_save.xml +++ b/core/res/res/layout/autofill_save.xml @@ -60,10 +60,11 @@ android:gravity="center" android:textAppearance="@style/AutofillSaveUiTitle"> </TextView> - <LinearLayout + <FrameLayout android:id="@+id/autofill_save_custom_subtitle" android:layout_width="match_parent" android:layout_height="wrap_content" + android:minHeight="0dp" android:visibility="gone"/> </LinearLayout> diff --git a/core/res/res/values/config_device_idle.xml b/core/res/res/values/config_device_idle.xml index 98a5ff9c4a790b7886f7d16b5508d365038b3297..bc9ca3decec32c6521ec629b81e475c030a9a94f 100644 --- a/core/res/res/values/config_device_idle.xml +++ b/core/res/res/values/config_device_idle.xml @@ -42,6 +42,15 @@ <!-- Default for DeviceIdleController.Constants.LIGHT_IDLE_FACTOR --> <item name="device_idle_light_idle_factor" format="float" type="integer">2.0</item> + <!-- Default for DeviceIdleController.Constants.LIGHT_IDLE_INCREASE_LINEARLY --> + <bool name="device_idle_light_idle_increase_linearly">false</bool> + + <!-- Default for DeviceIdleController.Constants.LIGHT_IDLE_LINEAR_INCREASE_FACTOR_MS --> + <integer name="device_idle_light_idle_linear_increase_factor_ms">300000</integer> + + <!-- Default for DeviceIdleController.Constants.LIGHT_IDLE_FLEX_LINEAR_INCREASE_FACTOR_MS --> + <integer name="device_idle_light_idle_flex_linear_increase_factor_ms">60000</integer> + <!-- Default for DeviceIdleController.Constants.LIGHT_MAX_IDLE_TIMEOUT --> <integer name="device_idle_light_max_idle_to_ms">900000</integer> diff --git a/core/res/res/values/config_telephony.xml b/core/res/res/values/config_telephony.xml index c68e6ad15546c317c2857f37152da5a46428b8e2..3ba150bcdd44f18ac4224db76d40865335d5d3e5 100644 --- a/core/res/res/values/config_telephony.xml +++ b/core/res/res/values/config_telephony.xml @@ -73,7 +73,7 @@ CarrierConfigManager#KEY_AUTO_DATA_SWITCH_RAT_SIGNAL_SCORE_STRING_ARRAY. If 0, the device always switch to the higher score SIM. If < 0, the network type and signal strength based auto switch is disabled. --> - <integer name="auto_data_switch_score_tolerance">-1</integer> + <integer name="auto_data_switch_score_tolerance">4000</integer> <java-symbol type="integer" name="auto_data_switch_score_tolerance" /> <!-- Boolean indicating whether the Iwlan data service supports persistence of iwlan ipsec diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 193f3adeedea4e4c906c445fff6991e81e74b88b..7f3069542306751eb6e57501bdd4b2350593962e 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -4537,7 +4537,10 @@ <java-symbol type="integer" name="device_idle_light_idle_to_init_flex_ms" /> <java-symbol type="integer" name="device_idle_light_idle_to_max_flex_ms" /> <java-symbol type="integer" name="device_idle_light_idle_factor" /> + <java-symbol type="bool" name="device_idle_light_idle_increase_linearly" /> <java-symbol type="integer" name="device_idle_light_max_idle_to_ms" /> + <java-symbol type="integer" name="device_idle_light_idle_linear_increase_factor_ms" /> + <java-symbol type="integer" name="device_idle_light_idle_flex_linear_increase_factor_ms" /> <java-symbol type="integer" name="device_idle_light_idle_maintenance_min_budget_ms" /> <java-symbol type="integer" name="device_idle_light_idle_maintenance_max_budget_ms" /> <java-symbol type="integer" name="device_idle_min_light_maintenance_time_ms" /> diff --git a/core/tests/BroadcastRadioTests/Android.bp b/core/tests/BroadcastRadioTests/Android.bp index 85d54e02d318076a63a6f4ed56a6087f823560aa..054d10c336e6058320455106a783cbfb835712e7 100644 --- a/core/tests/BroadcastRadioTests/Android.bp +++ b/core/tests/BroadcastRadioTests/Android.bp @@ -38,7 +38,7 @@ android_test { static_libs: [ "services.core", "androidx.test.rules", - "truth-prebuilt", + "truth", "testng", "mockito-target-extended", ], diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/TunerSessionTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/TunerSessionTest.java index a1952282dd0b7351debfdd8768e315932f9cf132..824f5910f96c31b7437dd82382b671d93693471a 100644 --- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/TunerSessionTest.java +++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/TunerSessionTest.java @@ -16,20 +16,20 @@ package com.android.server.broadcastradio.aidl; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.after; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.any; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyBoolean; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyInt; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.doThrow; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.eq; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.never; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.timeout; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; import static org.junit.Assert.assertThrows; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyBoolean; -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.timeout; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; import android.app.compat.CompatChanges; import android.graphics.Bitmap; @@ -81,8 +81,8 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase { private static final int USER_ID_1 = 11; private static final int USER_ID_2 = 12; - private static final VerificationWithTimeout CALLBACK_TIMEOUT = - timeout(/* millis= */ 200); + private static final int CALLBACK_TIMEOUT_MS = 200; + private static final VerificationWithTimeout CALLBACK_TIMEOUT = timeout(CALLBACK_TIMEOUT_MS); private static final int SIGNAL_QUALITY = 90; private static final long AM_FM_FREQUENCY_SPACING = 500; private static final long[] AM_FM_FREQUENCY_LIST = {97_500, 98_100, 99_100}; @@ -166,12 +166,12 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase { @Before public void setup() throws Exception { - when(mUserHandleMock.getIdentifier()).thenReturn(USER_ID_1); doReturn(true).when(() -> CompatChanges.isChangeEnabled( eq(ConversionUtils.RADIO_U_VERSION_REQUIRED), anyInt())); + doReturn(USER_ID_1).when(mUserHandleMock).getIdentifier(); + doReturn(mUserHandleMock).when(() -> Binder.getCallingUserHandle()); doReturn(true).when(() -> RadioServiceUserController.isCurrentOrSystemUser()); doReturn(USER_ID_1).when(() -> RadioServiceUserController.getCurrentUser()); - doReturn(mUserHandleMock).when(() -> Binder.getCallingUserHandle()); mRadioModule = new RadioModule(mBroadcastRadioMock, AidlTestUtils.makeDefaultModuleProperties()); @@ -222,7 +222,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase { return Result.OK; }).when(mBroadcastRadioMock).seek(anyBoolean(), anyBoolean()); - when(mBroadcastRadioMock.getImage(anyInt())).thenReturn(null); + doReturn(null).when(mBroadcastRadioMock).getImage(anyInt()); doAnswer(invocation -> { int configFlag = (int) invocation.getArguments()[0]; @@ -275,7 +275,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase { mTunerSessions[0].setConfiguration(FM_BAND_CONFIG); - verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT.times(0)) + verify(mAidlTunerCallbackMocks[0], after(CALLBACK_TIMEOUT_MS).times(0)) .onConfigurationChanged(FM_BAND_CONFIG); } @@ -446,25 +446,10 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase { mTunerSessions[0].tune(initialSel); - verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT.times(0)) + verify(mAidlTunerCallbackMocks[0], after(CALLBACK_TIMEOUT_MS).times(0)) .onCurrentProgramInfoChanged(tuneInfo); } - @Test - public void tune_forSystemUser() throws Exception { - when(mUserHandleMock.getIdentifier()).thenReturn(UserHandle.USER_SYSTEM); - doReturn(mUserHandleMock).when(() -> Binder.getCallingUserHandle()); - doReturn(true).when(() -> RadioServiceUserController.isCurrentOrSystemUser()); - ProgramSelector initialSel = AidlTestUtils.makeFmSelector(AM_FM_FREQUENCY_LIST[1]); - RadioManager.ProgramInfo tuneInfo = - AidlTestUtils.makeProgramInfo(initialSel, SIGNAL_QUALITY); - openAidlClients(/* numClients= */ 1); - - mTunerSessions[0].tune(initialSel); - - verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT).onCurrentProgramInfoChanged(tuneInfo); - } - @Test public void tune_withUnknownErrorFromHal_fails() throws Exception { openAidlClients(/* numClients= */ 1); @@ -525,7 +510,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase { mTunerSessions[0].step(/* directionDown= */ true, /* skipSubChannel= */ false); - verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT.times(0)) + verify(mAidlTunerCallbackMocks[0], after(CALLBACK_TIMEOUT_MS).times(0)) .onCurrentProgramInfoChanged(any()); } @@ -604,7 +589,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase { mTunerSessions[0].seek(/* directionDown= */ true, /* skipSubChannel= */ false); - verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT.times(0)) + verify(mAidlTunerCallbackMocks[0], after(CALLBACK_TIMEOUT_MS).times(0)) .onCurrentProgramInfoChanged(seekUpInfo); } @@ -638,6 +623,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase { openAidlClients(/* numClients= */ 1); ProgramSelector initialSel = AidlTestUtils.makeFmSelector(AM_FM_FREQUENCY_LIST[1]); mTunerSessions[0].tune(initialSel); + verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT).onCurrentProgramInfoChanged(any()); doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser()); mTunerSessions[0].cancel(); @@ -686,8 +672,8 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase { public void getImage_whenHalThrowsException_fails() throws Exception { openAidlClients(/* numClients= */ 1); String exceptionMessage = "HAL service died."; - when(mBroadcastRadioMock.getImage(anyInt())) - .thenThrow(new RemoteException(exceptionMessage)); + doThrow(new RemoteException(exceptionMessage)).when(mBroadcastRadioMock) + .getImage(anyInt()); RuntimeException thrown = assertThrows(RuntimeException.class, () -> { mTunerSessions[0].getImage(/* id= */ 1); @@ -713,7 +699,8 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase { mTunerSessions[0].startBackgroundScan(); - verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT.times(0)).onBackgroundScanComplete(); + verify(mAidlTunerCallbackMocks[0], after(CALLBACK_TIMEOUT_MS).times(0)) + .onBackgroundScanComplete(); } @Test @@ -905,7 +892,8 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase { mHalTunerCallback.onProgramListUpdated(AidlTestUtils.makeHalChunk(/* purge= */ false, /* complete= */ true, List.of(TEST_FM_INFO), new ArrayList<>())); - verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT.times(0)).onProgramListUpdated(any()); + verify(mAidlTunerCallbackMocks[0], after(CALLBACK_TIMEOUT_MS).times(0)) + .onProgramListUpdated(any()); } @Test @@ -1160,8 +1148,8 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase { Map<String, String> parametersSet = Map.of("mockParam1", "mockValue1", "mockParam2", "mockValue2"); String exceptionMessage = "HAL service died."; - when(mBroadcastRadioMock.setParameters(any())) - .thenThrow(new RemoteException(exceptionMessage)); + doThrow(new RemoteException(exceptionMessage)).when(mBroadcastRadioMock) + .setParameters(any()); RuntimeException thrown = assertThrows(RuntimeException.class, () -> { mTunerSessions[0].setParameters(parametersSet); @@ -1186,8 +1174,8 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase { openAidlClients(/* numClients= */ 1); List<String> parameterKeys = List.of("mockKey1", "mockKey2"); String exceptionMessage = "HAL service died."; - when(mBroadcastRadioMock.getParameters(any())) - .thenThrow(new RemoteException(exceptionMessage)); + doThrow(new RemoteException(exceptionMessage)).when(mBroadcastRadioMock) + .getParameters(any()); RuntimeException thrown = assertThrows(RuntimeException.class, () -> { mTunerSessions[0].getParameters(parameterKeys); @@ -1198,7 +1186,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase { } @Test - public void onCurrentProgramInfoChanged_withNoncurrentUser_doesNotInvokeCallback() + public void onCurrentProgramInfoChanged_withNonCurrentUser_doesNotInvokeCallback() throws Exception { openAidlClients(1); doReturn(USER_ID_2).when(() -> RadioServiceUserController.getCurrentUser()); @@ -1206,7 +1194,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase { mHalTunerCallback.onCurrentProgramInfoChanged(AidlTestUtils.makeHalProgramInfo( AidlTestUtils.makeHalFmSelector(AM_FM_FREQUENCY_LIST[1]), SIGNAL_QUALITY)); - verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT.times(0)) + verify(mAidlTunerCallbackMocks[0], after(CALLBACK_TIMEOUT_MS).times(0)) .onCurrentProgramInfoChanged(any()); } diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/TunerSessionHidlTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/TunerSessionHidlTest.java index fac9eaafe94c56de8bfb20c34040f05d4c52a6c7..3b9d7ba5de3eb68e4174c00f58338d72c0ddaacf 100644 --- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/TunerSessionHidlTest.java +++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/TunerSessionHidlTest.java @@ -16,22 +16,22 @@ package com.android.server.broadcastradio.hal2; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.after; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.any; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyBoolean; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyInt; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.doThrow; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.eq; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.never; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.timeout; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; import static com.google.common.truth.Truth.assertWithMessage; import static org.junit.Assert.assertThrows; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyBoolean; -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.timeout; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; import android.graphics.Bitmap; import android.hardware.broadcastradio.V2_0.Constants; @@ -78,8 +78,8 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase { private static final int USER_ID_1 = 11; private static final int USER_ID_2 = 12; - private static final VerificationWithTimeout CALLBACK_TIMEOUT = - timeout(/* millis= */ 200); + private static final int CALLBACK_TIMEOUT_MS = 200; + private static final VerificationWithTimeout CALLBACK_TIMEOUT = timeout(CALLBACK_TIMEOUT_MS); private static final int SIGNAL_QUALITY = 1; private static final long AM_FM_FREQUENCY_SPACING = 500; private static final long[] AM_FM_FREQUENCY_LIST = {97_500, 98_100, 99_100}; @@ -113,7 +113,7 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase { @Before public void setup() throws Exception { - when(mUserHandleMock.getIdentifier()).thenReturn(USER_ID_1); + doReturn(USER_ID_1).when(mUserHandleMock).getIdentifier(); doReturn(mUserHandleMock).when(() -> Binder.getCallingUserHandle()); doReturn(true).when(() -> RadioServiceUserController.isCurrentOrSystemUser()); doReturn(USER_ID_1).when(() -> RadioServiceUserController.getCurrentUser()); @@ -170,7 +170,7 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase { return Result.OK; }).when(mHalTunerSessionMock).scan(anyBoolean(), anyBoolean()); - when(mBroadcastRadioMock.getImage(anyInt())).thenReturn(new ArrayList<Byte>(0)); + doReturn(new ArrayList<Byte>(0)).when(mBroadcastRadioMock).getImage(anyInt()); doAnswer(invocation -> { int configFlag = (int) invocation.getArguments()[0]; @@ -227,7 +227,7 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase { mTunerSessions[0].setConfiguration(FM_BAND_CONFIG); - verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT.times(0)) + verify(mAidlTunerCallbackMocks[0], after(CALLBACK_TIMEOUT_MS).times(0)) .onConfigurationChanged(FM_BAND_CONFIG); } @@ -379,7 +379,7 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase { mTunerSessions[0].tune(initialSel); - verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT.times(0)) + verify(mAidlTunerCallbackMocks[0], after(CALLBACK_TIMEOUT_MS).times(0)) .onCurrentProgramInfoChanged(tuneInfo); } @@ -397,20 +397,6 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase { .that(thrown).hasMessageThat().contains(Result.toString(Result.UNKNOWN_ERROR)); } - @Test - public void tune_forSystemUser() throws Exception { - when(mUserHandleMock.getIdentifier()).thenReturn(UserHandle.USER_SYSTEM); - doReturn(mUserHandleMock).when(() -> Binder.getCallingUserHandle()); - doReturn(true).when(() -> RadioServiceUserController.isCurrentOrSystemUser()); - ProgramSelector initialSel = TestUtils.makeFmSelector(AM_FM_FREQUENCY_LIST[1]); - RadioManager.ProgramInfo tuneInfo = TestUtils.makeProgramInfo(initialSel, SIGNAL_QUALITY); - openAidlClients(/* numClients= */ 1); - - mTunerSessions[0].tune(initialSel); - - verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT).onCurrentProgramInfoChanged(tuneInfo); - } - @Test public void step_withDirectionUp() throws Exception { long initFreq = AM_FM_FREQUENCY_LIST[1]; @@ -455,7 +441,7 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase { mTunerSessions[0].step(/* directionDown= */ true, /* skipSubChannel= */ false); - verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT.times(0)) + verify(mAidlTunerCallbackMocks[0], after(CALLBACK_TIMEOUT_MS).times(0)) .onCurrentProgramInfoChanged(any()); } @@ -533,7 +519,7 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase { mTunerSessions[0].seek(/* directionDown= */ true, /* skipSubChannel= */ false); - verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT.times(0)) + verify(mAidlTunerCallbackMocks[0], after(CALLBACK_TIMEOUT_MS).times(0)) .onCurrentProgramInfoChanged(seekUpInfo); } @@ -562,18 +548,6 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase { verify(mHalTunerSessionMock).cancel(); } - @Test - public void cancel_forNonCurrentUser() throws Exception { - openAidlClients(/* numClients= */ 1); - ProgramSelector initialSel = TestUtils.makeFmSelector(AM_FM_FREQUENCY_LIST[1]); - mTunerSessions[0].tune(initialSel); - doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser()); - - mTunerSessions[0].cancel(); - - verify(mHalTunerSessionMock, never()).cancel(); - } - @Test public void cancel_forNonCurrentUser_doesNotCancel() throws Exception { openAidlClients(/* numClients= */ 1); @@ -627,8 +601,7 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase { public void getImage_whenHalThrowsException_fails() throws Exception { openAidlClients(/* numClients= */ 1); String exceptionMessage = "HAL service died."; - when(mBroadcastRadioMock.getImage(anyInt())) - .thenThrow(new RemoteException(exceptionMessage)); + doThrow(new RemoteException(exceptionMessage)).when(mBroadcastRadioMock).getImage(anyInt()); RuntimeException thrown = assertThrows(RuntimeException.class, () -> { mTunerSessions[0].getImage(/* id= */ 1); @@ -654,7 +627,8 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase { mTunerSessions[0].startBackgroundScan(); - verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT.times(0)).onBackgroundScanComplete(); + verify(mAidlTunerCallbackMocks[0], after(CALLBACK_TIMEOUT_MS).times(0)) + .onBackgroundScanComplete(); } @Test @@ -845,8 +819,8 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase { Map<String, String> parametersSet = Map.of("mockParam1", "mockValue1", "mockParam2", "mockValue2"); String exceptionMessage = "HAL service died."; - when(mHalTunerSessionMock.setParameters(any())) - .thenThrow(new RemoteException(exceptionMessage)); + doThrow(new RemoteException(exceptionMessage)).when(mHalTunerSessionMock) + .setParameters(any()); RuntimeException thrown = assertThrows(RuntimeException.class, () -> { mTunerSessions[0].setParameters(parametersSet); @@ -871,8 +845,8 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase { openAidlClients(/* numClients= */ 1); List<String> parameterKeys = List.of("mockKey1", "mockKey2"); String exceptionMessage = "HAL service died."; - when(mHalTunerSessionMock.getParameters(any())) - .thenThrow(new RemoteException(exceptionMessage)); + doThrow(new RemoteException(exceptionMessage)).when(mHalTunerSessionMock) + .getParameters(any()); RuntimeException thrown = assertThrows(RuntimeException.class, () -> { mTunerSessions[0].getParameters(parameterKeys); @@ -883,7 +857,7 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase { } @Test - public void onCurrentProgramInfoChanged_withNoncurrentUser_doesNotInvokeCallback() + public void onCurrentProgramInfoChanged_withNonCurrentUser_doesNotInvokeCallback() throws Exception { openAidlClients(1); doReturn(USER_ID_2).when(() -> RadioServiceUserController.getCurrentUser()); @@ -891,7 +865,7 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase { mHalTunerCallback.onCurrentProgramInfoChanged(TestUtils.makeHalProgramInfo( TestUtils.makeHalFmSelector(/* freq= */ 97300), SIGNAL_QUALITY)); - verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT.times(0)) + verify(mAidlTunerCallbackMocks[0], after(CALLBACK_TIMEOUT_MS).times(0)) .onCurrentProgramInfoChanged(any()); } diff --git a/core/tests/GameManagerTests/Android.bp b/core/tests/GameManagerTests/Android.bp index 8c5d6d5a76a1fb6145a72c1ae6546d6ac89f3d67..0e3bc6562edbd042fd24b681437c8c6bf92aee5c 100644 --- a/core/tests/GameManagerTests/Android.bp +++ b/core/tests/GameManagerTests/Android.bp @@ -30,7 +30,7 @@ android_test { "frameworks-base-testutils", "junit", "platform-test-annotations", - "truth-prebuilt", + "truth", ], libs: ["android.test.runner"], platform_apis: true, diff --git a/core/tests/PackageInstallerSessions/Android.bp b/core/tests/PackageInstallerSessions/Android.bp index 6f2366e325747e49c82a3aa1bf46453fda870860..b631df1fcf578e62992e859dbab92c970e0427e9 100644 --- a/core/tests/PackageInstallerSessions/Android.bp +++ b/core/tests/PackageInstallerSessions/Android.bp @@ -35,7 +35,7 @@ android_test { "frameworks-base-testutils", "platform-test-annotations", "testng", - "truth-prebuilt", + "truth", ], libs: [ diff --git a/core/tests/batterystatstests/BatteryUsageStatsProtoTests/Android.bp b/core/tests/batterystatstests/BatteryUsageStatsProtoTests/Android.bp index 52608351775cf45656b11b6f28cf74e7b0c2a8c6..1fb5f2c0789b10aa33ac408d61b33b7128c53fd6 100644 --- a/core/tests/batterystatstests/BatteryUsageStatsProtoTests/Android.bp +++ b/core/tests/batterystatstests/BatteryUsageStatsProtoTests/Android.bp @@ -18,7 +18,7 @@ android_test { "platform-test-annotations", "platformprotosnano", "statsdprotolite", - "truth-prebuilt", + "truth", ], libs: ["android.test.runner"], diff --git a/core/tests/bugreports/Android.bp b/core/tests/bugreports/Android.bp index 2b34ee2646f37b503731dfa2d782c6e2c222ee21..7c1ac487bfdbe481b32d93aca8a347809900d210 100644 --- a/core/tests/bugreports/Android.bp +++ b/core/tests/bugreports/Android.bp @@ -32,7 +32,7 @@ android_test { static_libs: [ "androidx.test.rules", "androidx.test.uiautomator_uiautomator", - "truth-prebuilt", + "truth", ], test_suites: ["general-tests"], sdk_version: "test_current", diff --git a/core/tests/coretests/Android.bp b/core/tests/coretests/Android.bp index 04622fda75df1b78695dc471fbb6ef8ecd7f861b..81dab0833af1577256d9ab3f2b20626c4cb5754b 100644 --- a/core/tests/coretests/Android.bp +++ b/core/tests/coretests/Android.bp @@ -58,7 +58,7 @@ android_test { "androidx.test.uiautomator_uiautomator", "platform-test-annotations", "platform-compat-test-rules", - "truth-prebuilt", + "truth", "print-test-util-lib", "testng", "servicestests-utils", @@ -149,7 +149,7 @@ android_library { "androidx.test.runner", "androidx.test.rules", "mockito-target-minus-junit4", - "truth-prebuilt", + "truth", ], libs: [ diff --git a/core/tests/hdmitests/Android.bp b/core/tests/hdmitests/Android.bp index 3d04937c91955502b8d0add14784d87f5e46b146..5f6eaf96a846e9a9f5b21f088740fc85cbf0618b 100644 --- a/core/tests/hdmitests/Android.bp +++ b/core/tests/hdmitests/Android.bp @@ -30,7 +30,7 @@ android_test { "frameworks-base-testutils", "guava-android-testlib", "platform-test-annotations", - "truth-prebuilt", + "truth", ], libs: ["android.test.runner"], platform_apis: true, diff --git a/core/tests/mockingcoretests/Android.bp b/core/tests/mockingcoretests/Android.bp index fde7c08715c7995c4d6a58802f68769382e022ff..2d778b1218d2331206618053bd904ab373540514 100644 --- a/core/tests/mockingcoretests/Android.bp +++ b/core/tests/mockingcoretests/Android.bp @@ -38,7 +38,7 @@ android_test { "androidx.test.ext.junit", "mockito-target-extended-minus-junit4", "platform-test-annotations", - "truth-prebuilt", + "truth", "testables", ], diff --git a/core/tests/nfctests/Android.bp b/core/tests/nfctests/Android.bp index c74600bbab22c11d6ff32c003f652a750277aac3..f81be494ad18338880743d07a36131587707d7f6 100644 --- a/core/tests/nfctests/Android.bp +++ b/core/tests/nfctests/Android.bp @@ -27,7 +27,7 @@ android_test { "androidx.test.ext.junit", "androidx.test.rules", "mockito-target-minus-junit4", - "truth-prebuilt", + "truth", ], libs: [ "android.test.runner", diff --git a/core/tests/overlaytests/device_self_targeting/Android.bp b/core/tests/overlaytests/device_self_targeting/Android.bp index 063c5694ab5be4b2ae7e9edf20cd7ec204cb08f7..931eac515e31f5926db89858baaa337ad725bd2c 100644 --- a/core/tests/overlaytests/device_self_targeting/Android.bp +++ b/core/tests/overlaytests/device_self_targeting/Android.bp @@ -30,7 +30,7 @@ android_test { "androidx.test.runner", "androidx.test.ext.junit", "mockito-target-minus-junit4", - "truth-prebuilt", + "truth", ], optimize: { diff --git a/core/tests/packagemonitortests/Android.bp b/core/tests/packagemonitortests/Android.bp index 7b5d7dff0a855aab7d3a1a51857ff9c925b78ce6..b08850e90d28fa9d899fc1fe3f6c5c8808d2f0fa 100644 --- a/core/tests/packagemonitortests/Android.bp +++ b/core/tests/packagemonitortests/Android.bp @@ -32,7 +32,7 @@ android_test { "compatibility-device-util-axt", "frameworks-base-testutils", "mockito-target-minus-junit4", - "truth-prebuilt", + "truth", ], libs: ["android.test.runner"], platform_apis: true, diff --git a/core/tests/privacytests/Android.bp b/core/tests/privacytests/Android.bp index bc3dd810be8c125aeef7de6cd72b82684ee9c7fa..4e24cd5d91cb6acf00d774cb49a1687184f0dc26 100644 --- a/core/tests/privacytests/Android.bp +++ b/core/tests/privacytests/Android.bp @@ -14,7 +14,7 @@ android_test { "junit", "rappor-tests", "androidx.test.rules", - "truth-prebuilt", + "truth", ], libs: ["android.test.runner"], platform_apis: true, diff --git a/core/tests/utiltests/Android.bp b/core/tests/utiltests/Android.bp index 3798da592cd50461e77b15f69df9a881c9834544..580e73c331a15e5ecd2fe9d0d5bb0f07374b1a6a 100644 --- a/core/tests/utiltests/Android.bp +++ b/core/tests/utiltests/Android.bp @@ -33,7 +33,7 @@ android_test { "frameworks-base-testutils", "mockito-target-minus-junit4", "androidx.test.ext.junit", - "truth-prebuilt", + "truth", "servicestests-utils", ], diff --git a/core/tests/vibrator/Android.bp b/core/tests/vibrator/Android.bp index 829409a36986d9c5da2c3fef9667dcc1c88d3998..09608e9bf5074c62763c880a168b6bfa92631bd3 100644 --- a/core/tests/vibrator/Android.bp +++ b/core/tests/vibrator/Android.bp @@ -18,7 +18,7 @@ android_test { "androidx.test.runner", "androidx.test.rules", "mockito-target-minus-junit4", - "truth-prebuilt", + "truth", "testng", ], diff --git a/errorprone/Android.bp b/errorprone/Android.bp index ad08026622d154b44ae11cea858221e9a70da8ba..c1d2235e3324168d569fe995fe292d3971074220 100644 --- a/errorprone/Android.bp +++ b/errorprone/Android.bp @@ -41,7 +41,7 @@ java_test_host { java_resource_dirs: ["tests/res"], java_resources: [":error_prone_android_framework_testdata"], static_libs: [ - "truth-prebuilt", + "truth", "kxml2-2.3.0", "compile-testing-prebuilt", "error_prone_android_framework_lib", diff --git a/libs/WindowManager/Jetpack/tests/unittest/Android.bp b/libs/WindowManager/Jetpack/tests/unittest/Android.bp index b6e743a2b7e1fc9f4079b31ef762183cf9f146c1..ed2ff2de245b6db6c6bcf18877dca3217f7c340f 100644 --- a/libs/WindowManager/Jetpack/tests/unittest/Android.bp +++ b/libs/WindowManager/Jetpack/tests/unittest/Android.bp @@ -37,7 +37,7 @@ android_test { "androidx.test.rules", "androidx.test.ext.junit", "mockito-target-extended-minus-junit4", - "truth-prebuilt", + "truth", "testables", "platform-test-annotations", ], diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BadgedImageView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BadgedImageView.java index f1ee8fa384858b66b4fc1ed867a7674bf7381ce2..a67821b7e819d5eda07be39583a2e3dc2af8813c 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BadgedImageView.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BadgedImageView.java @@ -318,7 +318,7 @@ public class BadgedImageView extends ConstraintLayout { /** * Animates the dot to the given scale, running the optional callback when the animation ends. */ - private void animateDotScale(float toScale, @Nullable Runnable after) { + public void animateDotScale(float toScale, @Nullable Runnable after) { mDotIsAnimating = true; // Don't restart the animation if we're already animating to the given value. diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflow.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflow.kt index df19757203eb1c319d2b81111860dfc68121e27c..dc099d9abda4e5f1bc93cc8a30aa50aed53bc134 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflow.kt +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflow.kt @@ -27,6 +27,7 @@ import android.graphics.drawable.ColorDrawable import android.graphics.drawable.InsetDrawable import android.util.PathParser import android.view.LayoutInflater +import android.view.View.VISIBLE import android.widget.FrameLayout import com.android.launcher3.icons.BubbleIconFactory import com.android.wm.shell.R @@ -156,7 +157,9 @@ class BubbleOverflow(private val context: Context, private val positioner: Bubbl fun setShowDot(show: Boolean) { showDot = show - overflowBtn?.updateDotVisibility(true /* animate */) + if (overflowBtn?.visibility == VISIBLE) { + overflowBtn?.updateDotVisibility(true /* animate */) + } } /** Creates the expanded view for bubbles showing in the stack view. */ 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 c124b532b89d08317349540f15e25f849df08ee8..2241c343a208bd53e572d5c8b80b1cb499bcd3a7 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 @@ -1864,6 +1864,14 @@ public class BubbleStackView extends FrameLayout : GONE); } + private void updateOverflowDotVisibility(boolean expanding) { + if (mBubbleOverflow.showDot()) { + mBubbleOverflow.getIconView().animateDotScale(expanding ? 1 : 0f, () -> { + mBubbleOverflow.setVisible(expanding ? VISIBLE : GONE); + }); + } + } + // via BubbleData.Listener void updateBubble(Bubble bubble) { animateInFlyoutForBubble(bubble); @@ -2274,6 +2282,7 @@ public class BubbleStackView extends FrameLayout if (mIsExpanded && mExpandedBubble.getExpandedView() != null) { maybeShowManageEdu(); } + updateOverflowDotVisibility(true /* expanding */); } /* after */); int index; if (mExpandedBubble != null && BubbleOverflow.KEY.equals(mExpandedBubble.getKey())) { @@ -2405,11 +2414,15 @@ public class BubbleStackView extends FrameLayout // since we're about to animate collapsed. mExpandedAnimationController.notifyPreparingToCollapse(); + updateOverflowDotVisibility(false /* expanding */); final Runnable collapseBackToStack = () -> mExpandedAnimationController.collapseBackToStack( mStackAnimationController .getStackPositionAlongNearestHorizontalEdge() /* collapseTo */, - () -> mBubbleContainer.setActiveController(mStackAnimationController)); + () -> { + mBubbleContainer.setActiveController(mStackAnimationController); + updateOverflowVisibility(); + }); final Runnable after = () -> { final BubbleViewProvider previouslySelected = mExpandedBubble; @@ -2424,7 +2437,6 @@ public class BubbleStackView extends FrameLayout Log.d(TAG, BubbleDebugConfig.formatBubblesString(getBubblesOnScreen(), mExpandedBubble)); } - updateOverflowVisibility(); updateZOrder(); updateBadges(true /* setBadgeForCollapsedStack */); afterExpandedViewAnimation(); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/ExpandedAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/ExpandedAnimationController.java index 4d7042bbb3d278730bc338c2c334605e56cc5522..738c94e82a950411aeb544ee6bf1f43d23c1a1c6 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/ExpandedAnimationController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/ExpandedAnimationController.java @@ -34,6 +34,8 @@ import androidx.dynamicanimation.animation.SpringForce; import com.android.wm.shell.R; import com.android.wm.shell.animation.Interpolators; import com.android.wm.shell.animation.PhysicsAnimator; +import com.android.wm.shell.bubbles.BadgedImageView; +import com.android.wm.shell.bubbles.BubbleOverflow; import com.android.wm.shell.bubbles.BubblePositioner; import com.android.wm.shell.bubbles.BubbleStackView; import com.android.wm.shell.common.magnetictarget.MagnetizedObject; @@ -63,6 +65,12 @@ public class ExpandedAnimationController /** Damping ratio for expand/collapse spring. */ private static final float DAMPING_RATIO_MEDIUM_LOW_BOUNCY = 0.65f; + /** + * Damping ratio for the overflow bubble spring; this is less bouncy so it doesn't bounce behind + * the top bubble when it goes to disappear. + */ + private static final float DAMPING_RATIO_OVERFLOW_BOUNCY = 0.90f; + /** Stiffness for the expand/collapse path-following animation. */ private static final int EXPAND_COLLAPSE_ANIM_STIFFNESS = 400; @@ -274,9 +282,14 @@ public class ExpandedAnimationController // of the screen where the bubble will be stacked. path.lineTo(stackedX, p.y); + // The overflow should animate to the collapse point, so 0 offset. + final boolean isOverflow = bubble instanceof BadgedImageView + && BubbleOverflow.KEY.equals(((BadgedImageView) bubble).getKey()); + final float offsetY = isOverflow + ? 0 + : Math.min(index, NUM_VISIBLE_WHEN_RESTING - 1) * mStackOffsetPx; // Then, draw a line down to the stack position. - path.lineTo(stackedX, mCollapsePoint.y - + Math.min(index, NUM_VISIBLE_WHEN_RESTING - 1) * mStackOffsetPx); + path.lineTo(stackedX, mCollapsePoint.y + offsetY); } // The lead bubble should be the bubble with the longest distance to travel when we're @@ -505,8 +518,12 @@ public class ExpandedAnimationController @Override SpringForce getSpringForce(DynamicAnimation.ViewProperty property, View view) { + boolean isOverflow = (view instanceof BadgedImageView) + && BubbleOverflow.KEY.equals(((BadgedImageView) view).getKey()); return new SpringForce() - .setDampingRatio(DAMPING_RATIO_MEDIUM_LOW_BOUNCY) + .setDampingRatio(isOverflow + ? DAMPING_RATIO_OVERFLOW_BOUNCY + : DAMPING_RATIO_MEDIUM_LOW_BOUNCY) .setStiffness(SpringForce.STIFFNESS_LOW); } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java index 11aa054676cb9f528ea313c7224eb2ef8f6fdd71..5dfba5e7ff1d5cf9faccebea8052d537710ebb4d 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java @@ -494,13 +494,14 @@ public abstract class WMShellModule { ToggleResizeDesktopTaskTransitionHandler toggleResizeDesktopTaskTransitionHandler, @DynamicOverride DesktopModeTaskRepository desktopModeTaskRepository, LaunchAdjacentController launchAdjacentController, + RecentsTransitionHandler recentsTransitionHandler, @ShellMainThread ShellExecutor mainExecutor ) { return new DesktopTasksController(context, shellInit, shellCommandHandler, shellController, displayController, shellTaskOrganizer, syncQueue, rootTaskDisplayAreaOrganizer, transitions, enterDesktopTransitionHandler, exitDesktopTransitionHandler, toggleResizeDesktopTaskTransitionHandler, desktopModeTaskRepository, - launchAdjacentController, mainExecutor); + launchAdjacentController, recentsTransitionHandler, mainExecutor); } @WMSingleton diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt index 09ba4f79326ecde091bae099e7d46dec4053056f..412a5b5a6997a73dc307cb88a81e5ba903aeb9ba 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt @@ -60,6 +60,8 @@ import com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP import com.android.wm.shell.desktopmode.DesktopModeTaskRepository.VisibleTasksListener import com.android.wm.shell.desktopmode.DesktopModeVisualIndicator.TO_DESKTOP_INDICATOR import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE +import com.android.wm.shell.recents.RecentsTransitionHandler +import com.android.wm.shell.recents.RecentsTransitionStateListener import com.android.wm.shell.splitscreen.SplitScreenController import com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_ENTER_DESKTOP import com.android.wm.shell.sysui.ShellCommandHandler @@ -68,7 +70,6 @@ import com.android.wm.shell.sysui.ShellInit import com.android.wm.shell.sysui.ShellSharedConstants import com.android.wm.shell.transition.OneShotRemoteHandler import com.android.wm.shell.transition.Transitions -import com.android.wm.shell.transition.Transitions.TransitionHandler import com.android.wm.shell.util.KtProtoLog import com.android.wm.shell.windowdecor.DesktopModeWindowDecoration import com.android.wm.shell.windowdecor.MoveToDesktopAnimator @@ -93,6 +94,7 @@ class DesktopTasksController( ToggleResizeDesktopTaskTransitionHandler, private val desktopModeTaskRepository: DesktopModeTaskRepository, private val launchAdjacentController: LaunchAdjacentController, + private val recentsTransitionHandler: RecentsTransitionHandler, @ShellMainThread private val mainExecutor: ShellExecutor ) : RemoteCallable<DesktopTasksController>, Transitions.TransitionHandler { @@ -119,6 +121,8 @@ class DesktopTasksController( com.android.wm.shell.R.dimen.desktop_mode_transition_area_width ) + private var recentsAnimationRunning = false + // This is public to avoid cyclic dependency; it is set by SplitScreenController lateinit var splitScreenController: SplitScreenController @@ -139,6 +143,19 @@ class DesktopTasksController( ) transitions.addHandler(this) desktopModeTaskRepository.addVisibleTasksListener(taskVisibilityListener, mainExecutor) + + recentsTransitionHandler.addTransitionStateListener( + object : RecentsTransitionStateListener { + override fun onAnimationStateChanged(running: Boolean) { + KtProtoLog.v( + WM_SHELL_DESKTOP_MODE, + "DesktopTasksController: recents animation state changed running=%b", + running + ) + recentsAnimationRunning = running + } + } + ) } /** Show all tasks, that are part of the desktop, on top of launcher */ @@ -644,6 +661,10 @@ class DesktopTasksController( val triggerTask = request.triggerTask val shouldHandleRequest = when { + recentsAnimationRunning -> { + reason = "recents animation is running" + false + } // Only handle open or to front transitions request.type != TRANSIT_OPEN && request.type != TRANSIT_TO_FRONT -> { reason = "transition type not handled (${request.type})" diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java index ead2f9cbd1addffd907c1ee4286f9fa552239b0e..d31476c638907c7529380f47da3983afb8d4f9b6 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java @@ -54,6 +54,7 @@ import android.window.WindowContainerToken; import android.window.WindowContainerTransaction; import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.os.IResultReceiver; import com.android.internal.protolog.common.ProtoLog; import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.protolog.ShellProtoLogGroup; @@ -279,7 +280,7 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler { mDeathHandler = () -> { ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION, "[%d] RecentsController.DeathRecipient: binder died", mInstanceId); - finish(mWillFinishToHome, false /* leaveHint */); + finish(mWillFinishToHome, false /* leaveHint */, null /* finishCb */); }; try { mListener.asBinder().linkToDeath(mDeathHandler, 0 /* flags */); @@ -313,7 +314,7 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler { } } if (mFinishCB != null) { - finishInner(toHome, false /* userLeave */); + finishInner(toHome, false /* userLeave */, null /* finishCb */); } else { cleanUp(); } @@ -670,7 +671,8 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler { // now and let it do its animation (since recents is going to be occluded). sendCancelWithSnapshots(); mExecutor.executeDelayed( - () -> finishInner(true /* toHome */, false /* userLeaveHint */), 0); + () -> finishInner(true /* toHome */, false /* userLeaveHint */, + null /* finishCb */), 0); return; } if (recentsOpening != null) { @@ -899,11 +901,12 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler { @Override @SuppressLint("NewApi") - public void finish(boolean toHome, boolean sendUserLeaveHint) { - mExecutor.execute(() -> finishInner(toHome, sendUserLeaveHint)); + public void finish(boolean toHome, boolean sendUserLeaveHint, IResultReceiver finishCb) { + mExecutor.execute(() -> finishInner(toHome, sendUserLeaveHint, finishCb)); } - private void finishInner(boolean toHome, boolean sendUserLeaveHint) { + private void finishInner(boolean toHome, boolean sendUserLeaveHint, + IResultReceiver runnerFinishCb) { if (mFinishCB == null) { Slog.e(TAG, "Duplicate call to finish"); return; @@ -993,6 +996,16 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler { } cleanUp(); finishCB.onTransitionFinished(wct.isEmpty() ? null : wct); + if (runnerFinishCb != null) { + try { + ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION, + "[%d] RecentsController.finishInner: calling finish callback", + mInstanceId); + runnerFinishCb.send(0, null); + } catch (RemoteException e) { + Slog.e(TAG, "Failed to report transition finished", e); + } + } } @Override diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java index 83dc7fa5e869aaa478e505ad2d52983d088e4fd8..e828eedc275c7671c262567180a4da14cdc55fd5 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java @@ -23,6 +23,7 @@ import static android.view.Display.DEFAULT_DISPLAY; import static android.view.WindowManager.TRANSIT_CHANGE; import static android.view.WindowManager.TRANSIT_TO_BACK; import static android.window.TransitionInfo.FLAG_IS_WALLPAPER; + import static com.android.wm.shell.common.split.SplitScreenConstants.FLAG_IS_DIVIDER_BAR; import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_UNDEFINED; import static com.android.wm.shell.pip.PipAnimationController.ANIM_TYPE_ALPHA; @@ -693,9 +694,19 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler, @NonNull SurfaceControl.Transaction startTransaction, @NonNull SurfaceControl.Transaction finishTransaction, @NonNull Transitions.TransitionFinishCallback finishCallback) { + Transitions.TransitionFinishCallback finishCB = wct -> { + mixed.mInFlightSubAnimations--; + if (mixed.mInFlightSubAnimations == 0) { + mActiveTransitions.remove(mixed); + finishCallback.onTransitionFinished(wct); + } + }; + + mixed.mInFlightSubAnimations++; boolean consumed = mRecentsHandler.startAnimation( - mixed.mTransition, info, startTransaction, finishTransaction, finishCallback); + mixed.mTransition, info, startTransaction, finishTransaction, finishCB); if (!consumed) { + mixed.mInFlightSubAnimations--; return false; } if (mDesktopTasksController != null) { diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java index e0635ac2e19a38915b50bbf1dfdca9ef6d065b90..de03f5826925615a47e9778cc329cb616b7a48ae 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java @@ -322,7 +322,6 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler { final Runnable onAnimFinish = () -> { if (!animations.isEmpty()) return; mAnimations.remove(transition); - info.releaseAllSurfaces(); finishCallback.onTransitionFinished(null /* wct */); }; diff --git a/libs/WindowManager/Shell/tests/unittest/Android.bp b/libs/WindowManager/Shell/tests/unittest/Android.bp index 54f94986d90cf4416f5890bd596f2de09aef0d0d..d09a90cd7dc76c042dd705cc72efaf039e732e58 100644 --- a/libs/WindowManager/Shell/tests/unittest/Android.bp +++ b/libs/WindowManager/Shell/tests/unittest/Android.bp @@ -45,7 +45,7 @@ android_test { "kotlinx-coroutines-core", "mockito-kotlin2", "mockito-target-extended-minus-junit4", - "truth-prebuilt", + "truth", "testables", "platform-test-annotations", "servicestests-utils", diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt index dea161786da2825abda381ba16932ca8c8bcc9c7..ebcb6407a6fd913da1086c88c61dc06c487a88c5 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt @@ -54,6 +54,8 @@ import com.android.wm.shell.desktopmode.DesktopTestHelpers.Companion.createFreef import com.android.wm.shell.desktopmode.DesktopTestHelpers.Companion.createFullscreenTask import com.android.wm.shell.desktopmode.DesktopTestHelpers.Companion.createHomeTask import com.android.wm.shell.desktopmode.DesktopTestHelpers.Companion.createSplitScreenTask +import com.android.wm.shell.recents.RecentsTransitionHandler +import com.android.wm.shell.recents.RecentsTransitionStateListener import com.android.wm.shell.splitscreen.SplitScreenController import com.android.wm.shell.sysui.ShellCommandHandler import com.android.wm.shell.sysui.ShellController @@ -101,11 +103,13 @@ class DesktopTasksControllerTest : ShellTestCase() { @Mock lateinit var launchAdjacentController: LaunchAdjacentController @Mock lateinit var desktopModeWindowDecoration: DesktopModeWindowDecoration @Mock lateinit var splitScreenController: SplitScreenController + @Mock lateinit var recentsTransitionHandler: RecentsTransitionHandler private lateinit var mockitoSession: StaticMockitoSession private lateinit var controller: DesktopTasksController private lateinit var shellInit: ShellInit private lateinit var desktopModeTaskRepository: DesktopModeTaskRepository + private lateinit var recentsTransitionStateListener: RecentsTransitionStateListener private val shellExecutor = TestShellExecutor() // Mock running tasks are registered here so we can get the list from mock shell task organizer @@ -126,6 +130,10 @@ class DesktopTasksControllerTest : ShellTestCase() { controller.splitScreenController = splitScreenController shellInit.init() + + val captor = ArgumentCaptor.forClass(RecentsTransitionStateListener::class.java) + verify(recentsTransitionHandler).addTransitionStateListener(captor.capture()) + recentsTransitionStateListener = captor.value } private fun createController(): DesktopTasksController { @@ -144,6 +152,7 @@ class DesktopTasksControllerTest : ShellTestCase() { mToggleResizeDesktopTaskTransitionHandler, desktopModeTaskRepository, launchAdjacentController, + recentsTransitionHandler, shellExecutor ) } @@ -355,7 +364,7 @@ class DesktopTasksControllerTest : ShellTestCase() { @Test fun moveToDesktop_splitTaskExitsSplit() { - var task = setUpSplitScreenTask() + val task = setUpSplitScreenTask() controller.moveToDesktop(desktopModeWindowDecoration, task) val wct = getLatestMoveToDesktopWct() assertThat(wct.changes[task.token.asBinder()]?.windowingMode) @@ -367,7 +376,7 @@ class DesktopTasksControllerTest : ShellTestCase() { @Test fun moveToDesktop_fullscreenTaskDoesNotExitSplit() { - var task = setUpFullscreenTask() + val task = setUpFullscreenTask() controller.moveToDesktop(desktopModeWindowDecoration, task) val wct = getLatestMoveToDesktopWct() assertThat(wct.changes[task.token.asBinder()]?.windowingMode) @@ -665,6 +674,20 @@ class DesktopTasksControllerTest : ShellTestCase() { assertThat(controller.handleRequest(Binder(), createTransition(task))).isNull() } + @Test + fun handleRequest_recentsAnimationRunning_returnNull() { + // Set up a visible freeform task so a fullscreen task should be converted to freeform + val freeformTask = setUpFreeformTask() + markTaskVisible(freeformTask) + + // Mark recents animation running + recentsTransitionStateListener.onAnimationStateChanged(true) + + // Open a fullscreen task, check that it does not result in a WCT with changes to it + val fullscreenTask = createFullscreenTask() + assertThat(controller.handleRequest(Binder(), createTransition(fullscreenTask))).isNull() + } + @Test fun stashDesktopApps_stateUpdates() { whenever(DesktopModeStatus.isStashingEnabled()).thenReturn(true) diff --git a/libs/dream/lowlight/tests/Android.bp b/libs/dream/lowlight/tests/Android.bp index 64b53cbb5c5a724d57e229d0dd1b52321cf7a860..4dafd0aa6df41cf2f2be2c0d5af8a6ff29f983c3 100644 --- a/libs/dream/lowlight/tests/Android.bp +++ b/libs/dream/lowlight/tests/Android.bp @@ -34,7 +34,7 @@ android_test { "mockito-target-extended-minus-junit4", "platform-test-annotations", "testables", - "truth-prebuilt", + "truth", ], libs: [ "android.test.mock", diff --git a/libs/securebox/tests/Android.bp b/libs/securebox/tests/Android.bp index 7df546ae0ff6649b26714265ce158b878149eb11..80b501da1aa57c3a390444d8df3eda871127a998 100644 --- a/libs/securebox/tests/Android.bp +++ b/libs/securebox/tests/Android.bp @@ -32,7 +32,7 @@ android_test { "platform-test-annotations", "testables", "testng", - "truth-prebuilt", + "truth", ], libs: [ "android.test.mock", diff --git a/media/tests/MediaFrameworkTest/Android.bp b/media/tests/MediaFrameworkTest/Android.bp index ca20225e8885b04c8ecea4f176199c610ecfa2bc..bdd7afeb2f658eb4c05d729cf19ef67a3b74801c 100644 --- a/media/tests/MediaFrameworkTest/Android.bp +++ b/media/tests/MediaFrameworkTest/Android.bp @@ -22,7 +22,7 @@ android_test { "android-ex-camera2", "testables", "testng", - "truth-prebuilt", + "truth", ], jni_libs: [ "libdexmakerjvmtiagent", diff --git a/media/tests/MediaRouter/Android.bp b/media/tests/MediaRouter/Android.bp index 4cccf897279805b2f31d832cfdf0dd2d92ab605a..61b18c88e7345117f43fb527cb835645cade46c4 100644 --- a/media/tests/MediaRouter/Android.bp +++ b/media/tests/MediaRouter/Android.bp @@ -24,7 +24,7 @@ android_test { "compatibility-device-util-axt", "mockito-target-minus-junit4", "testng", - "truth-prebuilt", + "truth", ], test_suites: ["general-tests"], platform_apis: true, diff --git a/media/tests/projection/Android.bp b/media/tests/projection/Android.bp index e313c46d1973cb29eef67360eb359fe2eba9a8ea..48cd8b69ade82d1f3716906e4994cdcacb0eec76 100644 --- a/media/tests/projection/Android.bp +++ b/media/tests/projection/Android.bp @@ -30,7 +30,7 @@ android_test { "platform-test-annotations", "testng", "testables", - "truth-prebuilt", + "truth", "platform-compat-test-rules", ], diff --git a/packages/ExternalStorageProvider/tests/Android.bp b/packages/ExternalStorageProvider/tests/Android.bp index 633f1861092110a2a57f64e8f074189943f0742f..86c62ef299e4c340c622c70c0c70c6ab7773f620 100644 --- a/packages/ExternalStorageProvider/tests/Android.bp +++ b/packages/ExternalStorageProvider/tests/Android.bp @@ -25,7 +25,7 @@ android_test { static_libs: [ "androidx.test.rules", "mockito-target", - "truth-prebuilt", + "truth", ], certificate: "platform", diff --git a/packages/FusedLocation/Android.bp b/packages/FusedLocation/Android.bp index 64b4c54e74ad38610699e01051d728f8dc7abb62..61a82701d1553006d5f77f3d5a680a5704dd3411 100644 --- a/packages/FusedLocation/Android.bp +++ b/packages/FusedLocation/Android.bp @@ -47,7 +47,7 @@ android_test { test_config: "test/AndroidTest.xml", srcs: [ "test/src/**/*.java", - "src/**/*.java", // include real sources because we're forced to test this directly + "src/**/*.java", // include real sources because we're forced to test this directly ], libs: [ "android.test.base", @@ -60,9 +60,9 @@ android_test { "androidx.test.ext.junit", "androidx.test.ext.truth", "mockito-target-minus-junit4", - "truth-prebuilt", + "truth", ], platform_apis: true, certificate: "platform", - test_suites: ["device-tests"] + test_suites: ["device-tests"], } diff --git a/packages/SettingsLib/Spa/testutils/Android.bp b/packages/SettingsLib/Spa/testutils/Android.bp index 4031cd7f7a6f070582432edeae0f875f798ee6e3..639d1a7a7f559e5544d51f01ac8dcd35c6ed2629 100644 --- a/packages/SettingsLib/Spa/testutils/Android.bp +++ b/packages/SettingsLib/Spa/testutils/Android.bp @@ -31,7 +31,7 @@ android_library { "androidx.compose.ui_ui-test-manifest", "androidx.lifecycle_lifecycle-runtime-testing", "mockito-kotlin2", - "truth-prebuilt", + "truth", ], kotlincflags: [ "-Xjvm-default=all", diff --git a/packages/SettingsLib/tests/integ/Android.bp b/packages/SettingsLib/tests/integ/Android.bp index b03c43cbdee5ebaed620520ce64152c32431c587..4b4caf5a620ecfec619b28305af4548f5b98395d 100644 --- a/packages/SettingsLib/tests/integ/Android.bp +++ b/packages/SettingsLib/tests/integ/Android.bp @@ -52,7 +52,7 @@ android_test { "flag-junit", "mockito-target-minus-junit4", "platform-test-annotations", - "truth-prebuilt", + "truth", "SettingsLibDeviceStateRotationLock", "SettingsLibSettingsSpinner", "SettingsLibUsageProgressBarPreference", diff --git a/packages/SettingsLib/tests/robotests/Android.bp b/packages/SettingsLib/tests/robotests/Android.bp index dd9cb9cf7abe45300d1c07147fd8cb142f60e26c..2d875cf7244d76a4d6262faa93269cc23f103637 100644 --- a/packages/SettingsLib/tests/robotests/Android.bp +++ b/packages/SettingsLib/tests/robotests/Android.bp @@ -96,6 +96,6 @@ java_library { libs: [ "Robolectric_all-target_upstream", "mockito-robolectric-prebuilt", - "truth-prebuilt", + "truth", ], } diff --git a/packages/SettingsLib/tests/unit/Android.bp b/packages/SettingsLib/tests/unit/Android.bp index 19ab1c69e98c60fa3fcd37cbae21ab4bd93f20ac..6d6e2ff8e59b18c4c0430d40362c3604763c9fcd 100644 --- a/packages/SettingsLib/tests/unit/Android.bp +++ b/packages/SettingsLib/tests/unit/Android.bp @@ -31,6 +31,6 @@ android_test { "SettingsLib", "androidx.test.ext.junit", "androidx.test.runner", - "truth-prebuilt", + "truth", ], } diff --git a/packages/SettingsProvider/Android.bp b/packages/SettingsProvider/Android.bp index 92ebe09fa441c648d1052f8e96c736819a79180f..f4ca260d4d8918139477d371411e010b3c22b43b 100644 --- a/packages/SettingsProvider/Android.bp +++ b/packages/SettingsProvider/Android.bp @@ -64,7 +64,7 @@ android_test { "SettingsLibDeviceStateRotationLock", "SettingsLibDisplayUtils", "platform-test-annotations", - "truth-prebuilt", + "truth", ], libs: [ "android.test.base", diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp index 3c57852759193fa4b7c9143fd3667f07b1572313..e40fcb2a633b85a239130117eb4581085fe17850 100644 --- a/packages/SystemUI/Android.bp +++ b/packages/SystemUI/Android.bp @@ -466,7 +466,7 @@ android_library { "hamcrest-library", "androidx.test.rules", "testables", - "truth-prebuilt", + "truth", "monet", "libmonet", "dagger2", @@ -583,7 +583,7 @@ android_robolectric_test { "android.test.runner", "android.test.base", "android.test.mock", - "truth-prebuilt", + "truth", ], upstream: true, diff --git a/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/AccessibilityMenuService.java b/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/AccessibilityMenuService.java index 008732e787f1302e9b7d240dcc99fb322836816a..96e1e3fa68a7f1a48d08a0361f4317a3e930d1dc 100644 --- a/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/AccessibilityMenuService.java +++ b/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/AccessibilityMenuService.java @@ -63,6 +63,7 @@ public class AccessibilityMenuService extends AccessibilityService private static final String TAG = "A11yMenuService"; private static final long BUFFER_MILLISECONDS_TO_PREVENT_UPDATE_FAILURE = 100L; + private static final long TAKE_SCREENSHOT_DELAY_MS = 100L; private static final int BRIGHTNESS_UP_INCREMENT_GAMMA = (int) Math.ceil(BrightnessUtils.GAMMA_SPACE_MAX * 0.11f); @@ -301,7 +302,14 @@ public class AccessibilityMenuService extends AccessibilityService } else if (viewTag == ShortcutId.ID_NOTIFICATION_VALUE.ordinal()) { performGlobalActionInternal(GLOBAL_ACTION_NOTIFICATIONS); } else if (viewTag == ShortcutId.ID_SCREENSHOT_VALUE.ordinal()) { - performGlobalActionInternal(GLOBAL_ACTION_TAKE_SCREENSHOT); + if (Flags.a11yMenuHideBeforeTakingAction()) { + // Delay before taking a screenshot to give time for the UI to close. + mHandler.postDelayed( + () -> performGlobalActionInternal(GLOBAL_ACTION_TAKE_SCREENSHOT), + TAKE_SCREENSHOT_DELAY_MS); + } else { + performGlobalActionInternal(GLOBAL_ACTION_TAKE_SCREENSHOT); + } } if (!Flags.a11yMenuHideBeforeTakingAction()) { diff --git a/packages/SystemUI/accessibility/accessibilitymenu/tests/Android.bp b/packages/SystemUI/accessibility/accessibilitymenu/tests/Android.bp index 538ecb3d438d512c3cf167b31a3efee9e75fa9b0..3fc351c32ec1a24340e1e98a456deb697e024759 100644 --- a/packages/SystemUI/accessibility/accessibilitymenu/tests/Android.bp +++ b/packages/SystemUI/accessibility/accessibilitymenu/tests/Android.bp @@ -32,7 +32,7 @@ android_test { "androidx.test.ext.junit", "compatibility-device-util-axt", "platform-test-annotations", - "truth-prebuilt", + "truth", ], srcs: [ "src/**/*.java", diff --git a/packages/SystemUI/aconfig/systemui.aconfig b/packages/SystemUI/aconfig/systemui.aconfig index 437f8afa8d7016d8e3feec8c3dae03888f0a8342..18117a890298807c8df42e918f22b049111dab6b 100644 --- a/packages/SystemUI/aconfig/systemui.aconfig +++ b/packages/SystemUI/aconfig/systemui.aconfig @@ -13,3 +13,11 @@ flag { description: "Enables all the sysui classic flags that are marked as being in teamfood" bug: "302578396" } + +flag { + name: "notifications_footer_view_refactor" + namespace: "systemui" + description: "Enables the refactored version of the footer view in the notification shade " + "(containing the \"Clear all\" button). Should not bring any behavior changes" + bug: "293167744" +} diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt index 0f2e4bace46d552f48ba417f19ed1741d45ade22..4aac27932924baf54ce6346b430130379eb7a57b 100644 --- a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt +++ b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt @@ -39,6 +39,7 @@ import android.view.ViewGroup import android.view.WindowManager import android.view.animation.Interpolator import android.view.animation.PathInterpolator +import androidx.annotation.AnyThread import androidx.annotation.BinderThread import androidx.annotation.UiThread import com.android.app.animation.Interpolators @@ -149,6 +150,10 @@ class ActivityLaunchAnimator( override fun onLaunchAnimationProgress(linearProgress: Float) { listeners.forEach { it.onLaunchAnimationProgress(linearProgress) } } + + override fun onLaunchAnimationCancelled() { + listeners.forEach { it.onLaunchAnimationCancelled() } + } } /** @@ -191,6 +196,7 @@ class ActivityLaunchAnimator( "ActivityLaunchAnimator.callback must be set before using this animator" ) val runner = createRunner(controller) + val runnerDelegate = runner.delegate!! val hideKeyguardWithAnimation = callback.isOnKeyguard() && !showOverLockscreen // Pass the RemoteAnimationAdapter to the intent starter only if we are not hiding the @@ -241,12 +247,15 @@ class ActivityLaunchAnimator( // If we expect an animation, post a timeout to cancel it in case the remote animation is // never started. if (willAnimate) { - runner.delegate.postTimeout() + runnerDelegate.postTimeout() // Hide the keyguard using the launch animation instead of the default unlock animation. if (hideKeyguardWithAnimation) { callback.hideKeyguardWithAnimation(runner) } + } else { + // We need to make sure delegate references are dropped to avoid memory leaks. + runner.dispose() } } @@ -344,6 +353,13 @@ class ActivityLaunchAnimator( */ fun onLaunchAnimationEnd() {} + /** + * The animation was cancelled. Note that [onLaunchAnimationEnd] will still be called after + * this if the animation was already started, i.e. if [onLaunchAnimationStart] was called + * before the cancellation. + */ + fun onLaunchAnimationCancelled() {} + /** Called when an activity launch animation made progress. */ fun onLaunchAnimationProgress(linearProgress: Float) {} } @@ -426,6 +442,39 @@ class ActivityLaunchAnimator( fun onLaunchAnimationCancelled(newKeyguardOccludedState: Boolean? = null) {} } + /** + * Invokes [onAnimationComplete] when animation is either cancelled or completed. Delegates all + * events to the passed [delegate]. + */ + @VisibleForTesting + inner class DelegatingAnimationCompletionListener( + private val delegate: Listener?, + private val onAnimationComplete: () -> Unit + ) : Listener { + var cancelled = false + + override fun onLaunchAnimationStart() { + delegate?.onLaunchAnimationStart() + } + + override fun onLaunchAnimationProgress(linearProgress: Float) { + delegate?.onLaunchAnimationProgress(linearProgress) + } + + override fun onLaunchAnimationEnd() { + delegate?.onLaunchAnimationEnd() + if (!cancelled) { + onAnimationComplete.invoke() + } + } + + override fun onLaunchAnimationCancelled() { + cancelled = true + delegate?.onLaunchAnimationCancelled() + onAnimationComplete.invoke() + } + } + @VisibleForTesting inner class Runner( controller: Controller, @@ -436,11 +485,21 @@ class ActivityLaunchAnimator( listener: Listener? = null ) : IRemoteAnimationRunner.Stub() { private val context = controller.launchContainer.context - internal val delegate: AnimationDelegate + + // This is being passed across IPC boundaries and cycles (through PendingIntentRecords, + // etc.) are possible. So we need to make sure we drop any references that might + // transitively cause leaks when we're done with animation. + @VisibleForTesting var delegate: AnimationDelegate? init { delegate = - AnimationDelegate(controller, callback, listener, launchAnimator, disableWmTimeout) + AnimationDelegate( + controller, + callback, + DelegatingAnimationCompletionListener(listener, this::dispose), + launchAnimator, + disableWmTimeout + ) } @BinderThread @@ -451,14 +510,33 @@ class ActivityLaunchAnimator( nonApps: Array<out RemoteAnimationTarget>?, finishedCallback: IRemoteAnimationFinishedCallback? ) { + val delegate = delegate context.mainExecutor.execute { - delegate.onAnimationStart(transit, apps, wallpapers, nonApps, finishedCallback) + if (delegate == null) { + Log.i(TAG, "onAnimationStart called after completion") + // Animation started too late and timed out already. We need to still + // signal back that we're done with it. + finishedCallback?.onAnimationFinished() + } else { + delegate.onAnimationStart(transit, apps, wallpapers, nonApps, finishedCallback) + } } } @BinderThread override fun onAnimationCancelled() { - context.mainExecutor.execute { delegate.onAnimationCancelled() } + val delegate = delegate + context.mainExecutor.execute { + delegate ?: Log.wtf(TAG, "onAnimationCancelled called after completion") + delegate?.onAnimationCancelled() + } + } + + @AnyThread + fun dispose() { + // Drop references to animation controller once we're done with the animation + // to avoid leaking. + context.mainExecutor.execute { delegate = null } } } @@ -584,6 +662,7 @@ class ActivityLaunchAnimator( ) } controller.onLaunchAnimationCancelled() + listener?.onLaunchAnimationCancelled() return } @@ -821,6 +900,7 @@ class ActivityLaunchAnimator( Log.d(TAG, "Calling controller.onLaunchAnimationCancelled() [animation timed out]") } controller.onLaunchAnimationCancelled() + listener?.onLaunchAnimationCancelled() } @UiThread @@ -842,6 +922,7 @@ class ActivityLaunchAnimator( ) } controller.onLaunchAnimationCancelled() + listener?.onLaunchAnimationCancelled() } private fun IRemoteAnimationFinishedCallback.invoke() { diff --git a/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/AnimateToScene.kt b/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/AnimateToScene.kt index 88944f10eab9e79084694fd203c2c7b0f50e8fe6..60c3fd3c4cdb30fca0b74f2701b13706f7ad1a6b 100644 --- a/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/AnimateToScene.kt +++ b/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/AnimateToScene.kt @@ -108,7 +108,7 @@ private fun CoroutineScope.animate( ) { val fromScene = layoutImpl.state.transitionState.currentScene val isUserInput = - (layoutImpl.state.transitionState as? TransitionState.Transition)?.isUserInputDriven + (layoutImpl.state.transitionState as? TransitionState.Transition)?.isInitiatedByUserInput ?: false val animationSpec = layoutImpl.transitions.transitionSpec(fromScene, target).spec @@ -119,9 +119,23 @@ private fun CoroutineScope.animate( val targetProgress = if (reversed) 0f else 1f val transition = if (reversed) { - OneOffTransition(target, fromScene, currentScene = target, isUserInput, animatable) + OneOffTransition( + fromScene = target, + toScene = fromScene, + currentScene = target, + isUserInput, + isUserInputOngoing = false, + animatable, + ) } else { - OneOffTransition(fromScene, target, currentScene = target, isUserInput, animatable) + OneOffTransition( + fromScene = fromScene, + toScene = target, + currentScene = target, + isUserInput, + isUserInputOngoing = false, + animatable, + ) } // Change the current layout state to use this new transition. @@ -142,7 +156,8 @@ private class OneOffTransition( override val fromScene: SceneKey, override val toScene: SceneKey, override val currentScene: SceneKey, - override val isUserInputDriven: Boolean, + override val isInitiatedByUserInput: Boolean, + override val isUserInputOngoing: Boolean, private val animatable: Animatable<Float, AnimationVector1D>, ) : TransitionState.Transition { override val progress: Float diff --git a/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/ObservableTransitionState.kt b/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/ObservableTransitionState.kt index ccdec6ea8c5e525ff3f97de0ce490011b4bc352a..1b79dbdee5104eafc7b3a321773c30e9b098b229 100644 --- a/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/ObservableTransitionState.kt +++ b/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/ObservableTransitionState.kt @@ -52,7 +52,14 @@ sealed class ObservableTransitionState { * scene, this value will remain true after the pointer is no longer touching the screen and * will be true in any transition created to animate back to the original position. */ - val isUserInputDriven: Boolean, + val isInitiatedByUserInput: Boolean, + + /** + * Whether user input is currently driving the transition. For example, if a user is + * dragging a pointer, this emits true. Once they lift their finger, this emits false while + * the transition completes/settles. + */ + val isUserInputOngoing: Flow<Boolean>, ) : ObservableTransitionState() } @@ -73,7 +80,8 @@ fun SceneTransitionLayoutState.observableTransitionState(): Flow<ObservableTrans fromScene = state.fromScene, toScene = state.toScene, progress = snapshotFlow { state.progress }, - isUserInputDriven = state.isUserInputDriven, + isInitiatedByUserInput = state.isInitiatedByUserInput, + isUserInputOngoing = snapshotFlow { state.isUserInputOngoing }, ) } } diff --git a/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/SceneTransitionLayoutState.kt b/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/SceneTransitionLayoutState.kt index 7a21211c3ddeada5408d27c59620c34ede5c9306..b9f83c545122ede4b7b37c8e3346a97e3629567c 100644 --- a/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/SceneTransitionLayoutState.kt +++ b/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/SceneTransitionLayoutState.kt @@ -70,6 +70,9 @@ sealed interface TransitionState { val progress: Float /** Whether the transition was triggered by user input rather than being programmatic. */ - val isUserInputDriven: Boolean + val isInitiatedByUserInput: Boolean + + /** Whether user input is currently driving the transition. */ + val isUserInputOngoing: Boolean } } diff --git a/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/SwipeToScene.kt b/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/SwipeToScene.kt index 1cbfe3057ff00d2e63dc3ea7e6bb1774931eb47d..e275fcaf45722a9980efcad9c548620752f446ae 100644 --- a/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/SwipeToScene.kt +++ b/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/SwipeToScene.kt @@ -66,7 +66,7 @@ internal fun Modifier.swipeToScene( // swipe in the other direction. val startDragImmediately = state == transition && - transition.isAnimatingOffset && + !transition.isUserInputOngoing && !currentScene.shouldEnableSwipes(orientation.opposite()) // The velocity threshold at which the intent of the user is to swipe up or down. It is the same @@ -126,7 +126,7 @@ private class SwipeTransition(initialScene: Scene) : TransitionState.Transition override val progress: Float get() { - val offset = if (isAnimatingOffset) offsetAnimatable.value else dragOffset + val offset = if (isUserInputOngoing) dragOffset else offsetAnimatable.value if (distance == 0f) { // This can happen only if fromScene == toScene. error( @@ -137,16 +137,15 @@ private class SwipeTransition(initialScene: Scene) : TransitionState.Transition return offset / distance } - override val isUserInputDriven = true + override val isInitiatedByUserInput = true + + var _isUserInputOngoing by mutableStateOf(false) + override val isUserInputOngoing: Boolean + get() = _isUserInputOngoing /** The current offset caused by the drag gesture. */ var dragOffset by mutableFloatStateOf(0f) - /** - * Whether the offset is animated (the user lifted their finger) or if it is driven by gesture. - */ - var isAnimatingOffset by mutableStateOf(false) - /** The animatable used to animate the offset once the user lifted its finger. */ val offsetAnimatable = Animatable(0f, visibilityThreshold = OffsetVisibilityThreshold) @@ -209,9 +208,11 @@ private fun onDragStarted( transition: SwipeTransition, orientation: Orientation, ) { + transition._isUserInputOngoing = true + if (layoutImpl.state.transitionState == transition) { // This [transition] was already driving the animation: simply take over it. - if (transition.isAnimatingOffset) { + if (!transition.isUserInputOngoing) { // Stop animating and start from where the current offset. Setting the animation job to // `null` will effectively cancel the animation. transition.stopOffsetAnimation() @@ -456,30 +457,29 @@ private fun CoroutineScope.animateOffset( ) { transition.startOffsetAnimation { launch { - if (!transition.isAnimatingOffset) { - transition.offsetAnimatable.snapTo(transition.dragOffset) - } - transition.isAnimatingOffset = true - - transition.offsetAnimatable.animateTo( - targetOffset, - // TODO(b/290184746): Make this spring spec configurable. - spring( - stiffness = Spring.StiffnessMediumLow, - visibilityThreshold = OffsetVisibilityThreshold - ), - initialVelocity = initialVelocity, - ) + if (transition.isUserInputOngoing) { + transition.offsetAnimatable.snapTo(transition.dragOffset) + } + transition._isUserInputOngoing = false + + transition.offsetAnimatable.animateTo( + targetOffset, + // TODO(b/290184746): Make this spring spec configurable. + spring( + stiffness = Spring.StiffnessMediumLow, + visibilityThreshold = OffsetVisibilityThreshold + ), + initialVelocity = initialVelocity, + ) - // Now that the animation is done, the state should be idle. Note that if the state - // was changed since this animation started, some external code changed it and we - // shouldn't do anything here. Note also that this job will be cancelled in the case - // where the user intercepts this swipe. - if (layoutImpl.state.transitionState == transition) { - layoutImpl.state.transitionState = TransitionState.Idle(targetScene) - } + // Now that the animation is done, the state should be idle. Note that if the state + // was changed since this animation started, some external code changed it and we + // shouldn't do anything here. Note also that this job will be cancelled in the case + // where the user intercepts this swipe. + if (layoutImpl.state.transitionState == transition) { + layoutImpl.state.transitionState = TransitionState.Idle(targetScene) } - .also { it.invokeOnCompletion { transition.isAnimatingOffset = false } } + } } } diff --git a/packages/SystemUI/compose/core/tests/Android.bp b/packages/SystemUI/compose/core/tests/Android.bp index 52c63854f62f77051568cb129a0055d66eac983e..8e9c5864ce706164250a075c6ba4877875a53263 100644 --- a/packages/SystemUI/compose/core/tests/Android.bp +++ b/packages/SystemUI/compose/core/tests/Android.bp @@ -43,7 +43,7 @@ android_test { "androidx.compose.ui_ui-test-junit4", "androidx.compose.ui_ui-test-manifest", - "truth-prebuilt", + "truth", ], kotlincflags: ["-Xjvm-default=all"], diff --git a/packages/SystemUI/compose/core/tests/src/com/android/compose/animation/scene/SwipeToSceneTest.kt b/packages/SystemUI/compose/core/tests/src/com/android/compose/animation/scene/SwipeToSceneTest.kt index 2232370f3dc02feb56e6e79d49ddac3d3753ce89..53ed2b5d3317b3320c440a390cb96ef7407141f3 100644 --- a/packages/SystemUI/compose/core/tests/src/com/android/compose/animation/scene/SwipeToSceneTest.kt +++ b/packages/SystemUI/compose/core/tests/src/com/android/compose/animation/scene/SwipeToSceneTest.kt @@ -122,7 +122,8 @@ class SwipeToSceneTest { assertThat(transition.toScene).isEqualTo(TestScenes.SceneB) assertThat(transition.currentScene).isEqualTo(TestScenes.SceneA) assertThat(transition.progress).isEqualTo(55.dp / LayoutWidth) - assertThat(transition.isUserInputDriven).isTrue() + assertThat(transition.isInitiatedByUserInput).isTrue() + assertThat(transition.isUserInputOngoing).isTrue() // Release the finger. We should now be animating back to A (currentScene = SceneA) given // that 55dp < positional threshold. @@ -134,7 +135,8 @@ class SwipeToSceneTest { assertThat(transition.toScene).isEqualTo(TestScenes.SceneB) assertThat(transition.currentScene).isEqualTo(TestScenes.SceneA) assertThat(transition.progress).isEqualTo(55.dp / LayoutWidth) - assertThat(transition.isUserInputDriven).isTrue() + assertThat(transition.isInitiatedByUserInput).isTrue() + assertThat(transition.isUserInputOngoing).isFalse() // Wait for the animation to finish. We should now be in scene A. rule.waitForIdle() @@ -156,7 +158,8 @@ class SwipeToSceneTest { assertThat(transition.toScene).isEqualTo(TestScenes.SceneC) assertThat(transition.currentScene).isEqualTo(TestScenes.SceneA) assertThat(transition.progress).isEqualTo(56.dp / LayoutHeight) - assertThat(transition.isUserInputDriven).isTrue() + assertThat(transition.isInitiatedByUserInput).isTrue() + assertThat(transition.isUserInputOngoing).isTrue() // Release the finger. We should now be animating to C (currentScene = SceneC) given // that 56dp >= positional threshold. @@ -168,7 +171,8 @@ class SwipeToSceneTest { assertThat(transition.toScene).isEqualTo(TestScenes.SceneC) assertThat(transition.currentScene).isEqualTo(TestScenes.SceneC) assertThat(transition.progress).isEqualTo(56.dp / LayoutHeight) - assertThat(transition.isUserInputDriven).isTrue() + assertThat(transition.isInitiatedByUserInput).isTrue() + assertThat(transition.isUserInputOngoing).isFalse() // Wait for the animation to finish. We should now be in scene C. rule.waitForIdle() diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt index 1f9c3e6d1ea1dd4d6c548f0873c5b96421dd7787..a33eac55ac3e76b7ddd0543de54dd29c4b4c4dfc 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt @@ -23,11 +23,13 @@ import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding +import androidx.compose.material3.windowsizeclass.WindowWidthSizeClass import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import com.android.compose.animation.scene.SceneScope +import com.android.compose.windowsizeclass.LocalWindowSizeClass import com.android.systemui.battery.BatteryMeterViewController import com.android.systemui.dagger.SysUISingleton import com.android.systemui.qs.footer.ui.compose.QuickSettings @@ -37,6 +39,7 @@ import com.android.systemui.scene.shared.model.SceneKey import com.android.systemui.scene.shared.model.SceneModel import com.android.systemui.scene.shared.model.UserAction import com.android.systemui.scene.ui.composable.ComposableScene +import com.android.systemui.shade.ui.composable.CollapsedShadeHeader import com.android.systemui.shade.ui.composable.ExpandedShadeHeader import com.android.systemui.statusbar.phone.StatusBarIconController import com.android.systemui.statusbar.phone.StatusBarIconController.TintedIconManager @@ -98,12 +101,22 @@ private fun SceneScope.QuickSettingsScene( .clickable(onClick = { viewModel.onContentClicked() }) .padding(start = 16.dp, end = 16.dp, bottom = 48.dp) ) { - ExpandedShadeHeader( - viewModel = viewModel.shadeHeaderViewModel, - createTintedIconManager = createTintedIconManager, - createBatteryMeterViewController = createBatteryMeterViewController, - statusBarIconController = statusBarIconController, - ) + when (LocalWindowSizeClass.current.widthSizeClass) { + WindowWidthSizeClass.Compact -> + ExpandedShadeHeader( + viewModel = viewModel.shadeHeaderViewModel, + createTintedIconManager = createTintedIconManager, + createBatteryMeterViewController = createBatteryMeterViewController, + statusBarIconController = statusBarIconController, + ) + else -> + CollapsedShadeHeader( + viewModel = viewModel.shadeHeaderViewModel, + createTintedIconManager = createTintedIconManager, + createBatteryMeterViewController = createBatteryMeterViewController, + statusBarIconController = statusBarIconController, + ) + } Spacer(modifier = Modifier.height(16.dp)) QuickSettings() } diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainer.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainer.kt index ef012660ad71e49bfd067b05cb446998fc9d304e..6359ce60ae701859f9fd58bb7b57a8065a265388 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainer.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainer.kt @@ -158,7 +158,8 @@ private fun SceneTransitionObservableTransitionState.toModel(): ObservableTransi fromScene = fromScene.toModel().key, toScene = toScene.toModel().key, progress = progress, - isUserInputDriven = isUserInputDriven, + isInitiatedByUserInput = isInitiatedByUserInput, + isUserInputOngoing = isUserInputOngoing, ) } } diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeHeader.kt b/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeHeader.kt index 6629a259858708a187c08aa9d07d38a753b50864..591fa76f423f15b0ef2dba519af2e82072ca7fd3 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeHeader.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeHeader.kt @@ -30,6 +30,7 @@ import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.widthIn +import androidx.compose.material3.windowsizeclass.WindowWidthSizeClass import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState import androidx.compose.runtime.derivedStateOf @@ -50,6 +51,7 @@ import com.android.compose.animation.scene.ElementKey import com.android.compose.animation.scene.SceneScope import com.android.compose.animation.scene.ValueKey import com.android.compose.animation.scene.animateSharedFloatAsState +import com.android.compose.windowsizeclass.LocalWindowSizeClass import com.android.settingslib.Utils import com.android.systemui.battery.BatteryMeterView import com.android.systemui.battery.BatteryMeterViewController @@ -98,12 +100,12 @@ fun SceneScope.CollapsedShadeHeader( ShadeHeader.Keys.transitionProgress, ShadeHeader.Elements.FormatPlaceholder ) - val useExpandedFormat by - remember(formatProgress) { derivedStateOf { formatProgress.value > 0.5f } } val cutoutWidth = LocalDisplayCutout.current.width() val cutoutLocation = LocalDisplayCutout.current.location + val useExpandedFormat = formatProgress.value > 0.5f || cutoutLocation != CutoutLocation.CENTER + // This layout assumes it is globally positioned at (0, 0) and is the // same size as the screen. Layout( @@ -131,6 +133,14 @@ fun SceneScope.CollapsedShadeHeader( { Row(horizontalArrangement = Arrangement.End) { SystemIconContainer { + when (LocalWindowSizeClass.current.widthSizeClass) { + WindowWidthSizeClass.Medium, + WindowWidthSizeClass.Expanded -> + ShadeCarrierGroup( + viewModel = viewModel, + modifier = Modifier.align(Alignment.CenterVertically), + ) + } StatusIcons( viewModel = viewModel, createTintedIconManager = createTintedIconManager, diff --git a/packages/SystemUI/customization/res/values-af/strings.xml b/packages/SystemUI/customization/res/values-af/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..4c2c6275e6d8272679031fbf0ef2386f20f176a4 --- /dev/null +++ b/packages/SystemUI/customization/res/values-af/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"Verstek vir digitaal"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-am/strings.xml b/packages/SystemUI/customization/res/values-am/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..847d7a541c950ae45063036c8cfce154a8cb3219 --- /dev/null +++ b/packages/SystemUI/customization/res/values-am/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"ዲጂታሠáŠá‰£áˆª"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-ar/strings.xml b/packages/SystemUI/customization/res/values-ar/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..57d1612b337de43c2f2a61bd715b19787e3809b2 --- /dev/null +++ b/packages/SystemUI/customization/res/values-ar/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"رقمية تلقائية"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-as/strings.xml b/packages/SystemUI/customization/res/values-as/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..2f3b64b9ceb6c85435163726eaaee4da8e760698 --- /dev/null +++ b/packages/SystemUI/customization/res/values-as/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"ডিজিটেল ডিফ’লà§à¦Ÿ"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-az/strings.xml b/packages/SystemUI/customization/res/values-az/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..eb52f95a45258f9d51c0e18d3d081f74dd5b3380 --- /dev/null +++ b/packages/SystemUI/customization/res/values-az/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"RÉ™qÉ™msal defolt"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/customization/res/values-b+sr+Latn/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..90e6678bdcd62a92dc938117751c6c5b6f1cd5e9 --- /dev/null +++ b/packages/SystemUI/customization/res/values-b+sr+Latn/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"Digitalni podrazumevani"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-be/strings.xml b/packages/SystemUI/customization/res/values-be/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..f327da2a40a4f42daf3d594d74d1c88d7edb64ca --- /dev/null +++ b/packages/SystemUI/customization/res/values-be/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"Ñлектронны, Ñтандартны шрыфт"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-bg/strings.xml b/packages/SystemUI/customization/res/values-bg/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..6e3754a62a2949033163460eb093c2c54789b6fb --- /dev/null +++ b/packages/SystemUI/customization/res/values-bg/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"Стандартно дигитално"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-bn/strings.xml b/packages/SystemUI/customization/res/values-bn/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..adf1256b6c82fa46028c6e6102720e121fd7bc59 --- /dev/null +++ b/packages/SystemUI/customization/res/values-bn/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"ডিজিটাল ডিফলà§à¦Ÿ"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-bs/strings.xml b/packages/SystemUI/customization/res/values-bs/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..8de04ab06503aea03ab4eb3607233fee69095bf2 --- /dev/null +++ b/packages/SystemUI/customization/res/values-bs/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"Digitalno zadano"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-ca/strings.xml b/packages/SystemUI/customization/res/values-ca/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..967bb3f6d2f51ed04976e3e2b9a1b703f9257983 --- /dev/null +++ b/packages/SystemUI/customization/res/values-ca/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"Digital predeterminat"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-cs/strings.xml b/packages/SystemUI/customization/res/values-cs/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..45da4d759ad426229f855df2ce1e8e0a9afce036 --- /dev/null +++ b/packages/SystemUI/customization/res/values-cs/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"Digitálnà výchozÃ"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-da/strings.xml b/packages/SystemUI/customization/res/values-da/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..3ffaa8b167c85ea6d4ae7098fc6d078aa99e7043 --- /dev/null +++ b/packages/SystemUI/customization/res/values-da/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"Standard (digital)"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-de/strings.xml b/packages/SystemUI/customization/res/values-de/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..64f95e05b2454c98868f0a5084146ec12e767a90 --- /dev/null +++ b/packages/SystemUI/customization/res/values-de/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"Digital (Standard)"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-el/strings.xml b/packages/SystemUI/customization/res/values-el/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..57134b566d0816621758ffc903e9e3eb8c82f45f --- /dev/null +++ b/packages/SystemUI/customization/res/values-el/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"Ψηφιακή Ï€Ïοεπιλογή"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-en-rAU/strings.xml b/packages/SystemUI/customization/res/values-en-rAU/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..a6110d5d5b092c5a57081f383a25f2be13da4f35 --- /dev/null +++ b/packages/SystemUI/customization/res/values-en-rAU/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"Digital default"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-en-rCA/strings.xml b/packages/SystemUI/customization/res/values-en-rCA/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..79919c07d1894bac022815bb24313bf566bfd4c0 --- /dev/null +++ b/packages/SystemUI/customization/res/values-en-rCA/strings.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <!-- no translation found for clock_default_description (5309401440896597541) --> + <skip /> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-en-rGB/strings.xml b/packages/SystemUI/customization/res/values-en-rGB/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..a6110d5d5b092c5a57081f383a25f2be13da4f35 --- /dev/null +++ b/packages/SystemUI/customization/res/values-en-rGB/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"Digital default"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-en-rIN/strings.xml b/packages/SystemUI/customization/res/values-en-rIN/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..a6110d5d5b092c5a57081f383a25f2be13da4f35 --- /dev/null +++ b/packages/SystemUI/customization/res/values-en-rIN/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"Digital default"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-en-rXC/strings.xml b/packages/SystemUI/customization/res/values-en-rXC/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..7c540dab2cfe27a1ea42722b88a1d18f1e32c47c --- /dev/null +++ b/packages/SystemUI/customization/res/values-en-rXC/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"‎â€â€Žâ€Žâ€Žâ€Žâ€Žâ€â€Žâ€â€â€â€Žâ€Žâ€Žâ€Žâ€â€â€â€Žâ€â€â€â€â€Žâ€Žâ€â€â€â€â€â€â€â€â€Žâ€Žâ€â€Žâ€Žâ€â€â€Žâ€â€Žâ€â€â€â€Žâ€â€â€Žâ€Žâ€â€Žâ€Žâ€Žâ€Žâ€â€â€â€â€Žâ€â€Žâ€â€â€â€Žâ€Žâ€â€â€Žâ€â€Žâ€Žâ€â€Žâ€â€â€Žâ€â€Žâ€â€â€â€â€â€Žâ€Žâ€Žâ€â€Žâ€Žâ€â€Žâ€â€ŽDigital default‎â€â€Žâ€Žâ€â€Ž"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-es-rUS/strings.xml b/packages/SystemUI/customization/res/values-es-rUS/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..59be786849e68ccaf7eacae2762645edc4986973 --- /dev/null +++ b/packages/SystemUI/customization/res/values-es-rUS/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"Configuración predeterminada digital"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-es/strings.xml b/packages/SystemUI/customization/res/values-es/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..03ef0e5a8cea59ab580e8afad15ef5f06b37b133 --- /dev/null +++ b/packages/SystemUI/customization/res/values-es/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"Digital predeterminada"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-et/strings.xml b/packages/SystemUI/customization/res/values-et/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..fec793e99619d1c544bdff40a74b7130dcea6eff --- /dev/null +++ b/packages/SystemUI/customization/res/values-et/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"Digitaalne vaikimisi"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-eu/strings.xml b/packages/SystemUI/customization/res/values-eu/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..a70c8085ccf0d1027dc0172a4a5faf68e55d68d1 --- /dev/null +++ b/packages/SystemUI/customization/res/values-eu/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"Digital lehenetsia"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-fa/strings.xml b/packages/SystemUI/customization/res/values-fa/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..6426d5112528d9c3ff652a475b79633ddbdf5057 --- /dev/null +++ b/packages/SystemUI/customization/res/values-fa/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"دیجیتال پیش‌Ùرض"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-fi/strings.xml b/packages/SystemUI/customization/res/values-fi/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..9b19373a3765d6784b897fe1e378ce9a5102ddfe --- /dev/null +++ b/packages/SystemUI/customization/res/values-fi/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"Digitaalinen (oletus)"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-fr-rCA/strings.xml b/packages/SystemUI/customization/res/values-fr-rCA/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..bbd1208b1922b1159fd6967992e5f29ac17cb6f2 --- /dev/null +++ b/packages/SystemUI/customization/res/values-fr-rCA/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"Numérique, par défaut"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-fr/strings.xml b/packages/SystemUI/customization/res/values-fr/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..5579a427fe7197ca711ddacedf782e524a5ecee9 --- /dev/null +++ b/packages/SystemUI/customization/res/values-fr/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"Numérique par défaut"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-gl/strings.xml b/packages/SystemUI/customization/res/values-gl/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..2da93c6f1e34934c7f5cf0749b0a0b46404a4ec0 --- /dev/null +++ b/packages/SystemUI/customization/res/values-gl/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"Predeterminada dixital"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-gu/strings.xml b/packages/SystemUI/customization/res/values-gu/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..c578a2e2d322bde54641741b070fb07bc064170a --- /dev/null +++ b/packages/SystemUI/customization/res/values-gu/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"ડિજિટલ ડિફૉલà«àªŸ"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-hi/strings.xml b/packages/SystemUI/customization/res/values-hi/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..6080f802af04fb8f1fded158d23b3d9e7316119c --- /dev/null +++ b/packages/SystemUI/customization/res/values-hi/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"डिजिटल डिफ़ॉलà¥à¤Ÿ"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-hr/strings.xml b/packages/SystemUI/customization/res/values-hr/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..0a1440fb683b6205f1106f2aeb3218c8ce004348 --- /dev/null +++ b/packages/SystemUI/customization/res/values-hr/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"Digitalni zadani"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-hu/strings.xml b/packages/SystemUI/customization/res/values-hu/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..32618a869a1fdf75fec6aaa65e988b71deec98e6 --- /dev/null +++ b/packages/SystemUI/customization/res/values-hu/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"Digitális, alapértelmezett"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-hy/strings.xml b/packages/SystemUI/customization/res/values-hy/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..d45afbf256abcbc73e256704480c1e3021a212ae --- /dev/null +++ b/packages/SystemUI/customization/res/values-hy/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"Ô¹Õ¾Õ¡ÕµÕ«Õ¶, Õ¯Õ¡Õ¶ÕÕ¡Õ¤Ö€Õ¾Õ¡Õ®"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-in/strings.xml b/packages/SystemUI/customization/res/values-in/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..a6110d5d5b092c5a57081f383a25f2be13da4f35 --- /dev/null +++ b/packages/SystemUI/customization/res/values-in/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"Digital default"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-is/strings.xml b/packages/SystemUI/customization/res/values-is/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..5a370d614f0f5676f5cad46227f7c223ce481f27 --- /dev/null +++ b/packages/SystemUI/customization/res/values-is/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"Stafræn, sjálfgefið"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-it/strings.xml b/packages/SystemUI/customization/res/values-it/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..2a5087d3066912ed0a8dbc7ea6cfc6801796cf03 --- /dev/null +++ b/packages/SystemUI/customization/res/values-it/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"Digitale - predefinito"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-iw/strings.xml b/packages/SystemUI/customization/res/values-iw/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..ddd28f21ad9974aceb0616b31ef9da4b51abda1c --- /dev/null +++ b/packages/SystemUI/customization/res/values-iw/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"דיגיטלי ברירת מחדל"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-ja/strings.xml b/packages/SystemUI/customization/res/values-ja/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..744604a17efafaad06145bf79d06363be14368cf --- /dev/null +++ b/packages/SystemUI/customization/res/values-ja/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"デジタル デフォルト"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-ka/strings.xml b/packages/SystemUI/customization/res/values-ka/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..88ba1dfc097699fa3293fd0c1a566a604deb06f1 --- /dev/null +++ b/packages/SystemUI/customization/res/values-ka/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"ციფრული ნáƒáƒ’ულისხმევი"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-kk/strings.xml b/packages/SystemUI/customization/res/values-kk/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..9ee6522c49ceba1ec0572c109822af61ee925aa2 --- /dev/null +++ b/packages/SystemUI/customization/res/values-kk/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"Цифрлық әдепкі"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-km/strings.xml b/packages/SystemUI/customization/res/values-km/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..bbc438a69bcd310959b42183c96d75c337697873 --- /dev/null +++ b/packages/SystemUI/customization/res/values-km/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"លំនាំដើមឌីជីážáž›"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-kn/strings.xml b/packages/SystemUI/customization/res/values-kn/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..e67319d4021b17be80ea941642e223bc1a9caea5 --- /dev/null +++ b/packages/SystemUI/customization/res/values-kn/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"ಡಿಜಿಟಲೠಡೀಫಾಲà³à²Ÿà³"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-ko/strings.xml b/packages/SystemUI/customization/res/values-ko/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..fa9103b01e6670865e78490a1c7f2e47eaee50bc --- /dev/null +++ b/packages/SystemUI/customization/res/values-ko/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"디지털 기본"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-ky/strings.xml b/packages/SystemUI/customization/res/values-ky/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..76cc5e211a405da7bd12f197f84ca135026a9219 --- /dev/null +++ b/packages/SystemUI/customization/res/values-ky/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"Демейки Ñанариптик"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-lo/strings.xml b/packages/SystemUI/customization/res/values-lo/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..28f50008bd73ad3d24cf9e75ceb3f465973345b0 --- /dev/null +++ b/packages/SystemUI/customization/res/values-lo/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"ດິຈິຕàºàº™àº•àº²àº¡àº„່າເລີ່ມຕົ້ນ"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-lt/strings.xml b/packages/SystemUI/customization/res/values-lt/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..2fe73154776250043f76e8c4b1487535413ce3f1 --- /dev/null +++ b/packages/SystemUI/customization/res/values-lt/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"Skaitmeninis numatytasis"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-lv/strings.xml b/packages/SystemUI/customization/res/values-lv/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..e0b904a8a1c974af26006ed3486875e24fc3fd53 --- /dev/null +++ b/packages/SystemUI/customization/res/values-lv/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"DigitÄlais pulkstenis — noklusÄ“jums"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-mk/strings.xml b/packages/SystemUI/customization/res/values-mk/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..9b95a6e32b3153f2cd3fcf88ba42b09a3b05c1b4 --- /dev/null +++ b/packages/SystemUI/customization/res/values-mk/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"Дигитален Ñтандарден приказ"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-ml/strings.xml b/packages/SystemUI/customization/res/values-ml/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..7f6be8a59904e04492ec4e0b68964317dad64079 --- /dev/null +++ b/packages/SystemUI/customization/res/values-ml/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"ഡിജിറàµà´±àµ½ ഡിഫോൾടàµà´Ÿàµ"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-mn/strings.xml b/packages/SystemUI/customization/res/values-mn/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..38369b6f527d87716390354548109e36e27b5716 --- /dev/null +++ b/packages/SystemUI/customization/res/values-mn/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"Дижитал өгөгдмөл"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-mr/strings.xml b/packages/SystemUI/customization/res/values-mr/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..821ff100ab137cda56994009867d004c9e1f588d --- /dev/null +++ b/packages/SystemUI/customization/res/values-mr/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"डिजिटल डीफॉलà¥à¤Ÿà¤¸à¤¹ कà¥à¤²à¥‰à¤• फेस"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-ms/strings.xml b/packages/SystemUI/customization/res/values-ms/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..2f61b47a232409b5fa3d345ab6e7682bfbb586d5 --- /dev/null +++ b/packages/SystemUI/customization/res/values-ms/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"Digital lalai"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-my/strings.xml b/packages/SystemUI/customization/res/values-my/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..3d137ebc3abbfeeb2e868e3e61949175aadf87e9 --- /dev/null +++ b/packages/SystemUI/customization/res/values-my/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"ဒစ်ဂျစ်á€á€šá€ºá€”ာရီ မူရင်း"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-nb/strings.xml b/packages/SystemUI/customization/res/values-nb/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..6eb4373c448c6b9f4d0d7fc20761b0e127556a5d --- /dev/null +++ b/packages/SystemUI/customization/res/values-nb/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"Digital – standard"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-ne/strings.xml b/packages/SystemUI/customization/res/values-ne/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..c5b087744a18b5e741dcb3b1a494c5b68be3150f --- /dev/null +++ b/packages/SystemUI/customization/res/values-ne/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"डिजिटल डिफलà¥à¤Ÿ"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-nl/strings.xml b/packages/SystemUI/customization/res/values-nl/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..4f46ab8b2ba5f853a07ecdbff3e1fb8ed38a886a --- /dev/null +++ b/packages/SystemUI/customization/res/values-nl/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"Standaard digitaal"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-or/strings.xml b/packages/SystemUI/customization/res/values-or/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..a74017f6b68995756ca61947e968020b936c718c --- /dev/null +++ b/packages/SystemUI/customization/res/values-or/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"ଡିଜିଟାଲ ଡିଫଲàଟ"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-pa/strings.xml b/packages/SystemUI/customization/res/values-pa/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..a77661a8f56b85c012deab680a8ea03c15afda1a --- /dev/null +++ b/packages/SystemUI/customization/res/values-pa/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"ਡਿਜੀਟਲ ਡਿਫਾਲਟ"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-pl/strings.xml b/packages/SystemUI/customization/res/values-pl/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..6f5b6f280dd1f61e366e8e6b6913405f5a8e0c15 --- /dev/null +++ b/packages/SystemUI/customization/res/values-pl/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"Cyfrowa domyÅ›lna"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-pt-rPT/strings.xml b/packages/SystemUI/customization/res/values-pt-rPT/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..c6c3cc046965df6f4a6b334773b782853b30e715 --- /dev/null +++ b/packages/SystemUI/customization/res/values-pt-rPT/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"Predefinição digital"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-pt/strings.xml b/packages/SystemUI/customization/res/values-pt/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..bbe4355432115638e3a177d9709a82374c54147b --- /dev/null +++ b/packages/SystemUI/customization/res/values-pt/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"Digital padrão"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-ro/strings.xml b/packages/SystemUI/customization/res/values-ro/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..ef163e96f79f8fa27fbf569a95f6d37b3cf0c785 --- /dev/null +++ b/packages/SystemUI/customization/res/values-ro/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"Implicit digital"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-ru/strings.xml b/packages/SystemUI/customization/res/values-ru/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..5ee928e0fa37ff5ab9dc28f293f48b19403ba3f2 --- /dev/null +++ b/packages/SystemUI/customization/res/values-ru/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"Цифровые чаÑÑ‹, Ñтандартный"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-si/strings.xml b/packages/SystemUI/customization/res/values-si/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..caf9610e921ede6a42e0bc4eb3de2c351ac6b192 --- /dev/null +++ b/packages/SystemUI/customization/res/values-si/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"ඩිජිටල් පෙරනිමිය"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-sk/strings.xml b/packages/SystemUI/customization/res/values-sk/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..1843f971d25124d3c811a3faf7388d8ffebf3645 --- /dev/null +++ b/packages/SystemUI/customization/res/values-sk/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"Digitálne predvolené"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-sl/strings.xml b/packages/SystemUI/customization/res/values-sl/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..12df66f571d3b5f55bbd1c7f4c86c6582fdf3888 --- /dev/null +++ b/packages/SystemUI/customization/res/values-sl/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"Digitalna (privzeta)"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-sq/strings.xml b/packages/SystemUI/customization/res/values-sq/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..1fc9f252175f3ff2859375f411b7abb7bb1b0858 --- /dev/null +++ b/packages/SystemUI/customization/res/values-sq/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"Dixhitale e parazgjedhur"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-sr/strings.xml b/packages/SystemUI/customization/res/values-sr/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..6b127c9f79e5d685ca64f4ef3f62c68c5768c3c4 --- /dev/null +++ b/packages/SystemUI/customization/res/values-sr/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"Дигитални подразумевани"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-sv/strings.xml b/packages/SystemUI/customization/res/values-sv/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..84ad25c96655cf6478d26bf17b599f6bd8c7bf77 --- /dev/null +++ b/packages/SystemUI/customization/res/values-sv/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"Digital standard"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-sw/strings.xml b/packages/SystemUI/customization/res/values-sw/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..e2ec3de573a82963fa74bbf94da960427a7c75bb --- /dev/null +++ b/packages/SystemUI/customization/res/values-sw/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"Dijitali chaguomsingi"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-ta/strings.xml b/packages/SystemUI/customization/res/values-ta/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..f4eea07b0aa5a5f5ce1a24e98735b53168f6f60a --- /dev/null +++ b/packages/SystemUI/customization/res/values-ta/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"டிஜிடà¯à®Ÿà®²à¯ இயலà¯à®ªà¯"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-te/strings.xml b/packages/SystemUI/customization/res/values-te/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..c7c77d527e7f53db1906fc547f23e32e1134be06 --- /dev/null +++ b/packages/SystemUI/customization/res/values-te/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"డిజిటలౠఆటోమేటికౠసెటà±à°Ÿà°¿à°‚à°—à±"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-th/strings.xml b/packages/SystemUI/customization/res/values-th/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..61d880eb1ad99975d20669e5b10fe301bffb4e81 --- /dev/null +++ b/packages/SystemUI/customization/res/values-th/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"ดิจิทัลà¹à¸šà¸šà¹€à¸£à¸´à¹ˆà¸¡à¸•à¹‰à¸™"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-tl/strings.xml b/packages/SystemUI/customization/res/values-tl/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..a3484a7b6d2a91f57e4c95903b9707eeaef51427 --- /dev/null +++ b/packages/SystemUI/customization/res/values-tl/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"Digital na default"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-tr/strings.xml b/packages/SystemUI/customization/res/values-tr/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..a90e9852ef2f94d2d1d8f3a2ccea14b950747d27 --- /dev/null +++ b/packages/SystemUI/customization/res/values-tr/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"Dijital varsayılan"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-uk/strings.xml b/packages/SystemUI/customization/res/values-uk/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..ee9b77b905a228388ab48ec9734da91d5c6ba7b9 --- /dev/null +++ b/packages/SystemUI/customization/res/values-uk/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"Цифровий, Ñтандартний"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-ur/strings.xml b/packages/SystemUI/customization/res/values-ur/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..06a6a7cd01fd57fd8b9d1ea796d365b41a959677 --- /dev/null +++ b/packages/SystemUI/customization/res/values-ur/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"ڈیجیٹل ÚˆÛŒÙالٹ"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-uz/strings.xml b/packages/SystemUI/customization/res/values-uz/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..6b31b048b4a1a2d9064303b77d72abe5e3e62de1 --- /dev/null +++ b/packages/SystemUI/customization/res/values-uz/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"Raqamli soat, standart"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-vi/strings.xml b/packages/SystemUI/customization/res/values-vi/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..830b6e2b16a1ef9738b6fdeb82ed950f2e6f130a --- /dev/null +++ b/packages/SystemUI/customization/res/values-vi/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"Mặt số mặc định"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-zh-rCN/strings.xml b/packages/SystemUI/customization/res/values-zh-rCN/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..747567e9fb659222cff2102e0da051f76ecc4fa1 --- /dev/null +++ b/packages/SystemUI/customization/res/values-zh-rCN/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"默认数å—"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-zh-rHK/strings.xml b/packages/SystemUI/customization/res/values-zh-rHK/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..c19cc68ff15077ba82dff0ca1145512545267e77 --- /dev/null +++ b/packages/SystemUI/customization/res/values-zh-rHK/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"æ•¸ç¢¼æ™‚é˜ (é è¨)"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-zh-rTW/strings.xml b/packages/SystemUI/customization/res/values-zh-rTW/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..6fcd313a291d03714a715014cd4c212572323682 --- /dev/null +++ b/packages/SystemUI/customization/res/values-zh-rTW/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"數ä½é è¨"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values-zu/strings.xml b/packages/SystemUI/customization/res/values-zu/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..c87c250ae1b9f4670632e6c9087718e7048e3da7 --- /dev/null +++ b/packages/SystemUI/customization/res/values-zu/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="clock_default_description" msgid="5309401440896597541">"Okuzenzakalelayo kwedijithali"</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/res/values/strings.xml b/packages/SystemUI/customization/res/values/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..897c842b6d4b099c02e24e04e579045ff8282d4b --- /dev/null +++ b/packages/SystemUI/customization/res/values/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2023, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <!-- default clock face name [CHAR LIMIT=NONE]--> + <string name="clock_default_name">Default</string> + + <!-- default clock face description [CHAR LIMIT=NONE]--> + <string name="clock_default_description">Digital default</string> +</resources> \ No newline at end of file diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockController.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockController.kt index b28920c590c5182cebd064fc2e87852392b39a8d..b076b2cacf08326dfa7bd2859b250b071e4ef26b 100644 --- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockController.kt +++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockController.kt @@ -65,7 +65,13 @@ class DefaultClockController( protected var onSecondaryDisplay: Boolean = false override val events: DefaultClockEvents - override val config = ClockConfig(DEFAULT_CLOCK_ID) + override val config: ClockConfig by lazy { + ClockConfig( + DEFAULT_CLOCK_ID, + resources.getString(R.string.clock_default_name), + resources.getString(R.string.clock_default_description) + ) + } init { val parent = FrameLayout(ctx) diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockProvider.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockProvider.kt index 949641a7f75edc2636fefd553c05d9c639250b1b..dd52e39488ac334b8102707994746fe7c4b813ea 100644 --- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockProvider.kt +++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockProvider.kt @@ -25,7 +25,6 @@ import com.android.systemui.plugins.ClockProvider import com.android.systemui.plugins.ClockSettings private val TAG = DefaultClockProvider::class.simpleName -const val DEFAULT_CLOCK_NAME = "Default Clock" const val DEFAULT_CLOCK_ID = "DEFAULT" /** Provides the default system clock */ @@ -35,8 +34,7 @@ class DefaultClockProvider( val resources: Resources, val hasStepClockAnimation: Boolean = false ) : ClockProvider { - override fun getClocks(): List<ClockMetadata> = - listOf(ClockMetadata(DEFAULT_CLOCK_ID, DEFAULT_CLOCK_NAME)) + override fun getClocks(): List<ClockMetadata> = listOf(ClockMetadata(DEFAULT_CLOCK_ID)) override fun createClock(settings: ClockSettings): ClockController { if (settings.clockId != DEFAULT_CLOCK_ID) { diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockProviderPlugin.kt b/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockProviderPlugin.kt index e2f4793b8f91be31042a11b705ba52530a9e27ae..485c27e161506157479e4f96494ca29ce7487f1d 100644 --- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockProviderPlugin.kt +++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockProviderPlugin.kt @@ -192,15 +192,18 @@ enum class ClockTickRate(val value: Int) { /** Some data about a clock design */ data class ClockMetadata( val clockId: ClockId, - val name: String, -) { - constructor(clockId: ClockId) : this(clockId, clockId) {} -} +) /** Render configuration for the full clock. Modifies the way systemUI behaves with this clock. */ data class ClockConfig( val id: String, + /** Localized name of the clock */ + val name: String, + + /** Localized accessibility description for the clock */ + val description: String, + /** Transition to AOD should move smartspace like large clock instead of small clock */ val useAlternateSmartspaceAODTransition: Boolean = false, diff --git a/packages/SystemUI/res-keyguard/layout/alternate_bouncer.xml b/packages/SystemUI/res-keyguard/layout/alternate_bouncer.xml new file mode 100644 index 0000000000000000000000000000000000000000..218735229a5d1a276fa33737c438cb7e18b3240a --- /dev/null +++ b/packages/SystemUI/res-keyguard/layout/alternate_bouncer.xml @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="utf-8"?><!-- + ~ Copyright (C) 2023 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + ~ + --> + +<FrameLayout + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:sysui="http://schemas.android.com/apk/res-auto" + android:id="@+id/alternate_bouncer" + android:focusable="true" + android:clickable="true" + android:layout_width="match_parent" + android:layout_height="match_parent"> + + <com.android.systemui.scrim.ScrimView + android:id="@+id/alternate_bouncer_scrim" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:importantForAccessibility="no" + sysui:ignoreRightInset="true" + /> +</FrameLayout> diff --git a/packages/SystemUI/res/layout/super_notification_shade.xml b/packages/SystemUI/res/layout/super_notification_shade.xml index d4b73a4e3de0704b7320f9209eb43401ab99abfb..acee4258b64d8405c25aca0d7c5878f0b77d569d 100644 --- a/packages/SystemUI/res/layout/super_notification_shade.xml +++ b/packages/SystemUI/res/layout/super_notification_shade.xml @@ -130,6 +130,11 @@ android:inflatedId="@+id/multi_shade" android:layout="@layout/multi_shade" /> + <include layout="@layout/alternate_bouncer" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:visibility="invisible" /> + <com.android.systemui.biometrics.AuthRippleView android:id="@+id/auth_ripple" android:layout_width="match_parent" diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentsAnimationControllerCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentsAnimationControllerCompat.java index 0094820f0dad17880e858ecb1a33814195661161..a6e04cec5f8603a2d7051ac177460c5ce2e58c74 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentsAnimationControllerCompat.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentsAnimationControllerCompat.java @@ -23,6 +23,7 @@ import android.view.SurfaceControl; import android.window.PictureInPictureSurfaceTransaction; import android.window.TaskSnapshot; +import com.android.internal.os.IResultReceiver; import com.android.systemui.shared.recents.model.ThumbnailData; public class RecentsAnimationControllerCompat { @@ -89,11 +90,16 @@ public class RecentsAnimationControllerCompat { * @param sendUserLeaveHint determines whether userLeaveHint will be set true to the previous * app. */ - public void finish(boolean toHome, boolean sendUserLeaveHint) { + public void finish(boolean toHome, boolean sendUserLeaveHint, IResultReceiver finishCb) { try { - mAnimationController.finish(toHome, sendUserLeaveHint); + mAnimationController.finish(toHome, sendUserLeaveHint, finishCb); } catch (RemoteException e) { Log.e(TAG, "Failed to finish recents animation", e); + try { + finishCb.send(0, null); + } catch (Exception ex) { + // Local call, can ignore + } } } diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorFake.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorFake.java index c0ee71cf0dc82d4dac8019858429585dbc107659..0dfaf0f4318de03b8070c44a70827e7b2f359c64 100644 --- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorFake.java +++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorFake.java @@ -18,8 +18,15 @@ package com.android.systemui.classifier; import android.view.MotionEvent; +import javax.inject.Inject; + /** */ public class FalsingCollectorFake implements FalsingCollector { + + @Inject + public FalsingCollectorFake() { + } + @Override public void onSuccessfulUnlock() { } diff --git a/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSysUIComponent.java b/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSysUIComponent.java index 046ccf165d07b0a02117cdb2d160c3eb562751e6..a90980fddfb0ef73219a37e8159ebf011b1c2950 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSysUIComponent.java +++ b/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSysUIComponent.java @@ -18,7 +18,6 @@ package com.android.systemui.dagger; import com.android.systemui.globalactions.ShutdownUiModule; import com.android.systemui.keyguard.CustomizationProvider; -import com.android.systemui.shade.ShadeModule; import com.android.systemui.statusbar.NotificationInsetsModule; import com.android.systemui.statusbar.QsFrameTranslateModule; @@ -33,7 +32,6 @@ import dagger.Subcomponent; DependencyProvider.class, NotificationInsetsModule.class, QsFrameTranslateModule.class, - ShadeModule.class, ShutdownUiModule.class, SystemUIBinder.class, SystemUIModule.class, diff --git a/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSystemUIModule.java index 9e5fd5572dbcea8bbcab8ebfc0fec8e2d15d6a99..1dd4abfa076787553a2a630515b2d1691506c537 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSystemUIModule.java +++ b/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSystemUIModule.java @@ -21,12 +21,9 @@ import static com.android.systemui.Dependency.LEAK_REPORT_EMAIL_NAME; import android.content.Context; import android.hardware.SensorPrivacyManager; -import android.os.Handler; -import com.android.internal.logging.UiEventLogger; import com.android.keyguard.KeyguardViewController; import com.android.systemui.battery.BatterySaverModule; -import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.dock.DockManager; import com.android.systemui.dock.DockManagerImpl; import com.android.systemui.doze.DozeHost; @@ -34,7 +31,6 @@ import com.android.systemui.media.dagger.MediaModule; import com.android.systemui.navigationbar.NavigationBarControllerModule; import com.android.systemui.navigationbar.gestural.GestureModule; import com.android.systemui.plugins.qs.QSFactory; -import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.power.dagger.PowerModule; import com.android.systemui.qs.dagger.QSModule; import com.android.systemui.qs.tileimpl.QSFactoryImpl; @@ -45,7 +41,7 @@ import com.android.systemui.scene.SceneContainerFrameworkModule; import com.android.systemui.screenshot.ReferenceScreenshotModule; import com.android.systemui.settings.dagger.MultiUserUtilsModule; import com.android.systemui.shade.NotificationShadeWindowControllerImpl; -import com.android.systemui.shade.ShadeExpansionStateManager; +import com.android.systemui.shade.ShadeModule; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.KeyboardShortcutsModule; import com.android.systemui.statusbar.NotificationLockscreenUserManager; @@ -53,20 +49,13 @@ import com.android.systemui.statusbar.NotificationLockscreenUserManagerImpl; import com.android.systemui.statusbar.NotificationShadeWindowController; import com.android.systemui.statusbar.dagger.StartCentralSurfacesModule; import com.android.systemui.statusbar.events.StatusBarEventsModule; -import com.android.systemui.statusbar.notification.collection.provider.VisualStabilityProvider; -import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager; import com.android.systemui.statusbar.phone.DozeServiceHost; -import com.android.systemui.statusbar.phone.HeadsUpManagerPhone; -import com.android.systemui.statusbar.phone.KeyguardBypassController; +import com.android.systemui.statusbar.phone.HeadsUpModule; import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager; import com.android.systemui.statusbar.phone.fragment.CollapsedStatusBarFragmentStartableModule; -import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper; import com.android.systemui.statusbar.policy.AospPolicyModule; -import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.statusbar.policy.DeviceProvisionedController; import com.android.systemui.statusbar.policy.DeviceProvisionedControllerImpl; -import com.android.systemui.statusbar.policy.HeadsUpManager; -import com.android.systemui.statusbar.policy.HeadsUpManagerLogger; import com.android.systemui.statusbar.policy.IndividualSensorPrivacyController; import com.android.systemui.statusbar.policy.IndividualSensorPrivacyControllerImpl; import com.android.systemui.statusbar.policy.SensorPrivacyController; @@ -100,11 +89,13 @@ import javax.inject.Named; BatterySaverModule.class, CollapsedStatusBarFragmentStartableModule.class, GestureModule.class, + HeadsUpModule.class, MediaModule.class, MultiUserUtilsModule.class, NavigationBarControllerModule.class, PowerModule.class, QSModule.class, + ShadeModule.class, ReferenceScreenshotModule.class, RotationLockModule.class, SceneContainerFrameworkModule.class, @@ -161,38 +152,6 @@ public abstract class ReferenceSystemUIModule { return true; } - @SysUISingleton - @Provides - static HeadsUpManagerPhone provideHeadsUpManagerPhone( - Context context, - HeadsUpManagerLogger headsUpManagerLogger, - StatusBarStateController statusBarStateController, - KeyguardBypassController bypassController, - GroupMembershipManager groupManager, - VisualStabilityProvider visualStabilityProvider, - ConfigurationController configurationController, - @Main Handler handler, - AccessibilityManagerWrapper accessibilityManagerWrapper, - UiEventLogger uiEventLogger, - ShadeExpansionStateManager shadeExpansionStateManager) { - return new HeadsUpManagerPhone( - context, - headsUpManagerLogger, - statusBarStateController, - bypassController, - groupManager, - visualStabilityProvider, - configurationController, - handler, - accessibilityManagerWrapper, - uiEventLogger, - shadeExpansionStateManager - ); - } - - @Binds - abstract HeadsUpManager bindHeadsUpManagerPhone(HeadsUpManagerPhone headsUpManagerPhone); - @Provides @SysUISingleton static Recents provideRecents(Context context, RecentsImplementation recentsImplementation, diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt b/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt index d89332d6d68671c03179421164a308b5e1214c24..5d6949b3e87f8232da39c105a994e251d43d8d01 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt +++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt @@ -37,6 +37,7 @@ import com.android.systemui.keyboard.PhysicalKeyboardCoreStartable import com.android.systemui.keyguard.KeyguardViewConfigurator import com.android.systemui.keyguard.KeyguardViewMediator import com.android.systemui.keyguard.data.quickaffordance.MuteQuickAffordanceCoreStartable +import com.android.systemui.keyguard.ui.binder.AlternateBouncerBinder import com.android.systemui.keyguard.ui.binder.KeyguardDismissActionBinder import com.android.systemui.keyguard.ui.binder.KeyguardDismissBinder import com.android.systemui.log.SessionTracker @@ -92,6 +93,11 @@ abstract class SystemUICoreStartableModule { @ClassKey(AuthController::class) abstract fun bindAuthController(service: AuthController): CoreStartable + @Binds + @IntoMap + @ClassKey(AlternateBouncerBinder::class) + abstract fun bindAlternateBouncerBinder(impl: AlternateBouncerBinder): CoreStartable + /** Inject into BiometricNotificationService */ @Binds @IntoMap diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt index d518c0805a34fd53f1822f45c07c2ff3b8d82e04..f6f24e0aecc0f0ef60efa76e1226d85f14ee00f0 100644 --- a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt +++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt @@ -304,6 +304,11 @@ object Flags { @JvmField val WALLPAPER_PICKER_PREVIEW_ANIMATION = releasedFlag("wallpaper_picker_preview_animation") + /** Flag to enable rest to unlock feature. */ + // TODO(b/303672286): Tracking bug + @JvmField + val REST_TO_UNLOCK: UnreleasedFlag = unreleasedFlag("rest_to_unlock") + /** * TODO(b/278086361): Tracking bug * Complete rewrite of the interactions between System UI and Window Manager involving keyguard @@ -326,7 +331,7 @@ object Flags { /** Flag to use a separate view for the alternate bouncer. */ // TODO(b/300440924): Tracking bug @JvmField - val ALTERNATE_BOUNCER_REFACTOR: UnreleasedFlag = unreleasedFlag("alternate_bouncer_view") + val ALTERNATE_BOUNCER_VIEW: UnreleasedFlag = unreleasedFlag("alternate_bouncer_view") // 300 - power menu // TODO(b/254512600): Tracking Bug 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 3ccf446fef591de03631c647af4605d935c4740e..d06f31fed8dbdb8d479e8082d9b550e521cbab3c 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 @@ -32,6 +32,7 @@ import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch import javax.inject.Inject +import kotlin.time.Duration.Companion.milliseconds @SysUISingleton class FromAlternateBouncerTransitionInteractor @@ -129,11 +130,11 @@ constructor( override fun getDefaultAnimatorForTransitionsToState(toState: KeyguardState): ValueAnimator { return ValueAnimator().apply { interpolator = Interpolators.LINEAR - duration = TRANSITION_DURATION_MS + duration = TRANSITION_DURATION_MS.inWholeMilliseconds } } companion object { - private const val TRANSITION_DURATION_MS = 300L + val TRANSITION_DURATION_MS = 300.milliseconds } } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardFaceAuthInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardFaceAuthInteractor.kt index e57c919a5b3ef661a9d15d3ac1bfea4c61f43a7d..89aca7631934699552a326bef6bc7caf1478cf2b 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardFaceAuthInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardFaceAuthInteractor.kt @@ -61,6 +61,7 @@ interface KeyguardFaceAuthInteractor { fun onSwipeUpOnBouncer() fun onPrimaryBouncerUserInput() fun onAccessibilityAction() + fun onWalletLaunched() } /** diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/NoopKeyguardFaceAuthInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/NoopKeyguardFaceAuthInteractor.kt index 596a1c01ca42fa670c2977193dcc1205706ce615..f38bb2b519e70562873a9b5df26fd3fbc324e56e 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/NoopKeyguardFaceAuthInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/NoopKeyguardFaceAuthInteractor.kt @@ -61,4 +61,5 @@ class NoopKeyguardFaceAuthInteractor @Inject constructor() : KeyguardFaceAuthInt override fun onSwipeUpOnBouncer() {} override fun onPrimaryBouncerUserInput() {} override fun onAccessibilityAction() {} + override fun onWalletLaunched() = Unit } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/SystemUIKeyguardFaceAuthInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/SystemUIKeyguardFaceAuthInteractor.kt index ef1d5ac2a6d4ddcc87c603819bbf11dbc82f3e69..797dec2c96255971d2be89fcfd60fea4c1f8a79a 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/SystemUIKeyguardFaceAuthInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/SystemUIKeyguardFaceAuthInteractor.kt @@ -24,6 +24,7 @@ import com.android.keyguard.KeyguardUpdateMonitor import com.android.systemui.CoreStartable import com.android.systemui.biometrics.data.repository.FacePropertyRepository import com.android.systemui.biometrics.shared.model.LockoutMode +import com.android.systemui.biometrics.shared.model.SensorStrength import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor import com.android.systemui.dagger.SysUISingleton @@ -33,7 +34,6 @@ import com.android.systemui.flags.FeatureFlags import com.android.systemui.flags.Flags import com.android.systemui.keyguard.data.repository.DeviceEntryFaceAuthRepository import com.android.systemui.keyguard.data.repository.DeviceEntryFingerprintAuthRepository -import com.android.systemui.keyguard.data.repository.KeyguardRepository import com.android.systemui.keyguard.shared.model.ErrorFaceAuthenticationStatus import com.android.systemui.keyguard.shared.model.FaceAuthenticationStatus import com.android.systemui.keyguard.shared.model.TransitionState @@ -44,6 +44,7 @@ import com.android.systemui.user.data.model.SelectionStatus import com.android.systemui.user.data.repository.UserRepository import com.android.systemui.util.kotlin.pairwise import com.android.systemui.util.kotlin.sample +import javax.inject.Inject import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.Flow @@ -56,7 +57,6 @@ import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.merge import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.yield -import javax.inject.Inject /** * Encapsulates business logic related face authentication being triggered for device entry from @@ -79,7 +79,6 @@ constructor( private val deviceEntryFingerprintAuthRepository: DeviceEntryFingerprintAuthRepository, private val userRepository: UserRepository, private val facePropertyRepository: FacePropertyRepository, - private val keyguardRepository: KeyguardRepository, private val faceWakeUpTriggersConfig: FaceWakeUpTriggersConfig, private val powerInteractor: PowerInteractor, ) : CoreStartable, KeyguardFaceAuthInteractor { @@ -207,6 +206,12 @@ constructor( runFaceAuth(FaceAuthUiEvent.FACE_AUTH_ACCESSIBILITY_ACTION, false) } + override fun onWalletLaunched() { + if (facePropertyRepository.sensorInfo.value?.strength == SensorStrength.STRONG) { + runFaceAuth(FaceAuthUiEvent.FACE_AUTH_TRIGGERED_OCCLUDING_APP_REQUESTED, true) + } + } + override fun registerListener(listener: FaceAuthenticationListener) { listeners.add(listener) } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/AlternateBouncerViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/AlternateBouncerViewBinder.kt new file mode 100644 index 0000000000000000000000000000000000000000..41af9e810fbf7a17207322ba2693fd55c955a924 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/AlternateBouncerViewBinder.kt @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.keyguard.ui.binder + +import android.view.View +import android.view.ViewGroup +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.repeatOnLifecycle +import com.android.systemui.CoreStartable +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.dagger.qualifiers.Application +import com.android.systemui.flags.FeatureFlagsClassic +import com.android.systemui.flags.Flags +import com.android.systemui.keyguard.ui.viewmodel.AlternateBouncerViewModel +import com.android.systemui.lifecycle.repeatWhenAttached +import com.android.systemui.res.R +import com.android.systemui.scrim.ScrimView +import com.android.systemui.shade.NotificationShadeWindowView +import com.android.systemui.statusbar.NotificationShadeWindowController +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.launch +import javax.inject.Inject + +@ExperimentalCoroutinesApi +@SysUISingleton +class AlternateBouncerBinder +@Inject +constructor( + private val notificationShadeWindowView: NotificationShadeWindowView, + private val featureFlags: FeatureFlagsClassic, + private val alternateBouncerViewModel: AlternateBouncerViewModel, + @Application private val scope: CoroutineScope, + private val notificationShadeWindowController: NotificationShadeWindowController, +) : CoreStartable { + override fun start() { + if (!featureFlags.isEnabled(Flags.ALTERNATE_BOUNCER_VIEW)) { + return + } + + AlternateBouncerViewBinder.bind( + notificationShadeWindowView.requireViewById(R.id.alternate_bouncer), + alternateBouncerViewModel, + scope, + notificationShadeWindowController, + ) + } +} + +/** + * Binds the alternate bouncer view to its view-model. + * + * To use this properly, users should maintain a one-to-one relationship between the [View] and the + * view-binding, binding each view only once. It is okay and expected for the same instance of the + * view-model to be reused for multiple view/view-binder bindings. + */ +@ExperimentalCoroutinesApi +object AlternateBouncerViewBinder { + + /** Binds the view to the view-model, continuing to update the former based on the latter. */ + @JvmStatic + fun bind( + view: ViewGroup, + viewModel: AlternateBouncerViewModel, + scope: CoroutineScope, + notificationShadeWindowController: NotificationShadeWindowController, + ) { + scope.launch { + // forcePluginOpen is necessary to show over occluded apps. + // This cannot be tied to the view's lifecycle because setting this allows the view + // to be started in the first place. + viewModel.forcePluginOpen.collect { + notificationShadeWindowController.setForcePluginOpen(it, this) + } + } + + val scrim = view.requireViewById(R.id.alternate_bouncer_scrim) as ScrimView + view.repeatWhenAttached { alternateBouncerViewContainer -> + repeatOnLifecycle(Lifecycle.State.STARTED) { + scrim.viewAlpha = 0f + + launch { + viewModel.onClickListener.collect { + // TODO (b/287599719): Support swiping to dismiss altBouncer + alternateBouncerViewContainer.setOnClickListener(it) + } + } + + launch { + viewModel.scrimAlpha.collect { + alternateBouncerViewContainer.visibility = + if (it < .1f) View.INVISIBLE else View.VISIBLE + scrim.viewAlpha = it + } + } + + launch { viewModel.scrimColor.collect { scrim.tint = it } } + } + } + } +} diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt index 5ae2abaea7884d0223ed86c40c33ed3f5976557e..c6d8ec7789f27d60778e353aa950bc3d84dccb50 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt @@ -27,11 +27,14 @@ import android.hardware.display.DisplayManager import android.os.Bundle import android.os.Handler import android.os.IBinder +import android.view.Display +import android.view.Display.DEFAULT_DISPLAY import android.view.LayoutInflater import android.view.SurfaceControlViewHost import android.view.View import android.view.ViewGroup import android.view.WindowManager +import android.view.WindowManager.LayoutParams.TYPE_KEYGUARD import android.widget.FrameLayout import androidx.constraintlayout.widget.ConstraintLayout import androidx.core.view.isInvisible @@ -125,6 +128,8 @@ constructor( private val shouldHideClock: Boolean = bundle.getBoolean(ClockPreviewConstants.KEY_HIDE_CLOCK, false) private val wallpaperColors: WallpaperColors? = bundle.getParcelable(KEY_COLORS) + private val displayId = bundle.getInt(KEY_DISPLAY_ID, DEFAULT_DISPLAY) + private val display: Display = displayManager.getDisplay(displayId) private var host: SurfaceControlViewHost @@ -164,7 +169,7 @@ constructor( host = SurfaceControlViewHost( context, - displayManager.getDisplay(bundle.getInt(KEY_DISPLAY_ID)), + displayManager.getDisplay(DEFAULT_DISPLAY), hostToken, "KeyguardPreviewRenderer" ) @@ -174,21 +179,27 @@ constructor( fun render() { mainHandler.post { - val rootView = FrameLayout(context) + val previewContext = context.createDisplayContext(display) - setupKeyguardRootView(rootView) + val rootView = FrameLayout(previewContext) + + setupKeyguardRootView(previewContext, rootView) if (!featureFlags.isEnabled(Flags.MIGRATE_SPLIT_KEYGUARD_BOTTOM_AREA)) { setUpBottomArea(rootView) } + val windowContext = context.createWindowContext(display, TYPE_KEYGUARD, null) + val windowManagerOfDisplay = windowContext.getSystemService(WindowManager::class.java) rootView.measure( View.MeasureSpec.makeMeasureSpec( - windowManager.currentWindowMetrics.bounds.width(), + windowManagerOfDisplay?.currentWindowMetrics?.bounds?.width() + ?: windowManager.currentWindowMetrics.bounds.width(), View.MeasureSpec.EXACTLY ), View.MeasureSpec.makeMeasureSpec( - windowManager.currentWindowMetrics.bounds.height(), + windowManagerOfDisplay?.currentWindowMetrics?.bounds?.height() + ?: windowManager.currentWindowMetrics.bounds.height(), View.MeasureSpec.EXACTLY ), ) @@ -251,7 +262,7 @@ constructor( * * The end padding is as follows: Below clock padding end */ - private fun setUpSmartspace(parentView: ViewGroup) { + private fun setUpSmartspace(previewContext: Context, parentView: ViewGroup) { if ( !lockscreenSmartspaceController.isEnabled() || !lockscreenSmartspaceController.isDateWeatherDecoupled() @@ -263,12 +274,12 @@ constructor( val topPadding: Int = KeyguardPreviewSmartspaceViewModel.getLargeClockSmartspaceTopPadding( - context.resources, + previewContext.resources, ) val startPadding: Int = - context.resources.getDimensionPixelSize(R.dimen.below_clock_padding_start) + previewContext.resources.getDimensionPixelSize(R.dimen.below_clock_padding_start) val endPadding: Int = - context.resources.getDimensionPixelSize(R.dimen.below_clock_padding_end) + previewContext.resources.getDimensionPixelSize(R.dimen.below_clock_padding_end) smartSpaceView?.let { it.setPaddingRelative(startPadding, topPadding, endPadding, 0) @@ -308,8 +319,8 @@ constructor( } @OptIn(ExperimentalCoroutinesApi::class) - private fun setupKeyguardRootView(rootView: FrameLayout) { - val keyguardRootView = KeyguardRootView(context, null).apply { removeAllViews() } + private fun setupKeyguardRootView(previewContext: Context, rootView: FrameLayout) { + val keyguardRootView = KeyguardRootView(previewContext, null).apply { removeAllViews() } disposables.add( KeyguardRootViewBinder.bind( keyguardRootView, @@ -333,10 +344,10 @@ constructor( if (featureFlags.isEnabled(Flags.MIGRATE_SPLIT_KEYGUARD_BOTTOM_AREA)) { setupShortcuts(keyguardRootView) } - setUpUdfps(rootView) + setUpUdfps(previewContext, rootView) if (!shouldHideClock) { - setUpClock(rootView) + setUpClock(previewContext, rootView) KeyguardPreviewClockViewBinder.bind( largeClockHostView, smallClockHostView, @@ -344,7 +355,7 @@ constructor( ) } - setUpSmartspace(rootView) + setUpSmartspace(previewContext, rootView) smartSpaceView?.let { KeyguardPreviewSmartspaceViewBinder.bind(it, smartspaceViewModel) } @@ -381,7 +392,7 @@ constructor( } } - private fun setUpUdfps(parentView: ViewGroup) { + private fun setUpUdfps(previewContext: Context, parentView: ViewGroup) { val sensorBounds = udfpsOverlayInteractor.udfpsOverlayParams.value.sensorBounds // If sensorBounds are default rect, then there is no UDFPS @@ -399,7 +410,7 @@ constructor( sensorBounds.bottom ) val finger = - LayoutInflater.from(context) + LayoutInflater.from(previewContext) .inflate( R.layout.udfps_keyguard_preview, parentView, @@ -408,12 +419,12 @@ constructor( parentView.addView(finger, fingerprintLayoutParams) } - private fun setUpClock(parentView: ViewGroup) { + private fun setUpClock(previewContext: Context, parentView: ViewGroup) { largeClockHostView = if (featureFlags.isEnabled(Flags.MIGRATE_KEYGUARD_STATUS_VIEW)) { parentView.requireViewById<FrameLayout>(R.id.lockscreen_clock_view_large) } else { - val hostView = FrameLayout(context) + val hostView = FrameLayout(previewContext) hostView.layoutParams = FrameLayout.LayoutParams( FrameLayout.LayoutParams.MATCH_PARENT, @@ -429,7 +440,7 @@ constructor( parentView.requireViewById<FrameLayout>(R.id.lockscreen_clock_view) } else { val resources = parentView.resources - val hostView = FrameLayout(context) + val hostView = FrameLayout(previewContext) val layoutParams = FrameLayout.LayoutParams( FrameLayout.LayoutParams.WRAP_CONTENT, diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerViewModel.kt new file mode 100644 index 0000000000000000000000000000000000000000..235a28d4ebc56caae60f3211dfd7f8c12a9d4fc3 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerViewModel.kt @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package com.android.systemui.keyguard.ui.viewmodel + +import android.graphics.Color +import android.view.View +import com.android.systemui.keyguard.domain.interactor.FromAlternateBouncerTransitionInteractor.Companion.TRANSITION_DURATION_MS +import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor +import com.android.systemui.keyguard.shared.model.KeyguardState.ALTERNATE_BOUNCER +import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow +import com.android.systemui.plugins.FalsingManager +import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager +import com.android.wm.shell.animation.Interpolators +import javax.inject.Inject +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.distinctUntilChanged +import kotlinx.coroutines.flow.flowOf +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.merge + +@ExperimentalCoroutinesApi +class AlternateBouncerViewModel +@Inject +constructor( + statusBarKeyguardViewManager: StatusBarKeyguardViewManager, + transitionInteractor: KeyguardTransitionInteractor, + falsingManager: FalsingManager, +) { + // When we're fully transitioned to the AlternateBouncer, the alpha of the scrim should be: + private val alternateBouncerScrimAlpha = .66f + private val toAlternateBouncerTransition = + KeyguardTransitionAnimationFlow( + transitionDuration = TRANSITION_DURATION_MS, + transitionFlow = transitionInteractor.anyStateToAlternateBouncerTransition, + ) + .createFlow( + duration = TRANSITION_DURATION_MS, + onStep = { it }, + onFinish = { 1f }, + // Reset on cancel + onCancel = { 0f }, + interpolator = Interpolators.FAST_OUT_SLOW_IN, + ) + private val fromAlternateBouncerTransition = + KeyguardTransitionAnimationFlow( + transitionDuration = TRANSITION_DURATION_MS, + transitionFlow = transitionInteractor.transitionStepsFromState(ALTERNATE_BOUNCER), + ) + .createFlow( + duration = TRANSITION_DURATION_MS, + onStep = { 1f - it }, + // Reset on cancel + onCancel = { 0f }, + interpolator = Interpolators.FAST_OUT_SLOW_IN, + ) + + /** Progress to a fully transitioned alternate bouncer. 1f represents fully transitioned. */ + private val transitionToAlternateBouncerProgress = + merge(fromAlternateBouncerTransition, toAlternateBouncerTransition) + + val forcePluginOpen: Flow<Boolean> = + transitionToAlternateBouncerProgress.map { it > 0f }.distinctUntilChanged() + + /** An observable for the scrim alpha. */ + val scrimAlpha = transitionToAlternateBouncerProgress.map { it * alternateBouncerScrimAlpha } + + /** An observable for the scrim color. Change color for easier debugging. */ + val scrimColor: Flow<Int> = flowOf(Color.BLACK) + + private val clickListener = + View.OnClickListener { + if (!falsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) { + statusBarKeyguardViewManager.showPrimaryBouncer(/* scrimmed */ true) + } + } + + val onClickListener: Flow<View.OnClickListener?> = + transitionToAlternateBouncerProgress + .map { + if (it == 1f) { + clickListener + } else { + null + } + } + .distinctUntilChanged() +} diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/UdfpsLockscreenViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/UdfpsLockscreenViewModel.kt index 54abc5bc695f32f8f693e6dd745d246b6b199730..0b1079f69d6e8afade9ab8dc0bdf440307dd2752 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/UdfpsLockscreenViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/UdfpsLockscreenViewModel.kt @@ -19,13 +19,13 @@ package com.android.systemui.keyguard.ui.viewmodel import android.content.Context import androidx.annotation.ColorInt import com.android.settingslib.Utils.getColorAttrDefaultColor -import com.android.systemui.res.R import com.android.systemui.keyguard.domain.interactor.BurnInOffsets import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor import com.android.systemui.keyguard.domain.interactor.UdfpsKeyguardInteractor import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.keyguard.shared.model.StatusBarState +import com.android.systemui.res.R import com.android.wm.shell.animation.Interpolators import javax.inject.Inject import kotlin.math.roundToInt @@ -62,7 +62,7 @@ open class UdfpsLockscreenViewModel( private val toAlternateBouncer: Flow<TransitionViewModel> = keyguardInteractor.statusBarState.flatMapLatest { statusBarState -> - transitionInteractor.anyStateToAlternateBouncerTransition.map { + transitionInteractor.transitionStepsToState(KeyguardState.ALTERNATE_BOUNCER).map { TransitionViewModel( alpha = 1f, scale = diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFragmentLegacy.java b/packages/SystemUI/src/com/android/systemui/qs/QSFragmentLegacy.java index 8589ae9305fded47433cd118a7c8f9ac1841e790..68bf88b16ae2a9a658432be109676b59d01fbd70 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSFragmentLegacy.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSFragmentLegacy.java @@ -72,7 +72,7 @@ public class QSFragmentLegacy extends LifecycleFragment implements QS { @Override public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { - QSFragmentComponent qsFragmentComponent = mQsComponentFactory.create(this); + QSFragmentComponent qsFragmentComponent = mQsComponentFactory.create(getView()); mQsImpl = mQsImplProvider.get(); mQsImpl.onComponentCreated(qsFragmentComponent, savedInstanceState); } diff --git a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSFragmentComponent.java b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSFragmentComponent.java index 327e858059f3b4f04be63bbc3ae8afe5f2da1dfc..ce8db789842a799aa6585f57e2cbd5c12b022e87 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSFragmentComponent.java +++ b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSFragmentComponent.java @@ -16,6 +16,9 @@ package com.android.systemui.qs.dagger; +import android.view.View; + +import com.android.systemui.dagger.qualifiers.RootView; import com.android.systemui.qs.QSFragmentLegacy; import dagger.BindsInstance; @@ -31,6 +34,7 @@ public interface QSFragmentComponent extends QSComponent { /** Factory for building a {@link QSFragmentComponent}. */ @Subcomponent.Factory interface Factory { - QSFragmentComponent create(@BindsInstance QSFragmentLegacy qsFragment); + /** */ + QSFragmentComponent create(@BindsInstance @RootView View view); } } diff --git a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSFragmentModule.java b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSFragmentModule.java index 0c9c24df5e3690a760368e466fb27a64faf55285..0e75b2157a7da70781789e848ca97183a7de887c 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSFragmentModule.java +++ b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSFragmentModule.java @@ -20,34 +20,17 @@ import static com.android.systemui.util.Utils.useCollapsedMediaInLandscape; import static com.android.systemui.util.Utils.useQsMediaPlayer; import android.content.Context; -import android.view.View; -import com.android.systemui.dagger.qualifiers.RootView; -import com.android.systemui.plugins.qs.QS; -import com.android.systemui.qs.QSFragmentLegacy; - -import javax.inject.Named; - -import dagger.Binds; import dagger.Module; import dagger.Provides; +import javax.inject.Named; + /** * Dagger Module for {@link QSFragmentComponent}. */ @Module(includes = {QSScopeModule.class}) public interface QSFragmentModule { - - @Provides - @RootView - static View provideRootView(QSFragmentLegacy qsFragment) { - return qsFragment.getView(); - } - - /** */ - @Binds - QS bindQS(QSFragmentLegacy qsFragment); - /** */ @Provides @Named(QSScopeModule.QS_USING_MEDIA_PLAYER) diff --git a/packages/SystemUI/src/com/android/systemui/qs/pipeline/domain/interactor/CurrentTilesInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/pipeline/domain/interactor/CurrentTilesInteractor.kt index c5512c15ccc2205331008106a0662d131ae620c2..4bb8c6e4bb2dc7e243e0b874daa7e3a2872fa483 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/pipeline/domain/interactor/CurrentTilesInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/pipeline/domain/interactor/CurrentTilesInteractor.kt @@ -272,7 +272,6 @@ constructor( // repository launch { tileSpecRepository.setTiles(currentUser.value, resolvedSpecs) } } - Log.d("Fabian", "Finished resolving tiles") } } } diff --git a/packages/SystemUI/src/com/android/systemui/scene/shared/model/ObservableTransitionState.kt b/packages/SystemUI/src/com/android/systemui/scene/shared/model/ObservableTransitionState.kt index 3927873f8ba8bbd754988d626e2ee953888f5c61..f704894e56e210a19989bfce6ba86744dd3c86f9 100644 --- a/packages/SystemUI/src/com/android/systemui/scene/shared/model/ObservableTransitionState.kt +++ b/packages/SystemUI/src/com/android/systemui/scene/shared/model/ObservableTransitionState.kt @@ -42,6 +42,13 @@ sealed class ObservableTransitionState { * scene, this value will remain true after the pointer is no longer touching the screen and * will be true in any transition created to animate back to the original position. */ - val isUserInputDriven: Boolean, + val isInitiatedByUserInput: Boolean, + + /** + * Whether user input is currently driving the transition. For example, if a user is + * dragging a pointer, this emits true. Once they lift their finger, this emits false while + * the transition completes/settles. + */ + val isUserInputOngoing: Flow<Boolean>, ) : ObservableTransitionState() } diff --git a/packages/SystemUI/src/com/android/systemui/settings/UserTrackerImpl.kt b/packages/SystemUI/src/com/android/systemui/settings/UserTrackerImpl.kt index 2f873019349cedd83e746b56cf8aabea7c5ab9b8..393a698bcdb7136f922f9a240dc301875c7dea3a 100644 --- a/packages/SystemUI/src/com/android/systemui/settings/UserTrackerImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/settings/UserTrackerImpl.kt @@ -132,6 +132,7 @@ open class UserTrackerImpl internal constructor( setUserIdInternal(startingUser) val filter = IntentFilter().apply { + addAction(Intent.ACTION_LOCALE_CHANGED) addAction(Intent.ACTION_USER_INFO_CHANGED) // These get called when a managed profile goes in or out of quiet mode. addAction(Intent.ACTION_MANAGED_PROFILE_AVAILABLE) @@ -149,6 +150,7 @@ open class UserTrackerImpl internal constructor( override fun onReceive(context: Context, intent: Intent) { when (intent.action) { + Intent.ACTION_LOCALE_CHANGED, Intent.ACTION_USER_INFO_CHANGED, Intent.ACTION_MANAGED_PROFILE_AVAILABLE, Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE, diff --git a/packages/SystemUI/src/com/android/systemui/shade/DebugDrawable.java b/packages/SystemUI/src/com/android/systemui/shade/DebugDrawable.java index 9235fcc8202f440c320096e5cb8720b2e120b8b1..c42fdf8e7b934c11bcac3cbea205ef3bac2d0499 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/DebugDrawable.java +++ b/packages/SystemUI/src/com/android/systemui/shade/DebugDrawable.java @@ -67,8 +67,6 @@ public class DebugDrawable extends Drawable { mDebugPaint.setStrokeWidth(2); mDebugPaint.setStyle(Paint.Style.STROKE); mDebugPaint.setTextSize(24); - String headerDebugInfo = mNotificationPanelViewController.getHeaderDebugInfo(); - if (headerDebugInfo != null) canvas.drawText(headerDebugInfo, 50, 100, mDebugPaint); drawDebugInfo(canvas, mNotificationPanelViewController.getMaxPanelHeight(), Color.RED, "getMaxPanelHeight()"); diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java index 1c62b6a184fa3088397b402dd2e3c9e5b74baeeb..2ef83dd42868073cdce78ad30b19a1732816a32a 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java +++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java @@ -138,7 +138,6 @@ import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor; import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor; import com.android.systemui.keyguard.shared.model.TransitionState; import com.android.systemui.keyguard.shared.model.TransitionStep; -import com.android.systemui.power.shared.model.WakefulnessModel; import com.android.systemui.keyguard.ui.binder.KeyguardLongPressViewBinder; import com.android.systemui.keyguard.ui.viewmodel.DreamingToLockscreenTransitionViewModel; import com.android.systemui.keyguard.ui.viewmodel.GoneToDreamingLockscreenHostedTransitionViewModel; @@ -162,9 +161,10 @@ import com.android.systemui.plugins.FalsingManager.FalsingTapListener; import com.android.systemui.plugins.qs.QS; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener; +import com.android.systemui.power.domain.interactor.PowerInteractor; +import com.android.systemui.power.shared.model.WakefulnessModel; import com.android.systemui.res.R; import com.android.systemui.shade.data.repository.ShadeRepository; -import com.android.systemui.power.domain.interactor.PowerInteractor; import com.android.systemui.shade.transition.ShadeTransitionController; import com.android.systemui.shared.system.QuickStepContract; import com.android.systemui.statusbar.CommandQueue; @@ -200,7 +200,6 @@ import com.android.systemui.statusbar.phone.BounceInterpolator; import com.android.systemui.statusbar.phone.CentralSurfaces; import com.android.systemui.statusbar.phone.DozeParameters; import com.android.systemui.statusbar.phone.HeadsUpAppearanceController; -import com.android.systemui.statusbar.phone.HeadsUpManagerPhone; import com.android.systemui.statusbar.phone.HeadsUpTouchHelper; import com.android.systemui.statusbar.phone.KeyguardBottomAreaView; import com.android.systemui.statusbar.phone.KeyguardBottomAreaViewController; @@ -217,6 +216,7 @@ import com.android.systemui.statusbar.phone.TapAgainViewController; import com.android.systemui.statusbar.phone.UnlockedScreenOffAnimationController; import com.android.systemui.statusbar.phone.fragment.CollapsedStatusBarFragment; import com.android.systemui.statusbar.policy.ConfigurationController; +import com.android.systemui.statusbar.policy.HeadsUpManager; import com.android.systemui.statusbar.policy.KeyguardQsUserSwitchController; import com.android.systemui.statusbar.policy.KeyguardStateController; import com.android.systemui.statusbar.policy.KeyguardUserSwitcherController; @@ -362,7 +362,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump private boolean mIsLaunchAnimationRunning; private float mOverExpansion; private CentralSurfaces mCentralSurfaces; - private HeadsUpManagerPhone mHeadsUpManager; + private HeadsUpManager mHeadsUpManager; private float mExpandedHeight = 0; /** The current squish amount for the predictive back animation */ private float mCurrentBackProgress = 0.0f; @@ -3026,7 +3026,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump return headsUpVisible || isExpanded() || mBouncerShowing; } - private void setHeadsUpManager(HeadsUpManagerPhone headsUpManager) { + private void setHeadsUpManager(HeadsUpManager headsUpManager) { mHeadsUpManager = headsUpManager; mHeadsUpManager.addListener(mOnHeadsUpChangedListener); mHeadsUpTouchHelper = new HeadsUpTouchHelper( @@ -3508,7 +3508,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump GestureRecorder recorder, Runnable hideExpandedRunnable, NotificationShelfController notificationShelfController, - HeadsUpManagerPhone headsUpManager) { + HeadsUpManager headsUpManager) { setHeadsUpManager(headsUpManager); // TODO(b/254859580): this can be injected. mCentralSurfaces = centralSurfaces; @@ -3557,10 +3557,6 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump mView.getViewTreeObserver().removeOnGlobalLayoutListener(listener); } - String getHeaderDebugInfo() { - return "USER " + mHeadsUpManager.getUser(); - } - @Override public void onThemeChanged() { mConfigurationListener.onThemeChanged(); diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java index 5c5cf7dd679c8417e4c8d3b882a5d6dffd4d2982..5414b3f30aa50eae97aebb94b34cc18d54c99e5c 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java +++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java @@ -37,7 +37,9 @@ import com.android.keyguard.dagger.KeyguardBouncerComponent; import com.android.systemui.Dumpable; import com.android.systemui.animation.ActivityLaunchAnimator; import com.android.systemui.back.domain.interactor.BackActionInteractor; +import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor; import com.android.systemui.bouncer.domain.interactor.BouncerMessageInteractor; +import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor; import com.android.systemui.bouncer.ui.binder.KeyguardBouncerViewBinder; import com.android.systemui.bouncer.ui.viewmodel.KeyguardBouncerViewModel; import com.android.systemui.classifier.FalsingCollector; @@ -105,6 +107,8 @@ public class NotificationShadeWindowViewController implements Dumpable { private final boolean mIsTrackpadCommonEnabled; private final FeatureFlags mFeatureFlags; private final KeyEventInteractor mKeyEventInteractor; + private final PrimaryBouncerInteractor mPrimaryBouncerInteractor; + private final AlternateBouncerInteractor mAlternateBouncerInteractor; private GestureDetector mPulsingWakeupGestureHandler; private GestureDetector mDreamingWakeupGestureHandler; private View mBrightnessMirror; @@ -181,7 +185,9 @@ public class NotificationShadeWindowViewController implements Dumpable { SystemClock clock, BouncerMessageInteractor bouncerMessageInteractor, BouncerLogger bouncerLogger, - KeyEventInteractor keyEventInteractor) { + KeyEventInteractor keyEventInteractor, + PrimaryBouncerInteractor primaryBouncerInteractor, + AlternateBouncerInteractor alternateBouncerInteractor) { mLockscreenShadeTransitionController = transitionController; mFalsingCollector = falsingCollector; mStatusBarStateController = statusBarStateController; @@ -209,6 +215,8 @@ public class NotificationShadeWindowViewController implements Dumpable { mIsTrackpadCommonEnabled = featureFlags.isEnabled(TRACKPAD_GESTURE_COMMON); mFeatureFlags = featureFlags; mKeyEventInteractor = keyEventInteractor; + mPrimaryBouncerInteractor = primaryBouncerInteractor; + mAlternateBouncerInteractor = alternateBouncerInteractor; // This view is not part of the newly inflated expanded status bar. mBrightnessMirror = mView.findViewById(R.id.brightness_mirror_container); @@ -431,8 +439,15 @@ public class NotificationShadeWindowViewController implements Dumpable { return true; } + boolean bouncerShowing; + if (mFeatureFlags.isEnabled(Flags.ALTERNATE_BOUNCER_VIEW)) { + bouncerShowing = mPrimaryBouncerInteractor.isBouncerShowing() + || mAlternateBouncerInteractor.isVisibleState(); + } else { + bouncerShowing = mService.isBouncerShowing(); + } if (mNotificationPanelViewController.isFullyExpanded() - && !mService.isBouncerShowing() + && !bouncerShowing && !mStatusBarStateController.isDozing()) { if (mDragDownHelper.isDragDownEnabled()) { // This handles drag down over lockscreen diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeController.java b/packages/SystemUI/src/com/android/systemui/shade/ShadeController.java index 447a15d34c05148074195e41be2f69c6604463be..2c4b0b990e6db2f400e5dcddb0eed6c44363d584 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/ShadeController.java +++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeController.java @@ -178,9 +178,6 @@ public interface ShadeController extends CoreStartable { /** Listens for shade visibility changes. */ interface ShadeVisibilityListener { - /** Called when the visibility of the shade changes. */ - void visibilityChanged(boolean visible); - /** Called when shade expanded and visible state changed. */ void expandedVisibleChanged(boolean expandedVisible); } diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeControllerImpl.java b/packages/SystemUI/src/com/android/systemui/shade/ShadeControllerImpl.java index 367449b9d59d8bdc64b5f1fe9d434f77a909b12a..fdc7eecd9b15766589b38477d359bf7d35888718 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/ShadeControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeControllerImpl.java @@ -24,6 +24,7 @@ import android.view.ViewTreeObserver; import android.view.WindowManager; import android.view.WindowManagerGlobal; +import com.android.systemui.DejankUtils; import com.android.systemui.assist.AssistManager; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Main; @@ -75,6 +76,7 @@ public final class ShadeControllerImpl implements ShadeController { private final ArrayList<Runnable> mPostCollapseRunnables = new ArrayList<>(); private boolean mExpandedVisible; + private boolean mLockscreenOrShadeVisible; private NotificationPresenter mPresenter; private NotificationShadeWindowViewController mNotificationShadeWindowViewController; @@ -399,8 +401,19 @@ public final class ShadeControllerImpl implements ShadeController { } private void notifyVisibilityChanged(boolean visible) { - mShadeVisibilityListener.visibilityChanged(visible); mWindowRootViewVisibilityInteractor.setIsLockscreenOrShadeVisible(visible); + if (mLockscreenOrShadeVisible != visible) { + mLockscreenOrShadeVisible = visible; + if (visible) { + // It would be best if this could be done as a side effect of listening to the + // [WindowRootViewVisibilityInteractor.isLockscreenOrShadeVisible] flow inside + // NotificationShadeWindowViewController. However, there's no guarantee that the + // flow will emit in the same frame as when the visibility changed, and we want the + // DejankUtils to be notified immediately, so we do it immediately here. + DejankUtils.notifyRendererOfExpensiveFrame( + getNotificationShadeWindowView(), "onShadeVisibilityChanged"); + } + } } private void notifyExpandedVisibleChanged(boolean expandedVisible) { diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeSurface.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeSurface.kt index 6ee6cbf69a706010a24cfb8e96eef58f90555269..4e23e7d97a01dd6da72f7161bfbe32b7891fc21f 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/ShadeSurface.kt +++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeSurface.kt @@ -20,7 +20,7 @@ import com.android.systemui.statusbar.GestureRecorder import com.android.systemui.statusbar.NotificationShelfController import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController import com.android.systemui.statusbar.phone.CentralSurfaces -import com.android.systemui.statusbar.phone.HeadsUpManagerPhone +import com.android.systemui.statusbar.policy.HeadsUpManager /** * Allows CentralSurfacesImpl to interact with the shade. Only CentralSurfacesImpl should reference @@ -34,7 +34,7 @@ interface ShadeSurface : ShadeViewController { recorder: GestureRecorder, hideExpandedRunnable: Runnable, notificationShelfController: NotificationShelfController, - headsUpManager: HeadsUpManagerPhone + headsUpManager: HeadsUpManager ) /** Cancels any pending collapses. */ diff --git a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractor.kt b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractor.kt index ac8333ae84adc5d2c23a883c4b6e68a8f06e71e9..6117f9f80e6c4c676545ad3a5134ebbf2c6c8524 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractor.kt @@ -19,7 +19,11 @@ package com.android.systemui.shade.domain.interactor import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.keyguard.data.repository.KeyguardRepository +import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor +import com.android.systemui.keyguard.shared.model.DozeStateModel +import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.keyguard.shared.model.StatusBarState +import com.android.systemui.power.domain.interactor.PowerInteractor import com.android.systemui.scene.domain.interactor.SceneInteractor import com.android.systemui.scene.shared.flag.SceneContainerFlags import com.android.systemui.scene.shared.model.ObservableTransitionState @@ -27,8 +31,9 @@ import com.android.systemui.scene.shared.model.SceneKey import com.android.systemui.shade.data.repository.ShadeRepository import com.android.systemui.statusbar.disableflags.data.repository.DisableFlagsRepository import com.android.systemui.statusbar.notification.stack.domain.interactor.SharedNotificationContainerInteractor +import com.android.systemui.statusbar.phone.DozeParameters import com.android.systemui.statusbar.pipeline.mobile.data.repository.UserSetupRepository -import com.android.systemui.statusbar.policy.DeviceProvisionedController +import com.android.systemui.statusbar.policy.data.repository.DeviceProvisioningRepository import com.android.systemui.user.domain.interactor.UserInteractor import com.android.systemui.util.kotlin.pairwise import javax.inject.Inject @@ -56,13 +61,16 @@ class ShadeInteractor @Inject constructor( @Application scope: CoroutineScope, + deviceProvisioningRepository: DeviceProvisioningRepository, disableFlagsRepository: DisableFlagsRepository, + dozeParams: DozeParameters, sceneContainerFlags: SceneContainerFlags, // TODO(b/300258424) convert to direct reference instead of provider sceneInteractorProvider: Provider<SceneInteractor>, keyguardRepository: KeyguardRepository, + keyguardTransitionInteractor: KeyguardTransitionInteractor, + powerInteractor: PowerInteractor, userSetupRepository: UserSetupRepository, - deviceProvisionedController: DeviceProvisionedController, userInteractor: UserInteractor, sharedNotificationContainerInteractor: SharedNotificationContainerInteractor, repository: ShadeRepository, @@ -187,6 +195,26 @@ constructor( combine(isUserInteractingWithShade, isUserInteractingWithShade) { shade, qs -> shade || qs } .distinctUntilChanged() + /** Are touches allowed on the notification panel? */ + val isShadeTouchable: Flow<Boolean> = + combine( + powerInteractor.isAsleep, + keyguardTransitionInteractor.isInTransitionToStateWhere { it == KeyguardState.AOD }, + keyguardRepository.dozeTransitionModel.map { it.to == DozeStateModel.DOZE_PULSING }, + deviceProvisioningRepository.isFactoryResetProtectionActive, + ) { isAsleep, goingToSleep, isPulsing, isFrpActive -> + when { + // Touches are disabled when Factory Reset Protection is active + isFrpActive -> false + // If the device is going to sleep, only accept touches if we're still + // animating + goingToSleep -> dozeParams.shouldControlScreenOff() + // If the device is asleep, only accept touches if there's a pulse + isAsleep -> isPulsing + else -> true + } + } + /** Emits true if the shade can be expanded from QQS to QS and false otherwise. */ val isExpandToQsEnabled: Flow<Boolean> = combine( @@ -194,8 +222,9 @@ constructor( isShadeEnabled, keyguardRepository.isDozing, userSetupRepository.isUserSetupFlow, - ) { disableFlags, isShadeEnabled, isDozing, isUserSetup -> - deviceProvisionedController.isDeviceProvisioned && + deviceProvisioningRepository.isDeviceProvisioned, + ) { disableFlags, isShadeEnabled, isDozing, isUserSetup, isDeviceProvisioned -> + isDeviceProvisioned && // Disallow QS during setup if it's a simple user switcher. (The user intends to // use the lock screen user switcher, QS is not needed.) (isUserSetup || !userInteractor.isSimpleUserSwitcher) && @@ -232,7 +261,7 @@ constructor( when (state) { is ObservableTransitionState.Idle -> false is ObservableTransitionState.Transition -> - state.isUserInputDriven && + state.isInitiatedByUserInput && (state.toScene == sceneKey || state.fromScene == sceneKey) } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt b/packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt index 3640ae06753738ff6255a99bafad2c3db6ac1183..4ea70264b15240c068bfad22595463df80580a41 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt @@ -31,22 +31,22 @@ import androidx.annotation.VisibleForTesting import com.android.app.animation.Interpolators import com.android.systemui.Dumpable import com.android.systemui.Gefingerpoken -import com.android.systemui.res.R import com.android.systemui.classifier.Classifier.NOTIFICATION_DRAG_DOWN import com.android.systemui.classifier.FalsingCollector import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dump.DumpManager import com.android.systemui.plugins.FalsingManager import com.android.systemui.plugins.statusbar.StatusBarStateController +import com.android.systemui.res.R import com.android.systemui.shade.ShadeExpansionStateManager import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow import com.android.systemui.statusbar.notification.row.ExpandableView import com.android.systemui.statusbar.notification.stack.NotificationRoundnessManager import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController -import com.android.systemui.statusbar.phone.HeadsUpManagerPhone import com.android.systemui.statusbar.phone.KeyguardBypassController import com.android.systemui.statusbar.policy.ConfigurationController +import com.android.systemui.statusbar.policy.HeadsUpManager import java.io.PrintWriter import javax.inject.Inject import kotlin.math.max @@ -63,7 +63,7 @@ constructor( context: Context, private val wakeUpCoordinator: NotificationWakeUpCoordinator, private val bypassController: KeyguardBypassController, - private val headsUpManager: HeadsUpManagerPhone, + private val headsUpManager: HeadsUpManager, private val roundnessManager: NotificationRoundnessManager, configurationController: ConfigurationController, private val statusBarStateController: StatusBarStateController, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorController.kt index c62546f67f8dde14277c3bcb316693c108fc44f9..756151bd57e0c03ce4b834ce2fe8073e92aa82ac 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorController.kt @@ -24,7 +24,7 @@ import com.android.systemui.animation.LaunchAnimator import com.android.systemui.statusbar.notification.data.repository.NotificationExpansionRepository import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow import com.android.systemui.statusbar.notification.stack.NotificationListContainer -import com.android.systemui.statusbar.phone.HeadsUpManagerPhone +import com.android.systemui.statusbar.policy.HeadsUpManager import com.android.systemui.statusbar.policy.HeadsUpUtil import kotlin.math.ceil import kotlin.math.max @@ -35,7 +35,7 @@ private const val TAG = "NotificationLaunchAnimatorController" class NotificationLaunchAnimatorControllerProvider( private val notificationExpansionRepository: NotificationExpansionRepository, private val notificationListContainer: NotificationListContainer, - private val headsUpManager: HeadsUpManagerPhone, + private val headsUpManager: HeadsUpManager, private val jankMonitor: InteractionJankMonitor ) { @JvmOverloads @@ -62,7 +62,7 @@ class NotificationLaunchAnimatorControllerProvider( class NotificationLaunchAnimatorController( private val notificationExpansionRepository: NotificationExpansionRepository, private val notificationListContainer: NotificationListContainer, - private val headsUpManager: HeadsUpManagerPhone, + private val headsUpManager: HeadsUpManager, private val notification: ExpandableNotificationRow, private val jankMonitor: InteractionJankMonitor, private val onFinishAnimationCallback: Runnable? @@ -152,16 +152,17 @@ class NotificationLaunchAnimatorController( } } - private val headsUpNotificationRow: ExpandableNotificationRow? get() { - val summaryEntry = notificationEntry.parent?.summary + private val headsUpNotificationRow: ExpandableNotificationRow? + get() { + val summaryEntry = notificationEntry.parent?.summary - return when { - headsUpManager.isAlerting(notificationKey) -> notification - summaryEntry == null -> null - headsUpManager.isAlerting(summaryEntry.key) -> summaryEntry.row - else -> null + return when { + headsUpManager.isAlerting(notificationKey) -> notification + summaryEntry == null -> null + headsUpManager.isAlerting(summaryEntry.key) -> summaryEntry.row + else -> null + } } - } private fun removeHun(animate: Boolean) { val row = headsUpNotificationRow ?: return diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.kt index 07eb8a00a17874e666dcf4118a409ed04fa39345..2d839704e0b73ad9c0a49a5a44b066457662397a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.kt @@ -37,8 +37,8 @@ import com.android.systemui.statusbar.notification.collection.coordinator.dagger import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener import com.android.systemui.statusbar.notification.collection.provider.SectionHeaderVisibilityProvider -import com.android.systemui.statusbar.notification.collection.provider.SeenNotificationsProviderImpl import com.android.systemui.statusbar.notification.interruption.KeyguardNotificationVisibilityProvider +import com.android.systemui.statusbar.notification.stack.domain.interactor.NotificationListInteractor import com.android.systemui.statusbar.policy.HeadsUpManager import com.android.systemui.statusbar.policy.headsUpEvents import com.android.systemui.util.asIndenting @@ -85,7 +85,7 @@ constructor( @Application private val scope: CoroutineScope, private val sectionHeaderVisibilityProvider: SectionHeaderVisibilityProvider, private val secureSettings: SecureSettings, - private val seenNotifsProvider: SeenNotificationsProviderImpl, + private val notificationListInteractor: NotificationListInteractor, private val statusBarStateController: StatusBarStateController, ) : Coordinator, Dumpable { @@ -351,7 +351,7 @@ constructor( override fun onCleanup() { logger.logProviderHasFilteredOutSeenNotifs(hasFilteredAnyNotifs) - seenNotifsProvider.hasFilteredOutSeenNotifications = hasFilteredAnyNotifs + notificationListInteractor.setHasFilteredOutSeenNotifications(hasFilteredAnyNotifs) hasFilteredAnyNotifs = false } } @@ -388,8 +388,8 @@ constructor( override fun dump(pw: PrintWriter, args: Array<out String>) = with(pw.asIndenting()) { println( - "seenNotifsProvider.hasFilteredOutSeenNotifications=" + - seenNotifsProvider.hasFilteredOutSeenNotifications + "notificationListInteractor.hasFilteredOutSeenNotifications.value=" + + notificationListInteractor.hasFilteredOutSeenNotifications.value ) println("unseen notifications:") indentIfPossible { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ViewConfigCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ViewConfigCoordinator.kt index 657c394d4e309e963d4af50094aa41dee71f03fe..c0f6748469919a2ea46ba2f49afb4c737b92f4f1 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ViewConfigCoordinator.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ViewConfigCoordinator.kt @@ -28,6 +28,7 @@ import com.android.systemui.statusbar.notification.collection.coordinator.dagger import com.android.systemui.statusbar.notification.row.NotificationGutsManager import com.android.systemui.statusbar.policy.ConfigurationController import com.android.systemui.util.Compile +import com.android.systemui.util.traceSection import javax.inject.Inject /** @@ -122,8 +123,10 @@ class ViewConfigCoordinator @Inject internal constructor( private fun updateNotificationsOnUiModeChanged() { log { "ViewConfigCoordinator.updateNotificationsOnUiModeChanged()" } - mPipeline?.allNotifs?.forEach { entry -> - entry.row?.onUiModeChanged() + traceSection("updateNotifOnUiModeChanged") { + mPipeline?.allNotifs?.forEach { entry -> + entry.row?.onUiModeChanged() + } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/SeenNotificationsProvider.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/SeenNotificationsProvider.kt deleted file mode 100644 index cff47e22029919ab302b08b29985f8b0d0e3220a..0000000000000000000000000000000000000000 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/SeenNotificationsProvider.kt +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) 2022 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.systemui.statusbar.notification.collection.provider - -import com.android.systemui.dagger.SysUISingleton -import dagger.Binds -import dagger.Module -import javax.inject.Inject - -/** Keeps track of whether "seen" notification content has been filtered out of the shade. */ -interface SeenNotificationsProvider { - /** Are any already-seen notifications currently filtered out of the shade? */ - val hasFilteredOutSeenNotifications: Boolean -} - -@Module -interface SeenNotificationsProviderModule { - @Binds - fun bindSeenNotificationsProvider( - impl: SeenNotificationsProviderImpl - ): SeenNotificationsProvider -} - -@SysUISingleton -class SeenNotificationsProviderImpl @Inject constructor() : SeenNotificationsProvider { - override var hasFilteredOutSeenNotifications: Boolean = false -} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewDiffer.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewDiffer.kt index 59fc387c4608f0cdcb51f6d219521f1e9f9aa398..1a88815acfafbabf27280e583b98d3f9aed37094 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewDiffer.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewDiffer.kt @@ -231,18 +231,24 @@ private class ShadeNode(val controller: NodeController) { fun getChildCount(): Int = controller.getChildCount() fun addChildAt(child: ShadeNode, index: Int) { - controller.addChildAt(child.controller, index) - child.controller.onViewAdded() + traceSection("ShadeNode#addChildAt") { + controller.addChildAt(child.controller, index) + child.controller.onViewAdded() + } } fun moveChildTo(child: ShadeNode, index: Int) { - controller.moveChildTo(child.controller, index) - child.controller.onViewMoved() + traceSection("ShadeNode#moveChildTo") { + controller.moveChildTo(child.controller, index) + child.controller.onViewMoved() + } } fun removeChild(child: ShadeNode, isTransfer: Boolean) { - controller.removeChild(child.controller, isTransfer) - child.controller.onViewRemoved() + traceSection("ShadeNode#removeChild") { + controller.removeChild(child.controller, isTransfer) + child.controller.onViewRemoved() + } } fun offerToKeepInParentForAnimation(): Boolean { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java index 8ee0de691557e211bc5b59d9f15fee930d58d7bc..733d774f8b80001ee356beedf4e16dfb2c9148e4 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java @@ -20,10 +20,10 @@ import android.content.Context; import com.android.internal.jank.InteractionJankMonitor; import com.android.systemui.CoreStartable; -import com.android.systemui.res.R; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.UiBackground; import com.android.systemui.plugins.statusbar.StatusBarStateController; +import com.android.systemui.res.R; import com.android.systemui.scene.domain.interactor.WindowRootViewVisibilityInteractor; import com.android.systemui.shade.ShadeEventsModule; import com.android.systemui.statusbar.NotificationListener; @@ -45,7 +45,6 @@ import com.android.systemui.statusbar.notification.collection.notifcollection.Co import com.android.systemui.statusbar.notification.collection.provider.NotificationDismissibilityProvider; import com.android.systemui.statusbar.notification.collection.provider.NotificationDismissibilityProviderImpl; import com.android.systemui.statusbar.notification.collection.provider.NotificationVisibilityProviderImpl; -import com.android.systemui.statusbar.notification.collection.provider.SeenNotificationsProviderModule; import com.android.systemui.statusbar.notification.collection.provider.VisibilityLocationProviderDelegator; import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager; import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManagerImpl; @@ -74,9 +73,9 @@ import com.android.systemui.statusbar.notification.stack.NotificationSectionsMan import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController; import com.android.systemui.statusbar.notification.stack.StackScrollAlgorithm; import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationListViewModelModule; -import com.android.systemui.statusbar.phone.HeadsUpManagerPhone; import com.android.systemui.statusbar.phone.KeyguardBypassController; import com.android.systemui.statusbar.phone.StatusBarNotificationActivityStarter; +import com.android.systemui.statusbar.policy.HeadsUpManager; import com.android.systemui.util.kotlin.JavaAdapter; import dagger.Binds; @@ -95,7 +94,6 @@ import javax.inject.Provider; @Module(includes = { CoordinatorsModule.class, KeyguardNotificationVisibilityProviderModule.class, - SeenNotificationsProviderModule.class, ShadeEventsModule.class, NotifPipelineChoreographerModule.class, NotificationSectionHeadersModule.class, @@ -206,7 +204,7 @@ public interface NotificationsModule { static NotificationLaunchAnimatorControllerProvider provideNotifLaunchAnimControllerProvider( NotificationExpansionRepository notificationExpansionRepository, NotificationListContainer notificationListContainer, - HeadsUpManagerPhone headsUpManager, + HeadsUpManager headsUpManager, InteractionJankMonitor jankMonitor) { return new NotificationLaunchAnimatorControllerProvider( notificationExpansionRepository, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconAreaControllerViewBinderWrapperImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconAreaControllerViewBinderWrapperImpl.kt index 5cc5e751ca8ed007ef6f923991ac8805cd65c9df..a77e67b6908d6e36f5747424c181c3f3b09da92c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconAreaControllerViewBinderWrapperImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconAreaControllerViewBinderWrapperImpl.kt @@ -118,7 +118,6 @@ constructor( private var aodIcons: NotificationIconContainer? = null private var aodBindJob: DisposableHandle? = null private var aodIconAppearTranslation = 0 - private var animationsEnabled = false private var aodIconTint = 0 private var aodIconsVisible = false private var showLowPriority = true @@ -157,9 +156,12 @@ constructor( } this.aodIcons = aodIcons this.aodIcons!!.setOnLockScreen(true) - aodBindJob = NotificationIconContainerViewBinder.bind(aodIcons, aodIconsViewModel) + aodBindJob = + NotificationIconContainerViewBinder.bind( + aodIcons, + aodIconsViewModel, + ) updateAodIconsVisibility(animate = false, forceUpdate = changed) - updateAnimations() if (changed) { updateAodNotificationIcons() } @@ -171,7 +173,10 @@ constructor( override fun setShelfIcons(icons: NotificationIconContainer) { if (shelfRefactor.expectEnabled()) { - NotificationIconContainerViewBinder.bind(icons, shelfIconsViewModel) + NotificationIconContainerViewBinder.bind( + icons, + shelfIconsViewModel, + ) shelfIcons = icons } } @@ -252,14 +257,10 @@ constructor( aodIcons!!.setDozing(isDozing, animate, 0) } - override fun setAnimationsEnabled(enabled: Boolean) { - animationsEnabled = enabled - updateAnimations() - } + override fun setAnimationsEnabled(enabled: Boolean) = unsupported override fun onStateChanged(newState: Int) { updateAodIconsVisibility(animate = false, forceUpdate = false) - updateAnimations() } override fun onThemeChanged() { @@ -348,7 +349,10 @@ constructor( val layoutInflater = LayoutInflater.from(context) notificationIconArea = inflateIconArea(layoutInflater) notificationIcons = notificationIconArea?.findViewById(R.id.notificationIcons) - NotificationIconContainerViewBinder.bind(notificationIcons!!, statusBarIconsViewModel) + NotificationIconContainerViewBinder.bind( + notificationIcons!!, + statusBarIconsViewModel, + ) } private fun updateIconLayoutParams(context: Context) { @@ -598,14 +602,6 @@ constructor( v.setDecorColor(tint) } - private fun updateAnimations() { - val inShade = statusBarStateController.state == StatusBarState.SHADE - if (aodIcons != null) { - aodIcons!!.setAnimationsEnabled(animationsEnabled && !inShade) - } - notificationIcons!!.setAnimationsEnabled(animationsEnabled && inShade) - } - private fun animateInAodIconTranslation() { if (!statusViewMigrated) { aodIcons!! @@ -702,7 +698,12 @@ constructor( companion object { private const val AOD_ICONS_APPEAR_DURATION: Long = 200 - @ColorInt private val DEFAULT_AOD_ICON_COLOR = -0x1 + + val unsupported: Nothing + get() = + error( + "Code path not supported when NOTIFICATION_ICON_CONTAINER_REFACTOR is disabled" + ) } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconContainerViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconContainerViewBinder.kt index 8293bb329a018239523a5922ae2152cac39d61c7..f8ff3e393033cf14140c3c8b8205db01b7801e7d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconContainerViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconContainerViewBinder.kt @@ -21,6 +21,7 @@ import com.android.systemui.lifecycle.repeatWhenAttached import com.android.systemui.statusbar.notification.icon.ui.viewmodel.NotificationIconContainerViewModel import com.android.systemui.statusbar.phone.NotificationIconContainer import kotlinx.coroutines.DisposableHandle +import kotlinx.coroutines.launch /** Binds a [NotificationIconContainer] to its [view model][NotificationIconContainerViewModel]. */ object NotificationIconContainerViewBinder { @@ -28,6 +29,10 @@ object NotificationIconContainerViewBinder { view: NotificationIconContainer, viewModel: NotificationIconContainerViewModel, ): DisposableHandle { - return view.repeatWhenAttached { repeatOnLifecycle(Lifecycle.State.CREATED) {} } + return view.repeatWhenAttached { + repeatOnLifecycle(Lifecycle.State.CREATED) { + launch { viewModel.animationsEnabled.collect(view::setAnimationsEnabled) } + } + } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerAlwaysOnDisplayViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerAlwaysOnDisplayViewModel.kt index f68b0ef7963842ef18c4814707fd7ef621706af1..90507fc82a79084c4553b4e6a86b70c23de5ba24 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerAlwaysOnDisplayViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerAlwaysOnDisplayViewModel.kt @@ -15,8 +15,24 @@ */ package com.android.systemui.statusbar.notification.icon.ui.viewmodel +import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor +import com.android.systemui.shade.domain.interactor.ShadeInteractor import javax.inject.Inject +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.combine /** View-model for the row of notification icons displayed on the always-on display. */ -class NotificationIconContainerAlwaysOnDisplayViewModel @Inject constructor() : - NotificationIconContainerViewModel +class NotificationIconContainerAlwaysOnDisplayViewModel +@Inject +constructor( + keyguardInteractor: KeyguardInteractor, + shadeInteractor: ShadeInteractor, +) : NotificationIconContainerViewModel { + override val animationsEnabled: Flow<Boolean> = + combine( + shadeInteractor.isShadeTouchable, + keyguardInteractor.isKeyguardVisible, + ) { panelTouchesEnabled, isKeyguardVisible -> + panelTouchesEnabled && isKeyguardVisible + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerShelfViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerShelfViewModel.kt index 933c76f19aee72f11cc6450ad268bd14d256c310..49f262de8f4a2dd932f16484746acff3b77a82f5 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerShelfViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerShelfViewModel.kt @@ -16,7 +16,11 @@ package com.android.systemui.statusbar.notification.icon.ui.viewmodel import javax.inject.Inject +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.flowOf /** View-model for the overflow row of notification icons displayed in the notification shade. */ class NotificationIconContainerShelfViewModel @Inject constructor() : - NotificationIconContainerViewModel + NotificationIconContainerViewModel { + override val animationsEnabled: Flow<Boolean> = flowOf(true) +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModel.kt index 2217646e60224d8cba141e0a92ac7953221e69ef..ee57b780b8c37443c8355180c2e12d8983feb455 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModel.kt @@ -15,8 +15,24 @@ */ package com.android.systemui.statusbar.notification.icon.ui.viewmodel +import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor +import com.android.systemui.shade.domain.interactor.ShadeInteractor import javax.inject.Inject +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.combine /** View-model for the row of notification icons displayed in the status bar, */ -class NotificationIconContainerStatusBarViewModel @Inject constructor() : - NotificationIconContainerViewModel +class NotificationIconContainerStatusBarViewModel +@Inject +constructor( + keyguardInteractor: KeyguardInteractor, + shadeInteractor: ShadeInteractor, +) : NotificationIconContainerViewModel { + override val animationsEnabled: Flow<Boolean> = + combine( + shadeInteractor.isShadeTouchable, + keyguardInteractor.isKeyguardShowing, + ) { panelTouchesEnabled, isKeyguardShowing -> + panelTouchesEnabled && !isKeyguardShowing + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerViewModel.kt index 892b2be9ed6e65c1b1c074ad49e31bae56f90f55..6f8ce4b1db4b4b01ae219bc9adeb260baf70314c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerViewModel.kt @@ -15,8 +15,13 @@ */ package com.android.systemui.statusbar.notification.icon.ui.viewmodel +import kotlinx.coroutines.flow.Flow + /** * View-model for the row of notification icons displayed in the NotificationShelf, StatusBar, and * AOD. */ -interface NotificationIconContainerViewModel +interface NotificationIconContainerViewModel { + /** Are changes to the icon container animated? */ + val animationsEnabled: Flow<Boolean> +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java index c61258b5e0ec4131d8b6229ec1b8e422f3c9ed0e..847d94861401caa7ccbcc19af4e592930b6a5969 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java @@ -355,12 +355,8 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView AnimatorListenerAdapter animationListener) { enableAppearDrawing(true); mIsHeadsUpAnimation = isHeadsUpAnimation; - if (mDrawingAppearAnimation) { - startAppearAnimation(false /* isAppearing */, translationDirection, - delay, duration, onFinishedRunnable, animationListener); - } else if (onFinishedRunnable != null) { - onFinishedRunnable.run(); - } + startAppearAnimation(false /* isAppearing */, translationDirection, + delay, duration, onFinishedRunnable, animationListener); return 0; } @@ -369,10 +365,8 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView Runnable onFinishRunnable) { enableAppearDrawing(true); mIsHeadsUpAnimation = isHeadsUpAppear; - if (mDrawingAppearAnimation) { - startAppearAnimation(true /* isAppearing */, isHeadsUpAppear ? 0.0f : -1.0f, delay, - duration, null, null); - } + startAppearAnimation(true /* isAppearing */, isHeadsUpAppear ? 0.0f : -1.0f, delay, + duration, null, null); } private void startAppearAnimation(boolean isAppearing, float translationDirection, long delay, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java index 6d6566058aed75cfd96557d4258ba8543e9ba17b..dc318a392ed5e78b736e066953b16923c043b84d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java @@ -46,7 +46,6 @@ import com.android.internal.logging.UiEventLogger; import com.android.internal.logging.nano.MetricsProto; import com.android.settingslib.notification.ConversationIconFactory; import com.android.systemui.CoreStartable; -import com.android.systemui.res.R; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dagger.qualifiers.Main; @@ -54,6 +53,7 @@ import com.android.systemui.people.widget.PeopleSpaceWidgetManager; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin; import com.android.systemui.plugins.statusbar.StatusBarStateController; +import com.android.systemui.res.R; import com.android.systemui.scene.domain.interactor.WindowRootViewVisibilityInteractor; import com.android.systemui.settings.UserContextProvider; import com.android.systemui.shade.ShadeController; @@ -69,8 +69,8 @@ import com.android.systemui.statusbar.notification.collection.render.NotifGutsVi import com.android.systemui.statusbar.notification.collection.render.NotifGutsViewManager; import com.android.systemui.statusbar.notification.stack.NotificationListContainer; import com.android.systemui.statusbar.phone.CentralSurfaces; -import com.android.systemui.statusbar.phone.HeadsUpManagerPhone; import com.android.systemui.statusbar.policy.DeviceProvisionedController; +import com.android.systemui.statusbar.policy.HeadsUpManager; import com.android.systemui.util.kotlin.JavaAdapter; import com.android.systemui.wmshell.BubblesManager; @@ -127,7 +127,7 @@ public class NotificationGutsManager implements NotifGutsViewManager, CoreStarta private final ShadeController mShadeController; private final WindowRootViewVisibilityInteractor mWindowRootViewVisibilityInteractor; private NotifGutsViewListener mGutsListener; - private final HeadsUpManagerPhone mHeadsUpManagerPhone; + private final HeadsUpManager mHeadsUpManager; private final ActivityStarter mActivityStarter; @Inject @@ -154,7 +154,7 @@ public class NotificationGutsManager implements NotifGutsViewManager, CoreStarta StatusBarStateController statusBarStateController, DeviceProvisionedController deviceProvisionedController, MetricsLogger metricsLogger, - HeadsUpManagerPhone headsUpManagerPhone, + HeadsUpManager headsUpManager, ActivityStarter activityStarter) { mContext = context; mMainHandler = mainHandler; @@ -179,7 +179,7 @@ public class NotificationGutsManager implements NotifGutsViewManager, CoreStarta mStatusBarStateController = statusBarStateController; mDeviceProvisionedController = deviceProvisionedController; mMetricsLogger = metricsLogger; - mHeadsUpManagerPhone = headsUpManagerPhone; + mHeadsUpManager = headsUpManager; mActivityStarter = activityStarter; } @@ -296,7 +296,7 @@ public class NotificationGutsManager implements NotifGutsViewManager, CoreStarta if (mGutsListener != null) { mGutsListener.onGutsClose(entry); } - mHeadsUpManagerPhone.setGutsShown(row.getEntry(), false); + mHeadsUpManager.setGutsShown(row.getEntry(), false); }); View gutsView = item.getGutsView(); @@ -676,7 +676,7 @@ public class NotificationGutsManager implements NotifGutsViewManager, CoreStarta row.closeRemoteInput(); mListContainer.onHeightChanged(row, true /* needsAnimation */); mGutsMenuItem = menuItem; - mHeadsUpManagerPhone.setGutsShown(row.getEntry(), true); + mHeadsUpManager.setGutsShown(row.getEntry(), true); } }; guts.post(mOpenRunnable); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java index 66b2555a4446939afb154953ad1aec26fcb6b67a..9695cb132ba9c7b9eb37de506850e6bdf653e93f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java @@ -99,7 +99,6 @@ import com.android.systemui.statusbar.notification.collection.PipelineDumper; import com.android.systemui.statusbar.notification.collection.notifcollection.DismissedByUserStats; import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener; import com.android.systemui.statusbar.notification.collection.provider.NotificationDismissibilityProvider; -import com.android.systemui.statusbar.notification.collection.provider.SeenNotificationsProvider; import com.android.systemui.statusbar.notification.collection.provider.VisibilityLocationProviderDelegator; import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager; import com.android.systemui.statusbar.notification.collection.render.NotifStackController; @@ -115,10 +114,10 @@ import com.android.systemui.statusbar.notification.row.ExpandableView; import com.android.systemui.statusbar.notification.row.NotificationGuts; import com.android.systemui.statusbar.notification.row.NotificationGutsManager; import com.android.systemui.statusbar.notification.row.NotificationSnooze; +import com.android.systemui.statusbar.notification.stack.domain.interactor.NotificationListInteractor; import com.android.systemui.statusbar.notification.stack.ui.viewbinder.NotificationListViewBinder; import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationListViewModel; import com.android.systemui.statusbar.phone.HeadsUpAppearanceController; -import com.android.systemui.statusbar.phone.HeadsUpManagerPhone; import com.android.systemui.statusbar.phone.HeadsUpTouchHelper; import com.android.systemui.statusbar.phone.KeyguardBypassController; import com.android.systemui.statusbar.phone.NotificationIconAreaController; @@ -127,6 +126,7 @@ import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener; import com.android.systemui.statusbar.policy.DeviceProvisionedController; import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener; +import com.android.systemui.statusbar.policy.HeadsUpManager; import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener; import com.android.systemui.statusbar.policy.SplitShadeStateController; import com.android.systemui.statusbar.policy.ZenModeController; @@ -156,7 +156,7 @@ public class NotificationStackScrollLayoutController { private final NotificationGutsManager mNotificationGutsManager; private final NotificationsController mNotificationsController; private final NotificationVisibilityProvider mVisibilityProvider; - private final HeadsUpManagerPhone mHeadsUpManager; + private final HeadsUpManager mHeadsUpManager; private final NotificationRoundnessManager mNotificationRoundnessManager; private final TunerService mTunerService; private final DeviceProvisionedController mDeviceProvisionedController; @@ -194,7 +194,7 @@ public class NotificationStackScrollLayoutController { private final GroupExpansionManager mGroupExpansionManager; private final NotifPipelineFlags mNotifPipelineFlags; - private final SeenNotificationsProvider mSeenNotificationsProvider; + private final NotificationListInteractor mNotificationListInteractor; private final KeyguardTransitionRepository mKeyguardTransitionRepo; private NotificationStackScrollLayout mView; @@ -631,7 +631,7 @@ public class NotificationStackScrollLayoutController { NotificationGutsManager notificationGutsManager, NotificationsController notificationsController, NotificationVisibilityProvider visibilityProvider, - HeadsUpManagerPhone headsUpManager, + HeadsUpManager headsUpManager, NotificationRoundnessManager notificationRoundnessManager, TunerService tunerService, DeviceProvisionedController deviceProvisionedController, @@ -662,7 +662,7 @@ public class NotificationStackScrollLayoutController { UiEventLogger uiEventLogger, NotificationRemoteInputManager remoteInputManager, VisibilityLocationProviderDelegator visibilityLocationProviderDelegator, - SeenNotificationsProvider seenNotificationsProvider, + NotificationListInteractor notificationListInteractor, ShadeController shadeController, InteractionJankMonitor jankMonitor, StackStateLogger stackLogger, @@ -715,7 +715,7 @@ public class NotificationStackScrollLayoutController { mUiEventLogger = uiEventLogger; mRemoteInputManager = remoteInputManager; mVisibilityLocationProviderDelegator = visibilityLocationProviderDelegator; - mSeenNotificationsProvider = seenNotificationsProvider; + mNotificationListInteractor = notificationListInteractor; mShadeController = shadeController; mNotifIconAreaController = notifIconAreaController; mFeatureFlags = featureFlags; @@ -2006,7 +2006,7 @@ public class NotificationStackScrollLayoutController { public void setNotifStats(@NonNull NotifStats notifStats) { mNotifStats = notifStats; mView.setHasFilteredOutSeenNotifications( - mSeenNotificationsProvider.getHasFilteredOutSeenNotifications()); + mNotificationListInteractor.getHasFilteredOutSeenNotifications().getValue()); updateFooter(); updateShowEmptyShadeView(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/data/repository/NotificationListRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/data/repository/NotificationListRepository.kt new file mode 100644 index 0000000000000000000000000000000000000000..f6ed8c884816aed3881d8de7464bc904986dc63b --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/data/repository/NotificationListRepository.kt @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.statusbar.notification.stack.data.repository + +import com.android.systemui.dagger.SysUISingleton +import javax.inject.Inject +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow + +/** Repository for information about the current notification list. */ +@SysUISingleton +class NotificationListRepository @Inject constructor() { + private val _hasFilteredOutSeenNotifications = MutableStateFlow(false) + val hasFilteredOutSeenNotifications: StateFlow<Boolean> = + _hasFilteredOutSeenNotifications.asStateFlow() + + fun setHasFilteredOutSeenNotifications(value: Boolean) { + _hasFilteredOutSeenNotifications.value = value + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/domain/interactor/NotificationListInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/domain/interactor/NotificationListInteractor.kt new file mode 100644 index 0000000000000000000000000000000000000000..3fd68a8bdd7c3283bf9214a2d77c69d69a9eeb43 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/domain/interactor/NotificationListInteractor.kt @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.statusbar.notification.stack.domain.interactor + +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.statusbar.notification.stack.data.repository.NotificationListRepository +import javax.inject.Inject +import kotlinx.coroutines.flow.StateFlow + +/** Interactor for business logic associated with the notification stack. */ +@SysUISingleton +class NotificationListInteractor +@Inject +constructor( + private val notificationListRepository: NotificationListRepository, +) { + /** Are any already-seen notifications currently filtered out of the shade? */ + val hasFilteredOutSeenNotifications: StateFlow<Boolean> + get() = notificationListRepository.hasFilteredOutSeenNotifications + + fun setHasFilteredOutSeenNotifications(value: Boolean) { + notificationListRepository.setHasFilteredOutSeenNotifications(value) + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java index 3e2f10dd1a0cc29d6d67cfce0f912d9e33cf4596..6e6318e780dcb619de37eb688d802afdd765b101 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java @@ -220,6 +220,7 @@ import com.android.systemui.statusbar.policy.ConfigurationController.Configurati import com.android.systemui.statusbar.policy.DeviceProvisionedController; import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener; import com.android.systemui.statusbar.policy.ExtensionController; +import com.android.systemui.statusbar.policy.HeadsUpManager; import com.android.systemui.statusbar.policy.KeyguardStateController; import com.android.systemui.statusbar.policy.UserInfoControllerImpl; import com.android.systemui.statusbar.policy.UserSwitcherController; @@ -236,6 +237,8 @@ import com.android.wm.shell.bubbles.Bubbles; import com.android.wm.shell.startingsurface.SplashscreenContentDrawer; import com.android.wm.shell.startingsurface.StartingSurface; +import dagger.Lazy; + import java.io.PrintWriter; import java.io.StringWriter; import java.util.List; @@ -247,8 +250,6 @@ import javax.inject.Inject; import javax.inject.Named; import javax.inject.Provider; -import dagger.Lazy; - /** * A class handling initialization and coordination between some of the key central surfaces in * System UI: The notification shade, the keyguard (lockscreen), and the status bar. @@ -417,7 +418,7 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { private final NotificationWakeUpCoordinator mWakeUpCoordinator; private final KeyguardBypassController mKeyguardBypassController; private final KeyguardStateController mKeyguardStateController; - private final HeadsUpManagerPhone mHeadsUpManager; + private final HeadsUpManager mHeadsUpManager; private final StatusBarTouchableRegionManager mStatusBarTouchableRegionManager; private final FalsingCollector mFalsingCollector; private final FalsingManager mFalsingManager; @@ -611,7 +612,7 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { NotificationWakeUpCoordinator notificationWakeUpCoordinator, KeyguardBypassController keyguardBypassController, KeyguardStateController keyguardStateController, - HeadsUpManagerPhone headsUpManagerPhone, + HeadsUpManager headsUpManager, DynamicPrivacyController dynamicPrivacyController, FalsingManager falsingManager, FalsingCollector falsingCollector, @@ -718,7 +719,7 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { mWakeUpCoordinator = notificationWakeUpCoordinator; mKeyguardBypassController = keyguardBypassController; mKeyguardStateController = keyguardStateController; - mHeadsUpManager = headsUpManagerPhone; + mHeadsUpManager = headsUpManager; mBackActionInteractor = backActionInteractor; mKeyguardIndicationController = keyguardIndicationController; mStatusBarTouchableRegionManager = statusBarTouchableRegionManager; @@ -1087,11 +1088,6 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { */ @VisibleForTesting void initShadeVisibilityListener() { mShadeController.setVisibilityListener(new ShadeController.ShadeVisibilityListener() { - @Override - public void visibilityChanged(boolean visible) { - onShadeVisibilityChanged(visible); - } - @Override public void expandedVisibleChanged(boolean expandedVisible) { if (expandedVisible) { @@ -1195,7 +1191,7 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { }); mStatusBarInitializer.initializeStatusBar(); - mStatusBarTouchableRegionManager.setup(this, getNotificationShadeWindowView()); + mStatusBarTouchableRegionManager.setup(getNotificationShadeWindowView()); createNavigationBar(result); @@ -2688,7 +2684,9 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { !mDozeServiceHost.isPulsing(), mDeviceProvisionedController.isFrpActive()); mShadeSurface.setTouchAndAnimationDisabled(disabled); - mNotificationIconAreaController.setAnimationsEnabled(!disabled); + if (!mFeatureFlags.isEnabled(Flags.NOTIFICATION_ICON_CONTAINER_REFACTOR)) { + mNotificationIconAreaController.setAnimationsEnabled(!disabled); + } } final ScreenLifecycle.Observer mScreenObserver = new ScreenLifecycle.Observer() { @@ -2844,13 +2842,16 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { mScrimController.setExpansionAffectsAlpha(!unlocking); if (mAlternateBouncerInteractor.isVisibleState()) { - if ((!mKeyguardStateController.isOccluded() || mShadeSurface.isPanelExpanded()) - && (mState == StatusBarState.SHADE || mState == StatusBarState.SHADE_LOCKED - || mTransitionToFullShadeProgress > 0f)) { - mScrimController.transitionTo(ScrimState.AUTH_SCRIMMED_SHADE); - } else { - mScrimController.transitionTo(ScrimState.AUTH_SCRIMMED); + if (!mFeatureFlags.isEnabled(Flags.ALTERNATE_BOUNCER_VIEW)) { + if ((!mKeyguardStateController.isOccluded() || mShadeSurface.isPanelExpanded()) + && (mState == StatusBarState.SHADE || mState == StatusBarState.SHADE_LOCKED + || mTransitionToFullShadeProgress > 0f)) { + mScrimController.transitionTo(ScrimState.AUTH_SCRIMMED_SHADE); + } else { + mScrimController.transitionTo(ScrimState.AUTH_SCRIMMED); + } } + // This will cancel the keyguardFadingAway animation if it is running. We need to do // this as otherwise it can remain pending and leave keyguard in a weird state. mUnlockScrimCallback.onCancelled(); @@ -2913,8 +2914,6 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { protected boolean mDeviceInteractive; - protected boolean mVisible; - protected DevicePolicyManager mDevicePolicyManager; private final PowerManager mPowerManager; protected StatusBarKeyguardViewManager mStatusBarKeyguardViewManager; @@ -3032,16 +3031,6 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { afterKeyguardGone); } - private void onShadeVisibilityChanged(boolean visible) { - if (mVisible != visible) { - mVisible = visible; - if (visible) { - DejankUtils.notifyRendererOfExpensiveFrame( - getNotificationShadeWindowView(), "onShadeVisibilityChanged"); - } - } - } - private void clearNotificationEffects() { try { mBarService.clearNotificationEffects(); @@ -3163,7 +3152,6 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { // TODO: Bring these out of CentralSurfaces. mUserInfoControllerImpl.onDensityOrFontScaleChanged(); mNotificationIconAreaController.onDensityOrFontScaleChanged(mContext); - mHeadsUpManager.onDensityOrFontScaleChanged(); } @Override @@ -3200,7 +3188,8 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { // down on the lockscreen), clear notification LED, vibration, // ringing. // Other transitions are covered in WindowRootViewVisibilityInteractor. - if (mVisible && (newState == StatusBarState.SHADE_LOCKED + if (mWindowRootViewVisibilityInteractor.isLockscreenOrShadeVisible().getValue() + && (newState == StatusBarState.SHADE_LOCKED || mStatusBarStateController.goingToFullShade())) { clearNotificationEffects(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java index 4849f64659d070e6db03783b46903ed7e5d49f81..d3d11ea4a9f38513f45456f5e6e6eaaafdcd6ca8 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java @@ -49,6 +49,7 @@ import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.policy.BatteryController; import com.android.systemui.statusbar.policy.DeviceProvisionedController; +import com.android.systemui.statusbar.policy.HeadsUpManager; import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener; import com.android.systemui.util.Assert; @@ -80,7 +81,7 @@ public final class DozeServiceHost implements DozeHost { private final WakefulnessLifecycle mWakefulnessLifecycle; private final SysuiStatusBarStateController mStatusBarStateController; private final DeviceProvisionedController mDeviceProvisionedController; - private final HeadsUpManagerPhone mHeadsUpManagerPhone; + private final HeadsUpManager mHeadsUpManager; private final BatteryController mBatteryController; private final ScrimController mScrimController; private final Lazy<BiometricUnlockController> mBiometricUnlockControllerLazy; @@ -106,7 +107,7 @@ public final class DozeServiceHost implements DozeHost { WakefulnessLifecycle wakefulnessLifecycle, SysuiStatusBarStateController statusBarStateController, DeviceProvisionedController deviceProvisionedController, - HeadsUpManagerPhone headsUpManagerPhone, BatteryController batteryController, + HeadsUpManager headsUpManager, BatteryController batteryController, ScrimController scrimController, Lazy<BiometricUnlockController> biometricUnlockControllerLazy, Lazy<AssistManager> assistManagerLazy, @@ -123,7 +124,7 @@ public final class DozeServiceHost implements DozeHost { mWakefulnessLifecycle = wakefulnessLifecycle; mStatusBarStateController = statusBarStateController; mDeviceProvisionedController = deviceProvisionedController; - mHeadsUpManagerPhone = headsUpManagerPhone; + mHeadsUpManager = headsUpManager; mBatteryController = batteryController; mScrimController = scrimController; mBiometricUnlockControllerLazy = biometricUnlockControllerLazy; @@ -135,7 +136,7 @@ public final class DozeServiceHost implements DozeHost { mNotificationWakeUpCoordinator = notificationWakeUpCoordinator; mAuthController = authController; mNotificationIconAreaController = notificationIconAreaController; - mHeadsUpManagerPhone.addListener(mOnHeadsUpChangedListener); + mHeadsUpManager.addListener(mOnHeadsUpChangedListener); mDozeInteractor = dozeInteractor; } @@ -337,8 +338,8 @@ public final class DozeServiceHost implements DozeHost { if (reason == DozeLog.PULSE_REASON_SENSOR_WAKE_REACH) { mScrimController.setWakeLockScreenSensorActive(true); } - if (mDozeScrimController.isPulsing() && mHeadsUpManagerPhone.hasNotifications()) { - mHeadsUpManagerPhone.extendHeadsUp(); + if (mDozeScrimController.isPulsing() && mHeadsUpManager.hasNotifications()) { + mHeadsUpManager.extendHeadsUp(); } else { mDozeScrimController.extendPulse(); } @@ -493,7 +494,7 @@ public final class DozeServiceHost implements DozeHost { mDozeScrimController.cancelPendingPulseTimeout(); } } - if (!isHeadsUp && !mHeadsUpManagerPhone.hasNotifications()) { + if (!isHeadsUp && !mHeadsUpManager.hasNotifications()) { // There are no longer any notifications to show. We should end the // pulse now. stopPulsing(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java index 270c40e801cda76604a3e0fcae6403025b651584..c493eeda707733945b1968a1a46e816eeb7f1b92 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java @@ -26,9 +26,9 @@ import androidx.annotation.NonNull; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.widget.ViewClippingUtil; -import com.android.systemui.res.R; import com.android.systemui.plugins.DarkIconDispatcher; import com.android.systemui.plugins.statusbar.StatusBarStateController; +import com.android.systemui.res.R; import com.android.systemui.shade.ShadeHeadsUpTracker; import com.android.systemui.shade.ShadeViewController; import com.android.systemui.statusbar.CommandQueue; @@ -43,6 +43,7 @@ import com.android.systemui.statusbar.notification.stack.NotificationRoundnessMa import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController; import com.android.systemui.statusbar.phone.fragment.dagger.StatusBarFragmentScope; import com.android.systemui.statusbar.policy.Clock; +import com.android.systemui.statusbar.policy.HeadsUpManager; import com.android.systemui.statusbar.policy.KeyguardStateController; import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener; import com.android.systemui.util.ViewController; @@ -70,7 +71,7 @@ public class HeadsUpAppearanceController extends ViewController<HeadsUpStatusBar private static final SourceType HEADS_UP = SourceType.from("HeadsUp"); private static final SourceType PULSING = SourceType.from("Pulsing"); private final NotificationIconAreaController mNotificationIconAreaController; - private final HeadsUpManagerPhone mHeadsUpManager; + private final HeadsUpManager mHeadsUpManager; private final NotificationStackScrollLayoutController mStackScrollerController; private final DarkIconDispatcher mDarkIconDispatcher; @@ -108,7 +109,7 @@ public class HeadsUpAppearanceController extends ViewController<HeadsUpStatusBar @Inject public HeadsUpAppearanceController( NotificationIconAreaController notificationIconAreaController, - HeadsUpManagerPhone headsUpManager, + HeadsUpManager headsUpManager, StatusBarStateController stateController, PhoneStatusBarTransitions phoneStatusBarTransitions, KeyguardBypassController bypassController, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java index a5ea1426164bce1d4eac1acab6dedc60b55d2e03..6b4382f731eab9cbd18f22a622ff2f51cd114004 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java @@ -29,11 +29,11 @@ import androidx.collection.ArraySet; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.logging.UiEventLogger; import com.android.internal.policy.SystemBarUtils; -import com.android.systemui.Dumpable; -import com.android.systemui.res.R; +import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener; +import com.android.systemui.res.R; import com.android.systemui.shade.ShadeExpansionStateManager; import com.android.systemui.statusbar.StatusBarState; import com.android.systemui.statusbar.notification.collection.NotificationEntry; @@ -42,10 +42,12 @@ import com.android.systemui.statusbar.notification.collection.provider.VisualSta import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper; +import com.android.systemui.statusbar.policy.AnimationStateHandler; +import com.android.systemui.statusbar.policy.BaseHeadsUpManager; import com.android.systemui.statusbar.policy.ConfigurationController; -import com.android.systemui.statusbar.policy.HeadsUpManager; import com.android.systemui.statusbar.policy.HeadsUpManagerLogger; import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener; +import com.android.systemui.statusbar.policy.OnHeadsUpPhoneListenerChange; import java.io.PrintWriter; import java.util.ArrayList; @@ -53,11 +55,11 @@ import java.util.HashSet; import java.util.List; import java.util.Stack; -/** - * A implementation of HeadsUpManager for phone and car. - */ -public class HeadsUpManagerPhone extends HeadsUpManager implements Dumpable, - OnHeadsUpChangedListener { +import javax.inject.Inject; + +/** A implementation of HeadsUpManager for phone. */ +@SysUISingleton +public class HeadsUpManagerPhone extends BaseHeadsUpManager implements OnHeadsUpChangedListener { private static final String TAG = "HeadsUpManagerPhone"; @VisibleForTesting @@ -102,7 +104,7 @@ public class HeadsUpManagerPhone extends HeadsUpManager implements Dumpable, /////////////////////////////////////////////////////////////////////////////////////////////// // Constructor: - + @Inject public HeadsUpManagerPhone(@NonNull final Context context, HeadsUpManagerLogger logger, StatusBarStateController statusBarStateController, @@ -154,7 +156,8 @@ public class HeadsUpManagerPhone extends HeadsUpManager implements Dumpable, /** * Add a listener to receive callbacks onHeadsUpGoingAway */ - void addHeadsUpPhoneListener(OnHeadsUpPhoneListenerChange listener) { + @Override + public void addHeadsUpPhoneListener(OnHeadsUpPhoneListenerChange listener) { mHeadsUpPhoneListeners.add(listener); } @@ -162,7 +165,8 @@ public class HeadsUpManagerPhone extends HeadsUpManager implements Dumpable, * Gets the touchable region needed for heads up notifications. Returns null if no touchable * region is required (ie: no heads up notification currently exists). */ - @Nullable Region getTouchableRegion() { + @Override + public @Nullable Region getTouchableRegion() { NotificationEntry topEntry = getTopEntry(); // This call could be made in an inconsistent state while the pinnedMode hasn't been @@ -197,8 +201,9 @@ public class HeadsUpManagerPhone extends HeadsUpManager implements Dumpable, * @param key the key of the touched notification * @return whether the touch is invalid and should be discarded */ - boolean shouldSwallowClick(@NonNull String key) { - HeadsUpManager.HeadsUpEntry entry = getHeadsUpEntry(key); + @Override + public boolean shouldSwallowClick(@NonNull String key) { + BaseHeadsUpManager.HeadsUpEntry entry = getHeadsUpEntry(key); return entry != null && mClock.currentTimeMillis() < entry.mPostTime; } @@ -238,7 +243,8 @@ public class HeadsUpManagerPhone extends HeadsUpManager implements Dumpable, * Set that we are exiting the headsUp pinned mode, but some notifications might still be * animating out. This is used to keep the touchable regions in a reasonable state. */ - void setHeadsUpGoingAway(boolean headsUpGoingAway) { + @Override + public void setHeadsUpGoingAway(boolean headsUpGoingAway) { if (headsUpGoingAway != mHeadsUpGoingAway) { mHeadsUpGoingAway = headsUpGoingAway; for (OnHeadsUpPhoneListenerChange listener : mHeadsUpPhoneListeners) { @@ -247,7 +253,8 @@ public class HeadsUpManagerPhone extends HeadsUpManager implements Dumpable, } } - boolean isHeadsUpGoingAway() { + @Override + public boolean isHeadsUpGoingAway() { return mHeadsUpGoingAway; } @@ -260,8 +267,8 @@ public class HeadsUpManagerPhone extends HeadsUpManager implements Dumpable, public void setRemoteInputActive( @NonNull NotificationEntry entry, boolean remoteInputActive) { HeadsUpEntryPhone headsUpEntry = getHeadsUpEntryPhone(entry.getKey()); - if (headsUpEntry != null && headsUpEntry.remoteInputActive != remoteInputActive) { - headsUpEntry.remoteInputActive = remoteInputActive; + if (headsUpEntry != null && headsUpEntry.mRemoteInputActive != remoteInputActive) { + headsUpEntry.mRemoteInputActive = remoteInputActive; if (remoteInputActive) { headsUpEntry.removeAutoRemovalCallbacks("setRemoteInputActive(true)"); } else { @@ -313,6 +320,7 @@ public class HeadsUpManagerPhone extends HeadsUpManager implements Dumpable, mSwipedOutKeys.add(key); } + @Override public boolean removeNotification(@NonNull String key, boolean releaseImmediately, boolean animate) { if (animate) { @@ -411,7 +419,7 @@ public class HeadsUpManagerPhone extends HeadsUpManager implements Dumpable, /////////////////////////////////////////////////////////////////////////////////////////////// // HeadsUpEntryPhone: - protected class HeadsUpEntryPhone extends HeadsUpManager.HeadsUpEntry { + protected class HeadsUpEntryPhone extends BaseHeadsUpManager.HeadsUpEntry { private boolean mGutsShownPinned; @@ -459,11 +467,11 @@ public class HeadsUpManagerPhone extends HeadsUpManager implements Dumpable, @Override public void setExpanded(boolean expanded) { - if (this.expanded == expanded) { + if (this.mExpanded == expanded) { return; } - this.expanded = expanded; + this.mExpanded = expanded; if (expanded) { removeAutoRemovalCallbacks("setExpanded(true)"); } else { @@ -504,21 +512,6 @@ public class HeadsUpManagerPhone extends HeadsUpManager implements Dumpable, } } - public interface AnimationStateHandler { - void setHeadsUpGoingAwayAnimationsAllowed(boolean allowed); - } - - /** - * Listener to register for HeadsUpNotification Phone changes. - */ - public interface OnHeadsUpPhoneListenerChange { - /** - * Called when a heads up notification is 'going away' or no longer 'going away'. - * See {@link HeadsUpManagerPhone#setHeadsUpGoingAway}. - */ - void onHeadsUpGoingAwayStateChanged(boolean headsUpGoingAway); - } - private final StateListener mStatusBarStateListener = new StateListener() { @Override public void onStateChanged(int newState) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpModule.kt new file mode 100644 index 0000000000000000000000000000000000000000..0d0f2cd50a298f15d10e9c45ae58b98526c9abbf --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpModule.kt @@ -0,0 +1,11 @@ +package com.android.systemui.statusbar.phone + +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.statusbar.policy.HeadsUpManager +import dagger.Binds +import dagger.Module + +@Module +interface HeadsUpModule { + @Binds @SysUISingleton fun bindsHeadsUpManager(hum: HeadsUpManagerPhone): HeadsUpManager +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java index dcbaac20eaccadfae3b6155daebd0e1480c19a4e..198272e9b162963d824ec76963612432db538442 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java @@ -26,13 +26,14 @@ import com.android.systemui.Gefingerpoken; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.systemui.statusbar.notification.row.ExpandableView; +import com.android.systemui.statusbar.policy.HeadsUpManager; /** * A helper class to handle touches on the heads-up views. */ public class HeadsUpTouchHelper implements Gefingerpoken { - private final HeadsUpManagerPhone mHeadsUpManager; + private final HeadsUpManager mHeadsUpManager; private final IStatusBarService mStatusBarService; private final Callback mCallback; private int mTrackingPointer; @@ -45,7 +46,7 @@ public class HeadsUpTouchHelper implements Gefingerpoken { private final HeadsUpNotificationViewController mPanel; private ExpandableNotificationRow mPickedChild; - public HeadsUpTouchHelper(HeadsUpManagerPhone headsUpManager, + public HeadsUpTouchHelper(HeadsUpManager headsUpManager, IStatusBarService statusBarService, Callback callback, HeadsUpNotificationViewController notificationPanelView) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeadsUpChangeListener.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeadsUpChangeListener.java index 4b39854e43ff08fcc4ea3b3cd3c59ea2581b9ff5..235ed25e2ea19a85fbe88196ea07328d2c60b938 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeadsUpChangeListener.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeadsUpChangeListener.java @@ -24,6 +24,7 @@ import com.android.systemui.statusbar.NotificationRemoteInputManager; import com.android.systemui.statusbar.NotificationShadeWindowController; import com.android.systemui.statusbar.StatusBarState; import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController; +import com.android.systemui.statusbar.policy.HeadsUpManager; import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener; import com.android.systemui.statusbar.window.StatusBarWindowController; @@ -39,7 +40,7 @@ public class StatusBarHeadsUpChangeListener implements OnHeadsUpChangedListener, private final ShadeViewController mShadeViewController; private final NotificationStackScrollLayoutController mNsslController; private final KeyguardBypassController mKeyguardBypassController; - private final HeadsUpManagerPhone mHeadsUpManager; + private final HeadsUpManager mHeadsUpManager; private final StatusBarStateController mStatusBarStateController; private final NotificationRemoteInputManager mNotificationRemoteInputManager; @@ -50,7 +51,7 @@ public class StatusBarHeadsUpChangeListener implements OnHeadsUpChangedListener, ShadeViewController shadeViewController, NotificationStackScrollLayoutController nsslController, KeyguardBypassController keyguardBypassController, - HeadsUpManagerPhone headsUpManager, + HeadsUpManager headsUpManager, StatusBarStateController statusBarStateController, NotificationRemoteInputManager notificationRemoteInputManager) { mNotificationShadeWindowController = notificationShadeWindowController; 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 eedf35f1e9d437628ba95c0193274019159f128a..62b2445de13ae7678198f935f26e173ba301ad2c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java @@ -1573,6 +1573,9 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb * notification shade's child views. */ public boolean shouldInterceptTouchEvent(MotionEvent event) { + if (mFlags.isEnabled(Flags.ALTERNATE_BOUNCER_VIEW)) { + return false; + } return mAlternateBouncerInteractor.isVisibleState(); } @@ -1581,6 +1584,10 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb * showing. */ public boolean onTouch(MotionEvent event) { + if (mFlags.isEnabled(Flags.ALTERNATE_BOUNCER_VIEW)) { + return false; + } + boolean handleTouch = shouldInterceptTouchEvent(event); if (handleTouch) { final boolean actionDown = event.getActionMasked() == MotionEvent.ACTION_DOWN; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java index dc4c7095237eb4204e09719c20571813ccbf1476..dbee080f238d1b28deeabb12977ea15f3aeaeb80 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java @@ -76,6 +76,7 @@ import com.android.systemui.statusbar.notification.interruption.NotificationInte import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRowDragController; import com.android.systemui.statusbar.notification.row.OnUserInteractionCallback; +import com.android.systemui.statusbar.policy.HeadsUpManager; import com.android.systemui.statusbar.policy.HeadsUpUtil; import com.android.systemui.statusbar.policy.KeyguardStateController; import com.android.systemui.wmshell.BubblesManager; @@ -102,7 +103,7 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit private final Executor mUiBgExecutor; private final NotificationVisibilityProvider mVisibilityProvider; - private final HeadsUpManagerPhone mHeadsUpManager; + private final HeadsUpManager mHeadsUpManager; private final ActivityStarter mActivityStarter; private final NotificationClickNotifier mClickNotifier; private final StatusBarKeyguardViewManager mStatusBarKeyguardViewManager; @@ -141,7 +142,7 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit Handler mainThreadHandler, Executor uiBgExecutor, NotificationVisibilityProvider visibilityProvider, - HeadsUpManagerPhone headsUpManager, + HeadsUpManager headsUpManager, ActivityStarter activityStarter, NotificationClickNotifier clickNotifier, StatusBarKeyguardViewManager statusBarKeyguardViewManager, @@ -213,7 +214,9 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit */ @Override public void onNotificationClicked(NotificationEntry entry, ExpandableNotificationRow row) { - mLogger.logStartingActivityFromClick(entry); + mLogger.logStartingActivityFromClick(entry, row.isHeadsUpState(), + mKeyguardStateController.isVisible(), + mNotificationShadeWindowController.getPanelExpanded()); if (mRemoteInputManager.isRemoteInputActive(entry)) { // We have an active remote input typed and the user clicked on the notification. diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterLogger.kt index 2d30a12c3948d8e90ce07dcf9fc9ae98c6793dca..4211cabcbc561e4acc0c7ef5c93d5e967c89fc7d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterLogger.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterLogger.kt @@ -30,11 +30,16 @@ import javax.inject.Inject class StatusBarNotificationActivityStarterLogger @Inject constructor( @NotifInteractionLog private val buffer: LogBuffer ) { - fun logStartingActivityFromClick(entry: NotificationEntry) { + fun logStartingActivityFromClick(entry: NotificationEntry, isHeadsUpState: Boolean, + isKeyguardVisible: Boolean, isPanelExpanded: Boolean) { buffer.log(TAG, DEBUG, { str1 = entry.logKey + bool1 = isHeadsUpState + bool2 = isKeyguardVisible + bool3 = isPanelExpanded }, { - "(1/5) onNotificationClicked: $str1" + "(1/5) onNotificationClicked: $str1 isHeadsUpState: $bool1 " + + "isKeyguardVisible: $bool2 isPanelExpanded: $bool3" }) } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java index fb7f9d1ec19b2b6a754b09467dd0757ebfb36349..2d14f6b3c508ba74d8835142d3b9df6d299da77c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java @@ -31,11 +31,11 @@ import android.view.View; import com.android.internal.statusbar.IStatusBarService; import com.android.systemui.InitController; -import com.android.systemui.res.R; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.ActivityStarter.OnDismissAction; import com.android.systemui.power.domain.interactor.PowerInteractor; +import com.android.systemui.res.R; import com.android.systemui.shade.NotificationShadeWindowView; import com.android.systemui.shade.QuickSettingsController; import com.android.systemui.shade.ShadeViewController; @@ -60,6 +60,7 @@ import com.android.systemui.statusbar.notification.row.NotificationGutsManager; import com.android.systemui.statusbar.notification.row.NotificationGutsManager.OnSettingsClickListener; import com.android.systemui.statusbar.notification.stack.NotificationListContainer; import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController; +import com.android.systemui.statusbar.policy.HeadsUpManager; import com.android.systemui.statusbar.policy.KeyguardStateController; import javax.inject.Inject; @@ -76,7 +77,7 @@ class StatusBarNotificationPresenter implements NotificationPresenter, CommandQu private final NotificationMediaManager mMediaManager; private final NotificationGutsManager mGutsManager; private final ShadeViewController mNotificationPanel; - private final HeadsUpManagerPhone mHeadsUpManager; + private final HeadsUpManager mHeadsUpManager; private final AboveShelfObserver mAboveShelfObserver; private final DozeScrimController mDozeScrimController; private final NotificationsInteractor mNotificationsInteractor; @@ -98,7 +99,7 @@ class StatusBarNotificationPresenter implements NotificationPresenter, CommandQu Context context, ShadeViewController panel, QuickSettingsController quickSettingsController, - HeadsUpManagerPhone headsUp, + HeadsUpManager headsUp, NotificationShadeWindowView statusBarWindow, ActivityStarter activityStarter, NotificationStackScrollLayoutController stackScrollerController, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java index 40bd8d3446b554ef4523e095c44af35e000d07c5..ba73c1098637cfc7fafa200a4ae605e584d0b9f5 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java @@ -31,15 +31,18 @@ import android.view.WindowInsets; import com.android.internal.policy.SystemBarUtils; import com.android.systemui.Dumpable; -import com.android.systemui.res.R; import com.android.systemui.ScreenDecorations; +import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor; +import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor; import com.android.systemui.dagger.SysUISingleton; +import com.android.systemui.res.R; import com.android.systemui.scene.domain.interactor.SceneInteractor; import com.android.systemui.scene.shared.flag.SceneContainerFlags; import com.android.systemui.shade.ShadeExpansionStateManager; import com.android.systemui.statusbar.NotificationShadeWindowController; import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener; +import com.android.systemui.statusbar.policy.HeadsUpManager; import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener; import com.android.systemui.util.kotlin.JavaAdapter; @@ -58,13 +61,12 @@ public final class StatusBarTouchableRegionManager implements Dumpable { private static final String TAG = "TouchableRegionManager"; private final Context mContext; - private final HeadsUpManagerPhone mHeadsUpManager; + private final HeadsUpManager mHeadsUpManager; private final NotificationShadeWindowController mNotificationShadeWindowController; private final UnlockedScreenOffAnimationController mUnlockedScreenOffAnimationController; private boolean mIsStatusBarExpanded = false; private boolean mShouldAdjustInsets = false; - private CentralSurfaces mCentralSurfaces; private View mNotificationShadeWindowView; private View mNotificationPanelView; private boolean mForceCollapsedUntilLayout = false; @@ -72,6 +74,8 @@ public final class StatusBarTouchableRegionManager implements Dumpable { private Region mTouchableRegion = new Region(); private int mDisplayCutoutTouchableRegionSize; private int mStatusBarHeight; + private final PrimaryBouncerInteractor mPrimaryBouncerInteractor; + private final AlternateBouncerInteractor mAlternateBouncerInteractor; private final OnComputeInternalInsetsListener mOnComputeInternalInsetsListener; @@ -80,12 +84,14 @@ public final class StatusBarTouchableRegionManager implements Dumpable { Context context, NotificationShadeWindowController notificationShadeWindowController, ConfigurationController configurationController, - HeadsUpManagerPhone headsUpManager, + HeadsUpManager headsUpManager, ShadeExpansionStateManager shadeExpansionStateManager, Provider<SceneInteractor> sceneInteractor, Provider<JavaAdapter> javaAdapter, SceneContainerFlags sceneContainerFlags, - UnlockedScreenOffAnimationController unlockedScreenOffAnimationController + UnlockedScreenOffAnimationController unlockedScreenOffAnimationController, + PrimaryBouncerInteractor primaryBouncerInteractor, + AlternateBouncerInteractor alternateBouncerInteractor ) { mContext = context; initResources(); @@ -128,13 +134,12 @@ public final class StatusBarTouchableRegionManager implements Dumpable { this::onShadeExpansionFullyChanged); } + mPrimaryBouncerInteractor = primaryBouncerInteractor; + mAlternateBouncerInteractor = alternateBouncerInteractor; mOnComputeInternalInsetsListener = this::onComputeInternalInsets; } - protected void setup( - @NonNull CentralSurfaces centralSurfaces, - @NonNull View notificationShadeWindowView) { - mCentralSurfaces = centralSurfaces; + protected void setup(@NonNull View notificationShadeWindowView) { mNotificationShadeWindowView = notificationShadeWindowView; mNotificationPanelView = mNotificationShadeWindowView.findViewById(R.id.notification_panel); } @@ -260,7 +265,8 @@ public final class StatusBarTouchableRegionManager implements Dumpable { // since we don't want stray touches to go through the light reveal scrim to whatever is // underneath. return mIsStatusBarExpanded - || mCentralSurfaces.isBouncerShowing() + || mPrimaryBouncerInteractor.isShowing().getValue() + || mAlternateBouncerInteractor.isVisibleState() || mUnlockedScreenOffAnimationController.isAnimationPlaying(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java index babd435c62ba599e20b2e833aa57efc381f70114..63c022c5bb6b145114cfe69395220a6857e0f6aa 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java @@ -38,11 +38,11 @@ import com.android.app.animation.Interpolators; import com.android.app.animation.InterpolatorsAndroidX; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.systemui.Dumpable; -import com.android.systemui.res.R; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.dump.DumpManager; import com.android.systemui.flags.FeatureFlags; import com.android.systemui.plugins.statusbar.StatusBarStateController; +import com.android.systemui.res.R; import com.android.systemui.shade.ShadeExpansionStateManager; import com.android.systemui.shade.ShadeViewController; import com.android.systemui.statusbar.CommandQueue; @@ -74,8 +74,6 @@ import com.android.systemui.util.CarrierConfigTracker.CarrierConfigChangedListen import com.android.systemui.util.CarrierConfigTracker.DefaultDataSubscriptionChangedListener; import com.android.systemui.util.settings.SecureSettings; -import kotlin.Unit; - import java.io.PrintWriter; import java.util.ArrayList; import java.util.Arrays; @@ -85,6 +83,7 @@ import java.util.Set; import java.util.concurrent.Executor; import javax.inject.Inject; +import kotlin.Unit; /** * Contains the collapsed status bar and handles hiding/showing based on disable flags @@ -279,7 +278,8 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); mDumpManager.registerDumpable(getClass().getSimpleName(), this); - mStatusBarFragmentComponent = mStatusBarFragmentComponentFactory.create(this); + mStatusBarFragmentComponent = mStatusBarFragmentComponentFactory.create( + (PhoneStatusBarView) getView()); mStatusBarFragmentComponent.init(); mStartableStates.clear(); for (Startable startable : mStatusBarFragmentComponent.getStartables()) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/dagger/StatusBarFragmentComponent.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/dagger/StatusBarFragmentComponent.java index d9a58442d856d8c51591893948294e3cb3f07d52..0618abbf00d8403f9a2f392f8f6bed09015c5fd4 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/dagger/StatusBarFragmentComponent.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/dagger/StatusBarFragmentComponent.java @@ -27,11 +27,11 @@ import com.android.systemui.statusbar.phone.StatusBarBoundsProvider; import com.android.systemui.statusbar.phone.StatusBarDemoMode; import com.android.systemui.statusbar.phone.fragment.CollapsedStatusBarFragment; -import java.util.Set; - import dagger.BindsInstance; import dagger.Subcomponent; +import java.util.Set; + /** * A subcomponent that gets re-created each time we create a new {@link CollapsedStatusBarFragment}. * @@ -54,7 +54,7 @@ public interface StatusBarFragmentComponent { @Subcomponent.Factory interface Factory { StatusBarFragmentComponent create( - @BindsInstance CollapsedStatusBarFragment collapsedStatusBarFragment); + @BindsInstance @RootView PhoneStatusBarView phoneStatusBarView); } /** diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/dagger/StatusBarFragmentModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/dagger/StatusBarFragmentModule.java index 6ef877bd57bfce6b0c80c93836b763d1ea21383c..3741f143dd8d5f48840821156af7e9a64a5e3090 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/dagger/StatusBarFragmentModule.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/dagger/StatusBarFragmentModule.java @@ -19,15 +19,14 @@ package com.android.systemui.statusbar.phone.fragment.dagger; import android.view.View; import android.view.ViewStub; -import com.android.systemui.res.R; import com.android.systemui.battery.BatteryMeterView; import com.android.systemui.dagger.qualifiers.RootView; +import com.android.systemui.res.R; import com.android.systemui.statusbar.HeadsUpStatusBarView; import com.android.systemui.statusbar.phone.PhoneStatusBarTransitions; import com.android.systemui.statusbar.phone.PhoneStatusBarView; import com.android.systemui.statusbar.phone.PhoneStatusBarViewController; import com.android.systemui.statusbar.phone.StatusBarLocation; -import com.android.systemui.statusbar.phone.fragment.CollapsedStatusBarFragment; import com.android.systemui.statusbar.phone.userswitcher.StatusBarUserSwitcherContainer; import com.android.systemui.statusbar.policy.Clock; import com.android.systemui.statusbar.window.StatusBarWindowController; @@ -49,15 +48,6 @@ public interface StatusBarFragmentModule { String START_SIDE_CONTENT = "start_side_content"; String END_SIDE_CONTENT = "end_side_content"; - /** */ - @Provides - @RootView - @StatusBarFragmentScope - static PhoneStatusBarView providePhoneStatusBarView( - CollapsedStatusBarFragment collapsedStatusBarFragment) { - return (PhoneStatusBarView) collapsedStatusBarFragment.getView(); - } - /** */ @Provides @StatusBarFragmentScope diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BaseHeadsUpManager.java similarity index 93% rename from packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java rename to packages/SystemUI/src/com/android/systemui/statusbar/policy/BaseHeadsUpManager.java index e59ec044bece25aef0b132f1418116fa8803a6b9..cec76f3140cd5bd587a20da10e389f880742d715 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BaseHeadsUpManager.java @@ -34,8 +34,8 @@ import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.UiEvent; import com.android.internal.logging.UiEventLogger; import com.android.systemui.EventLogTags; -import com.android.systemui.res.R; import com.android.systemui.dagger.qualifiers.Main; +import com.android.systemui.res.R; import com.android.systemui.statusbar.AlertingNotificationManager; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.InflationFlag; @@ -47,7 +47,8 @@ import java.io.PrintWriter; * A manager which handles heads up notifications which is a special mode where * they simply peek from the top of the screen. */ -public abstract class HeadsUpManager extends AlertingNotificationManager { +public abstract class BaseHeadsUpManager extends AlertingNotificationManager implements + HeadsUpManager { private static final String TAG = "HeadsUpManager"; private static final String SETTING_HEADS_UP_SNOOZE_LENGTH_MS = "heads_up_snooze_length_ms"; @@ -81,7 +82,7 @@ public abstract class HeadsUpManager extends AlertingNotificationManager { } } - public HeadsUpManager(@NonNull final Context context, + public BaseHeadsUpManager(@NonNull final Context context, HeadsUpManagerLogger logger, @Main Handler handler, AccessibilityManagerWrapper accessibilityManagerWrapper, @@ -131,6 +132,7 @@ public abstract class HeadsUpManager extends AlertingNotificationManager { mListeners.remove(listener); } + /** Updates the notification with the given key. */ public void updateNotification(@NonNull String key, boolean alert) { super.updateNotification(key, alert); HeadsUpEntry headsUpEntry = getHeadsUpEntry(key); @@ -146,7 +148,7 @@ public abstract class HeadsUpManager extends AlertingNotificationManager { // the NotificationEntry into AlertingNotificationManager's mAlertEntries map. return hasFullScreenIntent(entry); } - return hasFullScreenIntent(entry) && !headsUpEntry.wasUnpinned; + return hasFullScreenIntent(entry) && !headsUpEntry.mWasUnpinned; } protected boolean hasFullScreenIntent(@NonNull NotificationEntry entry) { @@ -154,11 +156,11 @@ public abstract class HeadsUpManager extends AlertingNotificationManager { } protected void setEntryPinned( - @NonNull HeadsUpManager.HeadsUpEntry headsUpEntry, boolean isPinned) { + @NonNull BaseHeadsUpManager.HeadsUpEntry headsUpEntry, boolean isPinned) { mLogger.logSetEntryPinned(headsUpEntry.mEntry, isPinned); NotificationEntry entry = headsUpEntry.mEntry; if (!isPinned) { - headsUpEntry.wasUnpinned = true; + headsUpEntry.mWasUnpinned = true; } if (entry.isRowPinned() != isPinned) { entry.setRowPinned(isPinned); @@ -292,10 +294,12 @@ public abstract class HeadsUpManager extends AlertingNotificationManager { mUser = user; } + /** Returns the ID of the current user. */ public int getUser() { return mUser; } + @Override public void dump(@NonNull PrintWriter pw, @NonNull String[] args) { pw.println("HeadsUpManager state:"); dumpInternal(pw, args); @@ -309,9 +313,9 @@ public abstract class HeadsUpManager extends AlertingNotificationManager { for (AlertEntry entry: mAlertEntries.values()) { pw.print(" HeadsUpEntry="); pw.println(entry.mEntry); } - int N = mSnoozedPackages.size(); - pw.println(" snoozed packages: " + N); - for (int i = 0; i < N; i++) { + int n = mSnoozedPackages.size(); + pw.println(" snoozed packages: " + n); + for (int i = 0; i < n; i++) { pw.print(" "); pw.print(mSnoozedPackages.valueAt(i)); pw.print(", "); pw.println(mSnoozedPackages.keyAt(i)); } @@ -399,20 +403,20 @@ public abstract class HeadsUpManager extends AlertingNotificationManager { * * @param entry the entry that might be indirectly removed by the user's action * - * @see com.android.systemui.statusbar.notification.collection.coordinator.HeadsUpCoordinator#mActionPressListener + * @see HeadsUpCoordinator#mActionPressListener * @see #canRemoveImmediately(String) */ public void setUserActionMayIndirectlyRemove(@NonNull NotificationEntry entry) { HeadsUpEntry headsUpEntry = getHeadsUpEntry(entry.getKey()); if (headsUpEntry != null) { - headsUpEntry.userActionMayIndirectlyRemove = true; + headsUpEntry.mUserActionMayIndirectlyRemove = true; } } @Override public boolean canRemoveImmediately(@NonNull String key) { HeadsUpEntry headsUpEntry = getHeadsUpEntry(key); - if (headsUpEntry != null && headsUpEntry.userActionMayIndirectlyRemove) { + if (headsUpEntry != null && headsUpEntry.mUserActionMayIndirectlyRemove) { return true; } return super.canRemoveImmediately(key); @@ -424,9 +428,6 @@ public abstract class HeadsUpManager extends AlertingNotificationManager { return new HeadsUpEntry(); } - public void onDensityOrFontScaleChanged() { - } - /** * Determines if the notification is for a critical call that must display on top of an active * input notification. @@ -445,16 +446,16 @@ public abstract class HeadsUpManager extends AlertingNotificationManager { * lifecycle automatically when created. */ protected class HeadsUpEntry extends AlertEntry { - public boolean remoteInputActive; - public boolean userActionMayIndirectlyRemove; + public boolean mRemoteInputActive; + public boolean mUserActionMayIndirectlyRemove; - protected boolean expanded; - protected boolean wasUnpinned; + protected boolean mExpanded; + protected boolean mWasUnpinned; @Override public boolean isSticky() { - return (mEntry.isRowPinned() && expanded) - || remoteInputActive + return (mEntry.isRowPinned() && mExpanded) + || mRemoteInputActive || hasFullScreenIntent(mEntry); } @@ -490,9 +491,9 @@ public abstract class HeadsUpManager extends AlertingNotificationManager { return 1; } - if (remoteInputActive && !headsUpEntry.remoteInputActive) { + if (mRemoteInputActive && !headsUpEntry.mRemoteInputActive) { return -1; - } else if (!remoteInputActive && headsUpEntry.remoteInputActive) { + } else if (!mRemoteInputActive && headsUpEntry.mRemoteInputActive) { return 1; } @@ -500,14 +501,14 @@ public abstract class HeadsUpManager extends AlertingNotificationManager { } public void setExpanded(boolean expanded) { - this.expanded = expanded; + this.mExpanded = expanded; } @Override public void reset() { super.reset(); - expanded = false; - remoteInputActive = false; + mExpanded = false; + mRemoteInputActive = false; } @Override diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.kt new file mode 100644 index 0000000000000000000000000000000000000000..d9527fe98b1a34a54ab2a81d431f5f502945d99c --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.kt @@ -0,0 +1,245 @@ +package com.android.systemui.statusbar.policy + +import android.graphics.Region +import com.android.systemui.Dumpable +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.statusbar.notification.collection.NotificationEntry +import dagger.Binds +import dagger.Module +import java.io.PrintWriter +import java.util.stream.Stream +import javax.inject.Inject + +/** + * A manager which handles heads up notifications which is a special mode where they simply peek + * from the top of the screen. + */ +interface HeadsUpManager : Dumpable { + /** The stream of all current notifications managed by this manager. */ + val allEntries: Stream<NotificationEntry> + + /** Add a listener to receive callbacks onHeadsUpGoingAway. */ + fun addHeadsUpPhoneListener(listener: OnHeadsUpPhoneListenerChange) + + /** Adds an OnHeadUpChangedListener to observe events. */ + fun addListener(listener: OnHeadsUpChangedListener) + + fun addSwipedOutNotification(key: String) + + /** + * Whether or not the alert can be removed currently. If it hasn't been on screen long enough it + * should not be removed unless forced + * + * @param key the key to check if removable + * @return true if the alert entry can be removed + */ + fun canRemoveImmediately(key: String): Boolean + + /** + * Compare two entries and decide how they should be ranked. + * + * @return -1 if the first argument should be ranked higher than the second, 1 if the second one + * should be ranked higher and 0 if they are equal. + */ + fun compare(a: NotificationEntry?, b: NotificationEntry?): Int + /** + * Extends the lifetime of the currently showing pulsing notification so that the pulse lasts + * longer. + */ + fun extendHeadsUp() + + /** Returns when a HUN entry should be removed in milliseconds from now. */ + fun getEarliestRemovalTime(key: String?): Long + + /** Returns the top Heads Up Notification, which appears to show at first. */ + fun getTopEntry(): NotificationEntry? + + /** + * Gets the touchable region needed for heads up notifications. Returns null if no touchable + * region is required (ie: no heads up notification currently exists). + */ + fun getTouchableRegion(): Region? + + /** + * Whether or not there are any active alerting notifications. + * + * @return true if there is an alert, false otherwise + */ + fun hasNotifications(): Boolean = false + + /** Returns whether there are any pinned Heads Up Notifications or not. */ + fun hasPinnedHeadsUp(): Boolean + + /** Returns whether or not the given notification is alerting and managed by this manager. */ + fun isAlerting(key: String): Boolean + + fun isHeadsUpGoingAway(): Boolean + + /** Returns if the given notification is snoozed or not. */ + fun isSnoozed(packageName: String): Boolean + + /** Returns whether the entry is (pinned and expanded) or (has an active remote input). */ + fun isSticky(key: String?): Boolean + + fun isTrackingHeadsUp(): Boolean + + fun onExpandingFinished() + + /** Removes the OnHeadUpChangedListener from the observer list. */ + fun removeListener(listener: OnHeadsUpChangedListener) + + /** + * Try to remove the notification. May not succeed if the notification has not been shown long + * enough and needs to be kept around. + * + * @param key the key of the notification to remove + * @param releaseImmediately force a remove regardless of earliest removal time + * @return true if notification is removed, false otherwise + */ + fun removeNotification(key: String, releaseImmediately: Boolean): Boolean + + /** + * Try to remove the notification. May not succeed if the notification has not been shown long + * enough and needs to be kept around. + * + * @param key the key of the notification to remove + * @param releaseImmediately force a remove regardless of earliest removal time + * @param animate if true, animate the removal + * @return true if notification is removed, false otherwise + */ + fun removeNotification(key: String, releaseImmediately: Boolean, animate: Boolean): Boolean + + /** Clears all managed notifications. */ + fun releaseAllImmediately() + + fun setAnimationStateHandler(handler: AnimationStateHandler) + + /** + * Set an entry to be expanded and therefore stick in the heads up area if it's pinned until + * it's collapsed again. + */ + fun setExpanded(entry: NotificationEntry, expanded: Boolean) + + /** + * Sets whether an entry's guts are exposed and therefore it should stick in the heads up area + * if it's pinned until it's hidden again. + */ + fun setGutsShown(entry: NotificationEntry, gutsShown: Boolean) + + /** + * Set that we are exiting the headsUp pinned mode, but some notifications might still be + * animating out. This is used to keep the touchable regions in a reasonable state. + */ + fun setHeadsUpGoingAway(headsUpGoingAway: Boolean) + + /** + * Notifies that a remote input textbox in notification gets active or inactive. + * + * @param entry The entry of the target notification. + * @param remoteInputActive True to notify active, False to notify inactive. + */ + fun setRemoteInputActive(entry: NotificationEntry, remoteInputActive: Boolean) + + fun setTrackingHeadsUp(tracking: Boolean) + + /** Sets the current user. */ + fun setUser(user: Int) + + /** + * Notes that the user took an action on an entry that might indirectly cause the system or the + * app to remove the notification. + * + * @param entry the entry that might be indirectly removed by the user's action + * @see + * com.android.systemui.statusbar.notification.collection.coordinator.HeadsUpCoordinator.mActionPressListener + * @see .canRemoveImmediately + */ + fun setUserActionMayIndirectlyRemove(entry: NotificationEntry) + + /** + * Decides whether a click is invalid for a notification, i.e. it has not been shown long enough + * that a user might have consciously clicked on it. + * + * @param key the key of the touched notification + * @return whether the touch is invalid and should be discarded + */ + fun shouldSwallowClick(key: String): Boolean + + /** + * Called when posting a new notification that should alert the user and appear on screen. Adds + * the notification to be managed. + * + * @param entry entry to show + */ + fun showNotification(entry: NotificationEntry) + + fun snooze() + + /** + * Unpins all pinned Heads Up Notifications. + * + * @param userUnPinned The unpinned action is trigger by user real operation. + */ + fun unpinAll(userUnPinned: Boolean) + + fun updateNotification(key: String, alert: Boolean) +} + +/** Sets the animation state of the HeadsUpManager. */ +interface AnimationStateHandler { + fun setHeadsUpGoingAwayAnimationsAllowed(allowed: Boolean) +} + +/** Listener to register for HeadsUpNotification Phone changes. */ +interface OnHeadsUpPhoneListenerChange { + /** + * Called when a heads up notification is 'going away' or no longer 'going away'. See + * [HeadsUpManager.setHeadsUpGoingAway]. + */ + fun onHeadsUpGoingAwayStateChanged(headsUpGoingAway: Boolean) +} + +/* No op impl of HeadsUpManager. */ +class HeadsUpManagerEmptyImpl @Inject constructor() : HeadsUpManager { + override val allEntries = Stream.empty<NotificationEntry>() + override fun addHeadsUpPhoneListener(listener: OnHeadsUpPhoneListenerChange) {} + override fun addListener(listener: OnHeadsUpChangedListener) {} + override fun addSwipedOutNotification(key: String) {} + override fun canRemoveImmediately(key: String) = false + override fun compare(a: NotificationEntry?, b: NotificationEntry?) = 0 + override fun dump(pw: PrintWriter, args: Array<out String>) {} + override fun extendHeadsUp() {} + override fun getEarliestRemovalTime(key: String?) = 0L + override fun getTouchableRegion(): Region? = null + override fun getTopEntry() = null + override fun hasPinnedHeadsUp() = false + override fun isAlerting(key: String) = false + override fun isHeadsUpGoingAway() = false + override fun isSnoozed(packageName: String) = false + override fun isSticky(key: String?) = false + override fun isTrackingHeadsUp() = false + override fun onExpandingFinished() {} + override fun releaseAllImmediately() {} + override fun removeListener(listener: OnHeadsUpChangedListener) {} + override fun removeNotification(key: String, releaseImmediately: Boolean) = false + override fun removeNotification(key: String, releaseImmediately: Boolean, animate: Boolean) = + false + override fun setAnimationStateHandler(handler: AnimationStateHandler) {} + override fun setExpanded(entry: NotificationEntry, expanded: Boolean) {} + override fun setGutsShown(entry: NotificationEntry, gutsShown: Boolean) {} + override fun setHeadsUpGoingAway(headsUpGoingAway: Boolean) {} + override fun setRemoteInputActive(entry: NotificationEntry, remoteInputActive: Boolean) {} + override fun setTrackingHeadsUp(tracking: Boolean) {} + override fun setUser(user: Int) {} + override fun setUserActionMayIndirectlyRemove(entry: NotificationEntry) {} + override fun shouldSwallowClick(key: String): Boolean = false + override fun showNotification(entry: NotificationEntry) {} + override fun snooze() {} + override fun unpinAll(userUnPinned: Boolean) {} + override fun updateNotification(key: String, alert: Boolean) {} +} + +@Module +interface HeadsUpEmptyImplModule { + @Binds @SysUISingleton fun bindsHeadsUpManager(noOpHum: HeadsUpManagerEmptyImpl): HeadsUpManager +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ResourcesSplitShadeStateController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ResourcesSplitShadeStateController.kt index c302d6aeadbccea4e4a73135fb5017759e6d7d7a..859e636a7714d72f671ae7eb18579c3fde22901f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ResourcesSplitShadeStateController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ResourcesSplitShadeStateController.kt @@ -17,6 +17,7 @@ package com.android.systemui.statusbar.policy import android.content.res.Resources import com.android.systemui.res.R +import javax.inject.Inject /** * Fake SplitShadeStateController @@ -24,7 +25,7 @@ import com.android.systemui.res.R * Identical behaviour to legacy implementation (that used LargeScreenUtils.kt) I.E., behaviour * based solely on resources, no extra flag logic. */ -class ResourcesSplitShadeStateController : SplitShadeStateController { +class ResourcesSplitShadeStateController @Inject constructor() : SplitShadeStateController { override fun shouldUseSplitNotificationShade(resources: Resources): Boolean { return resources.getBoolean(R.bool.config_use_split_notification_shade) } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/StatusBarPolicyModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/StatusBarPolicyModule.java index a77c69236946f8f75252a6c04a640d7ff224d7f9..818ba9512e15391253940df02ef8887cba3a3485 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/StatusBarPolicyModule.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/StatusBarPolicyModule.java @@ -70,6 +70,7 @@ import com.android.systemui.statusbar.policy.ZenModeController; import com.android.systemui.statusbar.policy.ZenModeControllerImpl; import com.android.systemui.statusbar.policy.bluetooth.BluetoothRepository; import com.android.systemui.statusbar.policy.bluetooth.BluetoothRepositoryImpl; +import com.android.systemui.statusbar.policy.data.repository.DeviceProvisioningRepositoryModule; import dagger.Binds; import dagger.Module; @@ -80,7 +81,7 @@ import java.util.concurrent.Executor; import javax.inject.Named; /** Dagger Module for code in the statusbar.policy package. */ -@Module +@Module(includes = { DeviceProvisioningRepositoryModule.class }) public interface StatusBarPolicyModule { String DEVICE_STATE_ROTATION_LOCK_DEFAULTS = "DEVICE_STATE_ROTATION_LOCK_DEFAULTS"; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/data/repository/DeviceProvisioningRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/data/repository/DeviceProvisioningRepository.kt new file mode 100644 index 0000000000000000000000000000000000000000..1160d657ba88a2bd19a4b52416ced2be4c0ffe24 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/data/repository/DeviceProvisioningRepository.kt @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.systemui.statusbar.policy.data.repository + +import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow +import com.android.systemui.statusbar.policy.DeviceProvisionedController +import dagger.Binds +import dagger.Module +import javax.inject.Inject +import kotlinx.coroutines.channels.awaitClose +import kotlinx.coroutines.flow.Flow + +/** Tracks state related to device provisioning. */ +interface DeviceProvisioningRepository { + /** + * Whether this device has been provisioned. + * + * @see android.provider.Settings.Global.DEVICE_PROVISIONED + */ + val isDeviceProvisioned: Flow<Boolean> + + /** Whether Factory Reset Protection (FRP) is currently active, locking the device. */ + val isFactoryResetProtectionActive: Flow<Boolean> +} + +@Module +interface DeviceProvisioningRepositoryModule { + @Binds fun bindsImpl(impl: DeviceProvisioningRepositoryImpl): DeviceProvisioningRepository +} + +class DeviceProvisioningRepositoryImpl +@Inject +constructor( + private val deviceProvisionedController: DeviceProvisionedController, +) : DeviceProvisioningRepository { + + override val isDeviceProvisioned: Flow<Boolean> = conflatedCallbackFlow { + val listener = + object : DeviceProvisionedController.DeviceProvisionedListener { + override fun onDeviceProvisionedChanged() { + trySend(deviceProvisionedController.isDeviceProvisioned) + } + } + deviceProvisionedController.addCallback(listener) + trySend(deviceProvisionedController.isDeviceProvisioned) + awaitClose { deviceProvisionedController.removeCallback(listener) } + } + + override val isFactoryResetProtectionActive: Flow<Boolean> = conflatedCallbackFlow { + val listener = + object : DeviceProvisionedController.DeviceProvisionedListener { + override fun onFrpActiveChanged() { + trySend(deviceProvisionedController.isFrpActive) + } + } + deviceProvisionedController.addCallback(listener) + trySend(deviceProvisionedController.isFrpActive) + awaitClose { deviceProvisionedController.removeCallback(listener) } + } +} diff --git a/packages/SystemUI/src/com/android/systemui/user/domain/interactor/UserInteractor.kt b/packages/SystemUI/src/com/android/systemui/user/domain/interactor/UserInteractor.kt index ce9d6fd752c5bb29dd005a6cca216b5f6342d6d8..dbc3bf3a75a2c4d38f4066b9c5648e9a1041f144 100644 --- a/packages/SystemUI/src/com/android/systemui/user/domain/interactor/UserInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/user/domain/interactor/UserInteractor.kt @@ -325,6 +325,7 @@ constructor( addAction(Intent.ACTION_USER_SWITCHED) addAction(Intent.ACTION_USER_STOPPED) addAction(Intent.ACTION_USER_UNLOCKED) + addAction(Intent.ACTION_LOCALE_CHANGED) }, user = UserHandle.SYSTEM, map = { intent, _ -> intent }, @@ -615,6 +616,7 @@ constructor( ) { val shouldRefreshAllUsers = when (intent.action) { + Intent.ACTION_LOCALE_CHANGED -> true Intent.ACTION_USER_SWITCHED -> { dismissDialog() val selectedUserId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1) @@ -644,6 +646,11 @@ constructor( } private fun restartSecondaryService(@UserIdInt userId: Int) { + // Do not start service for user that is marked for deletion. + if (!manager.aliveUsers.map { it.id }.contains(userId)) { + return + } + val intent = Intent(applicationContext, SystemUISecondaryUserService::class.java) // Disconnect from the old secondary user's service val secondaryUserId = repository.secondaryUserId @@ -657,6 +664,7 @@ constructor( // Connect to the new secondary user's service (purely to ensure that a persistent // SystemUI application is created for that user) + if (userId != Process.myUserHandle().identifier) { applicationContext.startServiceAsUser( intent, diff --git a/packages/SystemUI/src/com/android/systemui/user/ui/viewmodel/UserSwitcherViewModel.kt b/packages/SystemUI/src/com/android/systemui/user/ui/viewmodel/UserSwitcherViewModel.kt index d3f83b1e18bd5131bdadd0f23f965317f029377b..20f0fa8cf46bb83b4cdf443d044bdc2e2e9e7ecc 100644 --- a/packages/SystemUI/src/com/android/systemui/user/ui/viewmodel/UserSwitcherViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/user/ui/viewmodel/UserSwitcherViewModel.kt @@ -68,6 +68,7 @@ constructor( private val hasCancelButtonBeenClicked = MutableStateFlow(false) private val isFinishRequiredDueToExecutedAction = MutableStateFlow(false) + private val userSwitched = MutableStateFlow(false) /** * Whether the observer should finish the experience. Once consumed, [onFinished] must be called @@ -89,6 +90,7 @@ constructor( fun onFinished() { hasCancelButtonBeenClicked.value = false isFinishRequiredDueToExecutedAction.value = false + userSwitched.value = false } /** Notifies that the user has clicked the "open menu" button. */ @@ -121,8 +123,9 @@ constructor( hasCancelButtonBeenClicked, // If an executed action told us to finish, we should finish, isFinishRequiredDueToExecutedAction, - ) { cancelButtonClicked, executedActionFinish -> - cancelButtonClicked || executedActionFinish + userSwitched, + ) { cancelButtonClicked, executedActionFinish, userSwitched -> + cancelButtonClicked || executedActionFinish || userSwitched } private fun toViewModel( @@ -191,7 +194,10 @@ constructor( return if (!model.isSelectable) { null } else { - { userInteractor.selectUser(model.id) } + { + userInteractor.selectUser(model.id) + userSwitched.value = true + } } } } diff --git a/packages/SystemUI/src/com/android/systemui/util/ReferenceExt.kt b/packages/SystemUI/src/com/android/systemui/util/ReferenceExt.kt new file mode 100644 index 0000000000000000000000000000000000000000..ac04d31041b6b09b82ed961d0b6af3f30fa48c35 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/util/ReferenceExt.kt @@ -0,0 +1,50 @@ +package com.android.systemui.util + +import java.lang.ref.SoftReference +import java.lang.ref.WeakReference +import kotlin.properties.ReadWriteProperty +import kotlin.reflect.KProperty + +/** + * Creates a Kotlin idiomatic weak reference. + * + * Usage: + * ``` + * var weakReferenceObj: Object? by weakReference(null) + * weakReferenceObj = Object() + * ``` + */ +fun <T> weakReference(obj: T? = null): ReadWriteProperty<Any?, T?> { + return object : ReadWriteProperty<Any?, T?> { + var weakRef = WeakReference<T?>(obj) + override fun getValue(thisRef: Any?, property: KProperty<*>): T? { + return weakRef.get() + } + + override fun setValue(thisRef: Any?, property: KProperty<*>, value: T?) { + weakRef = WeakReference(value) + } + } +} + +/** + * Creates a Kotlin idiomatic soft reference. + * + * Usage: + * ``` + * var softReferenceObj: Object? by softReference(null) + * softReferenceObj = Object() + * ``` + */ +fun <T> softReference(obj: T? = null): ReadWriteProperty<Any?, T?> { + return object : ReadWriteProperty<Any?, T?> { + var softRef = SoftReference<T?>(obj) + override fun getValue(thisRef: Any?, property: KProperty<*>): T? { + return softRef.get() + } + + override fun setValue(thisRef: Any?, property: KProperty<*>, value: T?) { + softRef = SoftReference(value) + } + } +} diff --git a/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletActivity.java b/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletActivity.java index 750b6f95d52e0b6f9df9592ff6e812600eeda551..2132904caa847c4635cb51d02f601223afe146a4 100644 --- a/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletActivity.java +++ b/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletActivity.java @@ -40,12 +40,13 @@ import com.android.internal.logging.UiEventLogger; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.keyguard.KeyguardUpdateMonitorCallback; import com.android.settingslib.Utils; -import com.android.systemui.res.R; import com.android.systemui.classifier.FalsingCollector; import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dagger.qualifiers.Main; +import com.android.systemui.keyguard.domain.interactor.KeyguardFaceAuthInteractor; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.FalsingManager; +import com.android.systemui.res.R; import com.android.systemui.settings.UserTracker; import com.android.systemui.statusbar.phone.KeyguardDismissUtil; import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager; @@ -68,6 +69,7 @@ public class WalletActivity extends ComponentActivity implements private final Executor mExecutor; private final Handler mHandler; private final FalsingManager mFalsingManager; + private final KeyguardFaceAuthInteractor mKeyguardFaceAuthInteractor; private FalsingCollector mFalsingCollector; private final UserTracker mUserTracker; private final KeyguardUpdateMonitor mKeyguardUpdateMonitor; @@ -91,7 +93,8 @@ public class WalletActivity extends ComponentActivity implements UserTracker userTracker, KeyguardUpdateMonitor keyguardUpdateMonitor, StatusBarKeyguardViewManager keyguardViewManager, - UiEventLogger uiEventLogger) { + UiEventLogger uiEventLogger, + KeyguardFaceAuthInteractor keyguardFaceAuthInteractor) { mKeyguardStateController = keyguardStateController; mKeyguardDismissUtil = keyguardDismissUtil; mActivityStarter = activityStarter; @@ -103,6 +106,7 @@ public class WalletActivity extends ComponentActivity implements mKeyguardUpdateMonitor = keyguardUpdateMonitor; mKeyguardViewManager = keyguardViewManager; mUiEventLogger = uiEventLogger; + mKeyguardFaceAuthInteractor = keyguardFaceAuthInteractor; } @Override @@ -209,6 +213,7 @@ public class WalletActivity extends ComponentActivity implements true, Utils.getColorAttrDefaultColor( this, com.android.internal.R.attr.colorAccentPrimary)); + mKeyguardFaceAuthInteractor.onWalletLaunched(); mKeyguardViewManager.requestFace(true); } diff --git a/packages/SystemUI/tests/src/com/android/TestMocksModule.kt b/packages/SystemUI/tests/src/com/android/TestMocksModule.kt index 8990583cf9de73575a67343aa126077d9710596d..c1be44ab8a8568c2e3a3ead1988e15d9aded2982 100644 --- a/packages/SystemUI/tests/src/com/android/TestMocksModule.kt +++ b/packages/SystemUI/tests/src/com/android/TestMocksModule.kt @@ -18,61 +18,94 @@ package com.android import android.app.ActivityManager import android.app.admin.DevicePolicyManager import android.os.UserManager +import android.util.DisplayMetrics +import com.android.internal.logging.MetricsLogger import com.android.keyguard.KeyguardSecurityModel import com.android.keyguard.KeyguardUpdateMonitor import com.android.systemui.GuestResumeSessionReceiver import com.android.systemui.demomode.DemoModeController +import com.android.systemui.dump.DumpManager +import com.android.systemui.keyguard.ScreenLifecycle +import com.android.systemui.keyguard.WakefulnessLifecycle import com.android.systemui.log.LogBuffer import com.android.systemui.log.dagger.BroadcastDispatcherLog import com.android.systemui.log.dagger.SceneFrameworkLog +import com.android.systemui.media.controls.ui.MediaHierarchyManager import com.android.systemui.plugins.ActivityStarter import com.android.systemui.plugins.DarkIconDispatcher import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.statusbar.NotificationListener +import com.android.systemui.statusbar.NotificationLockscreenUserManager import com.android.systemui.statusbar.NotificationMediaManager +import com.android.systemui.statusbar.NotificationShadeDepthController +import com.android.systemui.statusbar.SysuiStatusBarStateController import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator +import com.android.systemui.statusbar.notification.stack.AmbientState +import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController +import com.android.systemui.statusbar.notification.stack.NotificationStackSizeCalculator import com.android.systemui.statusbar.phone.DozeParameters import com.android.systemui.statusbar.phone.KeyguardBypassController +import com.android.systemui.statusbar.phone.LSShadeTransitionLogger import com.android.systemui.statusbar.phone.ScreenOffAnimationController -import com.android.systemui.statusbar.policy.ConfigurationController +import com.android.systemui.statusbar.phone.ScrimController import com.android.systemui.statusbar.policy.DeviceProvisionedController -import com.android.systemui.statusbar.policy.SplitShadeStateController import com.android.systemui.statusbar.window.StatusBarWindowController import com.android.systemui.util.mockito.mock import com.android.wm.shell.bubbles.Bubbles +import dagger.Binds import dagger.Module import dagger.Provides import java.util.Optional -@Module +@Module(includes = [TestMocksModule.Bindings::class]) data class TestMocksModule( @get:Provides val activityStarter: ActivityStarter = mock(), + @get:Provides val ambientState: AmbientState = mock(), @get:Provides val bubbles: Optional<Bubbles> = Optional.of(mock()), - @get:Provides val configurationController: ConfigurationController = mock(), @get:Provides val darkIconDispatcher: DarkIconDispatcher = mock(), @get:Provides val demoModeController: DemoModeController = mock(), @get:Provides val deviceProvisionedController: DeviceProvisionedController = mock(), @get:Provides val dozeParameters: DozeParameters = mock(), + @get:Provides val dumpManager: DumpManager = mock(), @get:Provides val guestResumeSessionReceiver: GuestResumeSessionReceiver = mock(), @get:Provides val keyguardBypassController: KeyguardBypassController = mock(), @get:Provides val keyguardSecurityModel: KeyguardSecurityModel = mock(), @get:Provides val keyguardUpdateMonitor: KeyguardUpdateMonitor = mock(), - @get:Provides val notifListener: NotificationListener = mock(), - @get:Provides val notifMediaManager: NotificationMediaManager = mock(), + @get:Provides val mediaHierarchyManager: MediaHierarchyManager = mock(), + @get:Provides val notificationListener: NotificationListener = mock(), + @get:Provides val notificationLockscreenUserManager: NotificationLockscreenUserManager = mock(), + @get:Provides val notificationMediaManager: NotificationMediaManager = mock(), + @get:Provides val notificationShadeDepthController: NotificationShadeDepthController = mock(), + @get:Provides + val notificationStackScrollLayoutController: NotificationStackScrollLayoutController = mock(), + @get:Provides val notificationStackSizeCalculator: NotificationStackSizeCalculator = mock(), + @get:Provides val notificationWakeUpCoordinator: NotificationWakeUpCoordinator = mock(), + @get:Provides val screenLifecycle: ScreenLifecycle = mock(), @get:Provides val screenOffAnimController: ScreenOffAnimationController = mock(), - @get:Provides val splitShadeStateController: SplitShadeStateController = mock(), - @get:Provides val statusBarStateController: StatusBarStateController = mock(), + @get:Provides val scrimController: ScrimController = mock(), + @get:Provides val statusBarStateController: SysuiStatusBarStateController = mock(), @get:Provides val statusBarWindowController: StatusBarWindowController = mock(), - @get:Provides val wakeUpCoordinator: NotificationWakeUpCoordinator = mock(), + @get:Provides val wakefulnessLifecycle: WakefulnessLifecycle = mock(), // log buffers @get:[Provides BroadcastDispatcherLog] val broadcastDispatcherLogger: LogBuffer = mock(), @get:[Provides SceneFrameworkLog] val sceneLogger: LogBuffer = mock(), + @get:Provides val lsShadeTransitionLogger: LSShadeTransitionLogger = mock(), // framework mocks @get:Provides val activityManager: ActivityManager = mock(), @get:Provides val devicePolicyManager: DevicePolicyManager = mock(), + @get:Provides val displayMetrics: DisplayMetrics = mock(), + @get:Provides val metricsLogger: MetricsLogger = mock(), @get:Provides val userManager: UserManager = mock(), -) +) { + @Module + interface Bindings { + @Binds + fun bindStatusBarStateController( + sysuiStatusBarStateController: SysuiStatusBarStateController, + ): StatusBarStateController + } +} diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPasswordViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPasswordViewControllerTest.kt index f943acd9180ea903e53e6112bdf5e16f2e166b0e..d8a2c5f76fcea1eeb38fc2b2f2a6a9c41c91c617 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPasswordViewControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPasswordViewControllerTest.kt @@ -25,7 +25,6 @@ import androidx.test.filters.SmallTest import com.android.internal.util.LatencyTracker import com.android.internal.widget.LockPatternUtils import com.android.systemui.res.R -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.classifier.FalsingCollector import com.android.systemui.flags.FakeFeatureFlags @@ -47,7 +46,6 @@ import org.mockito.Mockito.`when` import org.mockito.MockitoAnnotations @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) @TestableLooper.RunWithLooper class KeyguardPasswordViewControllerTest : SysuiTestCase() { diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt index e09009389f8bee8ae23e80b92dce104589f7b772..dc1618d128b3201a51e3ed573baf675f1be55b3e 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt @@ -25,7 +25,6 @@ import androidx.test.filters.SmallTest import com.android.internal.util.LatencyTracker import com.android.internal.widget.LockPatternUtils import com.android.systemui.res.R -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.classifier.FalsingCollector import com.android.systemui.classifier.FalsingCollectorFake @@ -53,7 +52,6 @@ import org.mockito.Mockito.`when` import org.mockito.MockitoAnnotations @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) @TestableLooper.RunWithLooper class KeyguardPatternViewControllerTest : SysuiTestCase() { diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinBasedInputViewControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinBasedInputViewControllerTest.java index 8322b37151ded35a497dcb1b7f1880ccb98f975b..4a24e4a1f40f6ae077da7d920c070577522ce7d1 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinBasedInputViewControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinBasedInputViewControllerTest.java @@ -31,14 +31,13 @@ import androidx.test.filters.SmallTest; import com.android.internal.util.LatencyTracker; import com.android.internal.widget.LockPatternUtils; import com.android.keyguard.KeyguardSecurityModel.SecurityMode; -import com.android.systemui.res.R; -import com.android.systemui.RoboPilotTest; import com.android.systemui.SysuiTestCase; import com.android.systemui.classifier.FalsingCollector; import com.android.systemui.classifier.FalsingCollectorFake; import com.android.systemui.classifier.SingleTapClassifier; import com.android.systemui.flags.FakeFeatureFlags; import com.android.systemui.flags.Flags; +import com.android.systemui.res.R; import org.junit.Before; import org.junit.Test; @@ -47,7 +46,6 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4.class) @RunWithLooper public class KeyguardPinBasedInputViewControllerTest extends SysuiTestCase { diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinViewControllerTest.kt index 2f08804d8c051ee00e0de4f94f2e465f172b46dd..9df4dd4df4d2908175c56ffafcf5ae99f1436e55 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinViewControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinViewControllerTest.kt @@ -26,7 +26,6 @@ import com.android.internal.util.LatencyTracker import com.android.internal.widget.LockPatternUtils import com.android.keyguard.KeyguardSecurityModel.SecurityMode import com.android.systemui.res.R -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.classifier.FalsingCollector import com.android.systemui.classifier.FalsingCollectorFake @@ -53,7 +52,6 @@ import org.mockito.Mockito.`when` import org.mockito.MockitoAnnotations @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) @TestableLooper.RunWithLooper class KeyguardPinViewControllerTest : SysuiTestCase() { diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.kt index d54843d39d212abea7c22261fd9e094e7263cbbb..62f9a9dcce70a9c22f4fb2688d2394b6142eb756 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.kt @@ -36,7 +36,6 @@ import com.android.internal.logging.UiEventLogger import com.android.internal.widget.LockPatternUtils import com.android.keyguard.KeyguardSecurityContainer.UserSwitcherViewMode.UserSwitcherCallback import com.android.keyguard.KeyguardSecurityModel.SecurityMode -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.biometrics.FaceAuthAccessibilityDelegate import com.android.systemui.biometrics.SideFpsController @@ -100,7 +99,6 @@ import org.mockito.Mockito.verify import org.mockito.MockitoAnnotations @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) @RunWithLooper class KeyguardSecurityContainerControllerTest : SysuiTestCase() { @@ -812,6 +810,7 @@ class KeyguardSecurityContainerControllerTest : SysuiTestCase() { SceneKey.Bouncer, flowOf(.5f), false, + isUserInputOngoing = flowOf(false), ) runCurrent() sceneInteractor.onSceneChanged(SceneModel(SceneKey.Bouncer, null), "reason") @@ -827,7 +826,8 @@ class KeyguardSecurityContainerControllerTest : SysuiTestCase() { SceneKey.Bouncer, SceneKey.Gone, flowOf(.5f), - false + false, + isUserInputOngoing = flowOf(false), ) runCurrent() sceneInteractor.onSceneChanged(SceneModel(SceneKey.Gone, null), "reason") @@ -844,7 +844,8 @@ class KeyguardSecurityContainerControllerTest : SysuiTestCase() { SceneKey.Gone, SceneKey.Bouncer, flowOf(.5f), - false + false, + isUserInputOngoing = flowOf(false), ) runCurrent() sceneInteractor.onSceneChanged(SceneModel(SceneKey.Bouncer, null), "reason") @@ -862,7 +863,8 @@ class KeyguardSecurityContainerControllerTest : SysuiTestCase() { SceneKey.Bouncer, SceneKey.Gone, flowOf(.5f), - false + false, + isUserInputOngoing = flowOf(false), ) runCurrent() sceneInteractor.onSceneChanged(SceneModel(SceneKey.Gone, null), "reason") @@ -878,6 +880,7 @@ class KeyguardSecurityContainerControllerTest : SysuiTestCase() { SceneKey.Lockscreen, flowOf(.5f), false, + isUserInputOngoing = flowOf(false), ) runCurrent() sceneInteractor.onSceneChanged(SceneModel(SceneKey.Lockscreen, null), "reason") @@ -895,6 +898,7 @@ class KeyguardSecurityContainerControllerTest : SysuiTestCase() { SceneKey.Gone, flowOf(.5f), false, + isUserInputOngoing = flowOf(false), ) runCurrent() sceneInteractor.onSceneChanged(SceneModel(SceneKey.Gone, null), "reason") diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java index aad11d90f5a43d320d722b1b1ff300e4207131cc..156e06843d15df1952728095c6324d700a1951e3 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java @@ -56,11 +56,10 @@ import androidx.constraintlayout.widget.ConstraintSet; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; -import com.android.systemui.res.R; -import com.android.systemui.RoboPilotTest; import com.android.systemui.SysuiTestCase; import com.android.systemui.classifier.FalsingA11yDelegate; import com.android.systemui.plugins.FalsingManager; +import com.android.systemui.res.R; import com.android.systemui.statusbar.policy.UserSwitcherController; import com.android.systemui.user.data.source.UserRecord; import com.android.systemui.util.settings.GlobalSettings; @@ -76,7 +75,6 @@ import org.mockito.junit.MockitoRule; import java.util.ArrayList; @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4.class) @TestableLooper.RunWithLooper() public class KeyguardSecurityContainerTest extends SysuiTestCase { diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityViewFlipperControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityViewFlipperControllerTest.java index b02b1f9df9fbcba821f47d630b4c7b5f2ff5335b..7bb6ef1c889589b3189dab3b66116db20e3ba4f6 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityViewFlipperControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityViewFlipperControllerTest.java @@ -35,10 +35,9 @@ import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; import com.android.keyguard.KeyguardSecurityModel.SecurityMode; -import com.android.systemui.res.R; -import com.android.systemui.RoboPilotTest; import com.android.systemui.SysuiTestCase; import com.android.systemui.flags.FeatureFlags; +import com.android.systemui.res.R; import org.junit.Before; import org.junit.Rule; @@ -50,7 +49,6 @@ import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4.class) @TestableLooper.RunWithLooper() public class KeyguardSecurityViewFlipperControllerTest extends SysuiTestCase { diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSimPinViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSimPinViewControllerTest.kt index d0bb5a9993271a5e9354dd5900e4eb15a76c9848..4290b8b28687cb442ba119093eac9a4a05e9a88e 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSimPinViewControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSimPinViewControllerTest.kt @@ -25,7 +25,6 @@ import androidx.test.filters.SmallTest import com.android.internal.util.LatencyTracker import com.android.internal.widget.LockPatternUtils import com.android.systemui.res.R -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.classifier.FalsingCollector import com.android.systemui.flags.FakeFeatureFlags @@ -44,7 +43,6 @@ import org.mockito.Mockito.`when` import org.mockito.MockitoAnnotations @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) @TestableLooper.RunWithLooper class KeyguardSimPinViewControllerTest : SysuiTestCase() { diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSimPukViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSimPukViewControllerTest.kt index 59cd26cc6b9be0653fc8e61d7d0a0f6933e7c42f..31ee6411f93b55965de7e5b555e23fc2b1b7924a 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSimPukViewControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSimPukViewControllerTest.kt @@ -25,7 +25,6 @@ import androidx.test.filters.SmallTest import com.android.internal.util.LatencyTracker import com.android.internal.widget.LockPatternUtils import com.android.systemui.res.R -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.classifier.FalsingCollector import com.android.systemui.flags.FakeFeatureFlags @@ -40,7 +39,6 @@ import org.mockito.Mockito import org.mockito.MockitoAnnotations @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) @TestableLooper.RunWithLooper class KeyguardSimPukViewControllerTest : SysuiTestCase() { diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java index e4e2b0a8d89f1b79efc291dbfef3d96f48cd1ed0..9a908d778943fb1b57ad31060996696c79ee82e3 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java @@ -29,9 +29,9 @@ import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.view.View; -import com.android.systemui.res.R; import com.android.systemui.plugins.ClockConfig; import com.android.systemui.plugins.ClockController; +import com.android.systemui.res.R; import com.android.systemui.statusbar.notification.AnimatableProperty; import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener; @@ -81,7 +81,7 @@ public class KeyguardStatusViewControllerTest extends KeyguardStatusViewControll public void updatePosition_primaryClockAnimation() { ClockController mockClock = mock(ClockController.class); when(mKeyguardClockSwitchController.getClock()).thenReturn(mockClock); - when(mockClock.getConfig()).thenReturn(new ClockConfig("MOCK", false, true)); + when(mockClock.getConfig()).thenReturn(new ClockConfig("MOCK", "", "", false, true)); mController.updatePosition(10, 15, 20f, true); @@ -96,7 +96,7 @@ public class KeyguardStatusViewControllerTest extends KeyguardStatusViewControll public void updatePosition_alternateClockAnimation() { ClockController mockClock = mock(ClockController.class); when(mKeyguardClockSwitchController.getClock()).thenReturn(mockClock); - when(mockClock.getConfig()).thenReturn(new ClockConfig("MOCK", true, true)); + when(mockClock.getConfig()).thenReturn(new ClockConfig("MOCK", "", "", true, true)); mController.updatePosition(10, 15, 20f, true); diff --git a/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityLaunchAnimatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityLaunchAnimatorTest.kt index 59c7e7669b63ccb8d93f7f2c452315a83108ecdb..8faf715521f8232594f11f7aa9a055a8f417543f 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityLaunchAnimatorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityLaunchAnimatorTest.kt @@ -166,6 +166,9 @@ class ActivityLaunchAnimatorTest : SysuiTestCase() { waitForIdleSync() verify(controller).onLaunchAnimationCancelled() verify(controller, never()).onLaunchAnimationStart(anyBoolean()) + verify(listener).onLaunchAnimationCancelled() + verify(listener, never()).onLaunchAnimationStart() + assertNull(runner.delegate) } @Test @@ -176,6 +179,9 @@ class ActivityLaunchAnimatorTest : SysuiTestCase() { waitForIdleSync() verify(controller).onLaunchAnimationCancelled() verify(controller, never()).onLaunchAnimationStart(anyBoolean()) + verify(listener).onLaunchAnimationCancelled() + verify(listener, never()).onLaunchAnimationStart() + assertNull(runner.delegate) } @Test @@ -194,6 +200,15 @@ class ActivityLaunchAnimatorTest : SysuiTestCase() { } } + @Test + fun disposeRunner_delegateDereferenced() { + val runner = activityLaunchAnimator.createRunner(controller) + assertNotNull(runner.delegate) + runner.dispose() + waitForIdleSync() + assertNull(runner.delegate) + } + private fun fakeWindow(): RemoteAnimationTarget { val bounds = Rect(10 /* left */, 20 /* top */, 30 /* right */, 40 /* bottom */) val taskInfo = ActivityManager.RunningTaskInfo() diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java index 2bc0171939b4e88fd98360b36b7d0b35e1d7a495..885abcb72f1a4b4a140c424aea2a0ffee9a212d1 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java @@ -17,12 +17,15 @@ package com.android.systemui.biometrics; import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT; + import static com.google.common.truth.Truth.assertThat; + import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertFalse; import static junit.framework.Assert.assertNotSame; import static junit.framework.Assert.assertNull; import static junit.framework.Assert.assertTrue; + import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyLong; @@ -79,7 +82,6 @@ import androidx.test.filters.SmallTest; import com.android.internal.R; import com.android.internal.jank.InteractionJankMonitor; import com.android.internal.widget.LockPatternUtils; -import com.android.systemui.RoboPilotTest; import com.android.systemui.SysuiTestCase; import com.android.systemui.biometrics.domain.interactor.LogContextInteractor; import com.android.systemui.biometrics.domain.interactor.PromptCredentialInteractor; @@ -114,7 +116,6 @@ import java.util.Random; @RunWith(AndroidJUnit4.class) @RunWithLooper @SmallTest -@RoboPilotTest public class AuthControllerTest extends SysuiTestCase { private static final long REQUEST_ID = 22; diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthDialogPanelInteractionDetectorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthDialogPanelInteractionDetectorTest.kt index 73654609ad7f3fdbf35215474fa3dce77d4f14dd..d68a3131da4c286e36be1017bb2bbe40b9728d10 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthDialogPanelInteractionDetectorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthDialogPanelInteractionDetectorTest.kt @@ -16,36 +16,18 @@ package com.android.systemui.biometrics -import android.app.ActivityManager -import android.os.UserManager import androidx.test.filters.SmallTest -import com.android.internal.logging.UiEventLogger -import com.android.keyguard.KeyguardUpdateMonitor +import com.android.SysUITestModule import com.android.systemui.SysuiTestCase -import com.android.systemui.common.ui.data.repository.FakeConfigurationRepository -import com.android.systemui.flags.FakeFeatureFlags +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.flags.FakeFeatureFlagsClassicModule import com.android.systemui.flags.Flags -import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository -import com.android.systemui.keyguard.domain.interactor.KeyguardInteractorFactory -import com.android.systemui.plugins.ActivityStarter -import com.android.systemui.scene.SceneTestUtils -import com.android.systemui.scene.shared.flag.FakeSceneContainerFlags import com.android.systemui.shade.data.repository.FakeShadeRepository -import com.android.systemui.shade.domain.interactor.ShadeInteractor -import com.android.systemui.statusbar.disableflags.data.repository.FakeDisableFlagsRepository -import com.android.systemui.statusbar.notification.stack.domain.interactor.SharedNotificationContainerInteractor -import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeUserSetupRepository -import com.android.systemui.statusbar.policy.DeviceProvisionedController -import com.android.systemui.statusbar.policy.ResourcesSplitShadeStateController -import com.android.systemui.telephony.data.repository.FakeTelephonyRepository -import com.android.systemui.telephony.domain.interactor.TelephonyInteractor -import com.android.systemui.user.data.repository.FakeUserRepository -import com.android.systemui.user.domain.interactor.GuestUserInteractor -import com.android.systemui.user.domain.interactor.HeadlessSystemUserMode -import com.android.systemui.user.domain.interactor.RefreshUsersScheduler -import com.android.systemui.user.domain.interactor.UserInteractor -import com.android.systemui.util.mockito.mock +import com.android.systemui.user.domain.UserDomainLayerModule +import dagger.BindsInstance +import dagger.Component import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest import org.junit.Before @@ -58,91 +40,27 @@ import org.mockito.MockitoAnnotations @SmallTest @OptIn(ExperimentalCoroutinesApi::class) class AuthDialogPanelInteractionDetectorTest : SysuiTestCase() { - private val utils = SceneTestUtils(this) - private val testScope = utils.testScope - private val testDispatcher = utils.testDispatcher - private val disableFlagsRepository = FakeDisableFlagsRepository() - private val featureFlags = FakeFeatureFlags() - private val keyguardRepository = FakeKeyguardRepository() - private val shadeRepository = FakeShadeRepository() - private val sceneContainerFlags = FakeSceneContainerFlags() - private val sceneInteractor = utils.sceneInteractor() - private val userSetupRepository = FakeUserSetupRepository() - private val userRepository = FakeUserRepository() - private val configurationRepository = FakeConfigurationRepository() - private val sharedNotificationContainerInteractor = - SharedNotificationContainerInteractor( - configurationRepository, - mContext, - ResourcesSplitShadeStateController() - ) - - private lateinit var detector: AuthDialogPanelInteractionDetector - private lateinit var shadeInteractor: ShadeInteractor - private lateinit var userInteractor: UserInteractor + + private val testComponent: TestComponent = + DaggerAuthDialogPanelInteractionDetectorTest_TestComponent.factory() + .create( + test = this, + featureFlags = + FakeFeatureFlagsClassicModule { + set(Flags.FACE_AUTH_REFACTOR, false) + set(Flags.FULL_SCREEN_USER_SWITCHER, true) + }, + ) @Mock private lateinit var action: Runnable - @Mock private lateinit var activityManager: ActivityManager - @Mock private lateinit var activityStarter: ActivityStarter - @Mock private lateinit var deviceProvisionedController: DeviceProvisionedController - @Mock private lateinit var guestInteractor: GuestUserInteractor - @Mock private lateinit var headlessSystemUserMode: HeadlessSystemUserMode - @Mock private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor - @Mock private lateinit var manager: UserManager - @Mock private lateinit var uiEventLogger: UiEventLogger + + private val testScope = testComponent.testScope + private val shadeRepository = testComponent.shadeRepository + private val detector = testComponent.detector @Before fun setUp() { MockitoAnnotations.initMocks(this) - - featureFlags.set(Flags.FACE_AUTH_REFACTOR, false) - featureFlags.set(Flags.FULL_SCREEN_USER_SWITCHER, true) - - val refreshUsersScheduler = - RefreshUsersScheduler( - applicationScope = testScope.backgroundScope, - mainDispatcher = testDispatcher, - repository = userRepository, - ) - userInteractor = - UserInteractor( - applicationContext = context, - repository = userRepository, - activityStarter = activityStarter, - keyguardInteractor = - KeyguardInteractorFactory.create(featureFlags = featureFlags) - .keyguardInteractor, - featureFlags = featureFlags, - manager = manager, - headlessSystemUserMode = headlessSystemUserMode, - applicationScope = testScope.backgroundScope, - telephonyInteractor = - TelephonyInteractor( - repository = FakeTelephonyRepository(), - ), - broadcastDispatcher = fakeBroadcastDispatcher, - keyguardUpdateMonitor = keyguardUpdateMonitor, - backgroundDispatcher = testDispatcher, - activityManager = activityManager, - refreshUsersScheduler = refreshUsersScheduler, - guestUserInteractor = guestInteractor, - uiEventLogger = uiEventLogger, - userRestrictionChecker = mock(), - ) - shadeInteractor = - ShadeInteractor( - testScope.backgroundScope, - disableFlagsRepository, - sceneContainerFlags, - { sceneInteractor }, - keyguardRepository, - userSetupRepository, - deviceProvisionedController, - userInteractor, - sharedNotificationContainerInteractor, - shadeRepository, - ) - detector = AuthDialogPanelInteractionDetector(testScope, { shadeInteractor }) } @Test @@ -215,4 +133,27 @@ class AuthDialogPanelInteractionDetectorTest : SysuiTestCase() { // Clean up job detector.disable() } + + @SysUISingleton + @Component( + modules = + [ + SysUITestModule::class, + UserDomainLayerModule::class, + ] + ) + interface TestComponent { + + val detector: AuthDialogPanelInteractionDetector + val shadeRepository: FakeShadeRepository + val testScope: TestScope + + @Component.Factory + interface Factory { + fun create( + @BindsInstance test: SysuiTestCase, + featureFlags: FakeFeatureFlagsClassicModule, + ): TestComponent + } + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/BiometricDisplayListenerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/BiometricDisplayListenerTest.java index 8547fa33c9de487272031bc829de854c4f4670bb..714461b715d6f97c225c962208893cae91a72e3e 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/BiometricDisplayListenerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/BiometricDisplayListenerTest.java @@ -38,7 +38,6 @@ import android.view.Surface; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; -import com.android.systemui.RoboPilotTest; import com.android.systemui.SysuiTestCase; import kotlin.Unit; @@ -53,7 +52,6 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4.class) @RunWithLooper(setAsMainLooper = true) public class BiometricDisplayListenerTest extends SysuiTestCase { diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/FaceHelpMessageDeferralTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/FaceHelpMessageDeferralTest.kt index ab5d8bea585b5a0b630567c602285796ca40c138..39f0d570cb261458a84cb1289418cadfb0bcb841 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/FaceHelpMessageDeferralTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/FaceHelpMessageDeferralTest.kt @@ -19,7 +19,6 @@ package com.android.systemui.biometrics import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.keyguard.logging.BiometricMessageDeferralLogger -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.dump.DumpManager import org.junit.Assert.assertEquals @@ -34,7 +33,6 @@ import org.mockito.Mockito.verify import org.mockito.MockitoAnnotations @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) class FaceHelpMessageDeferralTest : SysuiTestCase() { val threshold = .75f diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/SideFpsControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/SideFpsControllerTest.kt index 57cf834bfa38b14071cfd8682cc0aa4572eb4a61..ef06e0efa01d10a3ae9d472f358c8fb76a35ec88 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/SideFpsControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/SideFpsControllerTest.kt @@ -53,7 +53,6 @@ import androidx.test.filters.SmallTest import com.airbnb.lottie.LottieAnimationView import com.android.keyguard.KeyguardUpdateMonitor import com.android.systemui.res.R -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.SysuiTestableContext import com.android.systemui.biometrics.data.repository.FakeDisplayStateRepository @@ -98,7 +97,6 @@ private const val SENSOR_ID = 1 private const val REAR_DISPLAY_MODE_DEVICE_STATE = 3 @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) @TestableLooper.RunWithLooper class SideFpsControllerTest : SysuiTestCase() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsBpViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsBpViewControllerTest.kt index 469f65a6cae553d83e149229572856c58de02596..e2aa984de46b37ab0be512d7b8a667af6b6cbf9f 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsBpViewControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsBpViewControllerTest.kt @@ -19,7 +19,6 @@ package com.android.systemui.biometrics import android.testing.TestableLooper import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor import com.android.systemui.dump.DumpManager @@ -35,7 +34,6 @@ import org.mockito.Mock import org.mockito.junit.MockitoJUnit @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) @TestableLooper.RunWithLooper class UdfpsBpViewControllerTest : SysuiTestCase() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt index 21e614f3db3a59af3f381955976c3d3b07e69f77..e9e9624580b3a7db5564c0191790298442b3aca9 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt @@ -38,7 +38,6 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.keyguard.KeyguardUpdateMonitor import com.android.systemui.res.R -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.animation.ActivityLaunchAnimator import com.android.systemui.biometrics.shared.model.UdfpsOverlayParams @@ -83,7 +82,6 @@ private const val SENSOR_HEIGHT = 60 @ExperimentalCoroutinesApi @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) @RunWithLooper(setAsMainLooper = true) class UdfpsControllerOverlayTest : SysuiTestCase() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java index ee3bd0d79ad87bd6e2ce4ed736a10e6be19b0695..a36f4e9ac2176792930687a5d01472f2a4fce7f6 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java @@ -20,12 +20,15 @@ import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPR import static android.view.MotionEvent.ACTION_DOWN; import static android.view.MotionEvent.ACTION_MOVE; import static android.view.MotionEvent.ACTION_UP; + import static com.android.internal.util.FunctionalUtils.ThrowingConsumer; import static com.android.systemui.classifier.Classifier.UDFPS_AUTHENTICATION; import static com.android.systemui.flags.Flags.ONE_WAY_HAPTICS_API_MIGRATION; + import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertFalse; import static junit.framework.Assert.assertTrue; + import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyFloat; @@ -74,8 +77,6 @@ import androidx.test.filters.SmallTest; import com.android.internal.logging.InstanceIdSequence; import com.android.internal.util.LatencyTracker; import com.android.keyguard.KeyguardUpdateMonitor; -import com.android.systemui.res.R; -import com.android.systemui.RoboPilotTest; import com.android.systemui.SysuiTestCase; import com.android.systemui.animation.ActivityLaunchAnimator; import com.android.systemui.biometrics.shared.model.UdfpsOverlayParams; @@ -94,6 +95,7 @@ import com.android.systemui.keyguard.ui.viewmodel.UdfpsKeyguardViewModels; import com.android.systemui.log.SessionTracker; import com.android.systemui.plugins.FalsingManager; import com.android.systemui.plugins.statusbar.StatusBarStateController; +import com.android.systemui.res.R; import com.android.systemui.statusbar.LockscreenShadeTransitionController; import com.android.systemui.statusbar.VibratorHelper; import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager; @@ -125,7 +127,6 @@ import java.util.Optional; import javax.inject.Provider; @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4.class) @RunWithLooper(setAsMainLooper = true) public class UdfpsControllerTest extends SysuiTestCase { diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsDialogMeasureAdapterTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsDialogMeasureAdapterTest.java index 280bfdf1aa8ccae879582fd6f2267126346f5844..cd9189bef7f189c5901fde10946946dd1c61e4b5 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsDialogMeasureAdapterTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsDialogMeasureAdapterTest.java @@ -27,7 +27,6 @@ import android.hardware.fingerprint.FingerprintSensorPropertiesInternal; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; -import com.android.systemui.RoboPilotTest; import com.android.systemui.SysuiTestCase; import org.junit.Test; @@ -38,7 +37,6 @@ import java.util.List; @RunWith(AndroidJUnit4.class) @SmallTest -@RoboPilotTest public class UdfpsDialogMeasureAdapterTest extends SysuiTestCase { @Test public void testUdfpsBottomSpacerHeightForPortrait() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsDisplayModeTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsDisplayModeTest.java index 1afb223b408953db417006b0c023c37a9dd7b9e7..5239966f192302c3f2e442cce9854782daa0b2cc 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsDisplayModeTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsDisplayModeTest.java @@ -30,7 +30,6 @@ import android.testing.TestableLooper.RunWithLooper; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; -import com.android.systemui.RoboPilotTest; import com.android.systemui.SysuiTestCase; import com.android.systemui.util.concurrency.FakeExecution; @@ -41,7 +40,6 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4.class) @RunWithLooper(setAsMainLooper = true) public class UdfpsDisplayModeTest extends SysuiTestCase { diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerTest.java index 8508f45b02f3288739c498808de6ae4cb8d7338c..b018a3e2ca6cf1e6d4fb69ea49b896bd424b9c10 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerTest.java @@ -31,14 +31,12 @@ import android.view.MotionEvent; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; -import com.android.systemui.RoboPilotTest; import com.android.systemui.statusbar.StatusBarState; import org.junit.Test; import org.junit.runner.RunWith; @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4.class) @TestableLooper.RunWithLooper(setAsMainLooper = true) diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerWithCoroutinesTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerWithCoroutinesTest.kt index 17f435b75d5a1e1fe0797c1051988aa76ec3a49d..da4548bc14c0158ce6812d378126b54581b06223 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerWithCoroutinesTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerWithCoroutinesTest.kt @@ -21,7 +21,6 @@ import android.testing.TestableLooper import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.keyguard.KeyguardSecurityModel -import com.android.systemui.RoboPilotTest import com.android.systemui.bouncer.data.repository.KeyguardBouncerRepository import com.android.systemui.bouncer.data.repository.KeyguardBouncerRepositoryImpl import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor @@ -58,7 +57,6 @@ import org.mockito.MockitoAnnotations @RunWith(AndroidJUnit4::class) @SmallTest -@RoboPilotTest @TestableLooper.RunWithLooper @kotlinx.coroutines.ExperimentalCoroutinesApi class UdfpsKeyguardViewLegacyControllerWithCoroutinesTest : diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsShellTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsShellTest.kt index 6d552544fee7748b58fb3bb0c66b35aa7020faab..8b374ae541271536473177d2530dc698cb08216b 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsShellTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsShellTest.kt @@ -21,7 +21,6 @@ import android.testing.TestableLooper import android.view.MotionEvent import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.biometrics.UdfpsController.UdfpsOverlayController import com.android.systemui.statusbar.commandline.CommandRegistry @@ -40,7 +39,6 @@ import org.mockito.Mockito.`when` as whenEver import org.mockito.junit.MockitoJUnit @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) @TestableLooper.RunWithLooper class UdfpsShellTest : SysuiTestCase() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsViewTest.kt index ebadfc78a079c8e9472e4b4db6e6827ba8ef0d26..0c8e7a5d356af37574d5696279bb8e6e64a9ad67 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsViewTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsViewTest.kt @@ -26,7 +26,6 @@ import android.view.Surface import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.res.R -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.biometrics.shared.model.UdfpsOverlayParams import com.android.systemui.util.mockito.any @@ -50,7 +49,6 @@ private const val SENSOR_Y = 250 private const val SENSOR_RADIUS = 10 @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) @TestableLooper.RunWithLooper class UdfpsViewTest : SysuiTestCase() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractorTest.kt index 0d172706b127954794f729f39d0548e14b27f54d..2d8adca04a5e61e4aef94304ba4aba8b8b2ce0fb 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractorTest.kt @@ -19,7 +19,6 @@ package com.android.systemui.bouncer.domain.interactor import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.keyguard.KeyguardUpdateMonitor -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.bouncer.data.repository.KeyguardBouncerRepository import com.android.systemui.bouncer.data.repository.KeyguardBouncerRepositoryImpl @@ -43,7 +42,6 @@ import org.mockito.MockitoAnnotations @OptIn(ExperimentalCoroutinesApi::class) @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) class AlternateBouncerInteractorTest : SysuiTestCase() { private lateinit var underTest: AlternateBouncerInteractor diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerCallbackInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerCallbackInteractorTest.kt index a81ca86f338d4a6b74fd3110de9baa006723b0e6..4aea4f329858e6c441b0c3eb4f9127336462486c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerCallbackInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerCallbackInteractorTest.kt @@ -19,7 +19,6 @@ package com.android.systemui.bouncer.domain.interactor import android.view.View import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import org.junit.Before import org.junit.Test @@ -29,7 +28,6 @@ import org.mockito.Mockito.verify import org.mockito.MockitoAnnotations @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) class PrimaryBouncerCallbackInteractorTest : SysuiTestCase() { private val mPrimaryBouncerCallbackInteractor = PrimaryBouncerCallbackInteractor() diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerInteractorWithCoroutinesTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerInteractorWithCoroutinesTest.kt index cb0b74f3015d2a922ff32f2005e5fd9faca1fe3b..2018e614ba00b59e4f6f737ce60a1b40a8c5ea1f 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerInteractorWithCoroutinesTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerInteractorWithCoroutinesTest.kt @@ -21,7 +21,6 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.keyguard.KeyguardSecurityModel import com.android.keyguard.KeyguardUpdateMonitor -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.bouncer.data.repository.FakeKeyguardBouncerRepository import com.android.systemui.bouncer.ui.BouncerView @@ -43,7 +42,6 @@ import org.mockito.Mockito import org.mockito.MockitoAnnotations @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) class PrimaryBouncerInteractorWithCoroutinesTest : SysuiTestCase() { private lateinit var repository: FakeKeyguardBouncerRepository diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/KeyguardBouncerViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/KeyguardBouncerViewModelTest.kt index 333bd214fe9a4428314825b5f306d7e623b1d883..802f8e6043fde3cf31eb374ab1ae8eb33f9263ca 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/KeyguardBouncerViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/KeyguardBouncerViewModelTest.kt @@ -21,7 +21,6 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.keyguard.KeyguardSecurityModel import com.android.keyguard.KeyguardUpdateMonitor -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.bouncer.data.repository.FakeKeyguardBouncerRepository import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerCallbackInteractor @@ -50,7 +49,6 @@ import org.mockito.Mockito import org.mockito.MockitoAnnotations @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) @kotlinx.coroutines.ExperimentalCoroutinesApi class KeyguardBouncerViewModelTest : SysuiTestCase() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/communal/data/repository/CommunalWidgetRepositoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/communal/data/repository/CommunalWidgetRepositoryImplTest.kt index 7fa828fbfaddd4a6b8ab0d344e688a0d50ea2c7c..3df9cbb29e4aeb17a0897983913a7fbbdae6f9c4 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/communal/data/repository/CommunalWidgetRepositoryImplTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/communal/data/repository/CommunalWidgetRepositoryImplTest.kt @@ -9,7 +9,6 @@ import android.os.UserHandle import android.os.UserManager import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.broadcast.BroadcastDispatcher import com.android.systemui.coroutines.collectLastValue @@ -40,7 +39,6 @@ import org.mockito.MockitoAnnotations @OptIn(ExperimentalCoroutinesApi::class) @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) class CommunalWidgetRepositoryImplTest : SysuiTestCase() { @Mock private lateinit var appWidgetManager: AppWidgetManager diff --git a/packages/SystemUI/tests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt index ddf788e47bf29e775478a8a1e56a8f16fb078fb0..cdc42e09683080583ecf56d0b03179a333a324f5 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt @@ -19,7 +19,6 @@ package com.android.systemui.communal.domain.interactor import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.communal.data.repository.FakeCommunalRepository import com.android.systemui.communal.data.repository.FakeCommunalWidgetRepository @@ -37,7 +36,6 @@ import org.mockito.Mock import org.mockito.MockitoAnnotations @SmallTest -@RoboPilotTest @OptIn(ExperimentalCoroutinesApi::class) @RunWith(AndroidJUnit4::class) class CommunalInteractorTest : SysuiTestCase() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/communal/ui/view/layout/blueprints/DefaultCommunalBlueprintTest.kt b/packages/SystemUI/tests/src/com/android/systemui/communal/ui/view/layout/blueprints/DefaultCommunalBlueprintTest.kt index a10eb295476e965a9e5f877d55a60de25e2bed0a..41a8be9663b7b38cfe1b83c265cf28bec955d5c9 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/communal/ui/view/layout/blueprints/DefaultCommunalBlueprintTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/communal/ui/view/layout/blueprints/DefaultCommunalBlueprintTest.kt @@ -5,7 +5,6 @@ import androidx.constraintlayout.widget.ConstraintLayout import androidx.constraintlayout.widget.ConstraintSet import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.communal.ui.view.layout.sections.DefaultCommunalWidgetSection import org.junit.Before @@ -15,7 +14,6 @@ import org.mockito.Mock import org.mockito.Mockito.verify import org.mockito.MockitoAnnotations -@RoboPilotTest @RunWith(AndroidJUnit4::class) @TestableLooper.RunWithLooper(setAsMainLooper = true) @SmallTest diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayAnimationsControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayAnimationsControllerTest.kt index 781ad6b10b70e684dc8696ba031bf57c6f77c4d3..8a35ef11a3647bc9ef2478c48ef6f498260ec335 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayAnimationsControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayAnimationsControllerTest.kt @@ -6,7 +6,6 @@ import android.animation.ValueAnimator import android.view.View import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.complication.ComplicationHostViewController import com.android.systemui.keyguard.ui.viewmodel.DreamingToLockscreenTransitionViewModel @@ -30,7 +29,6 @@ import org.mockito.Mockito.times import org.mockito.Mockito.verify import org.mockito.MockitoAnnotations -@RoboPilotTest @SmallTest @RunWith(AndroidJUnit4::class) class DreamOverlayAnimationsControllerTest : SysuiTestCase() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayCallbackControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayCallbackControllerTest.kt index 21192fa11da3d511f6b56be73a79ef89083de5dc..2c6c793c97f5a7c8a147bfa29ab35a53c1015ff9 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayCallbackControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayCallbackControllerTest.kt @@ -17,7 +17,6 @@ package com.android.systemui.dreams import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.google.common.truth.Truth.assertThat import org.junit.Before @@ -30,7 +29,6 @@ import org.mockito.Mockito.times import org.mockito.Mockito.verify import org.mockito.MockitoAnnotations -@RoboPilotTest @SmallTest @RunWith(AndroidJUnit4::class) class DreamOverlayCallbackControllerTest : SysuiTestCase() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayContainerViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayContainerViewControllerTest.java index 7c36642f5417f3ba4eecf575c95cca83038371a0..2af6566e993a2d94f271ff0c160d3ba2d9d4a4d7 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayContainerViewControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayContainerViewControllerTest.java @@ -38,7 +38,6 @@ import androidx.test.filters.SmallTest; import com.android.dream.lowlight.LowLightTransitionCoordinator; import com.android.keyguard.BouncerPanelExpansionCalculator; -import com.android.systemui.RoboPilotTest; import com.android.systemui.SysuiTestCase; import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerCallbackInteractor; import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerCallbackInteractor.PrimaryBouncerExpansionCallback; @@ -53,7 +52,6 @@ import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; -@RoboPilotTest @SmallTest @RunWith(AndroidJUnit4.class) public class DreamOverlayContainerViewControllerTest extends SysuiTestCase { diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayNotificationCountProviderTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayNotificationCountProviderTest.java index be7638ef31e679cb2e00ae8e5a3ef51bc0c21b81..d379dc6f3dc1a12bec504f3855134dcb300f5703 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayNotificationCountProviderTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayNotificationCountProviderTest.java @@ -26,7 +26,6 @@ import android.service.notification.StatusBarNotification; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; -import com.android.systemui.RoboPilotTest; import com.android.systemui.SysuiTestCase; import com.android.systemui.statusbar.NotificationListener; import com.android.systemui.statusbar.NotificationListener.NotificationHandler; @@ -38,7 +37,6 @@ import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; -@RoboPilotTest @SmallTest @RunWith(AndroidJUnit4.class) public class DreamOverlayNotificationCountProviderTest extends SysuiTestCase { diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayServiceTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayServiceTest.java index 8379f73402cf306bc0cd7d1d816c962d3c1664bc..e5f997257cfac9e96486b3b7f2a82302d91dd101 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayServiceTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayServiceTest.java @@ -49,7 +49,6 @@ import androidx.test.filters.SmallTest; import com.android.internal.logging.UiEventLogger; import com.android.keyguard.KeyguardUpdateMonitor; -import com.android.systemui.RoboPilotTest; import com.android.systemui.SysuiTestCase; import com.android.systemui.complication.ComplicationLayoutEngine; import com.android.systemui.dreams.complication.HideComplicationTouchHandler; @@ -72,7 +71,6 @@ import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; -@RoboPilotTest @SmallTest @RunWith(AndroidJUnit4.class) public class DreamOverlayServiceTest extends SysuiTestCase { diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStateControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStateControllerTest.java index 2ef227c245c3e18214bee81e296d633898c24601..365f67b5e56607ad3e99e59733d1075ea7793571 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStateControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStateControllerTest.java @@ -29,7 +29,6 @@ import static org.mockito.Mockito.when; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; -import com.android.systemui.RoboPilotTest; import com.android.systemui.SysuiTestCase; import com.android.systemui.complication.Complication; import com.android.systemui.flags.FeatureFlags; @@ -48,7 +47,6 @@ import org.mockito.MockitoAnnotations; import java.util.Collection; -@RoboPilotTest @SmallTest @RunWith(AndroidJUnit4.class) public class DreamOverlayStateControllerTest extends SysuiTestCase { diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStatusBarItemsProviderTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStatusBarItemsProviderTest.java index 12cb332c7cc55ede9a29c6a4f52003b9bbfadb42..7ff345cdcf7ed9efd4aebb14d2e4373a636b75ce 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStatusBarItemsProviderTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStatusBarItemsProviderTest.java @@ -24,7 +24,6 @@ import static org.mockito.Mockito.verify; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; -import com.android.systemui.RoboPilotTest; import com.android.systemui.SysuiTestCase; import org.junit.Before; @@ -36,7 +35,6 @@ import org.mockito.MockitoAnnotations; import java.util.List; import java.util.concurrent.Executor; -@RoboPilotTest @SmallTest @RunWith(AndroidJUnit4.class) public class DreamOverlayStatusBarItemsProviderTest extends SysuiTestCase { diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStatusBarViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStatusBarViewControllerTest.java index 9566e81ed08d44bbd298527e07c1dab27108ac4e..39db2beb4c4450b5df81a83f4a29f36c0b49e215 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStatusBarViewControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStatusBarViewControllerTest.java @@ -46,11 +46,10 @@ 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.RoboPilotTest; import com.android.systemui.SysuiTestCase; import com.android.systemui.log.LogBuffer; import com.android.systemui.log.core.FakeLogBuffer; +import com.android.systemui.res.R; import com.android.systemui.settings.UserTracker; import com.android.systemui.statusbar.policy.IndividualSensorPrivacyController; import com.android.systemui.statusbar.policy.NextAlarmController; @@ -72,7 +71,6 @@ import java.util.List; import java.util.Optional; import java.util.concurrent.Executor; -@RoboPilotTest @SmallTest @RunWith(AndroidJUnit4.class) public class DreamOverlayStatusBarViewControllerTest extends SysuiTestCase { diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/HideComplicationTouchHandlerTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/HideComplicationTouchHandlerTest.java index d32788df30be673b5258edf9852e33f10cc733b3..315a24bfd9457d408e8fcb22865297295c72995e 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/HideComplicationTouchHandlerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/HideComplicationTouchHandlerTest.java @@ -30,7 +30,6 @@ import androidx.concurrent.futures.CallbackToFutureAdapter; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; -import com.android.systemui.RoboPilotTest; import com.android.systemui.SysuiTestCase; import com.android.systemui.complication.Complication; import com.android.systemui.dreams.DreamOverlayStateController; @@ -49,7 +48,6 @@ import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; -@RoboPilotTest @SmallTest @RunWith(AndroidJUnit4.class) public class HideComplicationTouchHandlerTest extends SysuiTestCase { diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/conditions/AssistantAttentionConditionTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/conditions/AssistantAttentionConditionTest.java index 4a7700fe1ca2f04dab1cc3dfcced1fff2e177112..e0c6ab20c6e10977f43ff7c63a48e52a8189ae36 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/dreams/conditions/AssistantAttentionConditionTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/conditions/AssistantAttentionConditionTest.java @@ -26,7 +26,6 @@ import static org.mockito.Mockito.verify; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; -import com.android.systemui.RoboPilotTest; import com.android.systemui.SysuiTestCase; import com.android.systemui.assist.AssistManager; import com.android.systemui.assist.AssistManager.VisualQueryAttentionListener; @@ -41,7 +40,6 @@ import org.mockito.MockitoAnnotations; import kotlinx.coroutines.CoroutineScope; -@RoboPilotTest @SmallTest @RunWith(AndroidJUnit4.class) public class AssistantAttentionConditionTest extends SysuiTestCase { diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/conditions/DreamConditionTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/conditions/DreamConditionTest.java index cd2efded7e85a581d1678e4c0740fbc0bfec2362..480754c176162cc93cc0bceebe0616729f1f7971 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/dreams/conditions/DreamConditionTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/conditions/DreamConditionTest.java @@ -31,7 +31,6 @@ import androidx.test.filters.SmallTest; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.keyguard.KeyguardUpdateMonitorCallback; -import com.android.systemui.RoboPilotTest; import com.android.systemui.SysuiTestCase; import com.android.systemui.shared.condition.Condition; @@ -44,7 +43,6 @@ import org.mockito.MockitoAnnotations; import kotlinx.coroutines.CoroutineScope; -@RoboPilotTest @SmallTest @RunWith(AndroidJUnit4.class) public class DreamConditionTest extends SysuiTestCase { diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandlerTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandlerTest.java index ffcaeee5259628fbc6266e868620ff3fc7913600..3d1efa59a11b64901805a90798501e20156507cb 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandlerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandlerTest.java @@ -17,6 +17,7 @@ package com.android.systemui.dreams.touch; import static com.google.common.truth.Truth.assertThat; + import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyFloat; import static org.mockito.ArgumentMatchers.eq; @@ -40,7 +41,6 @@ import androidx.test.filters.SmallTest; import com.android.internal.logging.UiEventLogger; import com.android.internal.widget.LockPatternUtils; -import com.android.systemui.RoboPilotTest; import com.android.systemui.SysuiTestCase; import com.android.systemui.bouncer.shared.constants.KeyguardBouncerConstants; import com.android.systemui.dreams.touch.scrim.ScrimController; @@ -64,7 +64,6 @@ import org.mockito.MockitoAnnotations; import java.util.Collections; import java.util.Optional; -@RoboPilotTest @SmallTest @RunWith(AndroidJUnit4.class) public class BouncerSwipeTouchHandlerTest extends SysuiTestCase { diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/ShadeTouchHandlerTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/ShadeTouchHandlerTest.java index ff6d97d3b380c421879132b97352b9e607942a9b..6aa821f15ab194029dbc2c714d26d3086c6634b1 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/ShadeTouchHandlerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/ShadeTouchHandlerTest.java @@ -27,7 +27,6 @@ import android.view.MotionEvent; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; -import com.android.systemui.RoboPilotTest; import com.android.systemui.SysuiTestCase; import com.android.systemui.shade.ShadeViewController; import com.android.systemui.shared.system.InputChannelCompat; @@ -43,7 +42,6 @@ import org.mockito.MockitoAnnotations; import java.util.Optional; -@RoboPilotTest @SmallTest @RunWith(AndroidJUnit4.class) public class ShadeTouchHandlerTest extends SysuiTestCase { diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/scrim/BouncerlessScrimControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/scrim/BouncerlessScrimControllerTest.java index da393818c6f76c23cca38400e59cee94d59b3b19..017fdbe8ac010f0d3c1995aeb1703ffe67674e12 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/scrim/BouncerlessScrimControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/scrim/BouncerlessScrimControllerTest.java @@ -26,7 +26,6 @@ import android.os.PowerManager; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; -import com.android.systemui.RoboPilotTest; import com.android.systemui.SysuiTestCase; import com.android.systemui.shade.ShadeExpansionChangeEvent; import com.android.systemui.util.concurrency.FakeExecutor; @@ -38,7 +37,6 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; -@RoboPilotTest @SmallTest @RunWith(AndroidJUnit4.class) public class BouncerlessScrimControllerTest extends SysuiTestCase { diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/scrim/ScrimManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/scrim/ScrimManagerTest.java index 81f6fe3e24d399112026b0f64520d6281e82c0ad..4ee4a60fbeaf04fef6fff50655c9d43175b2c8d3 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/scrim/ScrimManagerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/scrim/ScrimManagerTest.java @@ -25,7 +25,6 @@ import static org.mockito.Mockito.when; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; -import com.android.systemui.RoboPilotTest; import com.android.systemui.SysuiTestCase; import com.android.systemui.statusbar.policy.KeyguardStateController; import com.android.systemui.util.concurrency.FakeExecutor; @@ -38,7 +37,6 @@ import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; -@RoboPilotTest @SmallTest @RunWith(AndroidJUnit4.class) public class ScrimManagerTest extends SysuiTestCase { diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/CameraQuickAffordanceConfigTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/CameraQuickAffordanceConfigTest.kt index cfee3b8f06ea3dedfd8e0636dd74d65d208812d2..e20d3afaca53aefda076bed8e431fccb259ebb19 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/CameraQuickAffordanceConfigTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/CameraQuickAffordanceConfigTest.kt @@ -23,7 +23,6 @@ import android.content.Context import android.content.pm.PackageManager import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.camera.CameraGestureHelper import com.android.systemui.settings.UserTracker @@ -43,7 +42,6 @@ import org.mockito.MockitoAnnotations @OptIn(ExperimentalCoroutinesApi::class) @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) class CameraQuickAffordanceConfigTest : SysuiTestCase() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfigTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfigTest.kt index 49168d08795878c3583e097111ac1fcfd95c3a92..faf97517ac596c4b2ab63137a2662e64b791ec2c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfigTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfigTest.kt @@ -26,7 +26,6 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.settingslib.notification.EnableZenModeDialog import com.android.systemui.res.R -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.animation.Expandable import com.android.systemui.common.shared.model.ContentDescription @@ -61,7 +60,6 @@ import org.mockito.MockitoAnnotations @OptIn(ExperimentalCoroutinesApi::class) @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) class DoNotDisturbQuickAffordanceConfigTest : SysuiTestCase() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/FakeKeyguardQuickAffordanceConfig.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/FakeKeyguardQuickAffordanceConfig.kt index c85c7f6785365df274e524da985181abc846dc24..548b5646f5d4f1b2f4c616d3625315207401f9ed 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/FakeKeyguardQuickAffordanceConfig.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/FakeKeyguardQuickAffordanceConfig.kt @@ -17,7 +17,6 @@ package com.android.systemui.keyguard.data.quickaffordance -import com.android.systemui.RoboPilotTest import com.android.systemui.animation.Expandable import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceConfig.OnTriggeredResult import kotlinx.coroutines.flow.Flow @@ -25,7 +24,6 @@ import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.yield /** Fake implementation of a quick affordance data source. */ -@RoboPilotTest class FakeKeyguardQuickAffordanceConfig( override val key: String, private val pickerName: String = key, diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/FlashlightQuickAffordanceConfigTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/FlashlightQuickAffordanceConfigTest.kt index c3e28ae848059123b4c86ec6e0fbb602183fb61f..4ae144c033144d1971fb0c4c5468031d1a5ab223 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/FlashlightQuickAffordanceConfigTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/FlashlightQuickAffordanceConfigTest.kt @@ -21,7 +21,6 @@ import android.content.Context import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.res.R -import com.android.systemui.RoboPilotTest import com.android.systemui.common.shared.model.Icon import com.android.systemui.keyguard.shared.quickaffordance.ActivationState import com.android.systemui.statusbar.policy.FlashlightController @@ -42,7 +41,6 @@ import org.mockito.MockitoAnnotations @OptIn(ExperimentalCoroutinesApi::class) @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) class FlashlightQuickAffordanceConfigTest : LeakCheckedTest() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigTest.kt index ef56a9892060755962a5f460cbf7aa1c3bf66d3f..7d68cc0a3560dd2ac80afce9f73443698d35a55f 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigTest.kt @@ -20,7 +20,6 @@ package com.android.systemui.keyguard.data.quickaffordance import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.res.R -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.animation.Expandable import com.android.systemui.controls.controller.ControlsController @@ -41,7 +40,6 @@ import org.mockito.Mockito.`when` as whenever import org.mockito.MockitoAnnotations @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) class HomeControlsKeyguardQuickAffordanceConfigTest : SysuiTestCase() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLegacySettingSyncerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLegacySettingSyncerTest.kt index 4f071bd9904fda7772a144b81e0cab460db8b3c0..1e80fb69c10769ff5bb73c8845934b9ffa457049 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLegacySettingSyncerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLegacySettingSyncerTest.kt @@ -23,7 +23,6 @@ import android.provider.Settings import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.res.R -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.settings.FakeUserTracker import com.android.systemui.shared.keyguard.shared.model.KeyguardQuickAffordanceSlots @@ -49,7 +48,6 @@ import org.mockito.MockitoAnnotations @OptIn(ExperimentalCoroutinesApi::class) @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) class KeyguardQuickAffordanceLegacySettingSyncerTest : SysuiTestCase() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManagerTest.kt index bd0b71df3e5c64485c3fea85dbfae73f85c7d9df..99a01858471c0d8bb17fa3247e12924f6950e4b3 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManagerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManagerTest.kt @@ -23,7 +23,6 @@ import android.content.pm.UserInfo import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.res.R -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.backup.BackupHelper import com.android.systemui.settings.FakeUserTracker @@ -53,7 +52,6 @@ import org.mockito.MockitoAnnotations @OptIn(ExperimentalCoroutinesApi::class) @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) class KeyguardQuickAffordanceLocalUserSelectionManagerTest : SysuiTestCase() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceRemoteUserSelectionManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceRemoteUserSelectionManagerTest.kt index 0797d07807b4e100d0bc9b94b37fc99c9edc0efd..a1c9f87ee7bc0bd1cb92349cb28df62f0eef4f4b 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceRemoteUserSelectionManagerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceRemoteUserSelectionManagerTest.kt @@ -21,7 +21,6 @@ import android.content.pm.UserInfo import android.os.UserHandle import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.settings.FakeUserTracker import com.android.systemui.shared.customization.data.content.FakeCustomizationProviderClient @@ -44,7 +43,6 @@ import org.mockito.MockitoAnnotations @OptIn(ExperimentalCoroutinesApi::class) @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) class KeyguardQuickAffordanceRemoteUserSelectionManagerTest : SysuiTestCase() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceConfigTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceConfigTest.kt index d8c0341e1979c2211b681722e36422ed915cc570..b15352bfe6ab1ed4794716fec25618aaee6ef708 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceConfigTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceConfigTest.kt @@ -21,7 +21,6 @@ import android.content.Context import android.media.AudioManager import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.settings.UserFileManager import com.android.systemui.settings.UserTracker @@ -46,7 +45,6 @@ import org.mockito.MockitoAnnotations @OptIn(ExperimentalCoroutinesApi::class) @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) class MuteQuickAffordanceConfigTest : SysuiTestCase() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfigTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfigTest.kt index 9d983b8c8943377ecea3cb77d3f09f51ca27a5db..521dea34513ed7213b4b632476b6a61597f4cf71 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfigTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfigTest.kt @@ -20,7 +20,6 @@ package com.android.systemui.keyguard.data.quickaffordance import android.content.Intent import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceConfig.OnTriggeredResult import com.android.systemui.qrcodescanner.controller.QRCodeScannerController @@ -40,7 +39,6 @@ import org.mockito.Mockito.verify import org.mockito.MockitoAnnotations @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) class QrCodeScannerKeyguardQuickAffordanceConfigTest : SysuiTestCase() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfigTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfigTest.kt index 613c4ce4ccef8d3b6b193890af1459b95ab08e7d..02db0d7a9a50270dcc325850ec794dff896cd26c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfigTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfigTest.kt @@ -24,7 +24,6 @@ import android.service.quickaccesswallet.WalletCard import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.res.R -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.animation.ActivityLaunchAnimator import com.android.systemui.animation.Expandable @@ -51,7 +50,6 @@ import org.mockito.MockitoAnnotations @OptIn(ExperimentalCoroutinesApi::class) @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) class QuickAccessWalletKeyguardQuickAffordanceConfigTest : SysuiTestCase() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/VideoCameraQuickAffordanceConfigTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/VideoCameraQuickAffordanceConfigTest.kt index 1414bace30904af855c20f06745614ab8d2505cf..a9b9c90116365489f39d1678a33c3286c9bbee06 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/VideoCameraQuickAffordanceConfigTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/VideoCameraQuickAffordanceConfigTest.kt @@ -21,7 +21,6 @@ import android.app.admin.DevicePolicyManager import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.ActivityIntentHelper -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.camera.CameraIntentsWrapper import com.android.systemui.coroutines.collectLastValue @@ -45,7 +44,6 @@ import org.mockito.MockitoAnnotations @OptIn(ExperimentalCoroutinesApi::class) @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) class VideoCameraQuickAffordanceConfigTest : SysuiTestCase() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/BiometricSettingsRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/BiometricSettingsRepositoryTest.kt index 944b059450c94af6b62a6858115e42cc29ff8aaa..d8cdf29284ed2fb025f23012aa9c0c98287e98b1 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/BiometricSettingsRepositoryTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/BiometricSettingsRepositoryTest.kt @@ -32,7 +32,6 @@ import com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUT import com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT import com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_TIMEOUT import com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.biometrics.AuthController import com.android.systemui.biometrics.data.repository.FaceSensorInfo @@ -79,7 +78,6 @@ import org.mockito.MockitoAnnotations @OptIn(ExperimentalCoroutinesApi::class) @SmallTest -@RoboPilotTest @TestableLooper.RunWithLooper(setAsMainLooper = true) @RunWith(AndroidJUnit4::class) class BiometricSettingsRepositoryTest : SysuiTestCase() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt index 307204da17617fc16bebb91a04d20fb5a99e2061..819d08a2086e9f65efdf46bdd8f089a3cca63510 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt @@ -44,7 +44,6 @@ import com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_TRIGGERED_NOTIFICATION_PAN import com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_TRIGGERED_SWIPE_UP_ON_BOUNCER import com.android.keyguard.KeyguardUpdateMonitor import com.android.systemui.res.R -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.biometrics.data.repository.FakeDisplayStateRepository import com.android.systemui.biometrics.data.repository.FakeFacePropertyRepository @@ -122,7 +121,6 @@ import java.io.StringWriter @OptIn(ExperimentalCoroutinesApi::class) @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() { private lateinit var underTest: DeviceEntryFaceAuthRepositoryImpl diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFingerprintAuthRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFingerprintAuthRepositoryTest.kt index def016ad8381022d98c5d9a610a985c70b804617..a58bc52bf8e52cadf6816e63e3b4bf7d94e2db60 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFingerprintAuthRepositoryTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFingerprintAuthRepositoryTest.kt @@ -22,7 +22,6 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.keyguard.KeyguardUpdateMonitor import com.android.keyguard.KeyguardUpdateMonitorCallback -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.biometrics.AuthController import com.android.systemui.coroutines.collectLastValue @@ -49,7 +48,6 @@ import org.mockito.MockitoAnnotations @OptIn(ExperimentalCoroutinesApi::class) @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) class DeviceEntryFingerprintAuthRepositoryTest : SysuiTestCase() { @Mock private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DevicePostureRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DevicePostureRepositoryTest.kt index 7eb8a26d9ab64ce3409e6adac85f8f4378aefb9e..9be5558f5cc2378c9d29ef25afc67f9137c7a8b5 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DevicePostureRepositoryTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DevicePostureRepositoryTest.kt @@ -18,7 +18,6 @@ package com.android.systemui.keyguard.data.repository import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue import com.android.systemui.keyguard.shared.model.DevicePosture @@ -39,7 +38,6 @@ import org.mockito.MockitoAnnotations @OptIn(ExperimentalCoroutinesApi::class) @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) class DevicePostureRepositoryTest : SysuiTestCase() { private lateinit var underTest: DevicePostureRepository diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt index 126b841610b4ebaaa71c49048ce09394f64a9fda..567e0a9717fcb75512b7c210aba65a7a5153cdad 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt @@ -22,7 +22,6 @@ import android.os.UserHandle import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.res.R -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue import com.android.systemui.keyguard.data.quickaffordance.FakeKeyguardQuickAffordanceConfig @@ -56,7 +55,6 @@ import org.mockito.ArgumentMatchers.anyString @OptIn(ExperimentalCoroutinesApi::class) @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) class KeyguardQuickAffordanceRepositoryTest : SysuiTestCase() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryImplTest.kt index 7983e30c66fb6d71cb0dd790b6101acafebf96d8..b9119e10b720aec960de7aaf615ab0ca7c1cde92 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryImplTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryImplTest.kt @@ -22,7 +22,6 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.keyguard.KeyguardUpdateMonitor import com.android.keyguard.KeyguardUpdateMonitorCallback -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.biometrics.AuthController import com.android.systemui.common.shared.model.Position @@ -64,7 +63,6 @@ import org.mockito.MockitoAnnotations @OptIn(ExperimentalCoroutinesApi::class) @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) class KeyguardRepositoryImplTest : SysuiTestCase() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/LightRevealScrimRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/LightRevealScrimRepositoryTest.kt index 4942cf84a6fcad0d7e69f5bebeb5a7440efb1a58..799bd5ac573984a3f4ff28f61643ff6c10a00110 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/LightRevealScrimRepositoryTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/LightRevealScrimRepositoryTest.kt @@ -20,7 +20,6 @@ import android.graphics.Point import android.testing.TestableLooper import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.animation.AnimatorTestRule import com.android.systemui.coroutines.collectLastValue @@ -46,7 +45,6 @@ import org.junit.runner.RunWith import org.mockito.MockitoAnnotations @SmallTest -@RoboPilotTest @OptIn(ExperimentalCoroutinesApi::class) @RunWith(AndroidJUnit4::class) class LightRevealScrimRepositoryTest : SysuiTestCase() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/TrustRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/TrustRepositoryTest.kt index 7f784d88da6de0f51bac6a2651f040a6cd3e43fd..ee47c58f4002edb97037eb6a2109b3f6559bbb89 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/TrustRepositoryTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/TrustRepositoryTest.kt @@ -21,7 +21,6 @@ import android.content.pm.UserInfo import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.keyguard.logging.TrustRepositoryLogger -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.FlowValue import com.android.systemui.coroutines.collectLastValue @@ -46,7 +45,6 @@ import org.mockito.MockitoAnnotations @OptIn(ExperimentalCoroutinesApi::class) @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) class TrustRepositoryTest : SysuiTestCase() { @Mock private lateinit var trustManager: TrustManager diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractorTest.kt index 181cc884c9f5967a06074f6247c58b5db4393a50..d6e19cbcb826b55f329adfa3da5a5c4d2e4544bf 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractorTest.kt @@ -19,7 +19,6 @@ package com.android.systemui.keyguard.domain.interactor import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository @@ -43,7 +42,6 @@ import org.mockito.MockitoAnnotations @OptIn(ExperimentalCoroutinesApi::class) @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) class KeyguardDismissActionInteractorTest : SysuiTestCase() { private lateinit var keyguardRepository: FakeKeyguardRepository diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissInteractorTest.kt index c407b14dcf6529f8cc6b8292d5f3fea6c4497007..a5cfbbfda196242bac2d36daaf06f9020dda5138 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissInteractorTest.kt @@ -22,7 +22,6 @@ import android.service.trust.TrustAgentService import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.keyguard.TrustGrantFlags -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue import com.android.systemui.keyguard.shared.model.DismissAction @@ -40,7 +39,6 @@ import org.junit.runner.RunWith import org.mockito.MockitoAnnotations @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) class KeyguardDismissInteractorTest : SysuiTestCase() { private lateinit var dispatcher: TestDispatcher diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardFaceAuthInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardFaceAuthInteractorTest.kt index b527510fc56f1dbd779ae9473c975a41a9bac794..06eb0dd364b5700bdcceccc146fcb11529acede6 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardFaceAuthInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardFaceAuthInteractorTest.kt @@ -28,8 +28,10 @@ import com.android.keyguard.FaceWakeUpTriggersConfig import com.android.keyguard.KeyguardSecurityModel import com.android.keyguard.KeyguardUpdateMonitor import com.android.systemui.SysuiTestCase +import com.android.systemui.biometrics.data.repository.FaceSensorInfo import com.android.systemui.biometrics.data.repository.FakeFacePropertyRepository import com.android.systemui.biometrics.shared.model.LockoutMode +import com.android.systemui.biometrics.shared.model.SensorStrength import com.android.systemui.bouncer.data.repository.FakeKeyguardBouncerRepository import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerCallbackInteractor @@ -156,7 +158,6 @@ class KeyguardFaceAuthInteractorTest : SysuiTestCase() { fakeDeviceEntryFingerprintAuthRepository, fakeUserRepository, facePropertyRepository, - fakeKeyguardRepository, faceWakeUpTriggersConfig, powerInteractor, ) @@ -439,6 +440,43 @@ class KeyguardFaceAuthInteractorTest : SysuiTestCase() { .isEqualTo(Pair(FaceAuthUiEvent.FACE_AUTH_TRIGGERED_SWIPE_UP_ON_BOUNCER, false)) } + @Test + fun faceAuthIsRequestedWhenWalletIsLaunchedAndIfFaceAuthIsStrong() = + testScope.runTest { + underTest.start() + facePropertyRepository.setSensorInfo(FaceSensorInfo(1, SensorStrength.STRONG)) + + underTest.onWalletLaunched() + + runCurrent() + assertThat(faceAuthRepository.runningAuthRequest.value) + .isEqualTo(Pair(FaceAuthUiEvent.FACE_AUTH_TRIGGERED_OCCLUDING_APP_REQUESTED, true)) + } + + @Test + fun faceAuthIsNotTriggeredIfFaceAuthIsWeak() = + testScope.runTest { + underTest.start() + facePropertyRepository.setSensorInfo(FaceSensorInfo(1, SensorStrength.WEAK)) + + underTest.onWalletLaunched() + + runCurrent() + assertThat(faceAuthRepository.runningAuthRequest.value).isNull() + } + + @Test + fun faceAuthIsNotTriggeredIfFaceAuthIsConvenience() = + testScope.runTest { + underTest.start() + facePropertyRepository.setSensorInfo(FaceSensorInfo(1, SensorStrength.CONVENIENCE)) + + underTest.onWalletLaunched() + + runCurrent() + assertThat(faceAuthRepository.runningAuthRequest.value).isNull() + } + @Test fun faceUnlockIsDisabledWhenFpIsLockedOut() = testScope.runTest { diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorTest.kt index ca52cdb227e55fb196f0a27ef75b167d6a994d52..9ee22c89405dd943c0cc40bced0c6540ee783707 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorTest.kt @@ -20,7 +20,6 @@ package com.android.systemui.keyguard.domain.interactor import android.app.StatusBarManager import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.bouncer.data.repository.FakeKeyguardBouncerRepository import com.android.systemui.common.ui.data.repository.FakeConfigurationRepository @@ -47,7 +46,6 @@ import org.junit.runner.RunWith @OptIn(ExperimentalCoroutinesApi::class) @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) class KeyguardInteractorTest : SysuiTestCase() { @@ -206,7 +204,8 @@ class KeyguardInteractorTest : SysuiTestCase() { fromScene = SceneKey.Gone, toScene = SceneKey.Lockscreen, progress = flowOf(0f), - isUserInputDriven = false, + isInitiatedByUserInput = false, + isUserInputOngoing = flowOf(false), ) runCurrent() assertThat(isAnimate).isFalse() diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorTest.kt index 13025a016eff5b1db2bed5ac27d55f7224b71dbd..0c74a38fea0472ca400c56fdc037abefc7beeb04 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorTest.kt @@ -22,7 +22,6 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.internal.logging.UiEventLogger import com.android.systemui.res.R -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue import com.android.systemui.flags.FakeFeatureFlags @@ -51,7 +50,6 @@ import org.mockito.MockitoAnnotations @OptIn(ExperimentalCoroutinesApi::class) @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) class KeyguardLongPressInteractorTest : SysuiTestCase() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt index 8c13bb465103c3ffd4b32998517ee533a0cc5ba6..347d580abf5bbe79035c62d2f39c8fe52b768ce4 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt @@ -23,7 +23,6 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.internal.widget.LockPatternUtils import com.android.systemui.res.R -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.animation.DialogLaunchAnimator import com.android.systemui.common.shared.model.ContentDescription @@ -73,7 +72,6 @@ import org.mockito.MockitoAnnotations @OptIn(ExperimentalCoroutinesApi::class) @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) class KeyguardQuickAffordanceInteractorTest : SysuiTestCase() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardSurfaceBehindInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardSurfaceBehindInteractorTest.kt index fdcc66b6c97405cf606e09b82c57e6e13f80476a..71fcf6f9955c675c7486ac15223aad0392c523ef 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardSurfaceBehindInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardSurfaceBehindInteractorTest.kt @@ -18,7 +18,6 @@ package com.android.systemui.keyguard.domain.interactor import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectValues import com.android.systemui.keyguard.data.repository.FakeKeyguardSurfaceBehindRepository @@ -41,7 +40,6 @@ import org.mockito.Mock import org.mockito.MockitoAnnotations.initMocks @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) @kotlinx.coroutines.ExperimentalCoroutinesApi class KeyguardSurfaceBehindInteractorTest : SysuiTestCase() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorTest.kt index fa93253642e3448a3ef68534d5b657d565ffd1b8..29b546bd49adb1313104295d7c3a796ba2394533 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorTest.kt @@ -19,7 +19,6 @@ package com.android.systemui.keyguard.domain.interactor import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectValues import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository @@ -42,7 +41,6 @@ import org.junit.Test import org.junit.runner.RunWith @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) @kotlinx.coroutines.ExperimentalCoroutinesApi class KeyguardTransitionInteractorTest : SysuiTestCase() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/LightRevealScrimInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/LightRevealScrimInteractorTest.kt index 906d948591408d8fb9d298ed59ec7486058abae3..c02add1d0ecb0b9415dac2ab1f190197615cb389 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/LightRevealScrimInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/LightRevealScrimInteractorTest.kt @@ -18,7 +18,6 @@ package com.android.systemui.keyguard.domain.interactor import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository import com.android.systemui.keyguard.data.repository.FakeLightRevealScrimRepository @@ -45,7 +44,6 @@ import org.mockito.MockitoAnnotations import org.mockito.Spy @SmallTest -@RoboPilotTest @OptIn(ExperimentalCoroutinesApi::class) @RunWith(AndroidJUnit4::class) class LightRevealScrimInteractorTest : SysuiTestCase() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorTest.kt index 73ecae5af9b3c715f2270b4ba3922f3c6a89d713..16f2fa22d5fba549722380129ba5f6a122757258 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorTest.kt @@ -18,7 +18,6 @@ package com.android.systemui.keyguard.domain.interactor import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectValues import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository @@ -38,7 +37,6 @@ import org.mockito.Mock import org.mockito.MockitoAnnotations.initMocks @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) @kotlinx.coroutines.ExperimentalCoroutinesApi class WindowManagerLockscreenVisibilityInteractorTest : SysuiTestCase() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/binder/KeyguardSurfaceBehindParamsApplierTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/binder/KeyguardSurfaceBehindParamsApplierTest.kt index a22f603ae92ae7b343f389523f6ff1829aa800d3..5b29a867ceaf53d725a57467069c82a493771d0b 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/binder/KeyguardSurfaceBehindParamsApplierTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/binder/KeyguardSurfaceBehindParamsApplierTest.kt @@ -20,7 +20,6 @@ import android.testing.TestableLooper.RunWithLooper import android.view.RemoteAnimationTarget import androidx.test.filters.SmallTest import com.android.keyguard.KeyguardViewController -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.animation.AnimatorTestRule import com.android.systemui.keyguard.domain.interactor.KeyguardSurfaceBehindInteractor @@ -41,7 +40,6 @@ import org.mockito.Mockito.doAnswer import org.mockito.MockitoAnnotations @SmallTest -@RoboPilotTest @RunWithLooper(setAsMainLooper = true) @kotlinx.coroutines.ExperimentalCoroutinesApi class KeyguardSurfaceBehindParamsApplierTest : SysuiTestCase() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/binder/WindowManagerLockscreenVisibilityManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/binder/WindowManagerLockscreenVisibilityManagerTest.kt index 7a17435b9165af59bcd50983d1c1a5aee419baae..9b2db3e5316cc975a9aa37621cca597bb2b693b2 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/binder/WindowManagerLockscreenVisibilityManagerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/binder/WindowManagerLockscreenVisibilityManagerTest.kt @@ -19,7 +19,6 @@ package com.android.systemui.keyguard.ui.binder import android.app.IActivityTaskManager import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.keyguard.WindowManagerLockscreenVisibilityManager import com.android.systemui.statusbar.policy.KeyguardStateController @@ -35,7 +34,6 @@ import org.mockito.Mockito.verifyNoMoreInteractions import org.mockito.MockitoAnnotations @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) @kotlinx.coroutines.ExperimentalCoroutinesApi class WindowManagerLockscreenVisibilityManagerTest : SysuiTestCase() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerViewModelTest.kt new file mode 100644 index 0000000000000000000000000000000000000000..1768f8c4385b8cacda824f8b66d00b0196c88e52 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerViewModelTest.kt @@ -0,0 +1,197 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package com.android.systemui.keyguard.ui.viewmodel + +import androidx.test.filters.SmallTest +import com.android.systemui.SysuiTestCase +import com.android.systemui.coroutines.collectLastValue +import com.android.systemui.coroutines.collectValues +import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository +import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor +import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractorFactory +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.plugins.FalsingManager +import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager +import com.google.common.collect.Range +import com.google.common.truth.Truth.assertThat +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.TestScope +import kotlinx.coroutines.test.UnconfinedTestDispatcher +import kotlinx.coroutines.test.runTest +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.JUnit4 +import org.mockito.Mock +import org.mockito.MockitoAnnotations + +@ExperimentalCoroutinesApi +@RunWith(JUnit4::class) +@SmallTest +class AlternateBouncerViewModelTest : SysuiTestCase() { + + private lateinit var testScope: TestScope + + @Mock private lateinit var statusBarKeyguardViewManager: StatusBarKeyguardViewManager + @Mock private lateinit var falsingManager: FalsingManager + + private lateinit var transitionRepository: FakeKeyguardTransitionRepository + private lateinit var transitionInteractor: KeyguardTransitionInteractor + private lateinit var underTest: AlternateBouncerViewModel + + @Before + fun setup() { + MockitoAnnotations.initMocks(this) + testScope = TestScope() + + val transitionInteractorWithDependencies = + KeyguardTransitionInteractorFactory.create(testScope.backgroundScope) + transitionInteractor = transitionInteractorWithDependencies.keyguardTransitionInteractor + transitionRepository = transitionInteractorWithDependencies.repository + underTest = + AlternateBouncerViewModel( + statusBarKeyguardViewManager, + transitionInteractor, + falsingManager, + ) + } + + @Test + fun transitionToAlternateBouncer_scrimAlphaUpdate() = + runTest(UnconfinedTestDispatcher()) { + val scrimAlphas by collectValues(underTest.scrimAlpha) + + transitionRepository.sendTransitionStep( + stepToAlternateBouncer(0f, TransitionState.STARTED) + ) + transitionRepository.sendTransitionStep(stepToAlternateBouncer(.4f)) + transitionRepository.sendTransitionStep(stepToAlternateBouncer(.6f)) + transitionRepository.sendTransitionStep(stepToAlternateBouncer(1f)) + + assertThat(scrimAlphas.size).isEqualTo(4) + scrimAlphas.forEach { assertThat(it).isIn(Range.closed(0f, 1f)) } + } + + @Test + fun transitionFromAlternateBouncer_scrimAlphaUpdate() = + runTest(UnconfinedTestDispatcher()) { + val scrimAlphas by collectValues(underTest.scrimAlpha) + + transitionRepository.sendTransitionStep( + stepFromAlternateBouncer(0f, TransitionState.STARTED) + ) + transitionRepository.sendTransitionStep(stepFromAlternateBouncer(.4f)) + transitionRepository.sendTransitionStep(stepFromAlternateBouncer(.6f)) + transitionRepository.sendTransitionStep(stepFromAlternateBouncer(1f)) + + assertThat(scrimAlphas.size).isEqualTo(4) + scrimAlphas.forEach { assertThat(it).isIn(Range.closed(0f, 1f)) } + } + + @Test + fun clickListenerUpdate() = + runTest(UnconfinedTestDispatcher()) { + val clickListener by collectLastValue(underTest.onClickListener) + + // keyguard state => ALTERNATE_BOUNCER + transitionRepository.sendTransitionStep( + stepToAlternateBouncer(0f, TransitionState.STARTED) + ) + assertThat(clickListener).isNull() + transitionRepository.sendTransitionStep(stepToAlternateBouncer(.3f)) + assertThat(clickListener).isNull() + transitionRepository.sendTransitionStep(stepToAlternateBouncer(.6f)) + assertThat(clickListener).isNull() + transitionRepository.sendTransitionStep(stepToAlternateBouncer(1f)) + assertThat(clickListener).isNotNull() + + // ALTERNATE_BOUNCER -> keyguard state + transitionRepository.sendTransitionStep( + stepFromAlternateBouncer(0f, TransitionState.STARTED) + ) + assertThat(clickListener).isNotNull() + transitionRepository.sendTransitionStep(stepFromAlternateBouncer(.3f)) + assertThat(clickListener).isNull() + transitionRepository.sendTransitionStep(stepFromAlternateBouncer(.6f)) + assertThat(clickListener).isNull() + transitionRepository.sendTransitionStep(stepFromAlternateBouncer(1f)) + assertThat(clickListener).isNull() + } + + @Test + fun forcePluginOpen() = + runTest(UnconfinedTestDispatcher()) { + val forcePluginOpen by collectLastValue(underTest.forcePluginOpen) + transitionRepository.sendTransitionStep( + stepToAlternateBouncer(0f, TransitionState.STARTED) + ) + transitionRepository.sendTransitionStep(stepToAlternateBouncer(.3f)) + transitionRepository.sendTransitionStep(stepToAlternateBouncer(.6f)) + transitionRepository.sendTransitionStep(stepToAlternateBouncer(1f)) + assertThat(forcePluginOpen).isTrue() + + transitionRepository.sendTransitionStep( + stepFromAlternateBouncer(0f, TransitionState.STARTED) + ) + transitionRepository.sendTransitionStep(stepFromAlternateBouncer(.3f)) + transitionRepository.sendTransitionStep(stepFromAlternateBouncer(.6f)) + transitionRepository.sendTransitionStep(stepFromAlternateBouncer(1f)) + assertThat(forcePluginOpen).isFalse() + } + + private fun stepToAlternateBouncer( + value: Float, + state: TransitionState = TransitionState.RUNNING + ): TransitionStep { + return step( + from = KeyguardState.LOCKSCREEN, + to = KeyguardState.ALTERNATE_BOUNCER, + value = value, + transitionState = state, + ) + } + + private fun stepFromAlternateBouncer( + value: Float, + state: TransitionState = TransitionState.RUNNING + ): TransitionStep { + return step( + from = KeyguardState.ALTERNATE_BOUNCER, + to = KeyguardState.LOCKSCREEN, + value = value, + transitionState = state, + ) + } + + private fun step( + from: KeyguardState, + to: KeyguardState, + value: Float, + transitionState: TransitionState + ): TransitionStep { + return TransitionStep( + from = from, + to = to, + value = value, + transitionState = transitionState, + ownerName = "AlternateBouncerViewModelTest" + ) + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModelTest.kt index bfc6f31c57db50644c50568e4a89baf478b12af8..6d47aed58dacf16463fcc242178f8845183a382f 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModelTest.kt @@ -18,7 +18,6 @@ package com.android.systemui.keyguard.ui.viewmodel import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractorFactory @@ -46,7 +45,6 @@ import org.junit.Test import org.junit.runner.RunWith @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) class DreamingToLockscreenTransitionViewModelTest : SysuiTestCase() { private lateinit var underTest: DreamingToLockscreenTransitionViewModel diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/GoneToDreamingTransitionViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/GoneToDreamingTransitionViewModelTest.kt index 75c8bff326b0f708bc22101ad23e99a9e247098b..cf2012989624bab94ef2043078548244d206195e 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/GoneToDreamingTransitionViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/GoneToDreamingTransitionViewModelTest.kt @@ -18,7 +18,6 @@ package com.android.systemui.keyguard.ui.viewmodel import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractorFactory @@ -37,7 +36,6 @@ import org.junit.Test import org.junit.runner.RunWith @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) class GoneToDreamingTransitionViewModelTest : SysuiTestCase() { private lateinit var underTest: GoneToDreamingTransitionViewModel diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingTransitionViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingTransitionViewModelTest.kt index 12fe07f0827ef8faa53b498efd2aff850b4b1168..89a1d2b3011d6e5d82e428309e6916b8f45d603f 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingTransitionViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingTransitionViewModelTest.kt @@ -18,7 +18,6 @@ package com.android.systemui.keyguard.ui.viewmodel import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractorFactory @@ -37,7 +36,6 @@ import org.junit.Test import org.junit.runner.RunWith @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) class LockscreenToDreamingTransitionViewModelTest : SysuiTestCase() { private lateinit var underTest: LockscreenToDreamingTransitionViewModel diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModelTest.kt index 83ae631ed164b8b53da3535250ae0677a88963cc..41f8856d5ca2d5dbaf0f402480a8ace8ec394d95 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModelTest.kt @@ -18,7 +18,6 @@ package com.android.systemui.keyguard.ui.viewmodel import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractorFactory @@ -37,7 +36,6 @@ import org.junit.Test import org.junit.runner.RunWith @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) class LockscreenToOccludedTransitionViewModelTest : SysuiTestCase() { private lateinit var underTest: LockscreenToOccludedTransitionViewModel diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModelTest.kt index 88603999cdd75f59daa6745c0c01e9bd91cad247..ec95cb8c43f10a4e5e8d519d1e184dba71905ca2 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModelTest.kt @@ -18,7 +18,6 @@ package com.android.systemui.keyguard.ui.viewmodel import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractorFactory @@ -37,7 +36,6 @@ import org.junit.Test import org.junit.runner.RunWith @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) class OccludedToLockscreenTransitionViewModelTest : SysuiTestCase() { private lateinit var underTest: OccludedToLockscreenTransitionViewModel diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModelTest.kt index da372eaf158c22d2ac0d9ce2a79578c3defdf78e..93640975901bb6ec20569503d0ac0a84a1e7595a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModelTest.kt @@ -18,7 +18,6 @@ package com.android.systemui.keyguard.ui.viewmodel import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor import com.android.systemui.coroutines.collectValues @@ -46,7 +45,6 @@ import org.mockito.Mock import org.mockito.MockitoAnnotations @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) class PrimaryBouncerToGoneTransitionViewModelTest : SysuiTestCase() { private lateinit var underTest: PrimaryBouncerToGoneTransitionViewModel diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/UdfpsAodViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/UdfpsAodViewModelTest.kt index 9ab9b3d160d1c920a47d6c68e8a7fdcc815961d4..32acefebfa6885739d5229a1165b3b8eee249c57 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/UdfpsAodViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/UdfpsAodViewModelTest.kt @@ -18,7 +18,6 @@ package com.android.systemui.keyguard.ui.viewmodel import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.bouncer.data.repository.KeyguardBouncerRepository import com.android.systemui.common.ui.data.repository.FakeConfigurationRepository @@ -46,7 +45,6 @@ import org.mockito.MockitoAnnotations @ExperimentalCoroutinesApi @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) class UdfpsAodViewModelTest : SysuiTestCase() { private val defaultPadding = 12 diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/AutoAddSettingsRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/AutoAddSettingsRepositoryTest.kt index 9a55f722c13cdad5bf444c27c8ac99afa11b343e..d277fcab36902c5b22d309f006380895d933aa55 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/AutoAddSettingsRepositoryTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/AutoAddSettingsRepositoryTest.kt @@ -19,7 +19,6 @@ package com.android.systemui.qs.pipeline.data.repository import android.provider.Settings import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue import com.android.systemui.qs.pipeline.shared.TileSpec @@ -39,7 +38,6 @@ import org.mockito.MockitoAnnotations @OptIn(ExperimentalCoroutinesApi::class) @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) class AutoAddSettingsRepositoryTest : SysuiTestCase() { private val secureSettings = FakeSettings() diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/CustomTileAddedSharedPreferencesRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/CustomTileAddedSharedPreferencesRepositoryTest.kt index 30f5811c373183978481dafdcc7896c079a54bd0..3db676d68f429ec0216fd87fca9b9933123d815b 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/CustomTileAddedSharedPreferencesRepositoryTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/CustomTileAddedSharedPreferencesRepositoryTest.kt @@ -20,7 +20,6 @@ import android.content.ComponentName import android.content.SharedPreferences import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.settings.UserFileManager import com.android.systemui.util.FakeSharedPreferences @@ -30,7 +29,6 @@ import org.junit.Test import org.junit.runner.RunWith @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) class CustomTileAddedSharedPreferencesRepositoryTest : SysuiTestCase() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/InstalledTilesComponentRepositoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/InstalledTilesComponentRepositoryImplTest.kt index 995de662aaf077874a57c56585fe7eb69d93f839..070e07a75d23614cfcf234b00f986cf244f537ad 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/InstalledTilesComponentRepositoryImplTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/InstalledTilesComponentRepositoryImplTest.kt @@ -32,7 +32,6 @@ import android.service.quicksettings.TileService import android.testing.TestableLooper import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue import com.android.systemui.util.mockito.any @@ -62,7 +61,6 @@ import org.mockito.Mockito.verify import org.mockito.MockitoAnnotations @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) @TestableLooper.RunWithLooper @OptIn(ExperimentalCoroutinesApi::class) diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/QSSettingsRestoredBroadcastRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/QSSettingsRestoredBroadcastRepositoryTest.kt index dc09a33adc1c0f4e7727bb4ca6597185ac7e14a0..ff8a9bd019fb2f5cb5eede054e02df88d6cb84f1 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/QSSettingsRestoredBroadcastRepositoryTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/QSSettingsRestoredBroadcastRepositoryTest.kt @@ -4,7 +4,6 @@ import android.content.Intent import android.provider.Settings import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.broadcast.FakeBroadcastDispatcher import com.android.systemui.coroutines.collectLastValue @@ -24,7 +23,6 @@ import org.mockito.MockitoAnnotations @SmallTest @OptIn(ExperimentalCoroutinesApi::class) @RunWith(AndroidJUnit4::class) -@RoboPilotTest class QSSettingsRestoredBroadcastRepositoryTest : SysuiTestCase() { private val dispatcher = StandardTestDispatcher() private val testScope = TestScope(dispatcher) diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/TileSpecSettingsRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/TileSpecSettingsRepositoryTest.kt index 08adebb87b1b6df8d74c204afbacbbb01c1ce64c..f7c3b213730c647517ea3a653ccb5372752a3179 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/TileSpecSettingsRepositoryTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/TileSpecSettingsRepositoryTest.kt @@ -20,7 +20,6 @@ import android.provider.Settings import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.res.R -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue import com.android.systemui.qs.pipeline.shared.TileSpec @@ -40,7 +39,6 @@ import org.mockito.Mock import org.mockito.MockitoAnnotations @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) @OptIn(ExperimentalCoroutinesApi::class) class TileSpecSettingsRepositoryTest : SysuiTestCase() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/TilesSettingConverterTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/TilesSettingConverterTest.kt index 20876237b476e333bd4507be2e578f20208ce793..9516c2181ac0e9aa79c7813247a862831513614c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/TilesSettingConverterTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/TilesSettingConverterTest.kt @@ -2,14 +2,12 @@ package com.android.systemui.qs.pipeline.data.repository import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.qs.pipeline.shared.TileSpec import com.google.common.truth.Truth.assertThat import org.junit.Test import org.junit.runner.RunWith -@RoboPilotTest @SmallTest @RunWith(AndroidJUnit4::class) class TilesSettingConverterTest : SysuiTestCase() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/UserAutoAddRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/UserAutoAddRepositoryTest.kt index 81fd72b11227906471e2bf2c2d5cd4fd4f7bc788..36e860e37ffa718aa4aac44b8f9bb889a12d61c2 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/UserAutoAddRepositoryTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/UserAutoAddRepositoryTest.kt @@ -3,7 +3,6 @@ package com.android.systemui.qs.pipeline.data.repository import android.provider.Settings import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue import com.android.systemui.qs.pipeline.data.model.RestoreData @@ -24,7 +23,6 @@ import org.mockito.Mock import org.mockito.MockitoAnnotations @OptIn(ExperimentalCoroutinesApi::class) -@RoboPilotTest @SmallTest @RunWith(AndroidJUnit4::class) class UserAutoAddRepositoryTest : SysuiTestCase() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/UserTileSpecRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/UserTileSpecRepositoryTest.kt index 389580c1326b4d071c3083d5a8cbf65ca3cd2d69..d4a9fabd68067c5cc7f7c87b5aeb6ecaa8cf5507 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/UserTileSpecRepositoryTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/UserTileSpecRepositoryTest.kt @@ -3,7 +3,6 @@ package com.android.systemui.qs.pipeline.data.repository import android.provider.Settings import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue import com.android.systemui.qs.pipeline.data.model.RestoreData @@ -23,7 +22,6 @@ import org.junit.runner.RunWith import org.mockito.Mock import org.mockito.MockitoAnnotations -@RoboPilotTest @SmallTest @OptIn(ExperimentalCoroutinesApi::class) @RunWith(AndroidJUnit4::class) diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/AutoAddableSettingListTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/AutoAddableSettingListTest.kt index 15e401d24b020d7d8293c02a0baf27ae4bfe6f6d..4454a3cb15fc53423752150ce354e7e34a4534c1 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/AutoAddableSettingListTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/AutoAddableSettingListTest.kt @@ -20,7 +20,6 @@ import android.content.ComponentName import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.res.R -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.qs.pipeline.shared.TileSpec import com.android.systemui.util.mockito.mock @@ -29,7 +28,6 @@ import org.junit.Test import org.junit.runner.RunWith @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) class AutoAddableSettingListTest : SysuiTestCase() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/AutoAddableSettingTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/AutoAddableSettingTest.kt index 7c6dd242a56992ffa4aef234c1ed9ac939e74ec4..d153e9d1d3615fa48d3d08dc2b3f9d76ab03d33b 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/AutoAddableSettingTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/AutoAddableSettingTest.kt @@ -18,7 +18,6 @@ package com.android.systemui.qs.pipeline.domain.autoaddable import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue import com.android.systemui.coroutines.collectValues @@ -36,7 +35,6 @@ import org.junit.runner.RunWith @OptIn(ExperimentalCoroutinesApi::class) @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) class AutoAddableSettingTest : SysuiTestCase() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/CallbackControllerAutoAddableTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/CallbackControllerAutoAddableTest.kt index 469eee3638893a0abeca61a7c4abe684c8881946..ec139e4c515e5173988e32520b5a831823178a99 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/CallbackControllerAutoAddableTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/CallbackControllerAutoAddableTest.kt @@ -18,7 +18,6 @@ package com.android.systemui.qs.pipeline.domain.autoaddable import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue import com.android.systemui.qs.pipeline.domain.model.AutoAddSignal @@ -36,7 +35,6 @@ import org.junit.runner.RunWith @OptIn(ExperimentalCoroutinesApi::class) @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) class CallbackControllerAutoAddableTest : SysuiTestCase() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/CastAutoAddableTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/CastAutoAddableTest.kt index b6eaa39222784c4c920d1204e7ea07f018293367..4fae532d417473f996bbd791a0aa0b7ff3275684 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/CastAutoAddableTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/CastAutoAddableTest.kt @@ -18,7 +18,6 @@ package com.android.systemui.qs.pipeline.domain.autoaddable import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue import com.android.systemui.qs.pipeline.domain.model.AutoAddSignal @@ -42,7 +41,6 @@ import org.mockito.MockitoAnnotations @OptIn(ExperimentalCoroutinesApi::class) @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) class CastAutoAddableTest : SysuiTestCase() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/DataSaverAutoAddableTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/DataSaverAutoAddableTest.kt index a755fbbdfd7f7a2a3881f481b3621fcd9cbcbb57..9e2d1f885e2d95ad54172968849ab6ec6a59eb16 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/DataSaverAutoAddableTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/DataSaverAutoAddableTest.kt @@ -18,7 +18,6 @@ package com.android.systemui.qs.pipeline.domain.autoaddable import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue import com.android.systemui.qs.pipeline.domain.model.AutoAddSignal @@ -41,7 +40,6 @@ import org.mockito.MockitoAnnotations @OptIn(ExperimentalCoroutinesApi::class) @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) class DataSaverAutoAddableTest : SysuiTestCase() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/DeviceControlsAutoAddableTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/DeviceControlsAutoAddableTest.kt index daacca51a915edf94383fc8f52cd5bb53ee83db7..0116bd9575d8c87c967ab42249622cc3de04bf24 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/DeviceControlsAutoAddableTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/DeviceControlsAutoAddableTest.kt @@ -18,7 +18,6 @@ package com.android.systemui.qs.pipeline.domain.autoaddable import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue import com.android.systemui.qs.pipeline.domain.model.AutoAddSignal @@ -44,7 +43,6 @@ import org.mockito.MockitoAnnotations @OptIn(ExperimentalCoroutinesApi::class) @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) class DeviceControlsAutoAddableTest : SysuiTestCase() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/HotspotAutoAddableTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/HotspotAutoAddableTest.kt index 4b5f7f6d07ef0475e8284d575ef7486b2d265f4e..e7ea9a66450c4106f35ad7a49e40cdb43a702946 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/HotspotAutoAddableTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/HotspotAutoAddableTest.kt @@ -18,7 +18,6 @@ package com.android.systemui.qs.pipeline.domain.autoaddable import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue import com.android.systemui.qs.pipeline.domain.model.AutoAddSignal @@ -41,7 +40,6 @@ import org.mockito.MockitoAnnotations @OptIn(ExperimentalCoroutinesApi::class) @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) class HotspotAutoAddableTest : SysuiTestCase() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/NightDisplayAutoAddableTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/NightDisplayAutoAddableTest.kt index 32d9db24a3b29f180613f03380baf3ec0e6c60bd..20fd3601f9efc7cedd4b37e3be4d3233a9c14185 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/NightDisplayAutoAddableTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/NightDisplayAutoAddableTest.kt @@ -19,7 +19,6 @@ package com.android.systemui.qs.pipeline.domain.autoaddable import android.hardware.display.NightDisplayListener import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue import com.android.systemui.dagger.NightDisplayListenerModule @@ -50,7 +49,6 @@ import org.mockito.MockitoAnnotations @OptIn(ExperimentalCoroutinesApi::class) @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) class NightDisplayAutoAddableTest : SysuiTestCase() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/ReduceBrightColorsAutoAddableTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/ReduceBrightColorsAutoAddableTest.kt index fb513a6bd197189423cb4bae927f0d39dd3e7d61..19ac63c36cab5f98ac301c16c71497f760d5d595 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/ReduceBrightColorsAutoAddableTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/ReduceBrightColorsAutoAddableTest.kt @@ -18,7 +18,6 @@ package com.android.systemui.qs.pipeline.domain.autoaddable import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue import com.android.systemui.qs.ReduceBrightColorsController @@ -44,7 +43,6 @@ import org.mockito.MockitoAnnotations @OptIn(ExperimentalCoroutinesApi::class) @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) class ReduceBrightColorsAutoAddableTest : SysuiTestCase() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/SafetyCenterAutoAddableTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/SafetyCenterAutoAddableTest.kt index 5ce15fa57b1f3f24cce451f0f483b74477483859..d645ee34619ba8f66544460a98e91f0e74228403 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/SafetyCenterAutoAddableTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/SafetyCenterAutoAddableTest.kt @@ -21,7 +21,6 @@ import android.content.pm.PackageManager import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.res.R -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue import com.android.systemui.coroutines.collectValues @@ -52,7 +51,6 @@ import org.mockito.MockitoAnnotations @OptIn(ExperimentalCoroutinesApi::class) @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) class SafetyCenterAutoAddableTest : SysuiTestCase() { private val testDispatcher = StandardTestDispatcher() diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/WalletAutoAddableTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/WalletAutoAddableTest.kt index 1c8cb541e613a7d9796535987e1961cd0ab00557..83ff35d8022d1f6aa73c1f10381e3474ddf47d90 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/WalletAutoAddableTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/WalletAutoAddableTest.kt @@ -18,7 +18,6 @@ package com.android.systemui.qs.pipeline.domain.autoaddable import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue import com.android.systemui.qs.pipeline.domain.model.AutoAddSignal @@ -38,7 +37,6 @@ import org.mockito.MockitoAnnotations @OptIn(ExperimentalCoroutinesApi::class) @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) class WalletAutoAddableTest : SysuiTestCase() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/WorkTileAutoAddableTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/WorkTileAutoAddableTest.kt index de1d29fdcbe5978e15fae44c7ce53b03e6ba919b..adccc84e494baf4e0cf8d13be01aa7bbb5fe8d6f 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/WorkTileAutoAddableTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/WorkTileAutoAddableTest.kt @@ -23,7 +23,6 @@ import android.content.pm.UserInfo.FLAG_PRIMARY import android.content.pm.UserInfo.FLAG_PROFILE import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue import com.android.systemui.qs.pipeline.domain.model.AutoAddSignal @@ -41,7 +40,6 @@ import org.mockito.MockitoAnnotations @OptIn(ExperimentalCoroutinesApi::class) @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) class WorkTileAutoAddableTest : SysuiTestCase() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/interactor/AutoAddInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/interactor/AutoAddInteractorTest.kt index bb18115c960c0fc700464f8e293cb75ef91af48d..41a7ec03408d8650c2b00b14c7557c421cc7aa7c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/interactor/AutoAddInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/interactor/AutoAddInteractorTest.kt @@ -18,7 +18,6 @@ package com.android.systemui.qs.pipeline.domain.interactor import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue import com.android.systemui.dump.DumpManager @@ -47,7 +46,6 @@ import org.mockito.Mockito.verify import org.mockito.MockitoAnnotations @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) @OptIn(ExperimentalCoroutinesApi::class) class AutoAddInteractorTest : SysuiTestCase() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/interactor/CurrentTilesInteractorImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/interactor/CurrentTilesInteractorImplTest.kt index a7505240caeb704977cb9fb3a71846786fd07cb5..a89338a38e890db7fe24be32c2879b6b4d5c24b9 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/interactor/CurrentTilesInteractorImplTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/interactor/CurrentTilesInteractorImplTest.kt @@ -24,7 +24,6 @@ import android.os.UserHandle import android.service.quicksettings.Tile import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue import com.android.systemui.dump.nano.SystemUIProtoDump @@ -71,7 +70,6 @@ import org.mockito.Mockito.verify import org.mockito.MockitoAnnotations @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) @OptIn(ExperimentalCoroutinesApi::class) class CurrentTilesInteractorImplTest : SysuiTestCase() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/interactor/PanelInteractorImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/interactor/PanelInteractorImplTest.kt index 151b256c4f5c23310968f173c1242e57378734ce..0d9711588a1f33403f2884e11dd5a8af99fa8f38 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/interactor/PanelInteractorImplTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/interactor/PanelInteractorImplTest.kt @@ -17,7 +17,6 @@ package com.android.systemui.qs.pipeline.domain.interactor import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.shade.ShadeController import org.junit.Before @@ -27,7 +26,6 @@ import org.mockito.Mock import org.mockito.Mockito.verify import org.mockito.MockitoAnnotations -@RoboPilotTest @RunWith(AndroidJUnit4::class) @SmallTest class PanelInteractorImplTest : SysuiTestCase() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/interactor/RestoreReconciliationInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/interactor/RestoreReconciliationInteractorTest.kt index 2e6b50b637dd1b978cff5de36866d129c924a2a8..f73cab8a10a3e3217260e42aaabe3b2dc5074192 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/interactor/RestoreReconciliationInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/interactor/RestoreReconciliationInteractorTest.kt @@ -2,7 +2,6 @@ package com.android.systemui.qs.pipeline.domain.interactor import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue import com.android.systemui.qs.pipeline.data.model.RestoreData @@ -20,7 +19,6 @@ import org.junit.Test import org.junit.runner.RunWith import org.mockito.MockitoAnnotations -@RoboPilotTest @RunWith(AndroidJUnit4::class) @SmallTest class RestoreReconciliationInteractorTest : SysuiTestCase() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/shared/TileSpecTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/shared/TileSpecTest.kt index 34c4c98429862963a19354fb096b23bf0f02d6e3..558e7694b54c06d249c0f551dfaa03ec6b224860 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/shared/TileSpecTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/shared/TileSpecTest.kt @@ -19,14 +19,12 @@ package com.android.systemui.qs.pipeline.shared import android.content.ComponentName import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.google.common.truth.Truth.assertThat import org.junit.Test import org.junit.runner.RunWith @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) class TileSpecTest : SysuiTestCase() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/base/actions/QSTileIntentUserActionHandlerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/base/actions/QSTileIntentUserActionHandlerTest.kt index 06b7a9fde873340d1a0228ff5edc2326a80ff716..5659f0173860778c4fdc684b41754e74eefbbce9 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/base/actions/QSTileIntentUserActionHandlerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/base/actions/QSTileIntentUserActionHandlerTest.kt @@ -19,7 +19,6 @@ package com.android.systemui.qs.tiles.base.actions import android.content.Intent import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.plugins.ActivityStarter import org.junit.Before @@ -32,7 +31,6 @@ import org.mockito.Mockito.verify import org.mockito.MockitoAnnotations @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) class QSTileIntentUserActionHandlerTest : SysuiTestCase() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/base/analytics/QSTileAnalyticsTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/base/analytics/QSTileAnalyticsTest.kt index 2c4e10eadfc9726a611babed4b865a52ea34987e..9861606fd1b1b3925b874ad20d174ed66ff421cc 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/base/analytics/QSTileAnalyticsTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/base/analytics/QSTileAnalyticsTest.kt @@ -20,7 +20,6 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.internal.logging.InstanceId import com.android.internal.logging.UiEventLogger -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.qs.QSEvent import com.android.systemui.qs.tiles.viewmodel.QSTileConfigTestBuilder @@ -34,7 +33,6 @@ import org.mockito.Mockito.verify import org.mockito.MockitoAnnotations @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) class QSTileAnalyticsTest : SysuiTestCase() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/base/interactor/DisabledByPolicyInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/base/interactor/DisabledByPolicyInteractorTest.kt index 4f25d12aea4989fe72e4e084d9262098c94a8c5d..a6199c25874b2425048d6c2644bab3915afb7b92 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/base/interactor/DisabledByPolicyInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/base/interactor/DisabledByPolicyInteractorTest.kt @@ -24,7 +24,6 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.settingslib.RestrictedLockUtils import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.plugins.ActivityStarter import com.android.systemui.util.mockito.any @@ -46,7 +45,6 @@ import org.mockito.Mockito.verify import org.mockito.MockitoAnnotations @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) class DisabledByPolicyInteractorTest : SysuiTestCase() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/base/logging/QSTileLoggerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/base/logging/QSTileLoggerTest.kt index 4401e0d60da626dd4ff04bbf4e885fdbc84ffe41..f1fcee318141ffbf3dd609cac66dc2488919f2c7 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/base/logging/QSTileLoggerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/base/logging/QSTileLoggerTest.kt @@ -18,7 +18,6 @@ package com.android.systemui.qs.tiles.base.logging import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.common.shared.model.ContentDescription import com.android.systemui.common.shared.model.Icon @@ -39,7 +38,6 @@ import org.mockito.Mock import org.mockito.MockitoAnnotations @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) class QSTileLoggerTest : SysuiTestCase() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelInterfaceComplianceTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelInterfaceComplianceTest.kt index 4760dfa3561d9f30a38949ae371f92eabfdba3cf..2084aeb7fe833cb172fd8255f3d60b6065a961c2 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelInterfaceComplianceTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelInterfaceComplianceTest.kt @@ -20,7 +20,6 @@ import android.testing.TestableLooper import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.MediumTest import com.android.internal.logging.InstanceId -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.classifier.FalsingManagerFake import com.android.systemui.common.shared.model.ContentDescription @@ -49,7 +48,6 @@ import org.mockito.MockitoAnnotations // TODO(b/299909368): Add more tests @MediumTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) @TestableLooper.RunWithLooper(setAsMainLooper = true) class QSTileViewModelInterfaceComplianceTest : SysuiTestCase() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt b/packages/SystemUI/tests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt index 61dd69a8126b5bdaac92d800b3b8083f07a1fdf2..2e16577bb24fd7c232cbd8cb9ffcc10ccdcd7249 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt @@ -52,6 +52,7 @@ import com.google.common.truth.Truth.assertWithMessage import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.Job import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.launch import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runCurrent @@ -462,7 +463,8 @@ class SceneFrameworkIntegrationTest : SysuiTestCase() { fromScene = getCurrentSceneInUi(), toScene = to.key, progress = progressFlow, - isUserInputDriven = false, + isInitiatedByUserInput = false, + isUserInputOngoing = flowOf(false), ) runCurrent() diff --git a/packages/SystemUI/tests/src/com/android/systemui/scene/data/repository/SceneContainerRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/scene/data/repository/SceneContainerRepositoryTest.kt index 432bd0f2a0507b577b94e8de24f6ab9e497fa452..740c6d9329dfd3f73735477bcb0861e91a12814a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/scene/data/repository/SceneContainerRepositoryTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/scene/data/repository/SceneContainerRepositoryTest.kt @@ -29,6 +29,7 @@ import com.android.systemui.scene.shared.model.SceneModel 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.runTest import org.junit.Test import org.junit.runner.RunWith @@ -119,7 +120,8 @@ class SceneContainerRepositoryTest : SysuiTestCase() { fromScene = SceneKey.Lockscreen, toScene = SceneKey.Shade, progress = progress, - isUserInputDriven = false, + isInitiatedByUserInput = false, + isUserInputOngoing = flowOf(false), ) assertThat(reflectedTransitionState).isEqualTo(transitionState.value) diff --git a/packages/SystemUI/tests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt index 8b23d183f1a6e5f3675a5561e7e181a342b787c7..31d26c0d88f95c3e42785974a9624872c4474a2f 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt @@ -83,7 +83,8 @@ class SceneInteractorTest : SysuiTestCase() { fromScene = SceneKey.Lockscreen, toScene = SceneKey.Shade, progress = progress, - isUserInputDriven = false, + isInitiatedByUserInput = false, + isUserInputOngoing = flowOf(false), ) assertThat(reflectedTransitionState).isEqualTo(transitionState.value) @@ -121,7 +122,8 @@ class SceneInteractorTest : SysuiTestCase() { fromScene = underTest.desiredScene.value.key, toScene = SceneKey.Shade, progress = progress, - isUserInputDriven = false, + isInitiatedByUserInput = false, + isUserInputOngoing = flowOf(false), ) assertThat(transitionTo).isEqualTo(SceneKey.Shade) @@ -158,7 +160,8 @@ class SceneInteractorTest : SysuiTestCase() { fromScene = SceneKey.Gone, toScene = SceneKey.Lockscreen, progress = flowOf(0.5f), - isUserInputDriven = false, + isInitiatedByUserInput = false, + isUserInputOngoing = flowOf(false), ) ) val transitioning by @@ -177,7 +180,8 @@ class SceneInteractorTest : SysuiTestCase() { fromScene = SceneKey.Shade, toScene = SceneKey.QuickSettings, progress = flowOf(0.5f), - isUserInputDriven = false, + isInitiatedByUserInput = false, + isUserInputOngoing = flowOf(false), ) ) underTest.setTransitionState(transitionState) @@ -194,7 +198,8 @@ class SceneInteractorTest : SysuiTestCase() { fromScene = SceneKey.Shade, toScene = SceneKey.Lockscreen, progress = flowOf(0.5f), - isUserInputDriven = false, + isInitiatedByUserInput = false, + isUserInputOngoing = flowOf(false), ) ) val transitioning by @@ -222,7 +227,8 @@ class SceneInteractorTest : SysuiTestCase() { fromScene = SceneKey.Shade, toScene = SceneKey.Lockscreen, progress = flowOf(0.5f), - isUserInputDriven = false, + isInitiatedByUserInput = false, + isUserInputOngoing = flowOf(false), ) assertThat(transitioning).isTrue() diff --git a/packages/SystemUI/tests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt b/packages/SystemUI/tests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt index 7b13de657657bc5ebd61f2fc53f4c15804ced86f..3b9621e5c6e06c6ecdb2fc3ad868296b58c44c7f 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt @@ -109,7 +109,8 @@ class SceneContainerStartableTest : SysuiTestCase() { fromScene = SceneKey.Gone, toScene = SceneKey.Shade, progress = flowOf(0.5f), - isUserInputDriven = false, + isInitiatedByUserInput = false, + isUserInputOngoing = flowOf(false), ) assertThat(isVisible).isTrue() sceneInteractor.onSceneChanged(SceneModel(SceneKey.Shade), "reason") @@ -122,7 +123,8 @@ class SceneContainerStartableTest : SysuiTestCase() { fromScene = SceneKey.Shade, toScene = SceneKey.Gone, progress = flowOf(0.5f), - isUserInputDriven = false, + isInitiatedByUserInput = false, + isUserInputOngoing = flowOf(false), ) assertThat(isVisible).isTrue() sceneInteractor.onSceneChanged(SceneModel(SceneKey.Gone), "reason") diff --git a/packages/SystemUI/tests/src/com/android/systemui/settings/UserTrackerImplReceiveTest.kt b/packages/SystemUI/tests/src/com/android/systemui/settings/UserTrackerImplReceiveTest.kt index 1bb2ff8251157f0ace82df0fd82d645fdc90d54d..263b0017221a364507b34841fdc87ba57ce3e47c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/settings/UserTrackerImplReceiveTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/settings/UserTrackerImplReceiveTest.kt @@ -42,6 +42,7 @@ class UserTrackerImplReceiveTest : SysuiTestCase() { @Parameterized.Parameters fun data(): Iterable<String> = listOf( + Intent.ACTION_LOCALE_CHANGED, Intent.ACTION_USER_INFO_CHANGED, Intent.ACTION_MANAGED_PROFILE_AVAILABLE, Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE, diff --git a/packages/SystemUI/tests/src/com/android/systemui/settings/UserTrackerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/settings/UserTrackerImplTest.kt index 52b25f85b8707698be295fbaed50cf9d6ccc0fbe..c32d2597bd61a8bd5da0851819222404b77d2189 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/settings/UserTrackerImplTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/settings/UserTrackerImplTest.kt @@ -177,7 +177,8 @@ class UserTrackerImplTest : SysuiTestCase() { verify(context) .registerReceiverForAllUsers(eq(tracker), capture(captor), isNull(), eq(handler)) with(captor.value) { - assertThat(countActions()).isEqualTo(6) + assertThat(countActions()).isEqualTo(7) + assertThat(hasAction(Intent.ACTION_LOCALE_CHANGED)).isTrue() assertThat(hasAction(Intent.ACTION_USER_INFO_CHANGED)).isTrue() assertThat(hasAction(Intent.ACTION_MANAGED_PROFILE_AVAILABLE)).isTrue() assertThat(hasAction(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE)).isTrue() diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java index dd77da38422fd2bacddaeb2b79c27c2f4aa6b6fe..8d8c70e26ab28fa0d7f52e3d64f21f4681d0fc29 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java @@ -79,7 +79,6 @@ import com.android.keyguard.dagger.KeyguardStatusBarViewComponent; import com.android.keyguard.dagger.KeyguardStatusViewComponent; import com.android.keyguard.dagger.KeyguardUserSwitcherComponent; import com.android.keyguard.logging.KeyguardLogger; -import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.biometrics.AuthController; import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor; @@ -120,6 +119,7 @@ import com.android.systemui.plugins.FalsingManager; import com.android.systemui.plugins.qs.QS; import com.android.systemui.power.domain.interactor.PowerInteractor; import com.android.systemui.qs.QSFragmentLegacy; +import com.android.systemui.res.R; import com.android.systemui.screenrecord.RecordingController; import com.android.systemui.shade.data.repository.FakeShadeRepository; import com.android.systemui.shade.data.repository.ShadeRepository; @@ -153,7 +153,6 @@ import com.android.systemui.statusbar.phone.CentralSurfaces; import com.android.systemui.statusbar.phone.ConfigurationControllerImpl; import com.android.systemui.statusbar.phone.DozeParameters; import com.android.systemui.statusbar.phone.HeadsUpAppearanceController; -import com.android.systemui.statusbar.phone.HeadsUpManagerPhone; import com.android.systemui.statusbar.phone.HeadsUpTouchHelper; import com.android.systemui.statusbar.phone.KeyguardBottomAreaView; import com.android.systemui.statusbar.phone.KeyguardBottomAreaViewController; @@ -170,6 +169,7 @@ import com.android.systemui.statusbar.phone.TapAgainViewController; import com.android.systemui.statusbar.phone.UnlockedScreenOffAnimationController; import com.android.systemui.statusbar.policy.CastController; import com.android.systemui.statusbar.policy.ConfigurationController; +import com.android.systemui.statusbar.policy.HeadsUpManager; import com.android.systemui.statusbar.policy.KeyguardQsUserSwitchController; import com.android.systemui.statusbar.policy.KeyguardStateController; import com.android.systemui.statusbar.policy.KeyguardUserSwitcherController; @@ -182,6 +182,8 @@ import com.android.systemui.util.time.FakeSystemClock; import com.android.systemui.util.time.SystemClock; import com.android.wm.shell.animation.FlingAnimationUtils; +import dagger.Lazy; + import org.junit.After; import org.junit.Before; import org.mockito.ArgumentCaptor; @@ -193,7 +195,6 @@ import org.mockito.stubbing.Answer; import java.util.List; import java.util.Optional; -import dagger.Lazy; import kotlinx.coroutines.CoroutineDispatcher; public class NotificationPanelViewControllerBaseTest extends SysuiTestCase { @@ -208,7 +209,7 @@ public class NotificationPanelViewControllerBaseTest extends SysuiTestCase { @Mock protected KeyguardBottomAreaViewController mKeyguardBottomAreaViewController; @Mock protected ViewPropertyAnimator mViewPropertyAnimator; @Mock protected KeyguardBottomAreaView mQsFrame; - @Mock protected HeadsUpManagerPhone mHeadsUpManager; + @Mock protected HeadsUpManager mHeadsUpManager; @Mock protected NotificationShelfController mNotificationShelfController; @Mock protected NotificationGutsManager mGutsManager; @Mock protected KeyguardStatusBarView mKeyguardStatusBar; @@ -527,7 +528,7 @@ public class NotificationPanelViewControllerBaseTest extends SysuiTestCase { NotificationWakeUpCoordinator coordinator = new NotificationWakeUpCoordinator( mDumpManager, - mock(HeadsUpManagerPhone.class), + mock(HeadsUpManager.class), new StatusBarStateControllerImpl(new UiEventLoggerFake(), mDumpManager, mInteractionJankMonitor, mShadeExpansionStateManager), mKeyguardBypassController, diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java index 2ed20908ba2fdeae8a8c79af47fca10256a87b1c..eb006100d5356d15a032193d682614a8826ae2a0 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java @@ -47,18 +47,34 @@ import android.view.WindowManager; import androidx.test.filters.SmallTest; import com.android.internal.colorextraction.ColorExtractor; +import com.android.keyguard.KeyguardSecurityModel; import com.android.systemui.SysuiTestCase; import com.android.systemui.biometrics.AuthController; +import com.android.systemui.bouncer.data.repository.FakeKeyguardBouncerRepository; +import com.android.systemui.classifier.FalsingCollectorFake; import com.android.systemui.colorextraction.SysuiColorExtractor; import com.android.systemui.common.ui.data.repository.FakeConfigurationRepository; +import com.android.systemui.deviceentry.data.repository.FakeDeviceEntryRepository; import com.android.systemui.dump.DumpManager; +import com.android.systemui.flags.FakeFeatureFlagsClassic; import com.android.systemui.keyguard.KeyguardViewMediator; +import com.android.systemui.keyguard.data.repository.FakeCommandQueue; import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository; +import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository; +import com.android.systemui.keyguard.domain.interactor.FromLockscreenTransitionInteractor; +import com.android.systemui.keyguard.domain.interactor.FromPrimaryBouncerTransitionInteractor; +import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor; +import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor; import com.android.systemui.plugins.statusbar.StatusBarStateController; +import com.android.systemui.power.data.repository.FakePowerRepository; +import com.android.systemui.power.domain.interactor.PowerInteractor; import com.android.systemui.res.R; import com.android.systemui.scene.FakeWindowRootViewComponent; import com.android.systemui.scene.SceneTestUtils; +import com.android.systemui.scene.data.repository.SceneContainerRepository; +import com.android.systemui.scene.domain.interactor.SceneInteractor; import com.android.systemui.scene.shared.flag.FakeSceneContainerFlags; +import com.android.systemui.scene.shared.logger.SceneLogger; import com.android.systemui.shade.data.repository.FakeShadeRepository; import com.android.systemui.shade.domain.interactor.ShadeInteractor; import com.android.systemui.statusbar.StatusBarState; @@ -71,9 +87,9 @@ import com.android.systemui.statusbar.phone.ScreenOffAnimationController; import com.android.systemui.statusbar.phone.ScrimController; import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeUserSetupRepository; import com.android.systemui.statusbar.policy.ConfigurationController; -import com.android.systemui.statusbar.policy.DeviceProvisionedController; import com.android.systemui.statusbar.policy.KeyguardStateController; import com.android.systemui.statusbar.policy.ResourcesSplitShadeStateController; +import com.android.systemui.statusbar.policy.data.repository.FakeDeviceProvisioningRepository; import com.android.systemui.user.domain.interactor.UserInteractor; import com.google.common.util.concurrent.MoreExecutors; @@ -109,6 +125,7 @@ public class NotificationShadeWindowControllerImplTest extends SysuiTestCase { @Mock private SysuiColorExtractor mColorExtractor; @Mock ColorExtractor.GradientColors mGradientColors; @Mock private DumpManager mDumpManager; + @Mock private KeyguardSecurityModel mKeyguardSecurityModel; @Mock private KeyguardStateController mKeyguardStateController; @Mock private ScreenOffAnimationController mScreenOffAnimationController; @Mock private AuthController mAuthController; @@ -123,6 +140,8 @@ public class NotificationShadeWindowControllerImplTest extends SysuiTestCase { private NotificationShadeWindowControllerImpl mNotificationShadeWindowController; private float mPreferredRefreshRate = -1; + private FromLockscreenTransitionInteractor mFromLockscreenTransitionInteractor; + private FromPrimaryBouncerTransitionInteractor mFromPrimaryBouncerTransitionInteractor; @Before public void setUp() { @@ -137,22 +156,86 @@ public class NotificationShadeWindowControllerImplTest extends SysuiTestCase { when(mDozeParameters.getAlwaysOn()).thenReturn(true); when(mColorExtractor.getNeutralColors()).thenReturn(mGradientColors); + FakeKeyguardRepository keyguardRepository = new FakeKeyguardRepository(); + FakeFeatureFlagsClassic featureFlags = new FakeFeatureFlagsClassic(); + FakeShadeRepository shadeRepository = new FakeShadeRepository(); + FakePowerRepository powerRepository = new FakePowerRepository(); + + PowerInteractor powerInteractor = new PowerInteractor( + powerRepository, + new FalsingCollectorFake(), + mScreenOffAnimationController, + mStatusBarStateController); + + SceneInteractor sceneInteractor = new SceneInteractor( + mTestScope.getBackgroundScope(), + new SceneContainerRepository( + mTestScope.getBackgroundScope(), + mUtils.fakeSceneContainerConfig(mUtils.fakeSceneKeys())), + powerRepository, + mock(SceneLogger.class)); + + FakeConfigurationRepository configurationRepository = new FakeConfigurationRepository(); + FakeSceneContainerFlags sceneContainerFlags = new FakeSceneContainerFlags(); + KeyguardInteractor keyguardInteractor = new KeyguardInteractor( + keyguardRepository, + new FakeCommandQueue(), + powerInteractor, + featureFlags, + sceneContainerFlags, + new FakeDeviceEntryRepository(), + new FakeKeyguardBouncerRepository(), + configurationRepository, + shadeRepository, + () -> sceneInteractor); + + FakeKeyguardTransitionRepository keyguardTransitionRepository = + new FakeKeyguardTransitionRepository(); + + KeyguardTransitionInteractor keyguardTransitionInteractor = + new KeyguardTransitionInteractor( + mTestScope.getBackgroundScope(), + keyguardTransitionRepository, + () -> keyguardInteractor, + () -> mFromLockscreenTransitionInteractor, + () -> mFromPrimaryBouncerTransitionInteractor); + + mFromLockscreenTransitionInteractor = new FromLockscreenTransitionInteractor( + keyguardTransitionRepository, + keyguardTransitionInteractor, + mTestScope.getBackgroundScope(), + keyguardInteractor, + featureFlags, + shadeRepository, + powerInteractor); + + mFromPrimaryBouncerTransitionInteractor = new FromPrimaryBouncerTransitionInteractor( + keyguardTransitionRepository, + keyguardTransitionInteractor, + mTestScope.getBackgroundScope(), + keyguardInteractor, + featureFlags, + mKeyguardSecurityModel, + powerInteractor); + mShadeInteractor = new ShadeInteractor( mTestScope.getBackgroundScope(), + new FakeDeviceProvisioningRepository(), new FakeDisableFlagsRepository(), - new FakeSceneContainerFlags(), - mUtils::sceneInteractor, - new FakeKeyguardRepository(), + mock(DozeParameters.class), + sceneContainerFlags, + () -> sceneInteractor, + keyguardRepository, + keyguardTransitionInteractor, + powerInteractor, new FakeUserSetupRepository(), - mock(DeviceProvisionedController.class), mock(UserInteractor.class), new SharedNotificationContainerInteractor( - new FakeConfigurationRepository(), + configurationRepository, mContext, new ResourcesSplitShadeStateController()), - new FakeShadeRepository() - ); + shadeRepository); mNotificationShadeWindowController = new NotificationShadeWindowControllerImpl( mContext, diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt index add1580f25a56d0cf09da48f6c5e6d0f0c20fd31..b4f9e8dcfb397957862005fe0bf4410813bede53 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt @@ -34,6 +34,7 @@ import com.android.systemui.back.domain.interactor.BackActionInteractor import com.android.systemui.biometrics.data.repository.FakeFacePropertyRepository import com.android.systemui.bouncer.data.repository.BouncerMessageRepositoryImpl import com.android.systemui.bouncer.data.repository.FakeKeyguardBouncerRepository +import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor import com.android.systemui.bouncer.domain.interactor.BouncerMessageInteractor import com.android.systemui.bouncer.domain.interactor.CountDownTimerUtil import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerCallbackInteractor @@ -144,6 +145,8 @@ class NotificationShadeWindowViewControllerTest : SysuiTestCase() { @Mock lateinit var primaryBouncerToGoneTransitionViewModel: PrimaryBouncerToGoneTransitionViewModel @Mock lateinit var keyEventInteractor: KeyEventInteractor + @Mock lateinit var primaryBouncerInteractor: PrimaryBouncerInteractor + @Mock lateinit var alternateBouncerInteractor: AlternateBouncerInteractor private val notificationExpansionRepository = NotificationExpansionRepository() private lateinit var fakeClock: FakeSystemClock @@ -176,6 +179,7 @@ class NotificationShadeWindowViewControllerTest : SysuiTestCase() { featureFlags.set(Flags.REVAMPED_BOUNCER_MESSAGES, true) featureFlags.set(Flags.LOCKSCREEN_WALLPAPER_DREAM_ENABLED, false) featureFlags.set(Flags.MIGRATE_NSSL, false) + featureFlags.set(Flags.ALTERNATE_BOUNCER_VIEW, false) testScope = TestScope() fakeClock = FakeSystemClock() @@ -248,6 +252,8 @@ class NotificationShadeWindowViewControllerTest : SysuiTestCase() { ), BouncerLogger(logcatLogBuffer("BouncerLog")), keyEventInteractor, + primaryBouncerInteractor, + alternateBouncerInteractor, ) underTest.setupExpandedStatusBar() underTest.setDragDownHelper(dragDownHelper) diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.kt index 00230202d9412b287cf8b54c8205f20031b60acd..189c9e25d9b0368ec9cbe834961a69a8a9b00be7 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.kt @@ -33,6 +33,7 @@ import com.android.systemui.back.domain.interactor.BackActionInteractor import com.android.systemui.biometrics.data.repository.FakeFacePropertyRepository import com.android.systemui.bouncer.data.repository.BouncerMessageRepositoryImpl import com.android.systemui.bouncer.data.repository.FakeKeyguardBouncerRepository +import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor import com.android.systemui.bouncer.domain.interactor.BouncerMessageInteractor import com.android.systemui.bouncer.domain.interactor.CountDownTimerUtil import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerCallbackInteractor @@ -141,6 +142,8 @@ class NotificationShadeWindowViewTest : SysuiTestCase() { Optional<UnfoldTransitionProgressProvider> @Mock private lateinit var notificationInsetsController: NotificationInsetsController @Mock private lateinit var keyguardTransitionInteractor: KeyguardTransitionInteractor + @Mock lateinit var primaryBouncerInteractor: PrimaryBouncerInteractor + @Mock lateinit var alternateBouncerInteractor: AlternateBouncerInteractor @Mock private lateinit var primaryBouncerToGoneTransitionViewModel: PrimaryBouncerToGoneTransitionViewModel @@ -180,6 +183,7 @@ class NotificationShadeWindowViewTest : SysuiTestCase() { featureFlags.set(Flags.REVAMPED_BOUNCER_MESSAGES, true) featureFlags.set(Flags.LOCKSCREEN_WALLPAPER_DREAM_ENABLED, false) featureFlags.set(Flags.MIGRATE_NSSL, false) + featureFlags.set(Flags.ALTERNATE_BOUNCER_VIEW, false) testScope = TestScope() controller = NotificationShadeWindowViewController( @@ -250,6 +254,8 @@ class NotificationShadeWindowViewTest : SysuiTestCase() { ), BouncerLogger(logcatLogBuffer("BouncerLog")), Mockito.mock(KeyEventInteractor::class.java), + primaryBouncerInteractor, + alternateBouncerInteractor, ) controller.setupExpandedStatusBar() diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerBaseTest.java index 8138b328a3c51f08182473d58af90a82ac53a6b0..65174bab7f638e6106a50e34cb8b5ef45467b74c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerBaseTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerBaseTest.java @@ -32,23 +32,39 @@ import android.view.accessibility.AccessibilityManager; import com.android.internal.jank.InteractionJankMonitor; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.UiEventLogger; +import com.android.keyguard.KeyguardSecurityModel; import com.android.keyguard.KeyguardStatusView; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.systemui.SysuiTestCase; +import com.android.systemui.bouncer.data.repository.FakeKeyguardBouncerRepository; +import com.android.systemui.classifier.FalsingCollectorFake; import com.android.systemui.common.ui.data.repository.FakeConfigurationRepository; +import com.android.systemui.deviceentry.data.repository.FakeDeviceEntryRepository; import com.android.systemui.dump.DumpManager; +import com.android.systemui.flags.FakeFeatureFlagsClassic; import com.android.systemui.flags.FeatureFlags; import com.android.systemui.fragments.FragmentHostManager; +import com.android.systemui.keyguard.data.repository.FakeCommandQueue; import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository; +import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository; +import com.android.systemui.keyguard.domain.interactor.FromLockscreenTransitionInteractor; +import com.android.systemui.keyguard.domain.interactor.FromPrimaryBouncerTransitionInteractor; import com.android.systemui.keyguard.domain.interactor.KeyguardFaceAuthInteractor; +import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor; +import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor; import com.android.systemui.media.controls.pipeline.MediaDataManager; import com.android.systemui.media.controls.ui.MediaHierarchyManager; import com.android.systemui.plugins.FalsingManager; import com.android.systemui.plugins.qs.QS; +import com.android.systemui.power.data.repository.FakePowerRepository; +import com.android.systemui.power.domain.interactor.PowerInteractor; import com.android.systemui.qs.QSFragmentLegacy; import com.android.systemui.res.R; import com.android.systemui.scene.SceneTestUtils; +import com.android.systemui.scene.data.repository.SceneContainerRepository; +import com.android.systemui.scene.domain.interactor.SceneInteractor; import com.android.systemui.scene.shared.flag.FakeSceneContainerFlags; +import com.android.systemui.scene.shared.logger.SceneLogger; import com.android.systemui.screenrecord.RecordingController; import com.android.systemui.shade.data.repository.FakeShadeRepository; import com.android.systemui.shade.domain.interactor.ShadeInteractor; @@ -64,19 +80,21 @@ import com.android.systemui.statusbar.disableflags.data.repository.FakeDisableFl import com.android.systemui.statusbar.notification.stack.AmbientState; import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController; import com.android.systemui.statusbar.notification.stack.domain.interactor.SharedNotificationContainerInteractor; +import com.android.systemui.statusbar.phone.DozeParameters; import com.android.systemui.statusbar.phone.KeyguardBottomAreaView; import com.android.systemui.statusbar.phone.KeyguardBypassController; import com.android.systemui.statusbar.phone.KeyguardStatusBarView; import com.android.systemui.statusbar.phone.LightBarController; import com.android.systemui.statusbar.phone.LockscreenGestureLogger; +import com.android.systemui.statusbar.phone.ScreenOffAnimationController; import com.android.systemui.statusbar.phone.ScrimController; import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager; import com.android.systemui.statusbar.phone.StatusBarTouchableRegionManager; import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeUserSetupRepository; import com.android.systemui.statusbar.policy.CastController; -import com.android.systemui.statusbar.policy.DeviceProvisionedController; import com.android.systemui.statusbar.policy.KeyguardStateController; import com.android.systemui.statusbar.policy.ResourcesSplitShadeStateController; +import com.android.systemui.statusbar.policy.data.repository.FakeDeviceProvisioningRepository; import com.android.systemui.user.domain.interactor.UserInteractor; import com.android.systemui.util.kotlin.JavaAdapter; @@ -103,8 +121,7 @@ public class QuickSettingsControllerBaseTest extends SysuiTestCase { protected SceneTestUtils mUtils = new SceneTestUtils(this); protected TestScope mTestScope = mUtils.getTestScope(); - @Mock - protected Resources mResources; + @Mock protected Resources mResources; @Mock protected KeyguardBottomAreaView mQsFrame; @Mock protected KeyguardStatusBarView mKeyguardStatusBar; @Mock protected QS mQs; @@ -126,6 +143,7 @@ public class QuickSettingsControllerBaseTest extends SysuiTestCase { @Mock protected NotificationShadeDepthController mNotificationShadeDepthController; @Mock protected ShadeHeaderController mShadeHeaderController; @Mock protected StatusBarTouchableRegionManager mStatusBarTouchableRegionManager; + @Mock protected DozeParameters mDozeParameters; @Mock protected KeyguardStateController mKeyguardStateController; @Mock protected KeyguardBypassController mKeyguardBypassController; @Mock protected KeyguardUpdateMonitor mKeyguardUpdateMonitor; @@ -144,7 +162,6 @@ public class QuickSettingsControllerBaseTest extends SysuiTestCase { @Mock protected DumpManager mDumpManager; @Mock protected UiEventLogger mUiEventLogger; @Mock protected CastController mCastController; - @Mock protected DeviceProvisionedController mDeviceProvisionedController; @Mock protected UserInteractor mUserInteractor; protected FakeDisableFlagsRepository mDisableFlagsRepository = new FakeDisableFlagsRepository(); @@ -161,6 +178,8 @@ public class QuickSettingsControllerBaseTest extends SysuiTestCase { new ShadeExpansionStateManager(); protected FragmentHostManager.FragmentListener mFragmentListener; + private FromLockscreenTransitionInteractor mFromLockscreenTransitionInteractor; + private FromPrimaryBouncerTransitionInteractor mFromPrimaryBouncerTransitionInteractor; @Before public void setup() { @@ -169,21 +188,89 @@ public class QuickSettingsControllerBaseTest extends SysuiTestCase { mStatusBarStateController = new StatusBarStateControllerImpl(mUiEventLogger, mDumpManager, mInteractionJankMonitor, mShadeExpansionStateManager); - when(mDeviceProvisionedController.isDeviceProvisioned()).thenReturn(true); + FakeDeviceProvisioningRepository deviceProvisioningRepository = + new FakeDeviceProvisioningRepository(); + deviceProvisioningRepository.setDeviceProvisioned(true); + FakeFeatureFlagsClassic featureFlags = new FakeFeatureFlagsClassic(); + FakePowerRepository powerRepository = new FakePowerRepository(); + FakeConfigurationRepository configurationRepository = new FakeConfigurationRepository(); + + PowerInteractor powerInteractor = new PowerInteractor( + powerRepository, + new FalsingCollectorFake(), + mock(ScreenOffAnimationController.class), + mStatusBarStateController); + + SceneInteractor sceneInteractor = new SceneInteractor( + mTestScope.getBackgroundScope(), + new SceneContainerRepository( + mTestScope.getBackgroundScope(), + mUtils.fakeSceneContainerConfig(mUtils.fakeSceneKeys())), + powerRepository, + mock(SceneLogger.class)); + + FakeSceneContainerFlags sceneContainerFlags = new FakeSceneContainerFlags(); + KeyguardInteractor keyguardInteractor = new KeyguardInteractor( + mKeyguardRepository, + new FakeCommandQueue(), + powerInteractor, + featureFlags, + sceneContainerFlags, + new FakeDeviceEntryRepository(), + new FakeKeyguardBouncerRepository(), + configurationRepository, + mShadeRepository, + () -> sceneInteractor); + + FakeKeyguardTransitionRepository keyguardTransitionRepository = + new FakeKeyguardTransitionRepository(); + + KeyguardTransitionInteractor keyguardTransitionInteractor = + new KeyguardTransitionInteractor( + mTestScope.getBackgroundScope(), + keyguardTransitionRepository, + () -> keyguardInteractor, + () -> mFromLockscreenTransitionInteractor, + () -> mFromPrimaryBouncerTransitionInteractor); + + mFromLockscreenTransitionInteractor = new FromLockscreenTransitionInteractor( + keyguardTransitionRepository, + keyguardTransitionInteractor, + mTestScope.getBackgroundScope(), + keyguardInteractor, + featureFlags, + mShadeRepository, + powerInteractor); + + mFromPrimaryBouncerTransitionInteractor = new FromPrimaryBouncerTransitionInteractor( + keyguardTransitionRepository, + keyguardTransitionInteractor, + mTestScope.getBackgroundScope(), + keyguardInteractor, + featureFlags, + mock(KeyguardSecurityModel.class), + powerInteractor); + + ResourcesSplitShadeStateController splitShadeStateController = + new ResourcesSplitShadeStateController(); + mShadeInteractor = new ShadeInteractor( mTestScope.getBackgroundScope(), + deviceProvisioningRepository, mDisableFlagsRepository, - new FakeSceneContainerFlags(), - () -> mUtils.sceneInteractor(), + mDozeParameters, + sceneContainerFlags, + () -> sceneInteractor, mKeyguardRepository, + keyguardTransitionInteractor, + powerInteractor, new FakeUserSetupRepository(), - mDeviceProvisionedController, mUserInteractor, new SharedNotificationContainerInteractor( - new FakeConfigurationRepository(), + configurationRepository, mContext, - new ResourcesSplitShadeStateController()), + splitShadeStateController), mShadeRepository ); @@ -262,7 +349,7 @@ public class QuickSettingsControllerBaseTest extends SysuiTestCase { mShadeInteractor, new JavaAdapter(mTestScope.getBackgroundScope()), mCastController, - new ResourcesSplitShadeStateController() + splitShadeStateController ); mQsController.init(); diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/ShadeControllerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/ShadeControllerImplTest.kt index b5841a9de150452ea76f5ace3b0933c409a6404e..215f8b1c462f7b29b2d980c8fdc41fa120a51e20 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/shade/ShadeControllerImplTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/ShadeControllerImplTest.kt @@ -17,6 +17,7 @@ package com.android.systemui.shade import android.testing.AndroidTestingRunner +import android.testing.TestableLooper.RunWithLooper import android.view.Display import android.view.WindowManager import androidx.test.filters.SmallTest @@ -54,6 +55,7 @@ import org.mockito.Mockito.verify import org.mockito.MockitoAnnotations @RunWith(AndroidTestingRunner::class) +@RunWithLooper(setAsMainLooper = true) @SmallTest class ShadeControllerImplTest : SysuiTestCase() { private val executor = FakeExecutor(FakeSystemClock()) diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/data/repository/ShadeInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/data/repository/ShadeInteractorTest.kt index 2be1c09843c104caa5f7c9c357ef154fe0cff752..bcb060ddb41752b29bf6bd7c3483ea97d7f91281 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/shade/data/repository/ShadeInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/data/repository/ShadeInteractorTest.kt @@ -16,50 +16,53 @@ package com.android.systemui.shade.data.repository -import android.app.ActivityManager import android.app.StatusBarManager.DISABLE2_NONE import android.app.StatusBarManager.DISABLE2_NOTIFICATION_SHADE import android.app.StatusBarManager.DISABLE2_QUICK_SETTINGS import android.content.pm.UserInfo import android.os.UserManager import androidx.test.filters.SmallTest -import com.android.internal.logging.UiEventLogger -import com.android.keyguard.KeyguardUpdateMonitor +import com.android.SysUITestModule +import com.android.TestMocksModule import com.android.systemui.SysuiTestCase import com.android.systemui.common.ui.data.repository.FakeConfigurationRepository import com.android.systemui.coroutines.collectLastValue -import com.android.systemui.flags.FakeFeatureFlags +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.flags.FakeFeatureFlagsClassicModule import com.android.systemui.flags.Flags import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository -import com.android.systemui.keyguard.domain.interactor.KeyguardInteractorFactory +import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository +import com.android.systemui.keyguard.shared.model.DozeStateModel +import com.android.systemui.keyguard.shared.model.DozeTransitionModel +import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.keyguard.shared.model.StatusBarState -import com.android.systemui.plugins.ActivityStarter +import com.android.systemui.keyguard.shared.model.TransitionState +import com.android.systemui.keyguard.shared.model.TransitionStep +import com.android.systemui.power.data.repository.FakePowerRepository +import com.android.systemui.power.shared.model.WakeSleepReason +import com.android.systemui.power.shared.model.WakefulnessState import com.android.systemui.res.R -import com.android.systemui.scene.SceneTestUtils -import com.android.systemui.scene.shared.flag.FakeSceneContainerFlags +import com.android.systemui.scene.domain.interactor.SceneInteractor import com.android.systemui.scene.shared.model.ObservableTransitionState import com.android.systemui.scene.shared.model.SceneKey import com.android.systemui.shade.domain.interactor.ShadeInteractor import com.android.systemui.statusbar.disableflags.data.model.DisableFlagsModel import com.android.systemui.statusbar.disableflags.data.repository.FakeDisableFlagsRepository -import com.android.systemui.statusbar.notification.stack.domain.interactor.SharedNotificationContainerInteractor +import com.android.systemui.statusbar.phone.DozeParameters import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeUserSetupRepository -import com.android.systemui.statusbar.policy.DeviceProvisionedController -import com.android.systemui.statusbar.policy.ResourcesSplitShadeStateController -import com.android.systemui.telephony.data.repository.FakeTelephonyRepository -import com.android.systemui.telephony.domain.interactor.TelephonyInteractor +import com.android.systemui.statusbar.policy.data.repository.FakeDeviceProvisioningRepository import com.android.systemui.user.data.model.UserSwitcherSettingsModel import com.android.systemui.user.data.repository.FakeUserRepository -import com.android.systemui.user.domain.interactor.GuestUserInteractor -import com.android.systemui.user.domain.interactor.HeadlessSystemUserMode -import com.android.systemui.user.domain.interactor.RefreshUsersScheduler -import com.android.systemui.user.domain.interactor.UserInteractor -import com.android.systemui.util.mockito.mock +import com.android.systemui.user.domain.UserDomainLayerModule import com.android.systemui.util.mockito.whenever import com.google.common.truth.Truth.assertThat +import dagger.BindsInstance +import dagger.Component import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest import org.junit.Before @@ -70,50 +73,55 @@ import org.mockito.MockitoAnnotations @SmallTest @OptIn(ExperimentalCoroutinesApi::class) class ShadeInteractorTest : SysuiTestCase() { - private lateinit var underTest: ShadeInteractor - private val utils = SceneTestUtils(this) - private val testScope = utils.testScope - private val featureFlags = FakeFeatureFlags() - private val sceneContainerFlags = FakeSceneContainerFlags() - private val sceneInteractor = utils.sceneInteractor() - private val userSetupRepository = FakeUserSetupRepository() - private val userRepository = FakeUserRepository() - private val disableFlagsRepository = FakeDisableFlagsRepository() - private val keyguardRepository = FakeKeyguardRepository() - private val shadeRepository = FakeShadeRepository() - private val configurationRepository = FakeConfigurationRepository() - private val sharedNotificationContainerInteractor = - SharedNotificationContainerInteractor( - configurationRepository, - mContext, - ResourcesSplitShadeStateController() - ) - - @Mock private lateinit var manager: UserManager - @Mock private lateinit var headlessSystemUserMode: HeadlessSystemUserMode - @Mock private lateinit var deviceProvisionedController: DeviceProvisionedController - @Mock private lateinit var activityStarter: ActivityStarter - @Mock private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor - @Mock private lateinit var activityManager: ActivityManager - @Mock private lateinit var uiEventLogger: UiEventLogger - @Mock private lateinit var guestInteractor: GuestUserInteractor - - private lateinit var userInteractor: UserInteractor + @Mock private lateinit var dozeParameters: DozeParameters + + private lateinit var testComponent: TestComponent + + private val configurationRepository + get() = testComponent.configurationRepository + private val deviceProvisioningRepository + get() = testComponent.deviceProvisioningRepository + private val disableFlagsRepository + get() = testComponent.disableFlagsRepository + private val keyguardRepository + get() = testComponent.keyguardRepository + private val keyguardTransitionRepository + get() = testComponent.keygaurdTransitionRepository + private val powerRepository + get() = testComponent.powerRepository + private val sceneInteractor + get() = testComponent.sceneInteractor + private val shadeRepository + get() = testComponent.shadeRepository + private val testScope + get() = testComponent.testScope + private val userRepository + get() = testComponent.userRepository + private val userSetupRepository + get() = testComponent.userSetupRepository + + private lateinit var underTest: ShadeInteractor @Before fun setUp() { MockitoAnnotations.initMocks(this) - featureFlags.set(Flags.FACE_AUTH_REFACTOR, false) - featureFlags.set(Flags.FULL_SCREEN_USER_SWITCHER, true) - - val refreshUsersScheduler = - RefreshUsersScheduler( - applicationScope = testScope.backgroundScope, - mainDispatcher = utils.testDispatcher, - repository = userRepository, - ) + testComponent = + DaggerShadeInteractorTest_TestComponent.factory() + .create( + test = this, + featureFlags = + FakeFeatureFlagsClassicModule { + set(Flags.FACE_AUTH_REFACTOR, false) + set(Flags.FULL_SCREEN_USER_SWITCHER, true) + }, + mocks = + TestMocksModule( + dozeParameters = dozeParameters, + ), + ) + underTest = testComponent.underTest runBlocking { val userInfos = @@ -131,44 +139,6 @@ class ShadeInteractorTest : SysuiTestCase() { userRepository.setUserInfos(userInfos) userRepository.setSelectedUserInfo(userInfos[0]) } - userInteractor = - UserInteractor( - applicationContext = context, - repository = userRepository, - activityStarter = activityStarter, - keyguardInteractor = - KeyguardInteractorFactory.create(featureFlags = featureFlags) - .keyguardInteractor, - featureFlags = featureFlags, - manager = manager, - headlessSystemUserMode = headlessSystemUserMode, - applicationScope = testScope.backgroundScope, - telephonyInteractor = - TelephonyInteractor( - repository = FakeTelephonyRepository(), - ), - broadcastDispatcher = fakeBroadcastDispatcher, - keyguardUpdateMonitor = keyguardUpdateMonitor, - backgroundDispatcher = utils.testDispatcher, - activityManager = activityManager, - refreshUsersScheduler = refreshUsersScheduler, - guestUserInteractor = guestInteractor, - uiEventLogger = uiEventLogger, - userRestrictionChecker = mock(), - ) - underTest = - ShadeInteractor( - testScope.backgroundScope, - disableFlagsRepository, - sceneContainerFlags, - { sceneInteractor }, - keyguardRepository, - userSetupRepository, - deviceProvisionedController, - userInteractor, - sharedNotificationContainerInteractor, - shadeRepository, - ) } @Test @@ -188,7 +158,7 @@ class ShadeInteractorTest : SysuiTestCase() { @Test fun isExpandToQsEnabled_deviceNotProvisioned_false() = testScope.runTest { - whenever(deviceProvisionedController.isDeviceProvisioned).thenReturn(false) + deviceProvisioningRepository.setDeviceProvisioned(false) val actual by collectLastValue(underTest.isExpandToQsEnabled) @@ -198,7 +168,7 @@ class ShadeInteractorTest : SysuiTestCase() { @Test fun isExpandToQsEnabled_userNotSetupAndSimpleUserSwitcher_false() = testScope.runTest { - whenever(deviceProvisionedController.isDeviceProvisioned).thenReturn(true) + deviceProvisioningRepository.setDeviceProvisioned(true) userSetupRepository.setUserSetup(false) userRepository.setSettings(UserSwitcherSettingsModel(isSimpleUserSwitcher = true)) @@ -211,7 +181,7 @@ class ShadeInteractorTest : SysuiTestCase() { @Test fun isExpandToQsEnabled_shadeNotEnabled_false() = testScope.runTest { - whenever(deviceProvisionedController.isDeviceProvisioned).thenReturn(true) + deviceProvisioningRepository.setDeviceProvisioned(true) userSetupRepository.setUserSetup(true) disableFlagsRepository.disableFlags.value = @@ -227,7 +197,7 @@ class ShadeInteractorTest : SysuiTestCase() { @Test fun isExpandToQsEnabled_quickSettingsNotEnabled_false() = testScope.runTest { - whenever(deviceProvisionedController.isDeviceProvisioned).thenReturn(true) + deviceProvisioningRepository.setDeviceProvisioned(true) userSetupRepository.setUserSetup(true) disableFlagsRepository.disableFlags.value = @@ -242,7 +212,7 @@ class ShadeInteractorTest : SysuiTestCase() { @Test fun isExpandToQsEnabled_dozing_false() = testScope.runTest { - whenever(deviceProvisionedController.isDeviceProvisioned).thenReturn(true) + deviceProvisioningRepository.setDeviceProvisioned(true) userSetupRepository.setUserSetup(true) disableFlagsRepository.disableFlags.value = DisableFlagsModel( @@ -259,7 +229,7 @@ class ShadeInteractorTest : SysuiTestCase() { @Test fun isExpandToQsEnabled_userSetup_true() = testScope.runTest { - whenever(deviceProvisionedController.isDeviceProvisioned).thenReturn(true) + deviceProvisioningRepository.setDeviceProvisioned(true) keyguardRepository.setIsDozing(false) disableFlagsRepository.disableFlags.value = DisableFlagsModel( @@ -276,7 +246,7 @@ class ShadeInteractorTest : SysuiTestCase() { @Test fun isExpandToQsEnabled_notSimpleUserSwitcher_true() = testScope.runTest { - whenever(deviceProvisionedController.isDeviceProvisioned).thenReturn(true) + deviceProvisioningRepository.setDeviceProvisioned(true) keyguardRepository.setIsDozing(false) disableFlagsRepository.disableFlags.value = DisableFlagsModel( @@ -293,7 +263,7 @@ class ShadeInteractorTest : SysuiTestCase() { @Test fun isExpandToQsEnabled_respondsToDozingUpdates() = testScope.runTest { - whenever(deviceProvisionedController.isDeviceProvisioned).thenReturn(true) + deviceProvisioningRepository.setDeviceProvisioned(true) keyguardRepository.setIsDozing(false) disableFlagsRepository.disableFlags.value = DisableFlagsModel( @@ -321,7 +291,7 @@ class ShadeInteractorTest : SysuiTestCase() { @Test fun isExpandToQsEnabled_respondsToDisableUpdates() = testScope.runTest { - whenever(deviceProvisionedController.isDeviceProvisioned).thenReturn(true) + deviceProvisioningRepository.setDeviceProvisioned(true) keyguardRepository.setIsDozing(false) disableFlagsRepository.disableFlags.value = DisableFlagsModel( @@ -353,7 +323,7 @@ class ShadeInteractorTest : SysuiTestCase() { @Test fun isExpandToQsEnabled_respondsToUserUpdates() = testScope.runTest { - whenever(deviceProvisionedController.isDeviceProvisioned).thenReturn(true) + deviceProvisioningRepository.setDeviceProvisioned(true) keyguardRepository.setIsDozing(false) disableFlagsRepository.disableFlags.value = DisableFlagsModel( @@ -625,7 +595,8 @@ class ShadeInteractorTest : SysuiTestCase() { fromScene = SceneKey.Lockscreen, toScene = key, progress = progress, - isUserInputDriven = false, + isInitiatedByUserInput = false, + isUserInputOngoing = flowOf(false), ) ) sceneInteractor.setTransitionState(transitionState) @@ -662,7 +633,8 @@ class ShadeInteractorTest : SysuiTestCase() { fromScene = key, toScene = SceneKey.Lockscreen, progress = progress, - isUserInputDriven = false, + isInitiatedByUserInput = false, + isUserInputOngoing = flowOf(false), ) ) sceneInteractor.setTransitionState(transitionState) @@ -698,7 +670,8 @@ class ShadeInteractorTest : SysuiTestCase() { fromScene = SceneKey.Lockscreen, toScene = SceneKey.Shade, progress = progress, - isUserInputDriven = false, + isInitiatedByUserInput = false, + isUserInputOngoing = flowOf(false), ) ) sceneInteractor.setTransitionState(transitionState) @@ -974,7 +947,8 @@ class ShadeInteractorTest : SysuiTestCase() { fromScene = SceneKey.Lockscreen, toScene = key, progress = progress, - isUserInputDriven = false, + isInitiatedByUserInput = false, + isUserInputOngoing = flowOf(false), ) ) sceneInteractor.setTransitionState(transitionState) @@ -1011,7 +985,8 @@ class ShadeInteractorTest : SysuiTestCase() { fromScene = SceneKey.Lockscreen, toScene = key, progress = progress, - isUserInputDriven = true, + isInitiatedByUserInput = true, + isUserInputOngoing = flowOf(false), ) ) sceneInteractor.setTransitionState(transitionState) @@ -1048,7 +1023,8 @@ class ShadeInteractorTest : SysuiTestCase() { fromScene = key, toScene = SceneKey.Lockscreen, progress = progress, - isUserInputDriven = false, + isInitiatedByUserInput = false, + isUserInputOngoing = flowOf(false), ) ) sceneInteractor.setTransitionState(transitionState) @@ -1085,7 +1061,8 @@ class ShadeInteractorTest : SysuiTestCase() { fromScene = key, toScene = SceneKey.Lockscreen, progress = progress, - isUserInputDriven = true, + isInitiatedByUserInput = true, + isUserInputOngoing = flowOf(false), ) ) sceneInteractor.setTransitionState(transitionState) @@ -1120,8 +1097,9 @@ class ShadeInteractorTest : SysuiTestCase() { ObservableTransitionState.Transition( fromScene = SceneKey.Lockscreen, toScene = SceneKey.QuickSettings, - progress = progress, - isUserInputDriven = true, + progress = MutableStateFlow(0f), + isInitiatedByUserInput = true, + isUserInputOngoing = flowOf(false), ) ) sceneInteractor.setTransitionState(transitionState) @@ -1129,4 +1107,168 @@ class ShadeInteractorTest : SysuiTestCase() { // THEN interacting is false assertThat(interacting).isFalse() } + + @Test + fun isShadeTouchable_isFalse_whenFrpIsActive() = + testScope.runTest { + deviceProvisioningRepository.setFactoryResetProtectionActive(true) + keyguardTransitionRepository.sendTransitionStep( + TransitionStep( + transitionState = TransitionState.STARTED, + ) + ) + val isShadeTouchable by collectLastValue(underTest.isShadeTouchable) + runCurrent() + assertThat(isShadeTouchable).isFalse() + } + + @Test + fun isShadeTouchable_isFalse_whenDeviceAsleepAndNotPulsing() = + testScope.runTest { + powerRepository.updateWakefulness( + rawState = WakefulnessState.ASLEEP, + lastWakeReason = WakeSleepReason.POWER_BUTTON, + lastSleepReason = WakeSleepReason.OTHER, + ) + // goingToSleep == false + // TODO: remove? + keyguardTransitionRepository.sendTransitionStep( + TransitionStep( + from = KeyguardState.GONE, + to = KeyguardState.LOCKSCREEN, + transitionState = TransitionState.STARTED, + ) + ) + keyguardRepository.setDozeTransitionModel( + DozeTransitionModel( + to = DozeStateModel.DOZE_AOD, + ) + ) + val isShadeTouchable by collectLastValue(underTest.isShadeTouchable) + runCurrent() + assertThat(isShadeTouchable).isFalse() + } + + @Test + fun isShadeTouchable_isTrue_whenDeviceAsleepAndPulsing() = + testScope.runTest { + powerRepository.updateWakefulness( + rawState = WakefulnessState.ASLEEP, + lastWakeReason = WakeSleepReason.POWER_BUTTON, + lastSleepReason = WakeSleepReason.OTHER, + ) + // goingToSleep == false + // TODO: remove? + keyguardTransitionRepository.sendTransitionStep( + TransitionStep( + from = KeyguardState.GONE, + to = KeyguardState.LOCKSCREEN, + transitionState = TransitionState.STARTED, + ) + ) + keyguardRepository.setDozeTransitionModel( + DozeTransitionModel( + to = DozeStateModel.DOZE_PULSING, + ) + ) + val isShadeTouchable by collectLastValue(underTest.isShadeTouchable) + runCurrent() + assertThat(isShadeTouchable).isTrue() + } + + @Test + fun isShadeTouchable_isFalse_whenStartingToSleepAndNotControlScreenOff() = + testScope.runTest { + powerRepository.updateWakefulness( + rawState = WakefulnessState.STARTING_TO_SLEEP, + lastWakeReason = WakeSleepReason.POWER_BUTTON, + lastSleepReason = WakeSleepReason.OTHER, + ) + // goingToSleep == true + keyguardTransitionRepository.sendTransitionStep( + TransitionStep( + from = KeyguardState.GONE, + to = KeyguardState.AOD, + transitionState = TransitionState.STARTED, + ) + ) + whenever(dozeParameters.shouldControlScreenOff()).thenReturn(false) + val isShadeTouchable by collectLastValue(underTest.isShadeTouchable) + runCurrent() + assertThat(isShadeTouchable).isFalse() + } + + @Test + fun isShadeTouchable_isTrue_whenStartingToSleepAndControlScreenOff() = + testScope.runTest { + powerRepository.updateWakefulness( + rawState = WakefulnessState.STARTING_TO_SLEEP, + lastWakeReason = WakeSleepReason.POWER_BUTTON, + lastSleepReason = WakeSleepReason.OTHER, + ) + // goingToSleep == true + keyguardTransitionRepository.sendTransitionStep( + TransitionStep( + from = KeyguardState.GONE, + to = KeyguardState.AOD, + transitionState = TransitionState.STARTED, + ) + ) + whenever(dozeParameters.shouldControlScreenOff()).thenReturn(true) + val isShadeTouchable by collectLastValue(underTest.isShadeTouchable) + runCurrent() + assertThat(isShadeTouchable).isTrue() + } + + @Test + fun isShadeTouchable_isTrue_whenNotAsleep() = + testScope.runTest { + powerRepository.updateWakefulness( + rawState = WakefulnessState.AWAKE, + lastWakeReason = WakeSleepReason.POWER_BUTTON, + lastSleepReason = WakeSleepReason.OTHER, + ) + keyguardTransitionRepository.sendTransitionStep( + TransitionStep( + transitionState = TransitionState.STARTED, + ) + ) + val isShadeTouchable by collectLastValue(underTest.isShadeTouchable) + runCurrent() + assertThat(isShadeTouchable).isTrue() + } + + @SysUISingleton + @Component( + modules = + [ + SysUITestModule::class, + UserDomainLayerModule::class, + ] + ) + interface TestComponent { + + val underTest: ShadeInteractor + + val configurationRepository: FakeConfigurationRepository + val deviceProvisioningRepository: FakeDeviceProvisioningRepository + val disableFlagsRepository: FakeDisableFlagsRepository + val keyguardRepository: FakeKeyguardRepository + val keygaurdTransitionRepository: FakeKeyguardTransitionRepository + val powerRepository: FakePowerRepository + val sceneInteractor: SceneInteractor + val shadeRepository: FakeShadeRepository + val testScope: TestScope + val userRepository: FakeUserRepository + val userSetupRepository: FakeUserSetupRepository + + @Component.Factory + interface Factory { + fun create( + @BindsInstance test: SysuiTestCase, + featureFlags: FakeFeatureFlagsClassicModule, + mocks: TestMocksModule, + ): TestComponent + } + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/data/repository/ShadeRepositoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/data/repository/ShadeRepositoryImplTest.kt index 7463e65d1d6fa38c6b57276d400a8865a62e6a84..6eeafefd0ac19e6d91f9d9cba0e23911f969a19d 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/shade/data/repository/ShadeRepositoryImplTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/data/repository/ShadeRepositoryImplTest.kt @@ -18,7 +18,6 @@ package com.android.systemui.shade.data.repository import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.shade.ShadeExpansionChangeEvent import com.android.systemui.shade.ShadeExpansionStateManager @@ -43,7 +42,6 @@ import org.mockito.MockitoAnnotations @OptIn(ExperimentalCoroutinesApi::class) @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) class ShadeRepositoryImplTest : SysuiTestCase() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/ui/viewmodel/ShadeHeaderViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/ui/viewmodel/ShadeHeaderViewModelTest.kt index 607cdab12f56b72cc3e19d4d3fc25fe404344010..bb20d94e7d3928be20a43facc2c91a1cca6d1bd1 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/shade/ui/viewmodel/ShadeHeaderViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/ui/viewmodel/ShadeHeaderViewModelTest.kt @@ -17,6 +17,7 @@ import com.android.systemui.statusbar.pipeline.shared.data.repository.FakeConnec import com.android.systemui.util.mockito.mock import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.Test @@ -84,7 +85,8 @@ class ShadeHeaderViewModelTest : SysuiTestCase() { fromScene = SceneKey.Shade, toScene = SceneKey.QuickSettings, progress = MutableStateFlow(0.5f), - isUserInputDriven = false, + isInitiatedByUserInput = false, + isUserInputOngoing = flowOf(false), ) ) ) @@ -102,7 +104,8 @@ class ShadeHeaderViewModelTest : SysuiTestCase() { fromScene = SceneKey.QuickSettings, toScene = SceneKey.Shade, progress = MutableStateFlow(0.5f), - isUserInputDriven = false, + isInitiatedByUserInput = false, + isUserInputOngoing = flowOf(false), ) ) ) @@ -120,7 +123,8 @@ class ShadeHeaderViewModelTest : SysuiTestCase() { fromScene = SceneKey.Gone, toScene = SceneKey.Shade, progress = MutableStateFlow(0.5f), - isUserInputDriven = false, + isInitiatedByUserInput = false, + isUserInputOngoing = flowOf(false), ) ) ) diff --git a/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/ClockRegistryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/ClockRegistryTest.kt index e714736812115b462ef89bb49ddcad3d3382a4c1..ae659f4d26769f2438f1d21502d73296aad6cf87 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/ClockRegistryTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/ClockRegistryTest.kt @@ -131,11 +131,10 @@ class ClockRegistryTest : SysuiTestCase() { fun addClock( id: ClockId, - name: String, create: (ClockId) -> ClockController = ::failFactory, getThumbnail: (ClockId) -> Drawable? = ::failThumbnail ): FakeClockPlugin { - metadata.add(ClockMetadata(id, name)) + metadata.add(ClockMetadata(id)) createCallbacks[id] = create thumbnailCallbacks[id] = getThumbnail return this @@ -149,7 +148,7 @@ class ClockRegistryTest : SysuiTestCase() { scope = TestScope(dispatcher) fakeDefaultProvider = FakeClockPlugin() - .addClock(DEFAULT_CLOCK_ID, DEFAULT_CLOCK_NAME, { mockDefaultClock }, { mockThumbnail }) + .addClock(DEFAULT_CLOCK_ID, { mockDefaultClock }, { mockThumbnail }) whenever(mockContext.contentResolver).thenReturn(mockContentResolver) val captor = argumentCaptor<PluginListener<ClockProviderPlugin>>() @@ -183,13 +182,13 @@ class ClockRegistryTest : SysuiTestCase() { @Test fun pluginRegistration_CorrectState() { val plugin1 = FakeClockPlugin() - .addClock("clock_1", "clock 1") - .addClock("clock_2", "clock 2") + .addClock("clock_1") + .addClock("clock_2") val lifecycle1 = FakeLifecycle("1", plugin1) val plugin2 = FakeClockPlugin() - .addClock("clock_3", "clock 3") - .addClock("clock_4", "clock 4") + .addClock("clock_3") + .addClock("clock_4") val lifecycle2 = FakeLifecycle("2", plugin2) pluginListener.onPluginLoaded(plugin1, mockContext, lifecycle1) @@ -198,11 +197,11 @@ class ClockRegistryTest : SysuiTestCase() { assertEquals( list.toSet(), setOf( - ClockMetadata(DEFAULT_CLOCK_ID, DEFAULT_CLOCK_NAME), - ClockMetadata("clock_1", "clock 1"), - ClockMetadata("clock_2", "clock 2"), - ClockMetadata("clock_3", "clock 3"), - ClockMetadata("clock_4", "clock 4") + ClockMetadata(DEFAULT_CLOCK_ID), + ClockMetadata("clock_1"), + ClockMetadata("clock_2"), + ClockMetadata("clock_3"), + ClockMetadata("clock_4") ) ) } @@ -216,13 +215,13 @@ class ClockRegistryTest : SysuiTestCase() { @Test fun clockIdConflict_ErrorWithoutCrash_unloadDuplicate() { val plugin1 = FakeClockPlugin() - .addClock("clock_1", "clock 1", { mockClock }, { mockThumbnail }) - .addClock("clock_2", "clock 2", { mockClock }, { mockThumbnail }) + .addClock("clock_1", { mockClock }, { mockThumbnail }) + .addClock("clock_2", { mockClock }, { mockThumbnail }) val lifecycle1 = spy(FakeLifecycle("1", plugin1)) val plugin2 = FakeClockPlugin() - .addClock("clock_1", "clock 1") - .addClock("clock_2", "clock 2") + .addClock("clock_1") + .addClock("clock_2") val lifecycle2 = spy(FakeLifecycle("2", plugin2)) pluginListener.onPluginLoaded(plugin1, mockContext, lifecycle1) @@ -231,9 +230,9 @@ class ClockRegistryTest : SysuiTestCase() { assertEquals( list.toSet(), setOf( - ClockMetadata(DEFAULT_CLOCK_ID, DEFAULT_CLOCK_NAME), - ClockMetadata("clock_1", "clock 1"), - ClockMetadata("clock_2", "clock 2") + ClockMetadata(DEFAULT_CLOCK_ID), + ClockMetadata("clock_1"), + ClockMetadata("clock_2") ) ) @@ -248,13 +247,13 @@ class ClockRegistryTest : SysuiTestCase() { @Test fun createCurrentClock_pluginConnected() { val plugin1 = FakeClockPlugin() - .addClock("clock_1", "clock 1") - .addClock("clock_2", "clock 2") + .addClock("clock_1") + .addClock("clock_2") val lifecycle1 = spy(FakeLifecycle("1", plugin1)) val plugin2 = FakeClockPlugin() - .addClock("clock_3", "clock 3", { mockClock }) - .addClock("clock_4", "clock 4") + .addClock("clock_3", { mockClock }) + .addClock("clock_4") val lifecycle2 = spy(FakeLifecycle("2", plugin2)) registry.applySettings(ClockSettings("clock_3", null)) @@ -268,13 +267,13 @@ class ClockRegistryTest : SysuiTestCase() { @Test fun activeClockId_changeAfterPluginConnected() { val plugin1 = FakeClockPlugin() - .addClock("clock_1", "clock 1") - .addClock("clock_2", "clock 2") + .addClock("clock_1") + .addClock("clock_2") val lifecycle1 = spy(FakeLifecycle("1", plugin1)) val plugin2 = FakeClockPlugin() - .addClock("clock_3", "clock 3", { mockClock }) - .addClock("clock_4", "clock 4") + .addClock("clock_3", { mockClock }) + .addClock("clock_4") val lifecycle2 = spy(FakeLifecycle("2", plugin2)) registry.applySettings(ClockSettings("clock_3", null)) @@ -289,13 +288,13 @@ class ClockRegistryTest : SysuiTestCase() { @Test fun createDefaultClock_pluginDisconnected() { val plugin1 = FakeClockPlugin() - .addClock("clock_1", "clock 1") - .addClock("clock_2", "clock 2") + .addClock("clock_1") + .addClock("clock_2") val lifecycle1 = spy(FakeLifecycle("1", plugin1)) val plugin2 = FakeClockPlugin() - .addClock("clock_3", "clock 3") - .addClock("clock_4", "clock 4") + .addClock("clock_3") + .addClock("clock_4") val lifecycle2 = spy(FakeLifecycle("2", plugin2)) registry.applySettings(ClockSettings("clock_3", null)) @@ -310,13 +309,13 @@ class ClockRegistryTest : SysuiTestCase() { @Test fun pluginRemoved_clockAndListChanged() { val plugin1 = FakeClockPlugin() - .addClock("clock_1", "clock 1") - .addClock("clock_2", "clock 2") + .addClock("clock_1") + .addClock("clock_2") val lifecycle1 = spy(FakeLifecycle("1", plugin1)) val plugin2 = FakeClockPlugin() - .addClock("clock_3", "clock 3", { mockClock }) - .addClock("clock_4", "clock 4") + .addClock("clock_3", { mockClock }) + .addClock("clock_4") val lifecycle2 = spy(FakeLifecycle("2", plugin2)) var changeCallCount = 0 @@ -415,13 +414,13 @@ class ClockRegistryTest : SysuiTestCase() { @Test fun pluginAddRemove_concurrentModification() { - val plugin1 = FakeClockPlugin().addClock("clock_1", "clock 1") + val plugin1 = FakeClockPlugin().addClock("clock_1") val lifecycle1 = FakeLifecycle("1", plugin1) - val plugin2 = FakeClockPlugin().addClock("clock_2", "clock 2") + val plugin2 = FakeClockPlugin().addClock("clock_2") val lifecycle2 = FakeLifecycle("2", plugin2) - val plugin3 = FakeClockPlugin().addClock("clock_3", "clock 3") + val plugin3 = FakeClockPlugin().addClock("clock_3") val lifecycle3 = FakeLifecycle("3", plugin3) - val plugin4 = FakeClockPlugin().addClock("clock_4", "clock 4") + val plugin4 = FakeClockPlugin().addClock("clock_4") val lifecycle4 = FakeLifecycle("4", plugin4) // Set the current clock to the final clock to load @@ -450,10 +449,10 @@ class ClockRegistryTest : SysuiTestCase() { // Verify all plugins were correctly loaded into the registry assertEquals(registry.getClocks().toSet(), setOf( - ClockMetadata("DEFAULT", "Default Clock"), - ClockMetadata("clock_2", "clock 2"), - ClockMetadata("clock_3", "clock 3"), - ClockMetadata("clock_4", "clock 4") + ClockMetadata("DEFAULT"), + ClockMetadata("clock_2"), + ClockMetadata("clock_3"), + ClockMetadata("clock_4") )) } @@ -527,8 +526,8 @@ class ClockRegistryTest : SysuiTestCase() { featureFlags.set(TRANSIT_CLOCK, flag) registry.isTransitClockEnabled = featureFlags.isEnabled(TRANSIT_CLOCK) val plugin = FakeClockPlugin() - .addClock("clock_1", "clock 1") - .addClock("DIGITAL_CLOCK_METRO", "metro clock") + .addClock("clock_1") + .addClock("DIGITAL_CLOCK_METRO") val lifecycle = FakeLifecycle("metro", plugin) pluginListener.onPluginLoaded(plugin, mockContext, lifecycle) @@ -536,17 +535,17 @@ class ClockRegistryTest : SysuiTestCase() { if (flag) { assertEquals( setOf( - ClockMetadata(DEFAULT_CLOCK_ID, DEFAULT_CLOCK_NAME), - ClockMetadata("clock_1", "clock 1"), - ClockMetadata("DIGITAL_CLOCK_METRO", "metro clock") + ClockMetadata(DEFAULT_CLOCK_ID), + ClockMetadata("clock_1"), + ClockMetadata("DIGITAL_CLOCK_METRO") ), list.toSet() ) } else { assertEquals( setOf( - ClockMetadata(DEFAULT_CLOCK_ID, DEFAULT_CLOCK_NAME), - ClockMetadata("clock_1", "clock 1") + ClockMetadata(DEFAULT_CLOCK_ID), + ClockMetadata("clock_1") ), list.toSet() ) diff --git a/packages/SystemUI/tests/src/com/android/systemui/smartspace/BcSmartspaceConfigProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/smartspace/BcSmartspaceConfigProviderTest.kt index 7a2d12269885667b3ba9a64639e9998f4aaf820b..b8fe2f911b5004a48e3700c252d65561f32a9da3 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/smartspace/BcSmartspaceConfigProviderTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/smartspace/BcSmartspaceConfigProviderTest.kt @@ -18,7 +18,6 @@ package com.android.systemui.smartspace import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.flags.FeatureFlags import com.android.systemui.flags.Flags @@ -33,7 +32,6 @@ import org.mockito.Mock import org.mockito.MockitoAnnotations @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) class BcSmartspaceConfigProviderTest : SysuiTestCase() { @Mock private lateinit var featureFlags: FeatureFlags diff --git a/packages/SystemUI/tests/src/com/android/systemui/smartspace/DreamSmartspaceControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/smartspace/DreamSmartspaceControllerTest.kt index f1c181fb22355f0c2861c9ae1d172a222e97ba79..e093859349913f627d9de77d54de83d2d42da960 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/smartspace/DreamSmartspaceControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/smartspace/DreamSmartspaceControllerTest.kt @@ -26,7 +26,6 @@ import android.view.ViewGroup import android.widget.FrameLayout import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.dreams.smartspace.DreamSmartspaceController import com.android.systemui.plugins.BcSmartspaceConfigPlugin @@ -53,7 +52,6 @@ import org.mockito.MockitoAnnotations import org.mockito.Spy @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) @TestableLooper.RunWithLooper class DreamSmartspaceControllerTest : SysuiTestCase() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/smartspace/LockscreenAndDreamTargetFilterTest.kt b/packages/SystemUI/tests/src/com/android/systemui/smartspace/LockscreenAndDreamTargetFilterTest.kt index 7af29ba28df16129c4653ce422adf572c66e3490..886c61ae29dd751a0ae8440e27b12b0b3cc866d9 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/smartspace/LockscreenAndDreamTargetFilterTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/smartspace/LockscreenAndDreamTargetFilterTest.kt @@ -25,7 +25,6 @@ import android.provider.Settings import android.testing.TestableLooper import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.settings.UserTracker import com.android.systemui.smartspace.filters.LockscreenAndDreamTargetFilter @@ -52,7 +51,6 @@ import org.mockito.MockitoAnnotations @SmallTest @TestableLooper.RunWithLooper -@RoboPilotTest @RunWith(AndroidJUnit4::class) class LockscreenAndDreamTargetFilterTest : SysuiTestCase() { @Mock diff --git a/packages/SystemUI/tests/src/com/android/systemui/smartspace/LockscreenPreconditionTest.kt b/packages/SystemUI/tests/src/com/android/systemui/smartspace/LockscreenPreconditionTest.kt index a7c223dc4b8a8e41c52329e12b8dce2797917582..0b5aea7d868391cdee8f793515ff2afac9d56d93 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/smartspace/LockscreenPreconditionTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/smartspace/LockscreenPreconditionTest.kt @@ -19,7 +19,6 @@ package com.android.systemui.smartspace import android.testing.TestableLooper import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.smartspace.preconditions.LockscreenPrecondition import com.android.systemui.statusbar.policy.DeviceProvisionedController @@ -36,7 +35,6 @@ import org.mockito.Mockito.verify import org.mockito.MockitoAnnotations @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) @TestableLooper.RunWithLooper class LockscreenPreconditionTest : SysuiTestCase() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt index 14e58e5f570a34d10c7ad21b7c24d143862ee015..e8923a5baca88ea52dae6845443e76b300680eb6 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt @@ -5,41 +5,32 @@ import android.testing.AndroidTestingRunner import android.testing.TestableLooper import android.testing.TestableLooper.RunWithLooper import androidx.test.filters.SmallTest +import com.android.SysUITestModule +import com.android.TestMocksModule import com.android.systemui.ExpandHelper -import com.android.systemui.res.R import com.android.systemui.SysuiTestCase -import com.android.systemui.classifier.FalsingCollector -import com.android.systemui.common.ui.data.repository.FakeConfigurationRepository -import com.android.systemui.dump.DumpManager -import com.android.systemui.keyguard.WakefulnessLifecycle -import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.flags.FakeFeatureFlagsClassicModule +import com.android.systemui.flags.Flags import com.android.systemui.media.controls.ui.MediaHierarchyManager -import com.android.systemui.plugins.ActivityStarter -import com.android.systemui.plugins.FalsingManager import com.android.systemui.plugins.qs.QS -import com.android.systemui.power.domain.interactor.PowerInteractorFactory -import com.android.systemui.scene.SceneTestUtils -import com.android.systemui.scene.shared.flag.FakeSceneContainerFlags +import com.android.systemui.res.R import com.android.systemui.shade.ShadeViewController -import com.android.systemui.shade.data.repository.FakeShadeRepository -import com.android.systemui.shade.domain.interactor.ShadeInteractor import com.android.systemui.statusbar.disableflags.data.model.DisableFlagsModel import com.android.systemui.statusbar.disableflags.data.repository.FakeDisableFlagsRepository import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow import com.android.systemui.statusbar.notification.row.NotificationTestHelper -import com.android.systemui.statusbar.notification.stack.AmbientState import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController -import com.android.systemui.statusbar.notification.stack.domain.interactor.SharedNotificationContainerInteractor import com.android.systemui.statusbar.phone.CentralSurfaces import com.android.systemui.statusbar.phone.KeyguardBypassController -import com.android.systemui.statusbar.phone.LSShadeTransitionLogger import com.android.systemui.statusbar.phone.ScrimController -import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeUserSetupRepository import com.android.systemui.statusbar.policy.FakeConfigurationController -import com.android.systemui.statusbar.policy.ResourcesSplitShadeStateController -import com.android.systemui.util.mockito.mock +import com.android.systemui.user.domain.UserDomainLayerModule +import dagger.BindsInstance +import dagger.Component import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runCurrent import org.junit.After import org.junit.Assert.assertFalse @@ -60,9 +51,8 @@ import org.mockito.Mockito import org.mockito.Mockito.clearInvocations import org.mockito.Mockito.never import org.mockito.Mockito.verify -import org.mockito.Mockito.verifyZeroInteractions -import org.mockito.junit.MockitoJUnit import org.mockito.Mockito.`when` as whenever +import org.mockito.junit.MockitoJUnit private fun <T> anyObject(): T { return Mockito.anyObject<T>() @@ -73,68 +63,38 @@ private fun <T> anyObject(): T { @RunWith(AndroidTestingRunner::class) @OptIn(ExperimentalCoroutinesApi::class) class LockscreenShadeTransitionControllerTest : SysuiTestCase() { - private val utils = SceneTestUtils(this) - private val testScope = utils.testScope - lateinit var transitionController: LockscreenShadeTransitionController + private lateinit var testComponent: TestComponent + + private val transitionController + get() = testComponent.transitionController + private val configurationController + get() = testComponent.configurationController + private val disableFlagsRepository + get() = testComponent.disableFlagsRepository + private val testScope + get() = testComponent.testScope + lateinit var row: ExpandableNotificationRow - @Mock lateinit var statusbarStateController: SysuiStatusBarStateController - @Mock lateinit var logger: LSShadeTransitionLogger - @Mock lateinit var dumpManager: DumpManager + + @Mock lateinit var centralSurfaces: CentralSurfaces + @Mock lateinit var depthController: NotificationShadeDepthController + @Mock lateinit var expandHelperCallback: ExpandHelper.Callback @Mock lateinit var keyguardBypassController: KeyguardBypassController @Mock lateinit var lockScreenUserManager: NotificationLockscreenUserManager - @Mock lateinit var falsingCollector: FalsingCollector - @Mock lateinit var ambientState: AmbientState - @Mock lateinit var wakefulnessLifecycle: WakefulnessLifecycle @Mock lateinit var mediaHierarchyManager: MediaHierarchyManager + @Mock lateinit var nsslController: NotificationStackScrollLayoutController + @Mock lateinit var qS: QS @Mock lateinit var scrimController: ScrimController - @Mock lateinit var falsingManager: FalsingManager @Mock lateinit var shadeViewController: ShadeViewController - @Mock lateinit var nsslController: NotificationStackScrollLayoutController - @Mock lateinit var depthController: NotificationShadeDepthController @Mock lateinit var stackscroller: NotificationStackScrollLayout - @Mock lateinit var expandHelperCallback: ExpandHelper.Callback - @Mock lateinit var mCentralSurfaces: CentralSurfaces - @Mock lateinit var qS: QS - @Mock lateinit var singleShadeOverScroller: SingleShadeLockScreenOverScroller - @Mock lateinit var splitShadeOverScroller: SplitShadeLockScreenOverScroller - @Mock lateinit var qsTransitionController: LockscreenShadeQsTransitionController - @Mock lateinit var activityStarter: ActivityStarter + @Mock lateinit var statusbarStateController: SysuiStatusBarStateController @Mock lateinit var transitionControllerCallback: LockscreenShadeTransitionController.Callback - private val sceneContainerFlags = FakeSceneContainerFlags() - private val sceneInteractor = utils.sceneInteractor() - private val disableFlagsRepository = FakeDisableFlagsRepository() - private val keyguardRepository = FakeKeyguardRepository() - private val configurationRepository = FakeConfigurationRepository() - private val sharedNotificationContainerInteractor = SharedNotificationContainerInteractor( - configurationRepository, - mContext, - ResourcesSplitShadeStateController() - ) - private val shadeInteractor = - ShadeInteractor( - testScope.backgroundScope, - disableFlagsRepository, - sceneContainerFlags, - { sceneInteractor }, - keyguardRepository, - userSetupRepository = FakeUserSetupRepository(), - deviceProvisionedController = mock(), - userInteractor = mock(), - sharedNotificationContainerInteractor, - repository = FakeShadeRepository(), - ) - private val powerInteractor = PowerInteractorFactory.create().powerInteractor - @JvmField @Rule val mockito = MockitoJUnit.rule() - private val configurationController = FakeConfigurationController() + @JvmField @Rule val mockito = MockitoJUnit.rule() @Before fun setup() { - // By default, have the shade enabled - disableFlagsRepository.disableFlags.value = DisableFlagsModel() - testScope.runCurrent() - val helper = NotificationTestHelper(mContext, mDependency, TestableLooper.get(this)) row = helper.createRow() context @@ -143,55 +103,9 @@ class LockscreenShadeTransitionControllerTest : SysuiTestCase() { context .getOrCreateTestableResources() .addOverride(R.dimen.lockscreen_shade_depth_controller_transition_distance, 100) - transitionController = - LockscreenShadeTransitionController( - statusBarStateController = statusbarStateController, - logger = logger, - keyguardBypassController = keyguardBypassController, - lockScreenUserManager = lockScreenUserManager, - falsingCollector = falsingCollector, - ambientState = ambientState, - mediaHierarchyManager = mediaHierarchyManager, - depthController = depthController, - wakefulnessLifecycle = wakefulnessLifecycle, - context = context, - configurationController = configurationController, - falsingManager = falsingManager, - dumpManager = dumpManager, - splitShadeOverScrollerFactory = { _, _ -> splitShadeOverScroller }, - singleShadeOverScrollerFactory = { singleShadeOverScroller }, - scrimTransitionController = - LockscreenShadeScrimTransitionController( - scrimController, - context, - configurationController, - dumpManager, - ResourcesSplitShadeStateController() - ), - keyguardTransitionControllerFactory = { notificationPanelController -> - LockscreenShadeKeyguardTransitionController( - mediaHierarchyManager, - notificationPanelController, - context, - configurationController, - dumpManager, - ResourcesSplitShadeStateController() - ) - }, - qsTransitionControllerFactory = { qsTransitionController }, - activityStarter = activityStarter, - shadeRepository = FakeShadeRepository(), - shadeInteractor = shadeInteractor, - powerInteractor = powerInteractor, - splitShadeStateController = ResourcesSplitShadeStateController() - ) - transitionController.addCallback(transitionControllerCallback) + whenever(nsslController.view).thenReturn(stackscroller) whenever(nsslController.expandHelperCallback).thenReturn(expandHelperCallback) - transitionController.shadeViewController = shadeViewController - transitionController.centralSurfaces = mCentralSurfaces - transitionController.qS = qS - transitionController.setStackScroller(nsslController) whenever(statusbarStateController.state).thenReturn(StatusBarState.KEYGUARD) whenever(nsslController.isInLockedDownShade).thenReturn(false) whenever(qS.isFullyCollapsed).thenReturn(true) @@ -199,9 +113,36 @@ class LockscreenShadeTransitionControllerTest : SysuiTestCase() { .thenReturn(true) whenever(lockScreenUserManager.shouldShowLockscreenNotifications()).thenReturn(true) whenever(lockScreenUserManager.isLockscreenPublicMode(anyInt())).thenReturn(true) - whenever(falsingCollector.shouldEnforceBouncer()).thenReturn(false) whenever(keyguardBypassController.bypassEnabled).thenReturn(false) - clearInvocations(mCentralSurfaces) + + testComponent = + DaggerLockscreenShadeTransitionControllerTest_TestComponent.factory() + .create( + test = this, + featureFlags = + FakeFeatureFlagsClassicModule { + set(Flags.FULL_SCREEN_USER_SWITCHER, false) + }, + mocks = + TestMocksModule( + notificationShadeDepthController = depthController, + keyguardBypassController = keyguardBypassController, + mediaHierarchyManager = mediaHierarchyManager, + notificationLockscreenUserManager = lockScreenUserManager, + notificationStackScrollLayoutController = nsslController, + scrimController = scrimController, + statusBarStateController = statusbarStateController, + ) + ) + + transitionController.addCallback(transitionControllerCallback) + transitionController.shadeViewController = shadeViewController + transitionController.centralSurfaces = centralSurfaces + transitionController.qS = qS + transitionController.setStackScroller(nsslController) + clearInvocations(centralSurfaces) + + testScope.runCurrent() } @After @@ -282,7 +223,7 @@ class LockscreenShadeTransitionControllerTest : SysuiTestCase() { transitionController.goToLockedShade(null) verify(statusbarStateController, never()).setState(anyInt()) verify(statusbarStateController).setLeaveOpenOnKeyguardHide(true) - verify(mCentralSurfaces).showBouncerWithDimissAndCancelIfKeyguard(anyObject(), anyObject()) + verify(centralSurfaces).showBouncerWithDimissAndCancelIfKeyguard(anyObject(), anyObject()) } @Test @@ -318,7 +259,7 @@ class LockscreenShadeTransitionControllerTest : SysuiTestCase() { verify(scrimController, never()).setTransitionToFullShadeProgress(anyFloat(), anyFloat()) verify(transitionControllerCallback, never()) .setTransitionToFullShadeAmount(anyFloat(), anyBoolean(), anyLong()) - verify(qsTransitionController, never()).dragDownAmount = anyFloat() + verify(qS, never()).setTransitionToFullShadeProgress(anyBoolean(), anyFloat(), anyFloat()) } @Test @@ -329,7 +270,7 @@ class LockscreenShadeTransitionControllerTest : SysuiTestCase() { verify(scrimController).setTransitionToFullShadeProgress(anyFloat(), anyFloat()) verify(transitionControllerCallback) .setTransitionToFullShadeAmount(anyFloat(), anyBoolean(), anyLong()) - verify(qsTransitionController).dragDownAmount = 10f + verify(qS).setTransitionToFullShadeProgress(eq(true), anyFloat(), anyFloat()) verify(depthController).transitionToFullShadeProgress = anyFloat() } @@ -532,8 +473,8 @@ class LockscreenShadeTransitionControllerTest : SysuiTestCase() { transitionController.dragDownAmount = 10f - verify(singleShadeOverScroller).expansionDragDownAmount = 10f - verifyZeroInteractions(splitShadeOverScroller) + verify(nsslController).setOverScrollAmount(0) + verify(scrimController, never()).setNotificationsOverScrollAmount(anyInt()) } @Test @@ -542,8 +483,8 @@ class LockscreenShadeTransitionControllerTest : SysuiTestCase() { transitionController.dragDownAmount = 10f - verify(splitShadeOverScroller).expansionDragDownAmount = 10f - verifyZeroInteractions(singleShadeOverScroller) + verify(nsslController).setOverScrollAmount(0) + verify(scrimController).setNotificationsOverScrollAmount(0) } @Test @@ -591,6 +532,32 @@ class LockscreenShadeTransitionControllerTest : SysuiTestCase() { progress: Float, lockScreenNotificationsProgress: Float ) { - scrimController.setTransitionToFullShadeProgress(progress, lockScreenNotificationsProgress) + setTransitionToFullShadeProgress(progress, lockScreenNotificationsProgress) + } + + @SysUISingleton + @Component( + modules = + [ + SysUITestModule::class, + UserDomainLayerModule::class, + ] + ) + interface TestComponent { + + val transitionController: LockscreenShadeTransitionController + + val configurationController: FakeConfigurationController + val disableFlagsRepository: FakeDisableFlagsRepository + val testScope: TestScope + + @Component.Factory + interface Factory { + fun create( + @BindsInstance test: SysuiTestCase, + featureFlags: FakeFeatureFlagsClassicModule, + mocks: TestMocksModule, + ): TestComponent + } } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/PulseExpansionHandlerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/PulseExpansionHandlerTest.kt index fbb8ebfb3e3b26676a1eea7e301cc2975bdc86a8..20e5c43cba193e615bf891aeecd868d92987927f 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/PulseExpansionHandlerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/PulseExpansionHandlerTest.kt @@ -29,9 +29,9 @@ import com.android.systemui.shade.ShadeExpansionStateManager import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator import com.android.systemui.statusbar.notification.row.ExpandableView import com.android.systemui.statusbar.notification.stack.NotificationRoundnessManager -import com.android.systemui.statusbar.phone.HeadsUpManagerPhone import com.android.systemui.statusbar.phone.KeyguardBypassController import com.android.systemui.statusbar.policy.ConfigurationController +import com.android.systemui.statusbar.policy.HeadsUpManager import com.android.systemui.util.mockito.mock import org.junit.Before import org.junit.Test @@ -52,7 +52,7 @@ class PulseExpansionHandlerTest : SysuiTestCase() { private val collapsedHeight = 300 private val wakeUpCoordinator: NotificationWakeUpCoordinator = mock() private val bypassController: KeyguardBypassController = mock() - private val headsUpManager: HeadsUpManagerPhone = mock() + private val headsUpManager: HeadsUpManager = mock() private val roundnessManager: NotificationRoundnessManager = mock() private val configurationController: ConfigurationController = mock() private val statusBarStateController: StatusBarStateController = mock() diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorControllerTest.kt index d86f8bbbeb15a7ba9a40efb2effc498116963c24..235ac5c2e9cc33ca065d4dbb789926e9e0463a84 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorControllerTest.kt @@ -8,15 +8,15 @@ import androidx.test.filters.SmallTest import com.android.internal.jank.InteractionJankMonitor import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue +import com.android.systemui.res.R import com.android.systemui.statusbar.notification.collection.GroupEntryBuilder import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder import com.android.systemui.statusbar.notification.data.repository.NotificationExpansionRepository import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow import com.android.systemui.statusbar.notification.row.NotificationTestHelper import com.android.systemui.statusbar.notification.stack.NotificationListContainer -import com.android.systemui.statusbar.phone.HeadsUpManagerPhone +import com.android.systemui.statusbar.policy.HeadsUpManager import com.android.systemui.statusbar.policy.HeadsUpUtil -import com.android.systemui.res.R import junit.framework.Assert.assertFalse import junit.framework.Assert.assertTrue import kotlinx.coroutines.test.TestScope @@ -37,7 +37,7 @@ import org.mockito.junit.MockitoJUnit @RunWithLooper class NotificationLaunchAnimatorControllerTest : SysuiTestCase() { @Mock lateinit var notificationListContainer: NotificationListContainer - @Mock lateinit var headsUpManager: HeadsUpManagerPhone + @Mock lateinit var headsUpManager: HeadsUpManager @Mock lateinit var jankMonitor: InteractionJankMonitor @Mock lateinit var onFinishAnimationCallback: Runnable diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.kt index 257cc5b1b85cf810ed2e86ddfa8aee1e0aebdd9f..4f1581cced912b8ea97964926abb32584316564e 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.kt @@ -43,8 +43,8 @@ import com.android.systemui.statusbar.notification.interruption.NotificationInte import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProviderWrapper.FullScreenIntentDecisionImpl import com.android.systemui.statusbar.notification.interruption.VisualInterruptionDecisionProvider import com.android.systemui.statusbar.notification.row.NotifBindPipeline.BindCallback +import com.android.systemui.statusbar.phone.HeadsUpManagerPhone import com.android.systemui.statusbar.phone.NotificationGroupTestHelper -import com.android.systemui.statusbar.policy.HeadsUpManager import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener import com.android.systemui.util.concurrency.FakeExecutor import com.android.systemui.util.mockito.any @@ -87,7 +87,7 @@ class HeadsUpCoordinatorTest : SysuiTestCase() { private val notifPipeline: NotifPipeline = mock() private val logger = HeadsUpCoordinatorLogger(logcatLogBuffer(), verbose = true) - private val headsUpManager: HeadsUpManager = mock() + private val headsUpManager: HeadsUpManagerPhone = mock() private val headsUpViewBinder: HeadsUpViewBinder = mock() private val visualInterruptionDecisionProvider: VisualInterruptionDecisionProvider = mock() private val remoteInputManager: NotificationRemoteInputManager = mock() @@ -435,7 +435,7 @@ class HeadsUpCoordinatorTest : SysuiTestCase() { private fun addHUN(entry: NotificationEntry) { huns.add(entry) - whenever(headsUpManager.topEntry).thenReturn(entry) + whenever(headsUpManager.getTopEntry()).thenReturn(entry) onHeadsUpChangedListener.onHeadsUpStateChanged(entry, true) notifLifetimeExtender.cancelLifetimeExtension(entry) } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.kt index fbd61f4fe3bdbcc225bc3a91afd65ecaa2e79a9b..546abd4ec79a4b29f36e4a84cb0fb87d660580b6 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.kt @@ -23,7 +23,6 @@ import android.provider.Settings import android.testing.AndroidTestingRunner import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase -import com.android.systemui.coroutines.advanceTimeBy import com.android.systemui.dump.DumpManager import com.android.systemui.dump.logcatLogBuffer import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository @@ -40,10 +39,10 @@ import com.android.systemui.statusbar.notification.collection.listbuilder.plugga import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.Pluggable import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener import com.android.systemui.statusbar.notification.collection.provider.SectionHeaderVisibilityProvider -import com.android.systemui.statusbar.notification.collection.provider.SeenNotificationsProvider -import com.android.systemui.statusbar.notification.collection.provider.SeenNotificationsProviderImpl import com.android.systemui.statusbar.notification.interruption.KeyguardNotificationVisibilityProvider import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow +import com.android.systemui.statusbar.notification.stack.data.repository.NotificationListRepository +import com.android.systemui.statusbar.notification.stack.domain.interactor.NotificationListInteractor import com.android.systemui.statusbar.policy.HeadsUpManager import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener import com.android.systemui.util.mockito.any @@ -247,7 +246,7 @@ class KeyguardCoordinatorTest : SysuiTestCase() { unseenFilter.onCleanup() // THEN: The SeenNotificationProvider has been updated to reflect the suppression - assertThat(seenNotificationsProvider.hasFilteredOutSeenNotifications).isTrue() + assertThat(notificationListInteractor.hasFilteredOutSeenNotifications.value).isTrue() } } @@ -598,7 +597,7 @@ class KeyguardCoordinatorTest : SysuiTestCase() { FakeSettings().apply { putInt(Settings.Secure.LOCK_SCREEN_SHOW_ONLY_UNSEEN_NOTIFICATIONS, 1) } - val seenNotificationsProvider = SeenNotificationsProviderImpl() + val notificationListInteractor = NotificationListInteractor(NotificationListRepository()) val keyguardCoordinator = KeyguardCoordinator( testDispatcher, @@ -611,7 +610,7 @@ class KeyguardCoordinatorTest : SysuiTestCase() { testScope.backgroundScope, sectionHeaderVisibilityProvider, fakeSettings, - seenNotificationsProvider, + notificationListInteractor, statusBarStateController, ) keyguardCoordinator.attach(notifPipeline) @@ -619,7 +618,7 @@ class KeyguardCoordinatorTest : SysuiTestCase() { KeyguardCoordinatorTestScope( keyguardCoordinator, testScope, - seenNotificationsProvider, + notificationListInteractor, fakeSettings, ) .testBlock() @@ -629,7 +628,7 @@ class KeyguardCoordinatorTest : SysuiTestCase() { private inner class KeyguardCoordinatorTestScope( private val keyguardCoordinator: KeyguardCoordinator, private val scope: TestScope, - val seenNotificationsProvider: SeenNotificationsProvider, + val notificationListInteractor: NotificationListInteractor, private val fakeSettings: FakeSettings, ) : CoroutineScope by scope { val testScheduler: TestCoroutineScheduler diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerAlwaysOnDisplayViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerAlwaysOnDisplayViewModelTest.kt new file mode 100644 index 0000000000000000000000000000000000000000..99c3b194a662cceab387f154db4a652f6ffac287 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerAlwaysOnDisplayViewModelTest.kt @@ -0,0 +1,282 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +@file:OptIn(ExperimentalCoroutinesApi::class) + +package com.android.systemui.statusbar.notification.icon.ui.viewmodel + +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.SmallTest +import com.android.SysUITestModule +import com.android.TestMocksModule +import com.android.systemui.SysuiTestCase +import com.android.systemui.biometrics.domain.BiometricsDomainLayerModule +import com.android.systemui.coroutines.collectLastValue +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.flags.FakeFeatureFlagsClassicModule +import com.android.systemui.flags.Flags +import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository +import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository +import com.android.systemui.keyguard.shared.model.DozeStateModel +import com.android.systemui.keyguard.shared.model.DozeTransitionModel +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.power.data.repository.FakePowerRepository +import com.android.systemui.power.shared.model.WakeSleepReason +import com.android.systemui.power.shared.model.WakefulnessState +import com.android.systemui.statusbar.phone.DozeParameters +import com.android.systemui.statusbar.policy.data.repository.FakeDeviceProvisioningRepository +import com.android.systemui.user.domain.UserDomainLayerModule +import com.android.systemui.util.mockito.whenever +import com.google.common.truth.Truth.assertThat +import dagger.BindsInstance +import dagger.Component +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.TestScope +import kotlinx.coroutines.test.runCurrent +import kotlinx.coroutines.test.runTest +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mock +import org.mockito.MockitoAnnotations + +@SmallTest +@RunWith(AndroidJUnit4::class) +class NotificationIconContainerAlwaysOnDisplayViewModelTest : SysuiTestCase() { + + @Mock private lateinit var dozeParams: DozeParameters + + private lateinit var testComponent: TestComponent + private val underTest + get() = testComponent.underTest + private val deviceProvisioningRepository + get() = testComponent.deviceProvisioningRepository + private val keyguardRepository + get() = testComponent.keyguardRepository + private val keyguardTransitionRepository + get() = testComponent.keyguardTransitionRepository + private val powerRepository + get() = testComponent.powerRepository + private val scope + get() = testComponent.scope + + @Before + fun setup() { + MockitoAnnotations.initMocks(this) + + testComponent = + DaggerNotificationIconContainerAlwaysOnDisplayViewModelTest_TestComponent.factory() + .create( + test = this, + featureFlags = + FakeFeatureFlagsClassicModule { + set(Flags.FACE_AUTH_REFACTOR, value = false) + set(Flags.FULL_SCREEN_USER_SWITCHER, value = false) + }, + mocks = + TestMocksModule( + dozeParameters = dozeParams, + ), + ) + + keyguardRepository.setKeyguardShowing(true) + keyguardRepository.setKeyguardOccluded(false) + deviceProvisioningRepository.setFactoryResetProtectionActive(false) + powerRepository.updateWakefulness( + rawState = WakefulnessState.AWAKE, + lastWakeReason = WakeSleepReason.OTHER, + lastSleepReason = WakeSleepReason.OTHER, + ) + } + + @Test + fun animationsEnabled_isFalse_whenFrpIsActive() = + scope.runTest { + deviceProvisioningRepository.setFactoryResetProtectionActive(true) + keyguardTransitionRepository.sendTransitionStep( + TransitionStep( + transitionState = TransitionState.STARTED, + ) + ) + val animationsEnabled by collectLastValue(underTest.animationsEnabled) + runCurrent() + assertThat(animationsEnabled).isFalse() + } + + @Test + fun animationsEnabled_isFalse_whenDeviceAsleepAndNotPulsing() = + scope.runTest { + powerRepository.updateWakefulness( + rawState = WakefulnessState.ASLEEP, + lastWakeReason = WakeSleepReason.POWER_BUTTON, + lastSleepReason = WakeSleepReason.OTHER, + ) + keyguardTransitionRepository.sendTransitionStep( + TransitionStep( + transitionState = TransitionState.STARTED, + ) + ) + keyguardRepository.setDozeTransitionModel( + DozeTransitionModel( + to = DozeStateModel.DOZE_AOD, + ) + ) + val animationsEnabled by collectLastValue(underTest.animationsEnabled) + runCurrent() + assertThat(animationsEnabled).isFalse() + } + + @Test + fun animationsEnabled_isTrue_whenDeviceAsleepAndPulsing() = + scope.runTest { + powerRepository.updateWakefulness( + rawState = WakefulnessState.ASLEEP, + lastWakeReason = WakeSleepReason.POWER_BUTTON, + lastSleepReason = WakeSleepReason.OTHER, + ) + keyguardTransitionRepository.sendTransitionStep( + TransitionStep( + transitionState = TransitionState.STARTED, + ) + ) + keyguardRepository.setDozeTransitionModel( + DozeTransitionModel( + to = DozeStateModel.DOZE_PULSING, + ) + ) + val animationsEnabled by collectLastValue(underTest.animationsEnabled) + runCurrent() + assertThat(animationsEnabled).isTrue() + } + + @Test + fun animationsEnabled_isFalse_whenStartingToSleepAndNotControlScreenOff() = + scope.runTest { + powerRepository.updateWakefulness( + rawState = WakefulnessState.STARTING_TO_SLEEP, + lastWakeReason = WakeSleepReason.POWER_BUTTON, + lastSleepReason = WakeSleepReason.OTHER, + ) + keyguardTransitionRepository.sendTransitionStep( + TransitionStep( + from = KeyguardState.GONE, + to = KeyguardState.AOD, + transitionState = TransitionState.STARTED, + ) + ) + whenever(dozeParams.shouldControlScreenOff()).thenReturn(false) + val animationsEnabled by collectLastValue(underTest.animationsEnabled) + runCurrent() + assertThat(animationsEnabled).isFalse() + } + + @Test + fun animationsEnabled_isTrue_whenStartingToSleepAndControlScreenOff() = + scope.runTest { + powerRepository.updateWakefulness( + rawState = WakefulnessState.STARTING_TO_SLEEP, + lastWakeReason = WakeSleepReason.POWER_BUTTON, + lastSleepReason = WakeSleepReason.OTHER, + ) + keyguardTransitionRepository.sendTransitionStep( + TransitionStep( + from = KeyguardState.GONE, + to = KeyguardState.AOD, + transitionState = TransitionState.STARTED, + ) + ) + whenever(dozeParams.shouldControlScreenOff()).thenReturn(true) + val animationsEnabled by collectLastValue(underTest.animationsEnabled) + runCurrent() + assertThat(animationsEnabled).isTrue() + } + + @Test + fun animationsEnabled_isTrue_whenNotAsleep() = + scope.runTest { + powerRepository.updateWakefulness( + rawState = WakefulnessState.AWAKE, + lastWakeReason = WakeSleepReason.POWER_BUTTON, + lastSleepReason = WakeSleepReason.OTHER, + ) + keyguardTransitionRepository.sendTransitionStep( + TransitionStep( + transitionState = TransitionState.STARTED, + ) + ) + val animationsEnabled by collectLastValue(underTest.animationsEnabled) + runCurrent() + assertThat(animationsEnabled).isTrue() + } + + @Test + fun animationsEnabled_isTrue_whenKeyguardIsShowing() = + scope.runTest { + keyguardTransitionRepository.sendTransitionStep( + TransitionStep( + transitionState = TransitionState.STARTED, + ) + ) + val animationsEnabled by collectLastValue(underTest.animationsEnabled) + + keyguardRepository.setKeyguardShowing(true) + keyguardRepository.setKeyguardOccluded(false) + runCurrent() + + assertThat(animationsEnabled).isTrue() + + keyguardRepository.setKeyguardOccluded(true) + runCurrent() + + assertThat(animationsEnabled).isFalse() + + keyguardRepository.setKeyguardShowing(false) + keyguardRepository.setKeyguardOccluded(true) + runCurrent() + + assertThat(animationsEnabled).isFalse() + } + + @SysUISingleton + @Component( + modules = + [ + SysUITestModule::class, + BiometricsDomainLayerModule::class, + UserDomainLayerModule::class, + ] + ) + interface TestComponent { + + val underTest: NotificationIconContainerAlwaysOnDisplayViewModel + + val deviceProvisioningRepository: FakeDeviceProvisioningRepository + val keyguardRepository: FakeKeyguardRepository + val keyguardTransitionRepository: FakeKeyguardTransitionRepository + val powerRepository: FakePowerRepository + val scope: TestScope + + @Component.Factory + interface Factory { + fun create( + @BindsInstance test: SysuiTestCase, + mocks: TestMocksModule, + featureFlags: FakeFeatureFlagsClassicModule, + ): TestComponent + } + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModelTest.kt new file mode 100644 index 0000000000000000000000000000000000000000..d1518f7e0d0891431b297c343464e17fb62cf887 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerStatusBarViewModelTest.kt @@ -0,0 +1,274 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +@file:OptIn(ExperimentalCoroutinesApi::class) + +package com.android.systemui.statusbar.notification.icon.ui.viewmodel + +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.SmallTest +import com.android.SysUITestModule +import com.android.TestMocksModule +import com.android.systemui.SysuiTestCase +import com.android.systemui.biometrics.domain.BiometricsDomainLayerModule +import com.android.systemui.coroutines.collectLastValue +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.flags.FakeFeatureFlagsClassicModule +import com.android.systemui.flags.Flags +import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository +import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository +import com.android.systemui.keyguard.shared.model.DozeStateModel +import com.android.systemui.keyguard.shared.model.DozeTransitionModel +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.power.data.repository.FakePowerRepository +import com.android.systemui.power.shared.model.WakeSleepReason +import com.android.systemui.power.shared.model.WakefulnessState +import com.android.systemui.statusbar.phone.DozeParameters +import com.android.systemui.statusbar.policy.data.repository.FakeDeviceProvisioningRepository +import com.android.systemui.user.domain.UserDomainLayerModule +import com.android.systemui.util.mockito.whenever +import com.google.common.truth.Truth.assertThat +import dagger.BindsInstance +import dagger.Component +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.TestScope +import kotlinx.coroutines.test.runCurrent +import kotlinx.coroutines.test.runTest +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mock +import org.mockito.MockitoAnnotations + +@SmallTest +@RunWith(AndroidJUnit4::class) +class NotificationIconContainerStatusBarViewModelTest : SysuiTestCase() { + + @Mock lateinit var dozeParams: DozeParameters + + private lateinit var testComponent: TestComponent + private val underTest: NotificationIconContainerStatusBarViewModel + get() = testComponent.underTest + private val deviceProvisioningRepository + get() = testComponent.deviceProvisioningRepository + private val keyguardTransitionRepository + get() = testComponent.keyguardTransitionRepository + private val keyguardRepository + get() = testComponent.keyguardRepository + private val powerRepository + get() = testComponent.powerRepository + private val scope + get() = testComponent.scope + + @Before + fun setup() { + MockitoAnnotations.initMocks(this) + + testComponent = + DaggerNotificationIconContainerStatusBarViewModelTest_TestComponent.factory() + .create( + test = this, + featureFlags = + FakeFeatureFlagsClassicModule { + set(Flags.FACE_AUTH_REFACTOR, value = false) + set(Flags.FULL_SCREEN_USER_SWITCHER, value = false) + }, + mocks = + TestMocksModule( + dozeParameters = dozeParams, + ), + ) + + keyguardRepository.setKeyguardShowing(false) + deviceProvisioningRepository.setFactoryResetProtectionActive(false) + powerRepository.updateWakefulness( + rawState = WakefulnessState.AWAKE, + lastWakeReason = WakeSleepReason.OTHER, + lastSleepReason = WakeSleepReason.OTHER, + ) + } + + @Test + fun animationsEnabled_isFalse_whenFrpIsActive() = + scope.runTest { + deviceProvisioningRepository.setFactoryResetProtectionActive(true) + keyguardTransitionRepository.sendTransitionStep( + TransitionStep( + transitionState = TransitionState.STARTED, + ) + ) + val animationsEnabled by collectLastValue(underTest.animationsEnabled) + runCurrent() + assertThat(animationsEnabled).isFalse() + } + + @Test + fun animationsEnabled_isFalse_whenDeviceAsleepAndNotPulsing() = + scope.runTest { + powerRepository.updateWakefulness( + rawState = WakefulnessState.ASLEEP, + lastWakeReason = WakeSleepReason.POWER_BUTTON, + lastSleepReason = WakeSleepReason.OTHER, + ) + keyguardTransitionRepository.sendTransitionStep( + TransitionStep( + transitionState = TransitionState.STARTED, + ) + ) + keyguardRepository.setDozeTransitionModel( + DozeTransitionModel( + to = DozeStateModel.DOZE_AOD, + ) + ) + val animationsEnabled by collectLastValue(underTest.animationsEnabled) + runCurrent() + assertThat(animationsEnabled).isFalse() + } + + @Test + fun animationsEnabled_isTrue_whenDeviceAsleepAndPulsing() = + scope.runTest { + powerRepository.updateWakefulness( + rawState = WakefulnessState.ASLEEP, + lastWakeReason = WakeSleepReason.POWER_BUTTON, + lastSleepReason = WakeSleepReason.OTHER, + ) + keyguardTransitionRepository.sendTransitionStep( + TransitionStep( + transitionState = TransitionState.STARTED, + ) + ) + keyguardRepository.setDozeTransitionModel( + DozeTransitionModel( + to = DozeStateModel.DOZE_PULSING, + ) + ) + val animationsEnabled by collectLastValue(underTest.animationsEnabled) + runCurrent() + assertThat(animationsEnabled).isTrue() + } + + @Test + fun animationsEnabled_isFalse_whenStartingToSleepAndNotControlScreenOff() = + scope.runTest { + powerRepository.updateWakefulness( + rawState = WakefulnessState.STARTING_TO_SLEEP, + lastWakeReason = WakeSleepReason.POWER_BUTTON, + lastSleepReason = WakeSleepReason.OTHER, + ) + keyguardTransitionRepository.sendTransitionStep( + TransitionStep( + from = KeyguardState.GONE, + to = KeyguardState.AOD, + transitionState = TransitionState.STARTED, + ) + ) + whenever(dozeParams.shouldControlScreenOff()).thenReturn(false) + val animationsEnabled by collectLastValue(underTest.animationsEnabled) + runCurrent() + assertThat(animationsEnabled).isFalse() + } + + @Test + fun animationsEnabled_isTrue_whenStartingToSleepAndControlScreenOff() = + scope.runTest { + powerRepository.updateWakefulness( + rawState = WakefulnessState.STARTING_TO_SLEEP, + lastWakeReason = WakeSleepReason.POWER_BUTTON, + lastSleepReason = WakeSleepReason.OTHER, + ) + keyguardTransitionRepository.sendTransitionStep( + TransitionStep( + from = KeyguardState.GONE, + to = KeyguardState.AOD, + transitionState = TransitionState.STARTED, + ) + ) + whenever(dozeParams.shouldControlScreenOff()).thenReturn(true) + val animationsEnabled by collectLastValue(underTest.animationsEnabled) + runCurrent() + assertThat(animationsEnabled).isTrue() + } + + @Test + fun animationsEnabled_isTrue_whenNotAsleep() = + scope.runTest { + powerRepository.updateWakefulness( + rawState = WakefulnessState.AWAKE, + lastWakeReason = WakeSleepReason.POWER_BUTTON, + lastSleepReason = WakeSleepReason.OTHER, + ) + keyguardTransitionRepository.sendTransitionStep( + TransitionStep( + transitionState = TransitionState.STARTED, + ) + ) + val animationsEnabled by collectLastValue(underTest.animationsEnabled) + runCurrent() + assertThat(animationsEnabled).isTrue() + } + + @Test + fun animationsEnabled_isTrue_whenKeyguardIsNotShowing() = + scope.runTest { + val animationsEnabled by collectLastValue(underTest.animationsEnabled) + + keyguardTransitionRepository.sendTransitionStep( + TransitionStep( + transitionState = TransitionState.STARTED, + ) + ) + keyguardRepository.setKeyguardShowing(true) + runCurrent() + + assertThat(animationsEnabled).isFalse() + + keyguardRepository.setKeyguardShowing(false) + runCurrent() + + assertThat(animationsEnabled).isTrue() + } + + @SysUISingleton + @Component( + modules = + [ + SysUITestModule::class, + BiometricsDomainLayerModule::class, + UserDomainLayerModule::class, + ] + ) + interface TestComponent { + + val underTest: NotificationIconContainerStatusBarViewModel + + val deviceProvisioningRepository: FakeDeviceProvisioningRepository + val keyguardTransitionRepository: FakeKeyguardTransitionRepository + val keyguardRepository: FakeKeyguardRepository + val powerRepository: FakePowerRepository + val scope: TestScope + + @Component.Factory + interface Factory { + fun create( + @BindsInstance test: SysuiTestCase, + mocks: TestMocksModule, + featureFlags: FakeFeatureFlagsClassicModule, + ): TestComponent + } + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java index 9f2afdf1b168be4c5fd22f1e766eee80bc4d69f2..1ab36b805ca6db584440f3f2baf61f078c08a92f 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java @@ -33,7 +33,6 @@ import static org.junit.Assert.fail; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.ArgumentMatchers.anySet; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.mock; @@ -89,8 +88,8 @@ import com.android.systemui.statusbar.notification.collection.provider.HighPrior import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier; import com.android.systemui.statusbar.notification.row.NotificationGutsManager.OnSettingsClickListener; import com.android.systemui.statusbar.notification.stack.NotificationListContainer; -import com.android.systemui.statusbar.phone.HeadsUpManagerPhone; import com.android.systemui.statusbar.policy.DeviceProvisionedController; +import com.android.systemui.statusbar.policy.HeadsUpManager; import com.android.systemui.util.concurrency.FakeExecutor; import com.android.systemui.util.kotlin.JavaAdapter; import com.android.systemui.util.time.FakeSystemClock; @@ -152,7 +151,7 @@ public class NotificationGutsManagerTest extends SysuiTestCase { @Mock private AssistantFeedbackController mAssistantFeedbackController; @Mock private NotificationLockscreenUserManager mNotificationLockscreenUserManager; @Mock private StatusBarStateController mStatusBarStateController; - @Mock private HeadsUpManagerPhone mHeadsUpManagerPhone; + @Mock private HeadsUpManager mHeadsUpManager; @Mock private ActivityStarter mActivityStarter; @Mock private UserManager mUserManager; @@ -171,7 +170,7 @@ public class NotificationGutsManagerTest extends SysuiTestCase { mTestScope.getBackgroundScope(), new WindowRootViewVisibilityRepository(mBarService, mExecutor), new FakeKeyguardRepository(), - mHeadsUpManagerPhone, + mHeadsUpManager, PowerInteractorFactory.create().getPowerInteractor()); mGutsManager = new NotificationGutsManager( @@ -198,7 +197,7 @@ public class NotificationGutsManagerTest extends SysuiTestCase { mStatusBarStateController, mDeviceProvisionedController, mMetricsLogger, - mHeadsUpManagerPhone, + mHeadsUpManager, mActivityStarter); mGutsManager.setUpWithPresenter(mPresenter, mNotificationListContainer, mOnSettingsClickListener); @@ -239,7 +238,7 @@ public class NotificationGutsManagerTest extends SysuiTestCase { anyInt(), anyBoolean(), any(Runnable.class)); - verify(mHeadsUpManagerPhone).setGutsShown(realRow.getEntry(), true); + verify(mHeadsUpManager).setGutsShown(realRow.getEntry(), true); assertEquals(View.VISIBLE, guts.getVisibility()); mGutsManager.closeAndSaveGuts(false, false, true, 0, 0, false); @@ -247,7 +246,7 @@ public class NotificationGutsManagerTest extends SysuiTestCase { verify(guts).closeControls(anyBoolean(), anyBoolean(), anyInt(), anyInt(), anyBoolean()); verify(row, times(1)).setGutsView(any()); mTestableLooper.processAllMessages(); - verify(mHeadsUpManagerPhone).setGutsShown(realRow.getEntry(), false); + verify(mHeadsUpManager).setGutsShown(realRow.getEntry(), false); } @Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java index ac680e6c902ef55d53e74563ef9e9618b4e2108b..cb731082b89b7408ee42849db58da8f779f61d9e 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java @@ -61,6 +61,7 @@ import com.android.systemui.flags.Flags; import com.android.systemui.media.controls.util.MediaFeatureFlag; import com.android.systemui.media.dialog.MediaOutputDialogFactory; import com.android.systemui.plugins.statusbar.StatusBarStateController; +import com.android.systemui.res.R; import com.android.systemui.statusbar.NotificationMediaManager; import com.android.systemui.statusbar.NotificationRemoteInputManager; import com.android.systemui.statusbar.NotificationShadeWindowController; @@ -81,14 +82,13 @@ import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow.OnExpandClickListener; import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.InflationFlag; import com.android.systemui.statusbar.notification.stack.NotificationChildrenContainerLogger; -import com.android.systemui.statusbar.phone.HeadsUpManagerPhone; import com.android.systemui.statusbar.phone.KeyguardBypassController; +import com.android.systemui.statusbar.policy.HeadsUpManager; import com.android.systemui.statusbar.policy.InflatedSmartReplyState; import com.android.systemui.statusbar.policy.InflatedSmartReplyViewHolder; import com.android.systemui.statusbar.policy.SmartReplyConstants; import com.android.systemui.statusbar.policy.SmartReplyStateInflater; import com.android.systemui.statusbar.policy.dagger.RemoteInputViewSubcomponent; -import com.android.systemui.res.R; import com.android.systemui.wmshell.BubblesManager; import com.android.systemui.wmshell.BubblesTestActivity; @@ -123,7 +123,7 @@ public class NotificationTestHelper { private final GroupMembershipManager mGroupMembershipManager; private final GroupExpansionManager mGroupExpansionManager; private ExpandableNotificationRow mRow; - private final HeadsUpManagerPhone mHeadsUpManager; + private final HeadsUpManager mHeadsUpManager; private final NotifBindPipeline mBindPipeline; private final NotifCollectionListener mBindPipelineEntryListener; private final RowContentBindStage mBindStage; @@ -161,7 +161,7 @@ public class NotificationTestHelper { mKeyguardBypassController = mock(KeyguardBypassController.class); mGroupMembershipManager = mock(GroupMembershipManager.class); mGroupExpansionManager = mock(GroupExpansionManager.class); - mHeadsUpManager = mock(HeadsUpManagerPhone.class); + mHeadsUpManager = mock(HeadsUpManager.class); mIconManager = new IconManager( mock(CommonNotifCollection.class), mock(LauncherApps.class), diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java index ffe312be8faeeb142846953b5467bf9f98ddf842..20197e3ed547d5c4f3ca3b4c643c6136f648cf6b 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java @@ -77,7 +77,6 @@ import com.android.systemui.statusbar.notification.NotifPipelineFlags; import com.android.systemui.statusbar.notification.collection.NotifCollection; import com.android.systemui.statusbar.notification.collection.NotifPipeline; import com.android.systemui.statusbar.notification.collection.provider.NotificationDismissibilityProvider; -import com.android.systemui.statusbar.notification.collection.provider.SeenNotificationsProviderImpl; import com.android.systemui.statusbar.notification.collection.provider.VisibilityLocationProviderDelegator; import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager; import com.android.systemui.statusbar.notification.collection.render.NotifStats; @@ -88,13 +87,15 @@ import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow import com.android.systemui.statusbar.notification.row.NotificationGutsManager; import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController.NotificationPanelEvent; import com.android.systemui.statusbar.notification.stack.NotificationSwipeHelper.NotificationCallback; +import com.android.systemui.statusbar.notification.stack.data.repository.NotificationListRepository; +import com.android.systemui.statusbar.notification.stack.domain.interactor.NotificationListInteractor; import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationListViewModel; -import com.android.systemui.statusbar.phone.HeadsUpManagerPhone; import com.android.systemui.statusbar.phone.KeyguardBypassController; import com.android.systemui.statusbar.phone.NotificationIconAreaController; import com.android.systemui.statusbar.phone.ScrimController; import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.statusbar.policy.DeviceProvisionedController; +import com.android.systemui.statusbar.policy.HeadsUpManager; import com.android.systemui.statusbar.policy.ResourcesSplitShadeStateController; import com.android.systemui.statusbar.policy.ZenModeController; import com.android.systemui.tuner.TunerService; @@ -124,7 +125,7 @@ public class NotificationStackScrollLayoutControllerTest extends SysuiTestCase { @Mock private NotificationGutsManager mNotificationGutsManager; @Mock private NotificationsController mNotificationsController; @Mock private NotificationVisibilityProvider mVisibilityProvider; - @Mock private HeadsUpManagerPhone mHeadsUpManager; + @Mock private HeadsUpManager mHeadsUpManager; @Mock private NotificationRoundnessManager mNotificationRoundnessManager; @Mock private TunerService mTunerService; @Mock private DeviceProvisionedController mDeviceProvisionedController; @@ -170,8 +171,8 @@ public class NotificationStackScrollLayoutControllerTest extends SysuiTestCase { @Captor private ArgumentCaptor<StatusBarStateController.StateListener> mStateListenerArgumentCaptor; - private final SeenNotificationsProviderImpl mSeenNotificationsProvider = - new SeenNotificationsProviderImpl(); + private final NotificationListInteractor mNotificationListInteractor = + new NotificationListInteractor(new NotificationListRepository()); private NotificationStackScrollLayoutController mController; @@ -503,7 +504,7 @@ public class NotificationStackScrollLayoutControllerTest extends SysuiTestCase { @Test public void testSetNotifStats_updatesHasFilteredOutSeenNotifications() { initController(/* viewIsAttached= */ true); - mSeenNotificationsProvider.setHasFilteredOutSeenNotifications(true); + mNotificationListInteractor.setHasFilteredOutSeenNotifications(true); mController.getNotifStackController().setNotifStats(NotifStats.getEmpty()); verify(mNotificationStackScrollLayout).setHasFilteredOutSeenNotifications(true); verify(mNotificationStackScrollLayout).updateFooter(); @@ -703,7 +704,7 @@ public class NotificationStackScrollLayoutControllerTest extends SysuiTestCase { mUiEventLogger, mRemoteInputManager, mVisibilityLocationProviderDelegator, - mSeenNotificationsProvider, + mNotificationListInteractor, mShadeController, mJankMonitor, mStackLogger, diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt index e254dd085b2ed7c686709489bcf56b4c78d7a8c8..ac11ff29b83a039352315a4341372e99df389097 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt @@ -19,36 +19,35 @@ package com.android.systemui.statusbar.notification.stack.ui.viewmodel import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.systemui.res.R +import com.android.SysUITestModule +import com.android.TestMocksModule import com.android.systemui.SysuiTestCase import com.android.systemui.common.shared.model.SharedNotificationContainerPosition import com.android.systemui.common.ui.data.repository.FakeConfigurationRepository import com.android.systemui.coroutines.collectLastValue +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.flags.FakeFeatureFlagsClassicModule +import com.android.systemui.flags.Flags import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor -import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor -import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractorFactory import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.keyguard.shared.model.StatusBarState import com.android.systemui.keyguard.shared.model.TransitionState import com.android.systemui.keyguard.shared.model.TransitionStep -import com.android.systemui.scene.SceneTestUtils -import com.android.systemui.scene.shared.flag.FakeSceneContainerFlags +import com.android.systemui.res.R import com.android.systemui.shade.data.repository.FakeShadeRepository -import com.android.systemui.shade.domain.interactor.ShadeInteractor -import com.android.systemui.statusbar.disableflags.data.repository.FakeDisableFlagsRepository import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController import com.android.systemui.statusbar.notification.stack.NotificationStackSizeCalculator import com.android.systemui.statusbar.notification.stack.domain.interactor.SharedNotificationContainerInteractor -import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeUserSetupRepository -import com.android.systemui.statusbar.policy.DeviceProvisionedController -import com.android.systemui.statusbar.policy.ResourcesSplitShadeStateController -import com.android.systemui.user.domain.interactor.UserInteractor +import com.android.systemui.user.domain.UserDomainLayerModule 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 dagger.BindsInstance +import dagger.Component +import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest import org.junit.Before @@ -60,29 +59,27 @@ import org.mockito.MockitoAnnotations @SmallTest @RunWith(AndroidJUnit4::class) class SharedNotificationContainerViewModelTest : SysuiTestCase() { - private val utils = SceneTestUtils(this) - - private val testScope = utils.testScope - - private val disableFlagsRepository = FakeDisableFlagsRepository() - private val userSetupRepository = FakeUserSetupRepository() - private val shadeRepository = FakeShadeRepository() - private val keyguardRepository = FakeKeyguardRepository() - private val sceneContainerFlags = FakeSceneContainerFlags() - private val sceneInteractor = utils.sceneInteractor() - - private lateinit var configurationRepository: FakeConfigurationRepository - private lateinit var sharedNotificationContainerInteractor: - SharedNotificationContainerInteractor - private lateinit var underTest: SharedNotificationContainerViewModel - private lateinit var keyguardInteractor: KeyguardInteractor - private lateinit var keyguardTransitionInteractor: KeyguardTransitionInteractor - private lateinit var keyguardTransitionRepository: FakeKeyguardTransitionRepository - private lateinit var shadeInteractor: ShadeInteractor + + private lateinit var testComponent: TestComponent + + private val shadeRepository + get() = testComponent.shadeRepository + private val keyguardRepository + get() = testComponent.keyguardRepository + private val configurationRepository + get() = testComponent.configurationRepository + private val sharedNotificationContainerInteractor: SharedNotificationContainerInteractor + get() = testComponent.sharedNotificationContainerInteractor + private val underTest: SharedNotificationContainerViewModel + get() = testComponent.underTest + private val keyguardInteractor: KeyguardInteractor + get() = testComponent.keyguardInteractor + private val keyguardTransitionRepository + get() = testComponent.keyguardTransitionRepository + private val testScope + get() = testComponent.testScope @Mock private lateinit var notificationStackSizeCalculator: NotificationStackSizeCalculator - @Mock private lateinit var deviceProvisionedController: DeviceProvisionedController - @Mock private lateinit var userInteractor: UserInteractor @Mock private lateinit var notificationStackScrollLayoutController: NotificationStackScrollLayoutController @@ -94,43 +91,21 @@ class SharedNotificationContainerViewModelTest : SysuiTestCase() { whenever(notificationStackScrollLayoutController.getView()).thenReturn(mock()) whenever(notificationStackScrollLayoutController.getShelfHeight()).thenReturn(0) - configurationRepository = FakeConfigurationRepository() - KeyguardTransitionInteractorFactory.create( - scope = testScope.backgroundScope, - ) - .also { - keyguardInteractor = it.keyguardInteractor - keyguardTransitionInteractor = it.keyguardTransitionInteractor - keyguardTransitionRepository = it.repository - } - sharedNotificationContainerInteractor = - SharedNotificationContainerInteractor( - configurationRepository, - mContext, - ResourcesSplitShadeStateController() - ) - shadeInteractor = - ShadeInteractor( - testScope.backgroundScope, - disableFlagsRepository, - sceneContainerFlags, - { sceneInteractor }, - keyguardRepository, - userSetupRepository, - deviceProvisionedController, - userInteractor, - sharedNotificationContainerInteractor, - shadeRepository, - ) - underTest = - SharedNotificationContainerViewModel( - sharedNotificationContainerInteractor, - keyguardInteractor, - keyguardTransitionInteractor, - notificationStackSizeCalculator, - notificationStackScrollLayoutController, - shadeInteractor - ) + testComponent = + DaggerSharedNotificationContainerViewModelTest_TestComponent.factory() + .create( + test = this, + featureFlags = + FakeFeatureFlagsClassicModule { + set(Flags.FULL_SCREEN_USER_SWITCHER, true) + }, + mocks = + TestMocksModule( + notificationStackSizeCalculator = notificationStackSizeCalculator, + notificationStackScrollLayoutController = + notificationStackScrollLayoutController, + ) + ) } @Test @@ -404,4 +379,34 @@ class SharedNotificationContainerViewModelTest : SysuiTestCase() { ) ) } + + @SysUISingleton + @Component( + modules = + [ + SysUITestModule::class, + UserDomainLayerModule::class, + ] + ) + interface TestComponent { + + val underTest: SharedNotificationContainerViewModel + + val configurationRepository: FakeConfigurationRepository + val keyguardRepository: FakeKeyguardRepository + val keyguardInteractor: KeyguardInteractor + val keyguardTransitionRepository: FakeKeyguardTransitionRepository + val shadeRepository: FakeShadeRepository + val sharedNotificationContainerInteractor: SharedNotificationContainerInteractor + val testScope: TestScope + + @Component.Factory + interface Factory { + fun create( + @BindsInstance test: SysuiTestCase, + featureFlags: FakeFeatureFlagsClassicModule, + mocks: TestMocksModule, + ): TestComponent + } + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java index a5d34840424011c8f92891c65396ef261e286d2b..e7dad6a2908f611b41c800bd431199fec78afe65 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java @@ -57,6 +57,7 @@ import com.android.systemui.statusbar.VibratorHelper; import com.android.systemui.statusbar.disableflags.DisableFlagsLogger; import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController; import com.android.systemui.statusbar.policy.DeviceProvisionedController; +import com.android.systemui.statusbar.policy.HeadsUpManager; import com.android.systemui.statusbar.policy.KeyguardStateController; import com.android.systemui.statusbar.policy.RemoteInputQuickSettingsDisabler; @@ -85,7 +86,7 @@ public class CentralSurfacesCommandQueueCallbacksTest extends SysuiTestCase { private final MetricsLogger mMetricsLogger = new FakeMetricsLogger(); @Mock private KeyguardUpdateMonitor mKeyguardUpdateMonitor; @Mock private KeyguardStateController mKeyguardStateController; - @Mock private HeadsUpManagerPhone mHeadsUpManager; + @Mock private HeadsUpManager mHeadsUpManager; @Mock private WakefulnessLifecycle mWakefulnessLifecycle; @Mock private DeviceProvisionedController mDeviceProvisionedController; @Mock private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager; diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java index e33fa22bfc0c928a33a6898eaf1f79d009d62593..f18af61dd314878e21bf557f429c68854c2bf75c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java @@ -85,7 +85,6 @@ import com.android.keyguard.KeyguardUpdateMonitor; import com.android.keyguard.TestScopeProvider; import com.android.keyguard.ViewMediatorCallback; import com.android.systemui.InitController; -import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.accessibility.floatingmenu.AccessibilityFloatingMenuController; import com.android.systemui.animation.ActivityLaunchAnimator; @@ -117,6 +116,7 @@ import com.android.systemui.plugins.PluginDependencyProvider; import com.android.systemui.plugins.PluginManager; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.power.domain.interactor.PowerInteractor; +import com.android.systemui.res.R; import com.android.systemui.scene.domain.interactor.WindowRootViewVisibilityInteractor; import com.android.systemui.settings.UserTracker; import com.android.systemui.settings.brightness.BrightnessSliderController; @@ -219,7 +219,7 @@ public class CentralSurfacesImplTest extends SysuiTestCase { @Mock private KeyguardIndicationController mKeyguardIndicationController; @Mock private NotificationStackScrollLayout mStackScroller; @Mock private NotificationStackScrollLayoutController mStackScrollerController; - @Mock private HeadsUpManagerPhone mHeadsUpManager; + @Mock private HeadsUpManager mHeadsUpManager; @Mock private NotificationPanelViewController mNotificationPanelViewController; @Mock private ShadeLogger mShadeLogger; @Mock private NotificationPanelView mNotificationPanelView; @@ -336,6 +336,7 @@ public class CentralSurfacesImplTest extends SysuiTestCase { mFeatureFlags.set(Flags.WM_ENABLE_PREDICTIVE_BACK_SYSUI, false); // Set default value to avoid IllegalStateException. mFeatureFlags.set(Flags.SHORTCUT_LIST_SEARCH_LAYOUT, false); + mFeatureFlags.setDefault(Flags.NOTIFICATION_ICON_CONTAINER_REFACTOR); // For the Shade to respond to Back gesture, we must enable the event routing mFeatureFlags.set(Flags.WM_SHADE_ALLOW_BACK_GESTURE, true); // For the Shade to animate during the Back gesture, we must enable the animation flag. @@ -343,6 +344,7 @@ public class CentralSurfacesImplTest extends SysuiTestCase { mFeatureFlags.set(Flags.LIGHT_REVEAL_MIGRATION, true); // Turn AOD on and toggle feature flag for jank fixes mFeatureFlags.set(Flags.ZJ_285570694_LOCKSCREEN_TRANSITION_FROM_AOD, true); + mFeatureFlags.set(Flags.ALTERNATE_BOUNCER_VIEW, false); when(mDozeParameters.getAlwaysOn()).thenReturn(true); IThermalService thermalService = mock(IThermalService.class); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java index ff6f40d539fc723714c2b46dbd1151532189dcdd..593c587c0f514d9b5d0bde6b7927d28830b1e937 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java @@ -53,6 +53,7 @@ import com.android.systemui.statusbar.StatusBarStateControllerImpl; import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator; import com.android.systemui.statusbar.policy.BatteryController; import com.android.systemui.statusbar.policy.DeviceProvisionedController; +import com.android.systemui.statusbar.policy.HeadsUpManager; import org.junit.Before; import org.junit.Test; @@ -72,7 +73,7 @@ public class DozeServiceHostTest extends SysuiTestCase { private DozeServiceHost mDozeServiceHost; - @Mock private HeadsUpManagerPhone mHeadsUpManager; + @Mock private HeadsUpManager mHeadsUpManager; @Mock private ScrimController mScrimController; @Mock private DozeScrimController mDozeScrimController; @Mock private StatusBarStateControllerImpl mStatusBarStateController; diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java index ec6286b66ed2c9fe61826d916d2066aaf6f5fd51..d84bb728a856954b8f8a136792d723d9a959affb 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java @@ -47,6 +47,7 @@ import com.android.systemui.statusbar.notification.row.NotificationTestHelper; import com.android.systemui.statusbar.notification.stack.NotificationRoundnessManager; import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController; import com.android.systemui.statusbar.policy.Clock; +import com.android.systemui.statusbar.policy.HeadsUpManager; import com.android.systemui.statusbar.policy.KeyguardStateController; import org.junit.Assert; @@ -72,7 +73,7 @@ public class HeadsUpAppearanceControllerTest extends SysuiTestCase { private ExpandableNotificationRow mRow; private NotificationEntry mEntry; private HeadsUpStatusBarView mHeadsUpStatusBarView; - private HeadsUpManagerPhone mHeadsUpManager; + private HeadsUpManager mHeadsUpManager; private View mOperatorNameView; private StatusBarStateController mStatusbarStateController; private PhoneStatusBarTransitions mPhoneStatusBarTransitions; @@ -93,7 +94,7 @@ public class HeadsUpAppearanceControllerTest extends SysuiTestCase { mEntry = mRow.getEntry(); mHeadsUpStatusBarView = new HeadsUpStatusBarView(mContext, mock(View.class), mock(TextView.class)); - mHeadsUpManager = mock(HeadsUpManagerPhone.class); + mHeadsUpManager = mock(HeadsUpManager.class); mOperatorNameView = new View(mContext); mStatusbarStateController = mock(StatusBarStateController.class); mPhoneStatusBarTransitions = mock(PhoneStatusBarTransitions.class); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java index 1bc522d72213f89aeb533d81a116bb0dd59b6731..cda2a74609bd5b0b4acc5856b71f18df00a0f255 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java @@ -32,8 +32,8 @@ import android.testing.TestableLooper; import androidx.test.filters.SmallTest; import com.android.internal.logging.UiEventLogger; -import com.android.systemui.res.R; import com.android.systemui.plugins.statusbar.StatusBarStateController; +import com.android.systemui.res.R; import com.android.systemui.shade.ShadeExpansionStateManager; import com.android.systemui.statusbar.AlertingNotificationManager; import com.android.systemui.statusbar.AlertingNotificationManagerTest; @@ -43,6 +43,7 @@ import com.android.systemui.statusbar.notification.collection.provider.VisualSta import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager; import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper; import com.android.systemui.statusbar.policy.ConfigurationController; +import com.android.systemui.statusbar.policy.HeadsUpManager; import com.android.systemui.statusbar.policy.HeadsUpManagerLogger; import org.junit.After; @@ -71,7 +72,6 @@ public class HeadsUpManagerPhoneTest extends AlertingNotificationManagerTest { @Mock private AccessibilityManagerWrapper mAccessibilityManagerWrapper; @Mock private ShadeExpansionStateManager mShadeExpansionStateManager; @Mock private UiEventLogger mUiEventLogger; - private boolean mLivesPastNormalTime; private static final class TestableHeadsUpManagerPhone extends HeadsUpManagerPhone { TestableHeadsUpManagerPhone( @@ -149,7 +149,7 @@ public class HeadsUpManagerPhoneTest extends AlertingNotificationManagerTest { @Test public void testSnooze() { - final HeadsUpManagerPhone hmp = createHeadsUpManagerPhone(); + final HeadsUpManager hmp = createHeadsUpManagerPhone(); final NotificationEntry entry = createEntry(/* id = */ 0); hmp.showNotification(entry); @@ -160,7 +160,7 @@ public class HeadsUpManagerPhoneTest extends AlertingNotificationManagerTest { @Test public void testSwipedOutNotification() { - final HeadsUpManagerPhone hmp = createHeadsUpManagerPhone(); + final HeadsUpManager hmp = createHeadsUpManagerPhone(); final NotificationEntry entry = createEntry(/* id = */ 0); hmp.showNotification(entry); @@ -176,7 +176,7 @@ public class HeadsUpManagerPhoneTest extends AlertingNotificationManagerTest { @Test public void testCanRemoveImmediately_swipedOut() { - final HeadsUpManagerPhone hmp = createHeadsUpManagerPhone(); + final HeadsUpManager hmp = createHeadsUpManagerPhone(); final NotificationEntry entry = createEntry(/* id = */ 0); hmp.showNotification(entry); @@ -189,7 +189,7 @@ public class HeadsUpManagerPhoneTest extends AlertingNotificationManagerTest { @Ignore("b/141538055") @Test public void testCanRemoveImmediately_notTopEntry() { - final HeadsUpManagerPhone hmp = createHeadsUpManagerPhone(); + final HeadsUpManager hmp = createHeadsUpManagerPhone(); final NotificationEntry earlierEntry = createEntry(/* id = */ 0); final NotificationEntry laterEntry = createEntry(/* id = */ 1); laterEntry.setRow(mRow); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java index bac857910329d9dfc2c362b94c9d8021fc0b52db..b36d09df59292d726de50773eed061d3d2ff0602 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java @@ -18,6 +18,9 @@ package com.android.systemui.statusbar.phone; import static com.android.systemui.bouncer.shared.constants.KeyguardBouncerConstants.EXPANSION_HIDDEN; import static com.android.systemui.bouncer.shared.constants.KeyguardBouncerConstants.EXPANSION_VISIBLE; + +import static kotlinx.coroutines.test.TestCoroutineDispatchersKt.StandardTestDispatcher; + import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; @@ -33,7 +36,6 @@ import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import static kotlinx.coroutines.test.TestCoroutineDispatchersKt.StandardTestDispatcher; import android.service.trust.TrustAgentService; import android.testing.AndroidTestingRunner; @@ -175,6 +177,7 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase { mFeatureFlags.set(Flags.REFACTOR_KEYGUARD_DISMISS_INTENT, false); mFeatureFlags.set(Flags.UDFPS_NEW_TOUCH_DETECTION, true); mFeatureFlags.set(Flags.KEYGUARD_WM_STATE_REFACTOR, false); + mFeatureFlags.set(Flags.ALTERNATE_BOUNCER_VIEW, false); when(mNotificationShadeWindowController.getWindowRootView()) .thenReturn(mNotificationShadeWindowView); @@ -760,6 +763,30 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase { verify(mPrimaryBouncerInteractor, never()).hide(); } + @Test + public void handleDispatchTouchEvent_alternateBouncerViewFlagEnabled() { + mStatusBarKeyguardViewManager.addCallback(mCallback); + + // GIVEN alternate bouncer view flag enabled & the alternate bouncer is visible + mFeatureFlags.set(Flags.ALTERNATE_BOUNCER_VIEW, true); + when(mAlternateBouncerInteractor.isVisibleState()).thenReturn(true); + + // THEN the touch is not acted upon + verify(mCallback, never()).onTouch(any()); + } + + @Test + public void onInterceptTouch_alternateBouncerViewFlagEnabled() { + // GIVEN alternate bouncer view flag enabled & the alternate bouncer is visible + mFeatureFlags.set(Flags.ALTERNATE_BOUNCER_VIEW, true); + when(mAlternateBouncerInteractor.isVisibleState()).thenReturn(true); + + // THEN the touch is not intercepted + assertFalse(mStatusBarKeyguardViewManager.shouldInterceptTouchEvent( + MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_DOWN, 0f, 0f, 0) + )); + } + @Test public void handleDispatchTouchEvent_alternateBouncerNotVisible() { mStatusBarKeyguardViewManager.addCallback(mCallback); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java index 8013e5eef44b43dc03c42dd89bfd595f0251e895..beac995c893b493797ef8850ec41a6ad5620ad37 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java @@ -92,6 +92,7 @@ import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow import com.android.systemui.statusbar.notification.row.NotificationTestHelper; import com.android.systemui.statusbar.notification.row.OnUserInteractionCallback; import com.android.systemui.statusbar.notification.stack.NotificationListContainer; +import com.android.systemui.statusbar.policy.HeadsUpManager; import com.android.systemui.statusbar.policy.KeyguardStateController; import com.android.systemui.util.concurrency.FakeExecutor; import com.android.systemui.util.time.FakeSystemClock; @@ -218,7 +219,7 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase { mScreenOffAnimationController, mStatusBarStateController).getPowerInteractor(); - HeadsUpManagerPhone headsUpManager = mock(HeadsUpManagerPhone.class); + HeadsUpManager headsUpManager = mock(HeadsUpManager.class); NotificationLaunchAnimatorControllerProvider notificationAnimationProvider = new NotificationLaunchAnimatorControllerProvider( new NotificationExpansionRepository(), diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java index 233f407813b2b8bf2cb044229572e13422a395d3..ee4f2089c05c66abb9032c033b01b869ebb2bace 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java @@ -15,6 +15,7 @@ package com.android.systemui.statusbar.phone; import static android.view.Display.DEFAULT_DISPLAY; + import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; @@ -59,6 +60,7 @@ import com.android.systemui.statusbar.notification.row.NotificationGutsManager; import com.android.systemui.statusbar.notification.stack.NotificationListContainer; import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout; import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController; +import com.android.systemui.statusbar.policy.HeadsUpManager; import com.android.systemui.statusbar.policy.KeyguardStateController; import org.junit.Before; @@ -106,7 +108,7 @@ public class StatusBarNotificationPresenterTest extends SysuiTestCase { mContext, shadeViewController, mock(QuickSettingsController.class), - mock(HeadsUpManagerPhone.class), + mock(HeadsUpManager.class), notificationShadeWindowView, mock(ActivityStarter.class), stackScrollLayoutController, diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositorySwitcherTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositorySwitcherTest.kt index dbaa29bb36886d53395f072e04010c25647dea11..d06a6e26b4ce24521f9bcd05326bef2c8fa0665d 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositorySwitcherTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositorySwitcherTest.kt @@ -20,7 +20,6 @@ import android.net.ConnectivityManager import android.net.wifi.WifiManager import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.demomode.DemoMode import com.android.systemui.demomode.DemoModeController @@ -53,7 +52,6 @@ import org.mockito.MockitoAnnotations @OptIn(ExperimentalCoroutinesApi::class) @Suppress("EXPERIMENTAL_IS_NOT_ENABLED") @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) class WifiRepositorySwitcherTest : SysuiTestCase() { private lateinit var underTest: WifiRepositorySwitcher diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/DisabledWifiRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/DisabledWifiRepositoryTest.kt index 206ac1d37074b2e1c42dec6d528d673caee1cfb2..ce00250467f6cd196f5ca54dc77ad58928c250b3 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/DisabledWifiRepositoryTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/DisabledWifiRepositoryTest.kt @@ -18,7 +18,6 @@ package com.android.systemui.statusbar.pipeline.wifi.data.repository.prod import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiNetworkModel @@ -28,7 +27,6 @@ import org.junit.Test import org.junit.runner.RunWith @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) class DisabledWifiRepositoryTest : SysuiTestCase() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImplTest.kt index c2e75aa85fcbf1a9c551f0090016ce4759043150..cf20ba87e8c2f310a33d0288e6258ba864777b54 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImplTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImplTest.kt @@ -35,7 +35,6 @@ import android.net.wifi.WifiManager.UNKNOWN_SSID import android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue import com.android.systemui.log.table.TableLogBuffer @@ -73,7 +72,6 @@ import org.mockito.MockitoAnnotations @Suppress("EXPERIMENTAL_IS_NOT_ENABLED") @OptIn(ExperimentalCoroutinesApi::class) @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) class WifiRepositoryImplTest : SysuiTestCase() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractorImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractorImplTest.kt index 1db80651bf9b8e061afdcada3c113a6aa049d1c9..7fbbfc77300ea28d3f79bd73e617d127829dfbd3 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractorImplTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractorImplTest.kt @@ -19,7 +19,6 @@ package com.android.systemui.statusbar.pipeline.wifi.domain.interactor import android.net.wifi.WifiManager import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue import com.android.systemui.statusbar.pipeline.shared.data.model.ConnectivitySlot @@ -43,7 +42,6 @@ import org.junit.runner.RunWith @OptIn(ExperimentalCoroutinesApi::class) @Suppress("EXPERIMENTAL_IS_NOT_ENABLED") @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) class WifiInteractorImplTest : SysuiTestCase() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelTest.kt index 49a2648a7caca2d93792065cd47d0c8a1455b640..2d1a27f1b133418c809c3fff1dacd5a989f554d9 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelTest.kt @@ -19,7 +19,6 @@ package com.android.systemui.statusbar.pipeline.wifi.ui.viewmodel import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.settingslib.AccessibilityContentDescriptions.WIFI_OTHER_DEVICE_CONNECTION -import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.common.shared.model.ContentDescription.Companion.loadContentDescription import com.android.systemui.coroutines.collectLastValue @@ -53,7 +52,6 @@ import org.mockito.Mockito.`when` as whenever import org.mockito.MockitoAnnotations @SmallTest -@RoboPilotTest @RunWith(AndroidJUnit4::class) class WifiViewModelTest : SysuiTestCase() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/HeadsUpManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/HeadsUpManagerTest.java index 64ebcd9e3abf16a4e0b44b322e8bfc5e9a9fe22c..4f3f56423eb04dd3a30fcbf05253da6aeee66faa 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/HeadsUpManagerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/HeadsUpManagerTest.java @@ -41,10 +41,13 @@ import android.app.PendingIntent; import android.app.Person; import android.content.Context; import android.content.Intent; +import android.graphics.Region; import android.os.Handler; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.test.filters.SmallTest; import com.android.internal.logging.UiEventLogger; @@ -73,7 +76,7 @@ public class HeadsUpManagerTest extends AlertingNotificationManagerTest { private final HeadsUpManagerLogger mLogger = spy(new HeadsUpManagerLogger(logcatLogBuffer())); @Mock private AccessibilityManagerWrapper mAccessibilityMgr; - private final class TestableHeadsUpManager extends HeadsUpManager { + private final class TestableHeadsUpManager extends BaseHeadsUpManager { TestableHeadsUpManager(Context context, HeadsUpManagerLogger logger, Handler handler, @@ -85,9 +88,78 @@ public class HeadsUpManagerTest extends AlertingNotificationManagerTest { mAutoDismissNotificationDecay = TEST_AUTO_DISMISS_TIME; mStickyDisplayTime = TEST_STICKY_AUTO_DISMISS_TIME; } + + // The following are only implemented by HeadsUpManagerPhone. If you need them, use that. + @Override + public void addHeadsUpPhoneListener(@NonNull OnHeadsUpPhoneListenerChange listener) { + throw new UnsupportedOperationException(); + } + + @Override + public void addSwipedOutNotification(@NonNull String key) { + throw new UnsupportedOperationException(); + } + + @Override + public void extendHeadsUp() { + throw new UnsupportedOperationException(); + } + + @Nullable + @Override + public Region getTouchableRegion() { + throw new UnsupportedOperationException(); + } + + @Override + public boolean isHeadsUpGoingAway() { + throw new UnsupportedOperationException(); + } + + @Override + public void onExpandingFinished() { + throw new UnsupportedOperationException(); + } + + @Override + public boolean removeNotification(@NonNull String key, boolean releaseImmediately, + boolean animate) { + throw new UnsupportedOperationException(); + } + + @Override + public void setAnimationStateHandler(@NonNull AnimationStateHandler handler) { + throw new UnsupportedOperationException(); + } + + @Override + public void setGutsShown(@NonNull NotificationEntry entry, boolean gutsShown) { + throw new UnsupportedOperationException(); + } + + @Override + public void setHeadsUpGoingAway(boolean headsUpGoingAway) { + throw new UnsupportedOperationException(); + } + + @Override + public void setRemoteInputActive(@NonNull NotificationEntry entry, + boolean remoteInputActive) { + throw new UnsupportedOperationException(); + } + + @Override + public void setTrackingHeadsUp(boolean tracking) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean shouldSwallowClick(@NonNull String key) { + throw new UnsupportedOperationException(); + } } - private HeadsUpManager createHeadsUpManager() { + private BaseHeadsUpManager createHeadsUpManager() { return new TestableHeadsUpManager(mContext, mLogger, mTestHandler, mAccessibilityMgr, mUiEventLoggerFake); } @@ -165,9 +237,10 @@ public class HeadsUpManagerTest extends AlertingNotificationManagerTest { @Test public void testHunRemovedLogging() { - final HeadsUpManager hum = createHeadsUpManager(); + final BaseHeadsUpManager hum = createHeadsUpManager(); final NotificationEntry notifEntry = createEntry(/* id = */ 0); - final HeadsUpManager.HeadsUpEntry headsUpEntry = mock(HeadsUpManager.HeadsUpEntry.class); + final BaseHeadsUpManager.HeadsUpEntry headsUpEntry = mock( + BaseHeadsUpManager.HeadsUpEntry.class); headsUpEntry.mEntry = notifEntry; hum.onAlertEntryRemoved(headsUpEntry); @@ -177,35 +250,37 @@ public class HeadsUpManagerTest extends AlertingNotificationManagerTest { @Test public void testShouldHeadsUpBecomePinned_hasFSI_notUnpinned_true() { - final HeadsUpManager hum = createHeadsUpManager(); + final BaseHeadsUpManager hum = createHeadsUpManager(); final NotificationEntry notifEntry = createFullScreenIntentEntry(/* id = */ 0); // Add notifEntry to ANM mAlertEntries map and make it NOT unpinned hum.showNotification(notifEntry); - final HeadsUpManager.HeadsUpEntry headsUpEntry = hum.getHeadsUpEntry(notifEntry.getKey()); - headsUpEntry.wasUnpinned = false; + final BaseHeadsUpManager.HeadsUpEntry headsUpEntry = hum.getHeadsUpEntry( + notifEntry.getKey()); + headsUpEntry.mWasUnpinned = false; assertTrue(hum.shouldHeadsUpBecomePinned(notifEntry)); } @Test public void testShouldHeadsUpBecomePinned_wasUnpinned_false() { - final HeadsUpManager hum = createHeadsUpManager(); + final BaseHeadsUpManager hum = createHeadsUpManager(); final NotificationEntry notifEntry = createFullScreenIntentEntry(/* id = */ 0); // Add notifEntry to ANM mAlertEntries map and make it unpinned hum.showNotification(notifEntry); - final HeadsUpManager.HeadsUpEntry headsUpEntry = hum.getHeadsUpEntry(notifEntry.getKey()); - headsUpEntry.wasUnpinned = true; + final BaseHeadsUpManager.HeadsUpEntry headsUpEntry = hum.getHeadsUpEntry( + notifEntry.getKey()); + headsUpEntry.mWasUnpinned = true; assertFalse(hum.shouldHeadsUpBecomePinned(notifEntry)); } @Test public void testShouldHeadsUpBecomePinned_noFSI_false() { - final HeadsUpManager hum = createHeadsUpManager(); + final BaseHeadsUpManager hum = createHeadsUpManager(); final NotificationEntry entry = createEntry(/* id = */ 0); assertFalse(hum.shouldHeadsUpBecomePinned(entry)); @@ -214,7 +289,7 @@ public class HeadsUpManagerTest extends AlertingNotificationManagerTest { @Test public void testShowNotification_autoDismissesIncludingTouchAcceptanceDelay() { - final HeadsUpManager hum = createHeadsUpManager(); + final BaseHeadsUpManager hum = createHeadsUpManager(); final NotificationEntry entry = createEntry(/* id = */ 0); useAccessibilityTimeout(false); @@ -228,7 +303,7 @@ public class HeadsUpManagerTest extends AlertingNotificationManagerTest { @Test public void testShowNotification_autoDismissesWithDefaultTimeout() { - final HeadsUpManager hum = createHeadsUpManager(); + final BaseHeadsUpManager hum = createHeadsUpManager(); final NotificationEntry entry = createEntry(/* id = */ 0); useAccessibilityTimeout(false); @@ -242,7 +317,7 @@ public class HeadsUpManagerTest extends AlertingNotificationManagerTest { @Test public void testShowNotification_stickyForSomeTime_autoDismissesWithStickyTimeout() { - final HeadsUpManager hum = createHeadsUpManager(); + final BaseHeadsUpManager hum = createHeadsUpManager(); final NotificationEntry entry = createStickyForSomeTimeEntry(/* id = */ 0); useAccessibilityTimeout(false); @@ -256,7 +331,7 @@ public class HeadsUpManagerTest extends AlertingNotificationManagerTest { @Test public void testShowNotification_sticky_neverAutoDismisses() { - final HeadsUpManager hum = createHeadsUpManager(); + final BaseHeadsUpManager hum = createHeadsUpManager(); final NotificationEntry entry = createStickyEntry(/* id = */ 0); useAccessibilityTimeout(false); @@ -278,7 +353,7 @@ public class HeadsUpManagerTest extends AlertingNotificationManagerTest { @Test public void testShowNotification_autoDismissesWithAccessibilityTimeout() { - final HeadsUpManager hum = createHeadsUpManager(); + final BaseHeadsUpManager hum = createHeadsUpManager(); final NotificationEntry entry = createEntry(/* id = */ 0); useAccessibilityTimeout(true); @@ -292,7 +367,7 @@ public class HeadsUpManagerTest extends AlertingNotificationManagerTest { @Test public void testShowNotification_stickyForSomeTime_autoDismissesWithAccessibilityTimeout() { - final HeadsUpManager hum = createHeadsUpManager(); + final BaseHeadsUpManager hum = createHeadsUpManager(); final NotificationEntry entry = createStickyForSomeTimeEntry(/* id = */ 0); useAccessibilityTimeout(true); @@ -306,7 +381,7 @@ public class HeadsUpManagerTest extends AlertingNotificationManagerTest { @Test public void testRemoveNotification_beforeMinimumDisplayTime() { - final HeadsUpManager hum = createHeadsUpManager(); + final BaseHeadsUpManager hum = createHeadsUpManager(); final NotificationEntry entry = createEntry(/* id = */ 0); useAccessibilityTimeout(false); @@ -329,7 +404,7 @@ public class HeadsUpManagerTest extends AlertingNotificationManagerTest { @Test public void testRemoveNotification_afterMinimumDisplayTime() { - final HeadsUpManager hum = createHeadsUpManager(); + final BaseHeadsUpManager hum = createHeadsUpManager(); final NotificationEntry entry = createEntry(/* id = */ 0); useAccessibilityTimeout(false); @@ -366,7 +441,7 @@ public class HeadsUpManagerTest extends AlertingNotificationManagerTest { @Test public void testRemoveNotification_releaseImmediately() { - final HeadsUpManager hum = createHeadsUpManager(); + final BaseHeadsUpManager hum = createHeadsUpManager(); final NotificationEntry entry = createEntry(/* id = */ 0); hum.showNotification(entry); @@ -382,14 +457,15 @@ public class HeadsUpManagerTest extends AlertingNotificationManagerTest { @Test public void testIsSticky_rowPinnedAndExpanded_true() { - final HeadsUpManager hum = createHeadsUpManager(); + final BaseHeadsUpManager hum = createHeadsUpManager(); final NotificationEntry notifEntry = createEntry(/* id = */ 0); when(mRow.isPinned()).thenReturn(true); notifEntry.setRow(mRow); hum.showNotification(notifEntry); - final HeadsUpManager.HeadsUpEntry headsUpEntry = hum.getHeadsUpEntry(notifEntry.getKey()); + final BaseHeadsUpManager.HeadsUpEntry headsUpEntry = hum.getHeadsUpEntry( + notifEntry.getKey()); headsUpEntry.setExpanded(true); assertTrue(hum.isSticky(notifEntry.getKey())); @@ -397,20 +473,21 @@ public class HeadsUpManagerTest extends AlertingNotificationManagerTest { @Test public void testIsSticky_remoteInputActive_true() { - final HeadsUpManager hum = createHeadsUpManager(); + final BaseHeadsUpManager hum = createHeadsUpManager(); final NotificationEntry notifEntry = createEntry(/* id = */ 0); hum.showNotification(notifEntry); - final HeadsUpManager.HeadsUpEntry headsUpEntry = hum.getHeadsUpEntry(notifEntry.getKey()); - headsUpEntry.remoteInputActive = true; + final BaseHeadsUpManager.HeadsUpEntry headsUpEntry = hum.getHeadsUpEntry( + notifEntry.getKey()); + headsUpEntry.mRemoteInputActive = true; assertTrue(hum.isSticky(notifEntry.getKey())); } @Test public void testIsSticky_hasFullScreenIntent_true() { - final HeadsUpManager hum = createHeadsUpManager(); + final BaseHeadsUpManager hum = createHeadsUpManager(); final NotificationEntry notifEntry = createFullScreenIntentEntry(/* id = */ 0); hum.showNotification(notifEntry); @@ -421,7 +498,7 @@ public class HeadsUpManagerTest extends AlertingNotificationManagerTest { @Test public void testIsSticky_stickyForSomeTime_false() { - final HeadsUpManager hum = createHeadsUpManager(); + final BaseHeadsUpManager hum = createHeadsUpManager(); final NotificationEntry entry = createStickyForSomeTimeEntry(/* id = */ 0); hum.showNotification(entry); @@ -432,21 +509,22 @@ public class HeadsUpManagerTest extends AlertingNotificationManagerTest { @Test public void testIsSticky_false() { - final HeadsUpManager hum = createHeadsUpManager(); + final BaseHeadsUpManager hum = createHeadsUpManager(); final NotificationEntry notifEntry = createEntry(/* id = */ 0); hum.showNotification(notifEntry); - final HeadsUpManager.HeadsUpEntry headsUpEntry = hum.getHeadsUpEntry(notifEntry.getKey()); + final BaseHeadsUpManager.HeadsUpEntry headsUpEntry = hum.getHeadsUpEntry( + notifEntry.getKey()); headsUpEntry.setExpanded(false); - headsUpEntry.remoteInputActive = false; + headsUpEntry.mRemoteInputActive = false; assertFalse(hum.isSticky(notifEntry.getKey())); } @Test public void testCompareTo_withNullEntries() { - final HeadsUpManager hum = createHeadsUpManager(); + final BaseHeadsUpManager hum = createHeadsUpManager(); final NotificationEntry alertEntry = new NotificationEntryBuilder().setTag("alert").build(); hum.showNotification(alertEntry); @@ -458,7 +536,7 @@ public class HeadsUpManagerTest extends AlertingNotificationManagerTest { @Test public void testCompareTo_withNonAlertEntries() { - final HeadsUpManager hum = createHeadsUpManager(); + final BaseHeadsUpManager hum = createHeadsUpManager(); final NotificationEntry nonAlertEntry1 = new NotificationEntryBuilder().setTag( "nae1").build(); @@ -474,9 +552,9 @@ public class HeadsUpManagerTest extends AlertingNotificationManagerTest { @Test public void testAlertEntryCompareTo_ongoingCallLessThanActiveRemoteInput() { - final HeadsUpManager hum = createHeadsUpManager(); + final BaseHeadsUpManager hum = createHeadsUpManager(); - final HeadsUpManager.HeadsUpEntry ongoingCall = hum.new HeadsUpEntry(); + final BaseHeadsUpManager.HeadsUpEntry ongoingCall = hum.new HeadsUpEntry(); ongoingCall.setEntry(new NotificationEntryBuilder() .setSbn(createSbn(/* id = */ 0, new Notification.Builder(mContext, "") @@ -484,9 +562,9 @@ public class HeadsUpManagerTest extends AlertingNotificationManagerTest { .setOngoing(true))) .build()); - final HeadsUpManager.HeadsUpEntry activeRemoteInput = hum.new HeadsUpEntry(); + final BaseHeadsUpManager.HeadsUpEntry activeRemoteInput = hum.new HeadsUpEntry(); activeRemoteInput.setEntry(createEntry(/* id = */ 1)); - activeRemoteInput.remoteInputActive = true; + activeRemoteInput.mRemoteInputActive = true; assertThat(ongoingCall.compareTo(activeRemoteInput)).isLessThan(0); assertThat(activeRemoteInput.compareTo(ongoingCall)).isGreaterThan(0); @@ -494,9 +572,9 @@ public class HeadsUpManagerTest extends AlertingNotificationManagerTest { @Test public void testAlertEntryCompareTo_incomingCallLessThanActiveRemoteInput() { - final HeadsUpManager hum = createHeadsUpManager(); + final BaseHeadsUpManager hum = createHeadsUpManager(); - final HeadsUpManager.HeadsUpEntry incomingCall = hum.new HeadsUpEntry(); + final BaseHeadsUpManager.HeadsUpEntry incomingCall = hum.new HeadsUpEntry(); final Person person = new Person.Builder().setName("person").build(); final PendingIntent intent = mock(PendingIntent.class); incomingCall.setEntry(new NotificationEntryBuilder() @@ -506,9 +584,9 @@ public class HeadsUpManagerTest extends AlertingNotificationManagerTest { .forIncomingCall(person, intent, intent)))) .build()); - final HeadsUpManager.HeadsUpEntry activeRemoteInput = hum.new HeadsUpEntry(); + final BaseHeadsUpManager.HeadsUpEntry activeRemoteInput = hum.new HeadsUpEntry(); activeRemoteInput.setEntry(createEntry(/* id = */ 1)); - activeRemoteInput.remoteInputActive = true; + activeRemoteInput.mRemoteInputActive = true; assertThat(incomingCall.compareTo(activeRemoteInput)).isLessThan(0); assertThat(activeRemoteInput.compareTo(incomingCall)).isGreaterThan(0); @@ -516,10 +594,10 @@ public class HeadsUpManagerTest extends AlertingNotificationManagerTest { @Test public void testPinEntry_logsPeek() { - final HeadsUpManager hum = createHeadsUpManager(); + final BaseHeadsUpManager hum = createHeadsUpManager(); // Needs full screen intent in order to be pinned - final HeadsUpManager.HeadsUpEntry entryToPin = hum.new HeadsUpEntry(); + final BaseHeadsUpManager.HeadsUpEntry entryToPin = hum.new HeadsUpEntry(); entryToPin.setEntry(createFullScreenIntentEntry(/* id = */ 0)); // Note: the standard way to show a notification would be calling showNotification rather @@ -530,13 +608,13 @@ public class HeadsUpManagerTest extends AlertingNotificationManagerTest { hum.onAlertEntryAdded(entryToPin); assertEquals(1, mUiEventLoggerFake.numLogs()); - assertEquals(HeadsUpManager.NotificationPeekEvent.NOTIFICATION_PEEK.getId(), + assertEquals(BaseHeadsUpManager.NotificationPeekEvent.NOTIFICATION_PEEK.getId(), mUiEventLoggerFake.eventId(0)); } @Test public void testSetUserActionMayIndirectlyRemove() { - final HeadsUpManager hum = createHeadsUpManager(); + final BaseHeadsUpManager hum = createHeadsUpManager(); final NotificationEntry notifEntry = createEntry(/* id = */ 0); hum.showNotification(notifEntry); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/data/repository/DeviceProvisioningRepositoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/data/repository/DeviceProvisioningRepositoryImplTest.kt new file mode 100644 index 0000000000000000000000000000000000000000..12694ae998c1240333c7c49b16d2327d7b9a2b52 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/data/repository/DeviceProvisioningRepositoryImplTest.kt @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +@file:OptIn(ExperimentalCoroutinesApi::class) + +package com.android.systemui.statusbar.policy.data.repository + +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.SmallTest +import com.android.systemui.SysuiTestCase +import com.android.systemui.coroutines.collectLastValue +import com.android.systemui.statusbar.policy.DeviceProvisionedController +import com.android.systemui.util.mockito.whenever +import com.android.systemui.util.mockito.withArgCaptor +import com.google.common.truth.Truth.assertThat +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.runCurrent +import kotlinx.coroutines.test.runTest +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mock +import org.mockito.Mockito.verify +import org.mockito.MockitoAnnotations + +@SmallTest +@RunWith(AndroidJUnit4::class) +class DeviceProvisioningRepositoryImplTest : SysuiTestCase() { + + @Mock lateinit var deviceProvisionedController: DeviceProvisionedController + + lateinit var underTest: DeviceProvisioningRepositoryImpl + + @Before + fun setup() { + MockitoAnnotations.initMocks(this) + underTest = + DeviceProvisioningRepositoryImpl( + deviceProvisionedController, + ) + } + + @Test + fun isDeviceProvisioned_reflectsCurrentControllerState() = runTest { + whenever(deviceProvisionedController.isDeviceProvisioned).thenReturn(true) + val deviceProvisioned by collectLastValue(underTest.isDeviceProvisioned) + assertThat(deviceProvisioned).isTrue() + } + + @Test + fun isDeviceProvisioned_updatesWhenControllerStateChanges_toTrue() = runTest { + val deviceProvisioned by collectLastValue(underTest.isDeviceProvisioned) + runCurrent() + whenever(deviceProvisionedController.isDeviceProvisioned).thenReturn(true) + withArgCaptor { verify(deviceProvisionedController).addCallback(capture()) } + .onDeviceProvisionedChanged() + assertThat(deviceProvisioned).isTrue() + } + + @Test + fun isDeviceProvisioned_updatesWhenControllerStateChanges_toFalse() = runTest { + val deviceProvisioned by collectLastValue(underTest.isDeviceProvisioned) + runCurrent() + whenever(deviceProvisionedController.isDeviceProvisioned).thenReturn(false) + withArgCaptor { verify(deviceProvisionedController).addCallback(capture()) } + .onDeviceProvisionedChanged() + assertThat(deviceProvisioned).isFalse() + } + + @Test + fun isFrpActive_reflectsCurrentControllerState() = runTest { + whenever(deviceProvisionedController.isFrpActive).thenReturn(true) + val frpActive by collectLastValue(underTest.isFactoryResetProtectionActive) + assertThat(frpActive).isTrue() + } + + @Test + fun isFrpActive_updatesWhenControllerStateChanges_toTrue() = runTest { + val frpActive by collectLastValue(underTest.isFactoryResetProtectionActive) + runCurrent() + whenever(deviceProvisionedController.isFrpActive).thenReturn(true) + withArgCaptor { verify(deviceProvisionedController).addCallback(capture()) } + .onFrpActiveChanged() + assertThat(frpActive).isTrue() + } + + @Test + fun isFrpActive_updatesWhenControllerStateChanges_toFalse() = runTest { + val frpActive by collectLastValue(underTest.isFactoryResetProtectionActive) + runCurrent() + whenever(deviceProvisionedController.isFrpActive).thenReturn(false) + withArgCaptor { verify(deviceProvisionedController).addCallback(capture()) } + .onFrpActiveChanged() + assertThat(frpActive).isFalse() + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/UserInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/UserInteractorTest.kt index af941d03f191a5219b06bc3cfadf6d044ef53898..c56266dde7523c792ac7a78cd98f6e7b132988a6 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/UserInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/UserInteractorTest.kt @@ -155,6 +155,9 @@ class UserInteractorTest : SysuiTestCase() { @Test fun createUserInteractor_nonProcessUser_startsSecondaryService() { + val userId = Process.myUserHandle().identifier + 1 + whenever(manager.aliveUsers).thenReturn(listOf(createUserInfo(userId, "abc"))) + createUserInteractor(false /* startAsProcessUser */) verify(spyContext).startServiceAsUser(any(), any()) } @@ -655,9 +658,10 @@ class UserInteractorTest : SysuiTestCase() { @Test fun userSwitchedBroadcast() { - createUserInteractor() testScope.runTest { val userInfos = createUserInfos(count = 2, includeGuest = false) + whenever(manager.aliveUsers).thenReturn(userInfos) + createUserInteractor() userRepository.setUserInfos(userInfos) userRepository.setSelectedUserInfo(userInfos[0]) userRepository.setSettings(UserSwitcherSettingsModel(isUserSwitcherEnabled = true)) @@ -727,6 +731,26 @@ class UserInteractorTest : SysuiTestCase() { } } + @Test + fun localeChanged_refreshUsers() { + createUserInteractor() + testScope.runTest { + val userInfos = createUserInfos(count = 2, includeGuest = false) + userRepository.setUserInfos(userInfos) + userRepository.setSelectedUserInfo(userInfos[0]) + runCurrent() + val refreshUsersCallCount = userRepository.refreshUsersCallCount + + fakeBroadcastDispatcher.sendIntentToMatchingReceiversOnly( + spyContext, + Intent(Intent.ACTION_LOCALE_CHANGED) + ) + runCurrent() + + assertThat(userRepository.refreshUsersCallCount).isEqualTo(refreshUsersCallCount + 1) + } + } + @Test fun nonSystemUserUnlockedBroadcast_doNotRefreshUsers() { createUserInteractor() @@ -985,6 +1009,13 @@ class UserInteractorTest : SysuiTestCase() { } } + @Test + fun initWithNoAliveUsers() { + whenever(manager.aliveUsers).thenReturn(listOf()) + createUserInteractor() + verify(spyContext, never()).startServiceAsUser(any(), any()) + } + private fun assertUsers( models: List<UserModel>?, count: Int, diff --git a/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/UserSwitcherViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/UserSwitcherViewModelTest.kt index 6932f5ed4b30e6cb2340512478114ce26b81c569..c236b12d723f73c638466d41cba15060c458ad26 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/UserSwitcherViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/UserSwitcherViewModelTest.kt @@ -28,6 +28,7 @@ import com.android.systemui.GuestResetOrExitSessionReceiver import com.android.systemui.GuestResumeSessionReceiver import com.android.systemui.SysuiTestCase import com.android.systemui.common.shared.model.Text +import com.android.systemui.coroutines.collectLastValue import com.android.systemui.flags.FakeFeatureFlags import com.android.systemui.flags.Flags import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository @@ -346,6 +347,24 @@ class UserSwitcherViewModelTest : SysuiTestCase() { job.cancel() } + @Test + fun isFinishRequested_finishesWhenUserButtonIsClicked() = + testScope.runTest { + setUsers(count = 2) + val isFinishRequested = mutableListOf<Boolean>() + val job = + launch(testDispatcher) { underTest.isFinishRequested.toList(isFinishRequested) } + + val userViewModels = collectLastValue(underTest.users) + assertThat(isFinishRequested.last()).isFalse() + + userViewModels.invoke()?.firstOrNull()?.onClicked?.invoke() + + assertThat(isFinishRequested.last()).isTrue() + + job.cancel() + } + @Test fun guestSelected_nameIsExitGuest() = testScope.runTest { diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java index 409ba4801d0d20bed541c916cd6dbccb9ad228db..c8327029026d5e251ac633fe406276dda332bb06 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java @@ -86,20 +86,36 @@ import androidx.test.filters.SmallTest; import com.android.internal.colorextraction.ColorExtractor; import com.android.internal.logging.UiEventLogger; import com.android.internal.statusbar.IStatusBarService; +import com.android.keyguard.KeyguardSecurityModel; import com.android.launcher3.icons.BubbleIconFactory; import com.android.systemui.SysuiTestCase; import com.android.systemui.biometrics.AuthController; +import com.android.systemui.bouncer.data.repository.FakeKeyguardBouncerRepository; +import com.android.systemui.classifier.FalsingCollectorFake; import com.android.systemui.colorextraction.SysuiColorExtractor; import com.android.systemui.common.ui.data.repository.FakeConfigurationRepository; +import com.android.systemui.deviceentry.data.repository.FakeDeviceEntryRepository; import com.android.systemui.dump.DumpManager; import com.android.systemui.flags.FakeFeatureFlags; +import com.android.systemui.flags.FakeFeatureFlagsClassic; import com.android.systemui.keyguard.KeyguardViewMediator; +import com.android.systemui.keyguard.data.repository.FakeCommandQueue; import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository; +import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository; +import com.android.systemui.keyguard.domain.interactor.FromLockscreenTransitionInteractor; +import com.android.systemui.keyguard.domain.interactor.FromPrimaryBouncerTransitionInteractor; +import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor; +import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor; import com.android.systemui.model.SysUiState; import com.android.systemui.plugins.statusbar.StatusBarStateController; +import com.android.systemui.power.data.repository.FakePowerRepository; +import com.android.systemui.power.domain.interactor.PowerInteractor; import com.android.systemui.scene.FakeWindowRootViewComponent; import com.android.systemui.scene.SceneTestUtils; +import com.android.systemui.scene.data.repository.SceneContainerRepository; +import com.android.systemui.scene.domain.interactor.SceneInteractor; import com.android.systemui.scene.shared.flag.FakeSceneContainerFlags; +import com.android.systemui.scene.shared.logger.SceneLogger; import com.android.systemui.settings.FakeDisplayTracker; import com.android.systemui.settings.UserTracker; import com.android.systemui.shade.NotificationShadeWindowControllerImpl; @@ -139,6 +155,7 @@ import com.android.systemui.statusbar.policy.HeadsUpManager; import com.android.systemui.statusbar.policy.KeyguardStateController; import com.android.systemui.statusbar.policy.ResourcesSplitShadeStateController; import com.android.systemui.statusbar.policy.ZenModeController; +import com.android.systemui.statusbar.policy.data.repository.FakeDeviceProvisioningRepository; import com.android.systemui.user.domain.interactor.UserInteractor; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.WindowManagerShellWrapper; @@ -329,6 +346,8 @@ public class BubblesTest extends SysuiTestCase { private UserHandle mUser0; private FakeBubbleProperties mBubbleProperties; + private FromLockscreenTransitionInteractor mFromLockscreenTransitionInteractor; + private FromPrimaryBouncerTransitionInteractor mFromPrimaryBouncerTransitionInteractor; @Before public void setUp() throws Exception { @@ -350,21 +369,94 @@ public class BubblesTest extends SysuiTestCase { when(mNotificationShadeWindowView.getViewTreeObserver()) .thenReturn(mock(ViewTreeObserver.class)); - mShadeInteractor = new ShadeInteractor( + + FakeDeviceProvisioningRepository deviceProvisioningRepository = + new FakeDeviceProvisioningRepository(); + deviceProvisioningRepository.setDeviceProvisioned(true); + FakeKeyguardRepository keyguardRepository = new FakeKeyguardRepository(); + FakeFeatureFlagsClassic featureFlags = new FakeFeatureFlagsClassic(); + FakeShadeRepository shadeRepository = new FakeShadeRepository(); + FakePowerRepository powerRepository = new FakePowerRepository(); + FakeConfigurationRepository configurationRepository = new FakeConfigurationRepository(); + + PowerInteractor powerInteractor = new PowerInteractor( + powerRepository, + new FalsingCollectorFake(), + mock(ScreenOffAnimationController.class), + mStatusBarStateController); + + SceneInteractor sceneInteractor = new SceneInteractor( mTestScope.getBackgroundScope(), - new FakeDisableFlagsRepository(), - new FakeSceneContainerFlags(), - mUtils::sceneInteractor, - new FakeKeyguardRepository(), - new FakeUserSetupRepository(), - mock(DeviceProvisionedController.class), - mock(UserInteractor.class), - new SharedNotificationContainerInteractor( - new FakeConfigurationRepository(), - mContext, - new ResourcesSplitShadeStateController()), - new FakeShadeRepository() - ); + new SceneContainerRepository( + mTestScope.getBackgroundScope(), + mUtils.fakeSceneContainerConfig(mUtils.fakeSceneKeys())), + powerRepository, + mock(SceneLogger.class)); + + FakeSceneContainerFlags sceneContainerFlags = new FakeSceneContainerFlags(); + KeyguardInteractor keyguardInteractor = new KeyguardInteractor( + keyguardRepository, + new FakeCommandQueue(), + powerInteractor, + featureFlags, + sceneContainerFlags, + new FakeDeviceEntryRepository(), + new FakeKeyguardBouncerRepository(), + configurationRepository, + shadeRepository, + () -> sceneInteractor); + + FakeKeyguardTransitionRepository keyguardTransitionRepository = + new FakeKeyguardTransitionRepository(); + + KeyguardTransitionInteractor keyguardTransitionInteractor = + new KeyguardTransitionInteractor( + mTestScope.getBackgroundScope(), + keyguardTransitionRepository, + () -> keyguardInteractor, + () -> mFromLockscreenTransitionInteractor, + () -> mFromPrimaryBouncerTransitionInteractor); + + mFromLockscreenTransitionInteractor = new FromLockscreenTransitionInteractor( + keyguardTransitionRepository, + keyguardTransitionInteractor, + mTestScope.getBackgroundScope(), + keyguardInteractor, + featureFlags, + shadeRepository, + powerInteractor); + + mFromPrimaryBouncerTransitionInteractor = new FromPrimaryBouncerTransitionInteractor( + keyguardTransitionRepository, + keyguardTransitionInteractor, + mTestScope.getBackgroundScope(), + keyguardInteractor, + featureFlags, + mock(KeyguardSecurityModel.class), + powerInteractor); + + ResourcesSplitShadeStateController splitShadeStateController = + new ResourcesSplitShadeStateController(); + + mShadeInteractor = + new ShadeInteractor( + mTestScope.getBackgroundScope(), + deviceProvisioningRepository, + new FakeDisableFlagsRepository(), + mDozeParameters, + sceneContainerFlags, + () -> sceneInteractor, + keyguardRepository, + keyguardTransitionInteractor, + powerInteractor, + new FakeUserSetupRepository(), + mock(UserInteractor.class), + new SharedNotificationContainerInteractor( + configurationRepository, + mContext, + splitShadeStateController), + new FakeShadeRepository() + ); mNotificationShadeWindowController = new NotificationShadeWindowControllerImpl( mContext, diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/FakeSystemUiModule.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/FakeSystemUiModule.kt index 0e594964bb3057ecb761c79fc995a310c391e461..813197b171adfe13c6e5e39cee2ab920f3ef3e23 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/FakeSystemUiModule.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/FakeSystemUiModule.kt @@ -15,21 +15,27 @@ */ package com.android.systemui +import com.android.systemui.classifier.FakeClassifierModule import com.android.systemui.data.FakeSystemUiDataLayerModule import com.android.systemui.flags.FakeFeatureFlagsClassicModule import com.android.systemui.log.FakeUiEventLoggerModule import com.android.systemui.scene.FakeSceneModule import com.android.systemui.settings.FakeSettingsModule +import com.android.systemui.statusbar.policy.FakeConfigurationControllerModule +import com.android.systemui.statusbar.policy.FakeSplitShadeStateControllerModule import com.android.systemui.util.concurrency.FakeExecutorModule import dagger.Module @Module( includes = [ + FakeClassifierModule::class, + FakeConfigurationControllerModule::class, FakeExecutorModule::class, FakeFeatureFlagsClassicModule::class, - FakeSettingsModule::class, FakeSceneModule::class, + FakeSettingsModule::class, + FakeSplitShadeStateControllerModule::class, FakeSystemUiDataLayerModule::class, FakeUiEventLoggerModule::class, ] diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/classifier/FakeClassifierModule.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/classifier/FakeClassifierModule.kt new file mode 100644 index 0000000000000000000000000000000000000000..23bad39a262e16580f9997dbaa84d9c039213c58 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/classifier/FakeClassifierModule.kt @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the specific language governing + * permissions and limitations under the License. + * + */ + +package com.android.systemui.classifier + +import dagger.Module + +@Module(includes = [FakeFalsingCollectorModule::class, FakeFalsingManagerModule::class]) +object FakeClassifierModule diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/classifier/FakeFalsingCollectorModule.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/classifier/FakeFalsingCollectorModule.kt new file mode 100644 index 0000000000000000000000000000000000000000..92acc9465bb0e1aebc5fd1f418fb96ee4647a8b4 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/classifier/FakeFalsingCollectorModule.kt @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the specific language governing + * permissions and limitations under the License. + * + */ + +package com.android.systemui.classifier + +import dagger.Binds +import dagger.Module + +@Module +interface FakeFalsingCollectorModule { + @Binds @FalsingCollectorActual fun bindFake(fake: FalsingCollectorFake): FalsingCollector + @Binds fun bindFakeLegacy(fake: FalsingCollectorFake): FalsingCollector +} diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/classifier/FakeFalsingManagerModule.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/classifier/FakeFalsingManagerModule.kt new file mode 100644 index 0000000000000000000000000000000000000000..554fc75ec1db36a354821052835d79b4c0b2b0d1 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/classifier/FakeFalsingManagerModule.kt @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the specific language governing + * permissions and limitations under the License. + * + */ + +package com.android.systemui.classifier + +import com.android.systemui.plugins.FalsingManager +import dagger.Binds +import dagger.Module + +@Module +interface FakeFalsingManagerModule { + @Binds fun bindFake(fake: FalsingManagerFake): FalsingManager +} diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/classifier/FalsingManagerFake.java b/packages/SystemUI/tests/utils/src/com/android/systemui/classifier/FalsingManagerFake.java index d47e88fc9385922fb75b6a45da210a7c963a34c6..5038285aef0058f7be6f63c3b4e1e721f50b70f8 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/classifier/FalsingManagerFake.java +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/classifier/FalsingManagerFake.java @@ -21,15 +21,19 @@ import static com.google.common.truth.Truth.assertWithMessage; import android.net.Uri; import com.android.internal.annotations.VisibleForTesting; +import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.plugins.FalsingManager; import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; +import javax.inject.Inject; + /** * Simple Fake for testing where {@link FalsingManager} is required. */ +@SysUISingleton public class FalsingManagerFake implements FalsingManager { private boolean mIsFalseTouch; private boolean mIsSimpleTap; @@ -46,6 +50,10 @@ public class FalsingManagerFake implements FalsingManager { private final List<FalsingBeliefListener> mFalsingBeliefListeners = new ArrayList<>(); private final List<FalsingTapListener> mTapListeners = new ArrayList<>(); + @Inject + public FalsingManagerFake() { + } + @Override public void onSuccessfulUnlock() { diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/data/FakeSystemUiDataLayerModule.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/data/FakeSystemUiDataLayerModule.kt index f866932309bb4d3058c0d2faed297c7c37422799..29fb52aabd398121312d01e0fc5f4d01bd720566 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/data/FakeSystemUiDataLayerModule.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/data/FakeSystemUiDataLayerModule.kt @@ -17,6 +17,7 @@ package com.android.systemui.data import com.android.systemui.bouncer.data.repository.FakeBouncerDataLayerModule import com.android.systemui.common.ui.data.FakeCommonDataLayerModule +import com.android.systemui.deviceentry.data.FakeDeviceEntryDataLayerModule import com.android.systemui.keyguard.data.FakeKeyguardDataLayerModule import com.android.systemui.power.data.FakePowerDataLayerModule import com.android.systemui.shade.data.repository.FakeShadeDataLayerModule @@ -28,8 +29,9 @@ import dagger.Module @Module( includes = [ - FakeCommonDataLayerModule::class, FakeBouncerDataLayerModule::class, + FakeCommonDataLayerModule::class, + FakeDeviceEntryDataLayerModule::class, FakeKeyguardDataLayerModule::class, FakePowerDataLayerModule::class, FakeShadeDataLayerModule::class, diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/data/FakeDeviceEntryDataLayerModule.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/data/FakeDeviceEntryDataLayerModule.kt new file mode 100644 index 0000000000000000000000000000000000000000..ef02bdd9c35cf12cbc758444747f03a3fb8c4546 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/data/FakeDeviceEntryDataLayerModule.kt @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the specific language governing + * permissions and limitations under the License. + * + */ + +package com.android.systemui.deviceentry.data + +import com.android.systemui.deviceentry.data.repository.FakeDeviceEntryRepositoryModule +import dagger.Module + +@Module(includes = [FakeDeviceEntryRepositoryModule::class]) object FakeDeviceEntryDataLayerModule diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/data/repository/FakeDeviceEntryRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/data/repository/FakeDeviceEntryRepository.kt index 5e60a09e006bcabb4ce9f35dadd326134d1482c3..26d95c0a0ea38d3f487b4bc431babccaac55b2a8 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/data/repository/FakeDeviceEntryRepository.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/data/repository/FakeDeviceEntryRepository.kt @@ -1,11 +1,16 @@ package com.android.systemui.deviceentry.data.repository +import com.android.systemui.dagger.SysUISingleton +import dagger.Binds +import dagger.Module +import javax.inject.Inject import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow /** Fake implementation of [DeviceEntryRepository] */ -class FakeDeviceEntryRepository : DeviceEntryRepository { +@SysUISingleton +class FakeDeviceEntryRepository @Inject constructor() : DeviceEntryRepository { private var isInsecureLockscreenEnabled = true private var isBypassEnabled = false @@ -33,3 +38,8 @@ class FakeDeviceEntryRepository : DeviceEntryRepository { this.isBypassEnabled = isBypassEnabled } } + +@Module +interface FakeDeviceEntryRepositoryModule { + @Binds fun bindFake(fake: FakeDeviceEntryRepository): DeviceEntryRepository +} diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/data/FakeStatusBarDataLayerModule.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/data/FakeStatusBarDataLayerModule.kt index 1bec82b0875b9dd2bff8ff7bb23627cde1669e96..822edfc7f6cdca8cfd7d99c5707dd643a4814d32 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/data/FakeStatusBarDataLayerModule.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/data/FakeStatusBarDataLayerModule.kt @@ -17,6 +17,7 @@ package com.android.systemui.statusbar.data import com.android.systemui.statusbar.disableflags.data.FakeStatusBarDisableFlagsDataLayerModule import com.android.systemui.statusbar.pipeline.data.FakeStatusBarPipelineDataLayerModule +import com.android.systemui.statusbar.policy.data.FakeStatusBarPolicyDataLayerModule import dagger.Module @Module( @@ -24,6 +25,7 @@ import dagger.Module [ FakeStatusBarDisableFlagsDataLayerModule::class, FakeStatusBarPipelineDataLayerModule::class, + FakeStatusBarPolicyDataLayerModule::class, ] ) object FakeStatusBarDataLayerModule diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/FakeConfigurationController.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/FakeConfigurationController.kt index 16a32686956204674a6faa5b2a92c09e450e183e..23477d86807c444c417a1f711c7a2a6491fe456c 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/FakeConfigurationController.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/FakeConfigurationController.kt @@ -1,9 +1,14 @@ package com.android.systemui.statusbar.policy import android.content.res.Configuration +import com.android.systemui.dagger.SysUISingleton +import dagger.Binds +import dagger.Module +import javax.inject.Inject /** Fake implementation of [ConfigurationController] for tests. */ -class FakeConfigurationController : ConfigurationController { +@SysUISingleton +class FakeConfigurationController @Inject constructor() : ConfigurationController { private var listeners = mutableListOf<ConfigurationController.ConfigurationListener>() @@ -33,3 +38,8 @@ class FakeConfigurationController : ConfigurationController { override fun isLayoutRtl(): Boolean = false } + +@Module +interface FakeConfigurationControllerModule { + @Binds fun bindFake(fake: FakeConfigurationController): ConfigurationController +} diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/FakeSplitShadeStateControllerModule.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/FakeSplitShadeStateControllerModule.kt new file mode 100644 index 0000000000000000000000000000000000000000..14bab84e62b25a3d317273d75f74118ae98dd2c0 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/FakeSplitShadeStateControllerModule.kt @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the specific language governing + * permissions and limitations under the License. + * + */ + +package com.android.systemui.statusbar.policy + +import dagger.Binds +import dagger.Module + +@Module +interface FakeSplitShadeStateControllerModule { + @Binds fun bindFake(fake: ResourcesSplitShadeStateController): SplitShadeStateController +} diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/RoboPilotTest.java b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/data/FakeStatusBarPolicyDataLayerModule.kt similarity index 58% rename from packages/SystemUI/tests/utils/src/com/android/systemui/RoboPilotTest.java rename to packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/data/FakeStatusBarPolicyDataLayerModule.kt index 3fff136db03a5fae487a57f11ebf353911cc4d10..5aece1bbbd3134c1ef33bcd2747954cb88fbec4f 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/RoboPilotTest.java +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/data/FakeStatusBarPolicyDataLayerModule.kt @@ -13,19 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +package com.android.systemui.statusbar.policy.data -package com.android.systemui; +import com.android.systemui.statusbar.policy.data.repository.FakeDeviceProvisioningRepositoryModule +import dagger.Module -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Mark as tests for Robolectric pilot projects. The filter can better help grouping test results - * that runs on CI - */ -@Target({ElementType.METHOD, ElementType.TYPE}) -@Retention(RetentionPolicy.RUNTIME) -public @interface RoboPilotTest { -} +@Module(includes = [FakeDeviceProvisioningRepositoryModule::class]) +object FakeStatusBarPolicyDataLayerModule diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/data/repository/FakeDeviceProvisioningRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/data/repository/FakeDeviceProvisioningRepository.kt new file mode 100644 index 0000000000000000000000000000000000000000..300229954044bd0db06a353c6023bed0c0816d24 --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/data/repository/FakeDeviceProvisioningRepository.kt @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.systemui.statusbar.policy.data.repository + +import com.android.systemui.dagger.SysUISingleton +import dagger.Binds +import dagger.Module +import javax.inject.Inject +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.MutableStateFlow + +@SysUISingleton +class FakeDeviceProvisioningRepository @Inject constructor() : DeviceProvisioningRepository { + private val _isDeviceProvisioned = MutableStateFlow(false) + override val isDeviceProvisioned: Flow<Boolean> = _isDeviceProvisioned + private val _isFactoryResetProtectionActive = MutableStateFlow(false) + override val isFactoryResetProtectionActive: Flow<Boolean> = _isFactoryResetProtectionActive + fun setDeviceProvisioned(isProvisioned: Boolean) { + _isDeviceProvisioned.value = isProvisioned + } + fun setFactoryResetProtectionActive(isActive: Boolean) { + _isFactoryResetProtectionActive.value = isActive + } +} + +@Module +interface FakeDeviceProvisioningRepositoryModule { + @Binds fun bindFake(fake: FakeDeviceProvisioningRepository): DeviceProvisioningRepository +} diff --git a/packages/WallpaperBackup/Android.bp b/packages/WallpaperBackup/Android.bp index 155dc1a6829553df57ae91911ff6340b2bf921ca..18f783146c7292e41b0ebe82e7791442e4fe3559 100644 --- a/packages/WallpaperBackup/Android.bp +++ b/packages/WallpaperBackup/Android.bp @@ -49,7 +49,7 @@ android_test { "androidx.test.core", "androidx.test.rules", "mockito-target-minus-junit4", - "truth-prebuilt", + "truth", ], resource_dirs: ["test/res"], certificate: "platform", diff --git a/packages/overlays/tests/Android.bp b/packages/overlays/tests/Android.bp index b781602399a3b3d8012fe67706dd6e3129fca152..0244c0fe05332d469c62471911dc8889aa0a72ee 100644 --- a/packages/overlays/tests/Android.bp +++ b/packages/overlays/tests/Android.bp @@ -34,7 +34,7 @@ android_test { "androidx.test.rules", "androidx.test.espresso.core", "mockito-target-minus-junit4", - "truth-prebuilt", + "truth", ], dxflags: ["--multi-dex"], } diff --git a/services/autofill/Android.bp b/services/autofill/Android.bp index d43a219e620583da8f17145398d821d2e2799649..eb23f2f9b435d8757f9310e4286dcd74dfef2ef6 100644 --- a/services/autofill/Android.bp +++ b/services/autofill/Android.bp @@ -19,19 +19,4 @@ java_library_static { defaults: ["platform_service_defaults"], srcs: [":services.autofill-sources"], libs: ["services.core"], - static_libs: ["autofill_flags_java_lib"], -} - -aconfig_declarations { - name: "autofill_flags", - package: "android.service.autofill", - srcs: [ - "bugfixes.aconfig", - "features.aconfig", - ], -} - -java_aconfig_library { - name: "autofill_flags_java_lib", - aconfig_declarations: "autofill_flags", } diff --git a/services/autofill/bugfixes.aconfig b/services/autofill/bugfixes.aconfig index ef237546378eff817ce608ee4d3f6fc1f44492e8..123b65c039ba0790be20f3f25734b9ac7227e46d 100644 --- a/services/autofill/bugfixes.aconfig +++ b/services/autofill/bugfixes.aconfig @@ -5,4 +5,11 @@ flag { namespace: "autofill" description: "Test flag " bug: "297380045" -} \ No newline at end of file +} + +flag { + name: "relayout" + namespace: "autofill" + description: "Mitigation for relayout issue" + bug: "294330426" +} diff --git a/services/core/java/com/android/server/PinnerService.java b/services/core/java/com/android/server/PinnerService.java index 9bab261bb0f4637494cb237eada367ef3f892b3c..93dca2f4f19248315a575537a3b858f1e05beae0 100644 --- a/services/core/java/com/android/server/PinnerService.java +++ b/services/core/java/com/android/server/PinnerService.java @@ -359,8 +359,10 @@ public final class PinnerService extends SystemService { @Override public void onChange(boolean selfChange, Uri uri) { if (userSetupCompleteUri.equals(uri)) { - sendPinAppMessage(KEY_HOME, ActivityManager.getCurrentUser(), - true /* force */); + if (mConfiguredToPinHome) { + sendPinAppMessage(KEY_HOME, ActivityManager.getCurrentUser(), + true /* force */); + } } } }, UserHandle.USER_ALL); diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java index 8cc2665b356280affd6aa245fa00eac694108d03..962f38f10b5de1968c95be9caba9c705ef32ec69 100644 --- a/services/core/java/com/android/server/StorageManagerService.java +++ b/services/core/java/com/android/server/StorageManagerService.java @@ -214,6 +214,9 @@ class StorageManagerService extends IStorageManager.Stub // external storage service. public static final int FAILED_MOUNT_RESET_TIMEOUT_SECONDS = 10; + /** Extended timeout for the system server watchdog. */ + private static final int SLOW_OPERATION_WATCHDOG_TIMEOUT_MS = 60 * 1000; + @GuardedBy("mLock") private final Set<Integer> mFuseMountedUser = new ArraySet<>(); @@ -1230,6 +1233,8 @@ class StorageManagerService extends IStorageManager.Stub private void onUserStopped(int userId) { Slog.d(TAG, "onUserStopped " + userId); + Watchdog.getInstance().setOneOffTimeoutForMonitors( + SLOW_OPERATION_WATCHDOG_TIMEOUT_MS, "#onUserStopped might be slow"); try { mVold.onUserStopped(userId); mStoraged.onUserStopped(userId); @@ -1312,6 +1317,8 @@ class StorageManagerService extends IStorageManager.Stub unlockedUsers.add(userId); } } + Watchdog.getInstance().setOneOffTimeoutForMonitors( + SLOW_OPERATION_WATCHDOG_TIMEOUT_MS, "#onUserStopped might be slow"); for (Integer userId : unlockedUsers) { try { mVold.onUserStopped(userId); @@ -3600,6 +3607,8 @@ class StorageManagerService extends IStorageManager.Stub @Override public ParcelFileDescriptor open() throws AppFuseMountException { + Watchdog.getInstance().setOneOffTimeoutForMonitors( + SLOW_OPERATION_WATCHDOG_TIMEOUT_MS, "#open might be slow"); try { final FileDescriptor fd = mVold.mountAppFuse(uid, mountId); mMounted = true; @@ -3612,6 +3621,8 @@ class StorageManagerService extends IStorageManager.Stub @Override public ParcelFileDescriptor openFile(int mountId, int fileId, int flags) throws AppFuseMountException { + Watchdog.getInstance().setOneOffTimeoutForMonitors( + SLOW_OPERATION_WATCHDOG_TIMEOUT_MS, "#openFile might be slow"); try { return new ParcelFileDescriptor( mVold.openAppFuseFile(uid, mountId, fileId, flags)); @@ -3622,6 +3633,8 @@ class StorageManagerService extends IStorageManager.Stub @Override public void close() throws Exception { + Watchdog.getInstance().setOneOffTimeoutForMonitors( + SLOW_OPERATION_WATCHDOG_TIMEOUT_MS, "#close might be slow"); if (mMounted) { mVold.unmountAppFuse(uid, mountId); mMounted = false; diff --git a/services/core/java/com/android/server/Watchdog.java b/services/core/java/com/android/server/Watchdog.java index b05b397a45de7d0472d0e9e0b294b17fa0a94c2c..55aa7164a67bbd2610f4c68032bf205fb4a7f1ed 100644 --- a/services/core/java/com/android/server/Watchdog.java +++ b/services/core/java/com/android/server/Watchdog.java @@ -643,6 +643,16 @@ public class Watchdog implements Dumpable { } } + /** + * Sets a one-off timeout for the next run of the watchdog for the monitor thread. + * + * <p>Simiar to {@link setOneOffTimeoutForCurrentThread} but used for monitors added through + * {@link #addMonitor} + */ + public void setOneOffTimeoutForMonitors(int oneOffTimeoutMillis, String reason) { + mMonitorChecker.setOneOffTimeoutLocked(oneOffTimeoutMillis, reason); + } + /** * Pauses Watchdog action for the currently running thread. Useful before executing long running * operations that could falsely trigger the watchdog. Each call to this will require a matching diff --git a/services/core/java/com/android/server/am/AnrTimer.java b/services/core/java/com/android/server/am/AnrTimer.java index 378a386022117717860a95b71589d3d9c9e32efb..9ba49ce35dad2996a9471c77082863f368e248c0 100644 --- a/services/core/java/com/android/server/am/AnrTimer.java +++ b/services/core/java/com/android/server/am/AnrTimer.java @@ -107,6 +107,14 @@ class AnrTimer<V> { */ private static final boolean ENABLE_TRACING = false; + /** + * Return true if the feature is enabled. By default, the value is take from the Flags class + * but it can be changed for local testing. + */ + private static boolean anrTimerServiceEnabled() { + return Flags.anrTimerServiceEnabled(); + } + /** * The status of an ANR timer. TIMER_INVALID status is returned when an error is detected. */ @@ -327,18 +335,33 @@ class AnrTimer<V> { */ @VisibleForTesting static class Injector { + private final Handler mReferenceHandler; + + Injector(@NonNull Handler handler) { + mReferenceHandler = handler; + } + /** - * Return a handler for the given Callback. + * Return a handler for the given Callback, based on the reference handler. The handler + * might be mocked, in which case it does not have a valid Looper. In this case, use the + * main Looper. */ + @NonNull Handler getHandler(@NonNull Handler.Callback callback) { - return null; + Looper looper = mReferenceHandler.getLooper(); + if (looper == null) looper = Looper.getMainLooper(); + return new Handler(looper, callback); }; - /** - * Return a CpuTracker. - */ + /** Return a CpuTracker. */ + @NonNull CpuTracker getTracker() { - return null; + return new CpuTracker(); + } + + /** Return true if the feature is enabled. */ + boolean getFeatureEnabled() { + return anrTimerServiceEnabled(); } } @@ -375,12 +398,6 @@ class AnrTimer<V> { /** The interface to fetch process statistics that might extend an ANR timeout. */ private final CpuTracker mCpu; - /** Create a HandlerTimerService based on the input handler. */ - HandlerTimerService(@NonNull Handler handler) { - mHandler = new Handler(handler.getLooper(), this::expires); - mCpu = new CpuTracker(); - } - /** Create a HandlerTimerService that directly uses the supplied handler and tracker. */ @VisibleForTesting HandlerTimerService(@NonNull Injector injector) { @@ -490,39 +507,57 @@ class AnrTimer<V> { */ private final boolean mLenientCancel = true; + /** + * The top-level switch for the feature enabled or disabled. + */ + private final FeatureSwitch mFeature; + /** * The common constructor. A null injector results in a normal, production timer. */ @VisibleForTesting AnrTimer(@NonNull Handler handler, int what, @NonNull String label, boolean extend, - @Nullable Injector injector) { + @NonNull Injector injector) { mHandler = handler; mWhat = what; mLabel = label; mExtend = extend; - if (injector == null) { - mTimerService = new HandlerTimerService(handler); + boolean enabled = injector.getFeatureEnabled(); + if (!enabled) { + mFeature = new FeatureDisabled(); + mTimerService = null; } else { + mFeature = new FeatureEnabled(); mTimerService = new HandlerTimerService(injector); + + synchronized (sAnrTimerList) { + sAnrTimerList.add(new WeakReference(this)); + } } - synchronized (sAnrTimerList) { - sAnrTimerList.add(new WeakReference(this)); - } - Log.i(TAG, formatSimple("created %s label: \"%s\"", mTimerService.toString(), label)); + Log.i(TAG, formatSimple("created %s label: \"%s\"", mTimerService, label)); } /** * Create one timer instance for production. The client can ask for extensible timeouts. */ AnrTimer(@NonNull Handler handler, int what, @NonNull String label, boolean extend) { - this(handler, what, label, extend, null); + this(handler, what, label, extend, new Injector(handler)); } /** * Create one timer instance for production. There are no extensible timeouts. */ AnrTimer(@NonNull Handler handler, int what, @NonNull String label) { - this(handler, what, label, false, null); + this(handler, what, label, false); + } + + /** + * Return true if the service is enabled on this instance. Clients should use this method to + * decide if the feature is enabled, and not read the flags directly. This method should be + * deleted if and when the feature is enabled permanently. + */ + boolean serviceEnabled() { + return mFeature.enabled(); } /** @@ -613,93 +648,186 @@ class AnrTimer<V> { Log.i(TAG, msg + " " + timer + " " + Objects.toString(timer.arg)); } - /** - * Start a timer. + /** + * The FeatureSwitch class provides a quick switch between feature-enabled behavior and + * feature-disabled behavior. */ - boolean start(@NonNull V arg, int pid, int uid, long timeoutMs) { - final Timer timer = Timer.obtain(pid, uid, arg, timeoutMs, this); - synchronized (mLock) { - Timer old = mTimerMap.get(arg); - if (old != null) { - // There is an existing timer. This is a protocol error in the client. Record - // the error and then clean up by canceling running timers and discarding expired - // timers. - restartedLocked(old.status, arg); - if (old.status == TIMER_EXPIRED) { - discard(arg); + private abstract class FeatureSwitch { + abstract boolean start(@NonNull V arg, int pid, int uid, long timeoutMs); + abstract boolean cancel(@NonNull V arg); + abstract boolean accept(@NonNull V arg); + abstract boolean discard(@NonNull V arg); + abstract boolean enabled(); + } + + /** + * The FeatureDisabled class bypasses almost all AnrTimer logic. It is used when the AnrTimer + * service is disabled via Flags.anrTimerServiceEnabled. + */ + private class FeatureDisabled extends FeatureSwitch { + /** Start a timer by sending a message to the client's handler. */ + boolean start(@NonNull V arg, int pid, int uid, long timeoutMs) { + final Message msg = mHandler.obtainMessage(mWhat, arg); + mHandler.sendMessageDelayed(msg, timeoutMs); + return true; + } + + /** Cancel a timer by removing the message from the client's handler. */ + boolean cancel(@NonNull V arg) { + mHandler.removeMessages(mWhat, arg); + return true; + } + + /** accept() is a no-op when the feature is disabled. */ + boolean accept(@NonNull V arg) { + return true; + } + + /** discard() is a no-op when the feature is disabled. */ + boolean discard(@NonNull V arg) { + return true; + } + + /** The feature is not enabled. */ + boolean enabled() { + return false; + } + } + + /** + * The FeatureEnabled class enables the AnrTimer logic. It is used when the AnrTimer service + * is enabled via Flags.anrTimerServiceEnabled. + */ + private class FeatureEnabled extends FeatureSwitch { + + /** + * Start a timer. + */ + boolean start(@NonNull V arg, int pid, int uid, long timeoutMs) { + final Timer timer = Timer.obtain(pid, uid, arg, timeoutMs, AnrTimer.this); + synchronized (mLock) { + Timer old = mTimerMap.get(arg); + if (old != null) { + // There is an existing timer. This is a protocol error in the client. + // Record the error and then clean up by canceling running timers and + // discarding expired timers. + restartedLocked(old.status, arg); + if (old.status == TIMER_EXPIRED) { + discard(arg); + } else { + cancel(arg); + } + } + if (mTimerService.start(timer)) { + timer.status = TIMER_RUNNING; + mTimerMap.put(arg, timer); + mTotalStarted++; + mMaxStarted = Math.max(mMaxStarted, mTimerMap.size()); + if (DEBUG) report(timer, "start"); + return true; } else { - cancel(arg); + Log.e(TAG, "AnrTimer.start failed"); + return false; } } - if (mTimerService.start(timer)) { - timer.status = TIMER_RUNNING; - mTimerMap.put(arg, timer); - mTotalStarted++; - mMaxStarted = Math.max(mMaxStarted, mTimerMap.size()); - if (DEBUG) report(timer, "start"); + } + + /** + * Cancel a timer. Return false if the timer was not found. + */ + boolean cancel(@NonNull V arg) { + synchronized (mLock) { + Timer timer = removeLocked(arg); + if (timer == null) { + if (!mLenientCancel) notFoundLocked("cancel", arg); + return false; + } + mTimerService.cancel(timer); + // There may be an expiration message in flight. Cancel it. + mHandler.removeMessages(mWhat, arg); + if (DEBUG) report(timer, "cancel"); + timer.release(); return true; - } else { - Log.e(TAG, "AnrTimer.start failed"); - return false; } } + + /** + * Accept a timer in the framework-level handler. The timeout has been accepted and the + * timeout handler is executing. Return false if the timer was not found. + */ + boolean accept(@NonNull V arg) { + synchronized (mLock) { + Timer timer = removeLocked(arg); + if (timer == null) { + notFoundLocked("accept", arg); + return false; + } + mTimerService.accept(timer); + traceEnd(timer); + if (DEBUG) report(timer, "accept"); + timer.release(); + return true; + } + } + + /** + * Discard a timer in the framework-level handler. For whatever reason, the timer is no + * longer interesting. No statistics are collected. Return false if the time was not + * found. + */ + boolean discard(@NonNull V arg) { + synchronized (mLock) { + Timer timer = removeLocked(arg); + if (timer == null) { + notFoundLocked("discard", arg); + return false; + } + mTimerService.discard(timer); + traceEnd(timer); + if (DEBUG) report(timer, "discard"); + timer.release(); + return true; + } + } + + /** The feature is enabled. */ + boolean enabled() { + return true; + } } /** - * Cancel a timer. Return false if the timer was not found. + * Start a timer associated with arg. If a timer already exists with the same arg, then that + * timer is canceled and a new timer is created. This returns false if the timer cannot be + * created. + */ + boolean start(@NonNull V arg, int pid, int uid, long timeoutMs) { + return mFeature.start(arg, pid, uid, timeoutMs); + } + + /** + * Cancel a running timer and remove it from any list. This returns true if the timer was + * found and false otherwise. It is not an error to cancel a non-existent timer. It is also + * not an error to cancel an expired timer. */ boolean cancel(@NonNull V arg) { - synchronized (mLock) { - Timer timer = removeLocked(arg); - if (timer == null) { - if (!mLenientCancel) notFoundLocked("cancel", arg); - return false; - } - mTimerService.cancel(timer); - // There may be an expiration message in flight. Cancel it. - mHandler.removeMessages(mWhat, arg); - if (DEBUG) report(timer, "cancel"); - timer.release(); - return true; - } + return mFeature.cancel(arg); } /** - * Accept a timer in the framework-level handler. The timeout has been accepted and the - * timeout handler is executing. Return false if the timer was not found. + * Accept an expired timer. This returns false if the timer was not found or if the timer was + * not expired. */ boolean accept(@NonNull V arg) { - synchronized (mLock) { - Timer timer = removeLocked(arg); - if (timer == null) { - notFoundLocked("accept", arg); - return false; - } - mTimerService.accept(timer); - traceEnd(timer); - if (DEBUG) report(timer, "accept"); - timer.release(); - return true; - } + return mFeature.accept(arg); } /** - * Discard a timer in the framework-level handler. For whatever reason, the timer is no - * longer interesting. No statistics are collected. Return false if the time was not found. + * Discard an expired timer. This returns false if the timer was not found or if the timer was + * not expired. */ boolean discard(@NonNull V arg) { - synchronized (mLock) { - Timer timer = removeLocked(arg); - if (timer == null) { - notFoundLocked("discard", arg); - return false; - } - mTimerService.discard(timer); - traceEnd(timer); - if (DEBUG) report(timer, "discard"); - timer.release(); - return true; - } + return mFeature.discard(arg); } /** diff --git a/services/core/java/com/android/server/am/AppBatteryTracker.java b/services/core/java/com/android/server/am/AppBatteryTracker.java index 907069de8c976c70fd122d9be202f952dd3aab7a..147f8d1a1e3271a91f0e064ca3a13b7531f7eeca 100644 --- a/services/core/java/com/android/server/am/AppBatteryTracker.java +++ b/services/core/java/com/android/server/am/AppBatteryTracker.java @@ -580,7 +580,11 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy> batteryStatsInternal); curDuration += curStart - lastUidBatteryUsageStartTs; try { - statsCommit.close(); + if (statsCommit != null) { + statsCommit.close(); + } else { + Slog.w(TAG, "Stat was null"); + } } catch (IOException e) { Slog.w(TAG, "Failed to close a stat"); } @@ -660,7 +664,11 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy> } } try { - stats.close(); + if (stats != null) { + stats.close(); + } else { + Slog.w(TAG, "Stat was null"); + } } catch (IOException e) { Slog.w(TAG, "Failed to close a stat"); } @@ -684,7 +692,11 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy> final BatteryUsageStats stats = statsList.get(0); for (int i = 1; i < statsList.size(); i++) { try { - statsList.get(i).close(); + if (statsList.get(i) != null) { + statsList.get(i).close(); + } else { + Slog.w(TAG, "Stat was null"); + } } catch (IOException e) { Slog.w(TAG, "Failed to close a stat in BatteryUsageStats List"); } diff --git a/services/core/java/com/android/server/am/BroadcastProcessQueue.java b/services/core/java/com/android/server/am/BroadcastProcessQueue.java index 5d31d1545b8da43d1ecdd481333591bf4c993709..e07c2bcaaaed3be439bdd2c5ccd1940c26412855 100644 --- a/services/core/java/com/android/server/am/BroadcastProcessQueue.java +++ b/services/core/java/com/android/server/am/BroadcastProcessQueue.java @@ -106,6 +106,14 @@ class BroadcastProcessQueue { private boolean mTimeoutScheduled; /** + * Snapshotted value of {@link ProcessRecord#getCpuDelayTime()}, typically + * used when deciding if we should extend the soft ANR timeout. + * + * Required when Flags.anrTimerServiceEnabled is false. + */ + long lastCpuDelayTime; + + /** * Snapshotted value of {@link ProcessStateRecord#getCurProcState()} before * dispatching the current broadcast to the receiver in this process. */ diff --git a/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java b/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java index eb219a8819c6ce70a3d6632bd04819a9d6c236ff..a428907073680b5a2cf65b2b0aa590488149f88c 100644 --- a/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java +++ b/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java @@ -258,6 +258,9 @@ class BroadcastQueueModernImpl extends BroadcastQueue { private static final int MSG_PROCESS_FREEZABLE_CHANGED = 6; private static final int MSG_UID_STATE_CHANGED = 7; + // Required when Flags.anrTimerServiceEnabled is false. + private static final int MSG_DELIVERY_TIMEOUT_SOFT = 8; + private void enqueueUpdateRunningList() { mLocalHandler.removeMessages(MSG_UPDATE_RUNNING_LIST); mLocalHandler.sendEmptyMessage(MSG_UPDATE_RUNNING_LIST); @@ -271,6 +274,13 @@ class BroadcastQueueModernImpl extends BroadcastQueue { updateRunningList(); return true; } + // Required when Flags.anrTimerServiceEnabled is false. + case MSG_DELIVERY_TIMEOUT_SOFT: { + synchronized (mService) { + deliveryTimeoutSoftLocked((BroadcastProcessQueue) msg.obj, msg.arg1); + return true; + } + } case MSG_DELIVERY_TIMEOUT: { deliveryTimeout((BroadcastProcessQueue) msg.obj); return true; @@ -1030,7 +1040,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue { queue.setTimeoutScheduled(true); final int softTimeoutMillis = (int) (r.isForeground() ? mFgConstants.TIMEOUT : mBgConstants.TIMEOUT); - mAnrTimer.start(queue, softTimeoutMillis); + startDeliveryTimeoutLocked(queue, softTimeoutMillis); } else { queue.setTimeoutScheduled(false); } @@ -1110,7 +1120,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue { // If we were trying to deliver a manifest broadcast, throw the error as we need // to try redelivering the broadcast to this receiver. if (receiver instanceof ResolveInfo) { - mAnrTimer.cancel(queue); + cancelDeliveryTimeoutLocked(queue); throw new BroadcastDeliveryFailedException(e); } finishReceiverActiveLocked(queue, BroadcastRecord.DELIVERY_FAILURE, @@ -1159,6 +1169,41 @@ class BroadcastQueueModernImpl extends BroadcastQueue { r.resultTo = null; } + // Required when Flags.anrTimerServiceEnabled is false. + private void startDeliveryTimeoutLocked(@NonNull BroadcastProcessQueue queue, + int softTimeoutMillis) { + if (mAnrTimer.serviceEnabled()) { + mAnrTimer.start(queue, softTimeoutMillis); + } else { + queue.lastCpuDelayTime = queue.app.getCpuDelayTime(); + mLocalHandler.sendMessageDelayed(Message.obtain(mLocalHandler, + MSG_DELIVERY_TIMEOUT_SOFT, softTimeoutMillis, 0, queue), softTimeoutMillis); + } + } + + // Required when Flags.anrTimerServiceEnabled is false. + private void cancelDeliveryTimeoutLocked(@NonNull BroadcastProcessQueue queue) { + mAnrTimer.cancel(queue); + if (!mAnrTimer.serviceEnabled()) { + mLocalHandler.removeMessages(MSG_DELIVERY_TIMEOUT_SOFT, queue); + } + } + + // Required when Flags.anrTimerServiceEnabled is false. + private void deliveryTimeoutSoftLocked(@NonNull BroadcastProcessQueue queue, + int softTimeoutMillis) { + if (queue.app != null) { + // Instead of immediately triggering an ANR, extend the timeout by + // the amount of time the process was runnable-but-waiting; we're + // only willing to do this once before triggering an hard ANR + final long cpuDelayTime = queue.app.getCpuDelayTime() - queue.lastCpuDelayTime; + final long hardTimeoutMillis = MathUtils.constrain(cpuDelayTime, 0, softTimeoutMillis); + mAnrTimer.start(queue, hardTimeoutMillis); + } else { + deliveryTimeoutLocked(queue); + } + } + private void deliveryTimeout(@NonNull BroadcastProcessQueue queue) { synchronized (mService) { deliveryTimeoutLocked(queue); @@ -1292,7 +1337,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue { mAnrTimer.discard(queue); } } else if (queue.timeoutScheduled()) { - mAnrTimer.cancel(queue); + cancelDeliveryTimeoutLocked(queue); } // Given that a receiver just finished, check if the "waitingFor" conditions are met. diff --git a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java index 4a0bc4b9ca6c8c84a7d3c2fa09659fc77e1066d4..816043e6554469064eccfa76c34c7ca211dc457e 100644 --- a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java +++ b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java @@ -131,12 +131,14 @@ public class SettingsToPropertiesMapper { "car_telemetry", "codec_fwk", "companion", + "content_protection", "context_hub", "core_experiments_team_internal", "core_graphics", "haptics", "hardware_backed_security_mainline", "machine_learning", + "mainline_sdk", "media_audio", "media_solutions", "nfc", diff --git a/services/core/java/com/android/server/am/flags.aconfig b/services/core/java/com/android/server/am/flags.aconfig index b03cc6295b8d5046db2c894535b037c7700af338..26d99d843c7eb6c9ae1ce1df8f0ebd33d67c4e3d 100644 --- a/services/core/java/com/android/server/am/flags.aconfig +++ b/services/core/java/com/android/server/am/flags.aconfig @@ -6,4 +6,12 @@ flag { description: "Utilize new OomAdjuster implementation" bug: "298055811" is_fixed_read_only: true -} \ No newline at end of file +} + +flag { + name: "anr_timer_service_enabled" + namespace: "system_performance" + is_fixed_read_only: true + description: "Feature flag for the ANR timer service" + bug: "282428924" +} diff --git a/services/core/java/com/android/server/content/SyncStorageEngine.java b/services/core/java/com/android/server/content/SyncStorageEngine.java index 9805fd3d13161409f09533cf193c9a6497d14fe4..333f62a81e94131747b8f008792c4311db614593 100644 --- a/services/core/java/com/android/server/content/SyncStorageEngine.java +++ b/services/core/java/com/android/server/content/SyncStorageEngine.java @@ -1845,7 +1845,7 @@ public class SyncStorageEngine { private void parseListenForTickles(TypedXmlPullParser parser) { int userId = 0; try { - parser.getAttributeInt(null, XML_ATTR_USER); + userId = parser.getAttributeInt(null, XML_ATTR_USER); } catch (XmlPullParserException e) { Slog.e(TAG, "error parsing the user for listen-for-tickles", e); } diff --git a/services/core/java/com/android/server/display/DisplayDeviceConfig.java b/services/core/java/com/android/server/display/DisplayDeviceConfig.java index 9e92c8d7342db16a4009e36f02a93648d81bd833..cfbe0c69b32019e22a81b05343b2a77588e06689 100644 --- a/services/core/java/com/android/server/display/DisplayDeviceConfig.java +++ b/services/core/java/com/android/server/display/DisplayDeviceConfig.java @@ -60,6 +60,9 @@ import com.android.server.display.config.LuxThrottling; import com.android.server.display.config.NitsMap; import com.android.server.display.config.NonNegativeFloatToFloatPoint; import com.android.server.display.config.Point; +import com.android.server.display.config.PowerThrottlingConfig; +import com.android.server.display.config.PowerThrottlingMap; +import com.android.server.display.config.PowerThrottlingPoint; import com.android.server.display.config.PredefinedBrightnessLimitNames; import com.android.server.display.config.RefreshRateConfigs; import com.android.server.display.config.RefreshRateRange; @@ -139,6 +142,30 @@ import javax.xml.datatype.DatatypeConfigurationException; * </screenBrightnessMap> * * <screenBrightnessDefault>0.65</screenBrightnessDefault> + * <powerThrottlingConfig> + * <brightnessLowestCapAllowed>0.1</brightnessLowestCapAllowed> + * <pollingWindowMillis>15</pollingWindowMillis> + * <powerThrottlingMap> + * <powerThrottlingPoint> + * <thermalStatus>severe</thermalStatus> + * <powerQuotaMilliWatts>200.6</powerQuotaMilliWatts> + * </powerThrottlingPoint> + * <powerThrottlingPoint> + * <thermalStatus>critical</thermalStatus> + * <powerQuotaMilliWatts>300</powerQuotaMilliWatts> + * </powerThrottlingPoint> + * </powerThrottlingMap> + * <powerThrottlingMap id="id_2"> // optional attribute, leave blank for default + * <powerThrottlingPoint> + * <thermalStatus>moderate</thermalStatus> + * <powerQuotaMilliWatts>400</powerQuotaMilliWatts> + * </powerThrottlingPoint> + * <powerThrottlingPoint> + * <thermalStatus>severe</thermalStatus> + * <powerQuotaMilliWatts>250</powerQuotaMilliWatts> + * </powerThrottlingPoint> + * </powerThrottlingMap> + * </powerThrottlingConfig> * * <thermalThrottling> * <brightnessThrottlingMap> @@ -669,6 +696,8 @@ public class DisplayDeviceConfig { private List<String> mQuirks; private boolean mIsHighBrightnessModeEnabled = false; private HighBrightnessModeData mHbmData; + @Nullable + private PowerThrottlingConfigData mPowerThrottlingConfigData; private DensityMapping mDensityMapping; private String mLoadedFrom = null; private Spline mSdrToHdrRatioSpline; @@ -781,6 +810,9 @@ public class DisplayDeviceConfig { private final HashMap<String, ThermalBrightnessThrottlingData> mThermalBrightnessThrottlingDataMapByThrottlingId = new HashMap<>(); + private final HashMap<String, PowerThrottlingData> + mPowerThrottlingDataMapByThrottlingId = new HashMap<>(); + private final Map<String, SparseArray<SurfaceControl.RefreshRateRange>> mRefreshRateThrottlingMap = new HashMap<>(); @@ -1458,6 +1490,14 @@ public class DisplayDeviceConfig { return hbmData; } + /** + * @return Power throttling configuration data for the display. + */ + @Nullable + public PowerThrottlingConfigData getPowerThrottlingConfigData() { + return mPowerThrottlingConfigData; + } + @NonNull public Map<BrightnessLimitMapType, Map<Float, Float>> getLuxThrottlingData() { return mLuxThrottlingData; @@ -1490,6 +1530,14 @@ public class DisplayDeviceConfig { return mRefreshRateThrottlingMap.get(key); } + /** + * @return power throttling configuration data for this display, for each throttling id. + **/ + public HashMap<String, PowerThrottlingData> + getPowerThrottlingDataMapByThrottlingId() { + return mPowerThrottlingDataMapByThrottlingId; + } + /** * @return Auto brightness darkening light debounce */ @@ -1702,6 +1750,9 @@ public class DisplayDeviceConfig { + ", mThermalBrightnessThrottlingDataMapByThrottlingId=" + mThermalBrightnessThrottlingDataMapByThrottlingId + "\n" + + ", mPowerThrottlingDataMapByThrottlingId=" + + mPowerThrottlingDataMapByThrottlingId + + "\n" + "mBrightnessRampFastDecrease=" + mBrightnessRampFastDecrease + ", mBrightnessRampFastIncrease=" + mBrightnessRampFastIncrease + ", mBrightnessRampSlowDecrease=" + mBrightnessRampSlowDecrease @@ -1853,6 +1904,7 @@ public class DisplayDeviceConfig { loadBrightnessConstraintsFromConfigXml(); loadBrightnessMap(config); loadThermalThrottlingConfig(config); + loadPowerThrottlingConfigData(config); loadHighBrightnessModeData(config); loadLuxThrottling(config); loadQuirks(config); @@ -2171,6 +2223,59 @@ public class DisplayDeviceConfig { } } + private boolean loadPowerThrottlingMaps(PowerThrottlingConfig throttlingConfig) { + final List<PowerThrottlingMap> maps = throttlingConfig.getPowerThrottlingMap(); + if (maps == null || maps.isEmpty()) { + Slog.i(TAG, "No power throttling map found"); + return false; + } + + for (PowerThrottlingMap map : maps) { + final List<PowerThrottlingPoint> points = map.getPowerThrottlingPoint(); + // At least 1 point is guaranteed by the display device config schema + List<PowerThrottlingData.ThrottlingLevel> throttlingLevels = + new ArrayList<>(points.size()); + + boolean badConfig = false; + for (PowerThrottlingPoint point : points) { + ThermalStatus status = point.getThermalStatus(); + if (!thermalStatusIsValid(status)) { + badConfig = true; + break; + } + + throttlingLevels.add(new PowerThrottlingData.ThrottlingLevel( + convertThermalStatus(status), + point.getPowerQuotaMilliWatts().floatValue())); + } + + if (!badConfig) { + String id = map.getId() == null ? DEFAULT_ID : map.getId(); + if (mPowerThrottlingDataMapByThrottlingId.containsKey(id)) { + throw new RuntimeException("Power throttling data with ID " + id + + " already exists"); + } + mPowerThrottlingDataMapByThrottlingId.put(id, + PowerThrottlingData.create(throttlingLevels)); + } + } + return true; + } + + private void loadPowerThrottlingConfigData(DisplayConfiguration config) { + final PowerThrottlingConfig powerThrottlingCfg = config.getPowerThrottlingConfig(); + if (powerThrottlingCfg == null) { + return; + } + if (!loadPowerThrottlingMaps(powerThrottlingCfg)) { + return; + } + float lowestBrightnessCap = powerThrottlingCfg.getBrightnessLowestCapAllowed().floatValue(); + int pollingWindowMillis = powerThrottlingCfg.getPollingWindowMillis().intValue(); + mPowerThrottlingConfigData = new PowerThrottlingConfigData(lowestBrightnessCap, + pollingWindowMillis); + } + private void loadRefreshRateSetting(DisplayConfiguration config) { final RefreshRateConfigs refreshRateConfigs = (config == null) ? null : config.getRefreshRate(); @@ -3378,6 +3483,148 @@ public class DisplayDeviceConfig { } } + /** + * Container for Power throttling configuration data. + * TODO(b/302814899): extract to separate class. + */ + public static class PowerThrottlingConfigData { + /** Lowest brightness cap allowed for this device. */ + public final float brightnessLowestCapAllowed; + /** Time window for polling power in seconds. */ + public final int pollingWindowMillis; + public PowerThrottlingConfigData(float brightnessLowestCapAllowed, + int pollingWindowMillis) { + this.brightnessLowestCapAllowed = brightnessLowestCapAllowed; + this.pollingWindowMillis = pollingWindowMillis; + } + + @Override + public String toString() { + return "PowerThrottlingConfigData{" + + "brightnessLowestCapAllowed: " + + brightnessLowestCapAllowed + + ", pollingWindowMillis: " + pollingWindowMillis + + "} "; + } + } + + /** + * Container for power throttling data. + * TODO(b/302814899): extract to separate class and unify with ThermalBrightnessThrottlingData. + */ + public static class PowerThrottlingData { + public List<ThrottlingLevel> throttlingLevels; + + /** + * thermal status to power quota mapping. + */ + public static class ThrottlingLevel { + public @PowerManager.ThermalStatus int thermalStatus; + public float powerQuotaMilliWatts; + + public ThrottlingLevel( + @PowerManager.ThermalStatus int thermalStatus, float powerQuotaMilliWatts) { + this.thermalStatus = thermalStatus; + this.powerQuotaMilliWatts = powerQuotaMilliWatts; + } + + @Override + public String toString() { + return "[" + thermalStatus + "," + powerQuotaMilliWatts + "]"; + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof ThrottlingLevel)) { + return false; + } + ThrottlingLevel otherThrottlingLevel = (ThrottlingLevel) obj; + + return otherThrottlingLevel.thermalStatus == this.thermalStatus + && otherThrottlingLevel.powerQuotaMilliWatts == this.powerQuotaMilliWatts; + } + + @Override + public int hashCode() { + int result = 1; + result = 31 * result + thermalStatus; + result = 31 * result + Float.hashCode(powerQuotaMilliWatts); + return result; + } + } + + + /** + * Creates multiple temperature based throttling levels of power quota. + */ + public static PowerThrottlingData create( + List<ThrottlingLevel> throttlingLevels) { + if (throttlingLevels == null || throttlingLevels.size() == 0) { + Slog.e(TAG, "PowerThrottlingData received null or empty throttling levels"); + return null; + } + + ThrottlingLevel prevLevel = throttlingLevels.get(0); + final int numLevels = throttlingLevels.size(); + for (int i = 1; i < numLevels; i++) { + ThrottlingLevel thisLevel = throttlingLevels.get(i); + + if (thisLevel.thermalStatus <= prevLevel.thermalStatus) { + Slog.e(TAG, "powerThrottlingMap must be strictly increasing, ignoring " + + "configuration. ThermalStatus " + thisLevel.thermalStatus + " <= " + + prevLevel.thermalStatus); + return null; + } + + if (thisLevel.powerQuotaMilliWatts >= prevLevel.powerQuotaMilliWatts) { + Slog.e(TAG, "powerThrottlingMap must be strictly decreasing, ignoring " + + "configuration. powerQuotaMilliWatts " + + thisLevel.powerQuotaMilliWatts + " >= " + + prevLevel.powerQuotaMilliWatts); + return null; + } + + prevLevel = thisLevel; + } + return new PowerThrottlingData(throttlingLevels); + } + + @Override + public String toString() { + return "PowerThrottlingData{" + + "throttlingLevels:" + throttlingLevels + + "} "; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (!(obj instanceof PowerThrottlingData)) { + return false; + } + + PowerThrottlingData otherData = (PowerThrottlingData) obj; + return throttlingLevels.equals(otherData.throttlingLevels); + } + + @Override + public int hashCode() { + return throttlingLevels.hashCode(); + } + + @VisibleForTesting + PowerThrottlingData(List<ThrottlingLevel> inLevels) { + throttlingLevels = new ArrayList<>(inLevels.size()); + for (ThrottlingLevel level : inLevels) { + throttlingLevels.add(new ThrottlingLevel(level.thermalStatus, + level.powerQuotaMilliWatts)); + } + } + } + /** * Container for brightness throttling data. */ diff --git a/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java b/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java index b6273e1daf82277997ec016cb13e97a553ca2eb5..d5382cb99d2203777cedb39cb83bd327e0bab2d9 100644 --- a/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java +++ b/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java @@ -51,22 +51,10 @@ public class DisplayManagerFlags { Flags.FLAG_ENABLE_DISPLAY_OFFLOAD, Flags::enableDisplayOffload); - private final FlagState mDisplayResolutionRangeVotingState = new FlagState( - Flags.FLAG_ENABLE_DISPLAY_RESOLUTION_RANGE_VOTING, - Flags::enableDisplayResolutionRangeVoting); - - private final FlagState mUserPreferredModeVoteState = new FlagState( - Flags.FLAG_ENABLE_USER_PREFERRED_MODE_VOTE, - Flags::enableUserPreferredModeVote); - private final FlagState mExternalDisplayLimitModeState = new FlagState( Flags.FLAG_ENABLE_MODE_LIMIT_FOR_EXTERNAL_DISPLAY, Flags::enableModeLimitForExternalDisplay); - private final FlagState mDisplaysRefreshRatesSynchronizationState = new FlagState( - Flags.FLAG_ENABLE_DISPLAYS_REFRESH_RATES_SYNCHRONIZATION, - Flags::enableDisplaysRefreshRatesSynchronization); - /** Returns whether connected display management is enabled or not. */ public boolean isConnectedDisplayManagementEnabled() { return mConnectedDisplayManagementFlagState.isEnabled(); @@ -90,7 +78,7 @@ public class DisplayManagerFlags { /** Returns whether resolution range voting feature is enabled or not. */ public boolean isDisplayResolutionRangeVotingEnabled() { - return mDisplayResolutionRangeVotingState.isEnabled(); + return isExternalDisplayLimitModeEnabled(); } /** @@ -98,7 +86,7 @@ public class DisplayManagerFlags { * {@link com.android.server.display.mode.DisplayModeDirector} */ public boolean isUserPreferredModeVoteEnabled() { - return mUserPreferredModeVoteState.isEnabled(); + return isExternalDisplayLimitModeEnabled(); } /** @@ -112,7 +100,7 @@ public class DisplayManagerFlags { * @return Whether displays refresh rate synchronization is enabled. */ public boolean isDisplaysRefreshRatesSynchronizationEnabled() { - return mDisplaysRefreshRatesSynchronizationState.isEnabled(); + return isExternalDisplayLimitModeEnabled(); } /** Returns whether displayoffload is enabled on not */ diff --git a/services/core/java/com/android/server/input/GestureMonitorSpyWindow.java b/services/core/java/com/android/server/input/GestureMonitorSpyWindow.java index 2ede56dcecd91b2f88d0802b3d537c2d690fb37f..a2c8748a91428ddbb47d3b6035bf4c7f4ad5e397 100644 --- a/services/core/java/com/android/server/input/GestureMonitorSpyWindow.java +++ b/services/core/java/com/android/server/input/GestureMonitorSpyWindow.java @@ -62,10 +62,10 @@ class GestureMonitorSpyWindow { mWindowHandle.ownerUid = uid; mWindowHandle.scaleFactor = 1.0f; mWindowHandle.replaceTouchableRegionWithCrop(null /* use this surface's bounds */); - mWindowHandle.inputConfig = - InputConfig.NOT_FOCUSABLE | InputConfig.SPY | InputConfig.TRUSTED_OVERLAY; + mWindowHandle.inputConfig = InputConfig.NOT_FOCUSABLE | InputConfig.SPY; final SurfaceControl.Transaction t = new SurfaceControl.Transaction(); + mWindowHandle.setTrustedOverlay(t, mInputSurface, true); t.setInputWindowInfo(mInputSurface, mWindowHandle); t.setLayer(mInputSurface, InputManagerService.INPUT_OVERLAY_LAYER_GESTURE_MONITOR); t.setPosition(mInputSurface, 0, 0); diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java index 6b399def4d7304281ebf4e0e8b03c164112a1aba..2533e029767900e0ac5ecf7bda48b77a273d9e10 100644 --- a/services/core/java/com/android/server/input/InputManagerService.java +++ b/services/core/java/com/android/server/input/InputManagerService.java @@ -117,6 +117,7 @@ import com.android.server.DisplayThread; import com.android.server.LocalServices; import com.android.server.Watchdog; import com.android.server.input.InputManagerInternal.LidSwitchCallback; +import com.android.server.input.debug.FocusEventDebugView; import com.android.server.inputmethod.InputMethodManagerInternal; import com.android.server.policy.WindowManagerPolicy; diff --git a/services/core/java/com/android/server/input/FocusEventDebugGlobalMonitor.java b/services/core/java/com/android/server/input/debug/FocusEventDebugGlobalMonitor.java similarity index 94% rename from services/core/java/com/android/server/input/FocusEventDebugGlobalMonitor.java rename to services/core/java/com/android/server/input/debug/FocusEventDebugGlobalMonitor.java index 67c221f7703766feb84994a6a3550da59b980477..2b21e49a4e034f31e710db4a6a65e5dce170524a 100644 --- a/services/core/java/com/android/server/input/FocusEventDebugGlobalMonitor.java +++ b/services/core/java/com/android/server/input/debug/FocusEventDebugGlobalMonitor.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.server.input; +package com.android.server.input.debug; import android.view.Display; import android.view.InputEvent; @@ -22,6 +22,7 @@ import android.view.InputEventReceiver; import android.view.MotionEvent; import com.android.server.UiThread; +import com.android.server.input.InputManagerService; /** * Receives input events before they are dispatched and reports them to FocusEventDebugView. diff --git a/services/core/java/com/android/server/input/FocusEventDebugView.java b/services/core/java/com/android/server/input/debug/FocusEventDebugView.java similarity index 50% rename from services/core/java/com/android/server/input/FocusEventDebugView.java rename to services/core/java/com/android/server/input/debug/FocusEventDebugView.java index 4b8fabde7d35347cb5b267af2b77f548251063e1..6eec0dee91528c5e8176af0c050e1d8f7d1888d2 100644 --- a/services/core/java/com/android/server/input/FocusEventDebugView.java +++ b/services/core/java/com/android/server/input/debug/FocusEventDebugView.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.server.input; +package com.android.server.input.debug; import static android.util.TypedValue.COMPLEX_UNIT_DIP; import static android.util.TypedValue.COMPLEX_UNIT_SP; @@ -24,11 +24,9 @@ import android.animation.LayoutTransition; import android.annotation.AnyThread; import android.annotation.Nullable; import android.content.Context; -import android.graphics.Canvas; import android.graphics.Color; import android.graphics.ColorFilter; import android.graphics.ColorMatrixColorFilter; -import android.graphics.Paint; import android.graphics.Typeface; import android.util.DisplayMetrics; import android.util.Pair; @@ -40,7 +38,6 @@ import android.view.KeyEvent; import android.view.MotionEvent; import android.view.RoundedCorner; import android.view.View; -import android.view.ViewConfiguration; import android.view.WindowInsets; import android.view.animation.AccelerateInterpolator; import android.widget.HorizontalScrollView; @@ -50,19 +47,17 @@ import android.widget.TextView; import com.android.internal.R; import com.android.internal.annotations.VisibleForTesting; +import com.android.server.input.InputManagerService; import java.util.HashMap; -import java.util.Iterator; -import java.util.Locale; import java.util.Map; -import java.util.concurrent.TimeUnit; import java.util.function.Supplier; /** * Displays focus events, such as physical keyboard KeyEvents and non-pointer MotionEvents on * the screen. */ -class FocusEventDebugView extends RelativeLayout { +public class FocusEventDebugView extends RelativeLayout { private static final String TAG = FocusEventDebugView.class.getSimpleName(); @@ -112,7 +107,7 @@ class FocusEventDebugView extends RelativeLayout { mOuterPadding = (int) TypedValue.applyDimension(COMPLEX_UNIT_DIP, OUTER_PADDING_DP, mDm); } - FocusEventDebugView(Context c, InputManagerService service) { + public FocusEventDebugView(Context c, InputManagerService service) { this(c, service, () -> new RotaryInputValueView(c), () -> new RotaryInputGraphView(c)); } @@ -149,11 +144,13 @@ class FocusEventDebugView extends RelativeLayout { return super.dispatchKeyEvent(event); } + /** Determines whether to show the key presses visualization. */ @AnyThread public void updateShowKeyPresses(boolean enabled) { post(() -> handleUpdateShowKeyPresses(enabled)); } + /** Determines whether to show the rotary input visualization. */ @AnyThread public void updateShowRotaryInput(boolean enabled) { post(() -> handleUpdateShowRotaryInput(enabled)); @@ -358,13 +355,6 @@ class FocusEventDebugView extends RelativeLayout { return mRotaryInputValueView != null; } - /** - * Converts a dimension in scaled pixel units to integer display pixels. - */ - private static int applyDimensionSp(int dimensionSp, DisplayMetrics dm) { - return (int) TypedValue.applyDimension(COMPLEX_UNIT_SP, dimensionSp, dm); - } - private static class PressedKeyView extends TextView { private static final ColorFilter sInvertColors = new ColorMatrixColorFilter(new float[]{ @@ -473,376 +463,4 @@ class FocusEventDebugView extends RelativeLayout { invalidate(); } } - - // TODO(b/286086154): move RotaryInputGraphView and RotaryInputValueView to a subpackage. - - /** Draws the most recent rotary input value and indicates whether the source is active. */ - @VisibleForTesting - static class RotaryInputValueView extends TextView { - - private static final int INACTIVE_TEXT_COLOR = 0xffff00ff; - private static final int ACTIVE_TEXT_COLOR = 0xff420f28; - private static final int TEXT_SIZE_SP = 8; - private static final int SIDE_PADDING_SP = 4; - /** Determines how long the active status lasts. */ - private static final int ACTIVE_STATUS_DURATION = 250 /* milliseconds */; - private static final ColorFilter ACTIVE_BACKGROUND_FILTER = - new ColorMatrixColorFilter(new float[]{ - 0, 0, 0, 0, 255, // red - 0, 0, 0, 0, 0, // green - 0, 0, 0, 0, 255, // blue - 0, 0, 0, 0, 200 // alpha - }); - - private final Runnable mUpdateActivityStatusCallback = () -> updateActivityStatus(false); - private final float mScaledVerticalScrollFactor; - - @VisibleForTesting - RotaryInputValueView(Context c) { - super(c); - - DisplayMetrics dm = mContext.getResources().getDisplayMetrics(); - mScaledVerticalScrollFactor = ViewConfiguration.get(c).getScaledVerticalScrollFactor(); - - setText(getFormattedValue(0)); - setTextColor(INACTIVE_TEXT_COLOR); - setTextSize(applyDimensionSp(TEXT_SIZE_SP, dm)); - setPaddingRelative(applyDimensionSp(SIDE_PADDING_SP, dm), 0, - applyDimensionSp(SIDE_PADDING_SP, dm), 0); - setTypeface(null, Typeface.BOLD); - setBackgroundResource(R.drawable.focus_event_rotary_input_background); - } - - void updateValue(float value) { - removeCallbacks(mUpdateActivityStatusCallback); - - setText(getFormattedValue(value * mScaledVerticalScrollFactor)); - - updateActivityStatus(true); - postDelayed(mUpdateActivityStatusCallback, ACTIVE_STATUS_DURATION); - } - - @VisibleForTesting - void updateActivityStatus(boolean active) { - if (active) { - setTextColor(ACTIVE_TEXT_COLOR); - getBackground().setColorFilter(ACTIVE_BACKGROUND_FILTER); - } else { - setTextColor(INACTIVE_TEXT_COLOR); - getBackground().clearColorFilter(); - } - } - - private static String getFormattedValue(float value) { - return String.format("%s%.1f", value < 0 ? "-" : "+", Math.abs(value)); - } - } - - /** - * Shows a graph with the rotary input values as a function of time. - * The graph gets reset if no action is received for a certain amount of time. - */ - @VisibleForTesting - static class RotaryInputGraphView extends View { - - private static final int FRAME_COLOR = 0xbf741b47; - private static final int FRAME_WIDTH_SP = 2; - private static final int FRAME_BORDER_GAP_SP = 10; - private static final int FRAME_TEXT_SIZE_SP = 10; - private static final int FRAME_TEXT_OFFSET_SP = 2; - private static final int GRAPH_COLOR = 0xffff00ff; - private static final int GRAPH_LINE_WIDTH_SP = 1; - private static final int GRAPH_POINT_RADIUS_SP = 4; - private static final long MAX_SHOWN_TIME_INTERVAL = TimeUnit.SECONDS.toMillis(5); - private static final float DEFAULT_FRAME_CENTER_POSITION = 0; - private static final int MAX_GRAPH_VALUES_SIZE = 400; - /** Maximum time between values so that they are considered part of the same gesture. */ - private static final long MAX_GESTURE_TIME = TimeUnit.SECONDS.toMillis(1); - - private final DisplayMetrics mDm; - /** - * Distance in position units (amount scrolled in display pixels) from the center to the - * top/bottom frame lines. - */ - private final float mFrameCenterToBorderDistance; - private final float mScaledVerticalScrollFactor; - private final Locale mDefaultLocale; - private final Paint mFramePaint = new Paint(); - private final Paint mFrameTextPaint = new Paint(); - private final Paint mGraphLinePaint = new Paint(); - private final Paint mGraphPointPaint = new Paint(); - - private final CyclicBuffer mGraphValues = new CyclicBuffer(MAX_GRAPH_VALUES_SIZE); - /** Position at which graph values are placed at the center of the graph. */ - private float mFrameCenterPosition = DEFAULT_FRAME_CENTER_POSITION; - - @VisibleForTesting - RotaryInputGraphView(Context c) { - super(c); - - mDm = mContext.getResources().getDisplayMetrics(); - // This makes the center-to-border distance equivalent to the display height, meaning - // that the total height of the graph is equivalent to 2x the display height. - mFrameCenterToBorderDistance = mDm.heightPixels; - mScaledVerticalScrollFactor = ViewConfiguration.get(c).getScaledVerticalScrollFactor(); - mDefaultLocale = Locale.getDefault(); - - mFramePaint.setColor(FRAME_COLOR); - mFramePaint.setStrokeWidth(applyDimensionSp(FRAME_WIDTH_SP, mDm)); - - mFrameTextPaint.setColor(GRAPH_COLOR); - mFrameTextPaint.setTextSize(applyDimensionSp(FRAME_TEXT_SIZE_SP, mDm)); - - mGraphLinePaint.setColor(GRAPH_COLOR); - mGraphLinePaint.setStrokeWidth(applyDimensionSp(GRAPH_LINE_WIDTH_SP, mDm)); - mGraphLinePaint.setStrokeCap(Paint.Cap.ROUND); - mGraphLinePaint.setStrokeJoin(Paint.Join.ROUND); - - mGraphPointPaint.setColor(GRAPH_COLOR); - mGraphPointPaint.setStrokeWidth(applyDimensionSp(GRAPH_POINT_RADIUS_SP, mDm)); - mGraphPointPaint.setStrokeCap(Paint.Cap.ROUND); - mGraphPointPaint.setStrokeJoin(Paint.Join.ROUND); - } - - /** - * Reads new scroll axis value and updates the list accordingly. Old positions are - * kept at the front (what you would get with getFirst), while the recent positions are - * kept at the back (what you would get with getLast). Also updates the frame center - * position to handle out-of-bounds cases. - */ - void addValue(float scrollAxisValue, long eventTime) { - // Remove values that are too old. - while (mGraphValues.getSize() > 0 - && (eventTime - mGraphValues.getFirst().mTime) > MAX_SHOWN_TIME_INTERVAL) { - mGraphValues.removeFirst(); - } - - // If there are no recent values, reset the frame center. - if (mGraphValues.getSize() == 0) { - mFrameCenterPosition = DEFAULT_FRAME_CENTER_POSITION; - } - - // Handle new value. We multiply the scroll axis value by the scaled scroll factor to - // get the amount of pixels to be scrolled. We also compute the accumulated position - // by adding the current value to the last one (if not empty). - final float displacement = scrollAxisValue * mScaledVerticalScrollFactor; - final float prevPos = (mGraphValues.getSize() == 0 ? 0 : mGraphValues.getLast().mPos); - final float pos = prevPos + displacement; - - mGraphValues.add(pos, eventTime); - - // The difference between the distance of the most recent position from the center - // frame (pos - mFrameCenterPosition) and the maximum allowed distance from the center - // frame (mFrameCenterToBorderDistance). - final float verticalDiff = Math.abs(pos - mFrameCenterPosition) - - mFrameCenterToBorderDistance; - // If needed, translate frame. - if (verticalDiff > 0) { - final int sign = pos - mFrameCenterPosition < 0 ? -1 : 1; - // Here, we update the center frame position by the exact amount needed for us to - // stay within the maximum allowed distance from the center frame. - mFrameCenterPosition += sign * verticalDiff; - } - - // Redraw canvas. - invalidate(); - } - - @Override - protected void onDraw(Canvas canvas) { - super.onDraw(canvas); - - // Note: vertical coordinates in Canvas go from top to bottom, - // that is bottomY > middleY > topY. - final int verticalMargin = applyDimensionSp(FRAME_BORDER_GAP_SP, mDm); - final int topY = verticalMargin; - final int bottomY = getHeight() - verticalMargin; - final int middleY = (topY + bottomY) / 2; - - // Note: horizontal coordinates in Canvas go from left to right, - // that is rightX > leftX. - final int leftX = 0; - final int rightX = getWidth(); - - // Draw the frame, which includes 3 lines that show the maximum, - // minimum and middle positions of the graph. - canvas.drawLine(leftX, topY, rightX, topY, mFramePaint); - canvas.drawLine(leftX, middleY, rightX, middleY, mFramePaint); - canvas.drawLine(leftX, bottomY, rightX, bottomY, mFramePaint); - - // Draw the position that each frame line corresponds to. - final int frameTextOffset = applyDimensionSp(FRAME_TEXT_OFFSET_SP, mDm); - canvas.drawText( - String.format(mDefaultLocale, "%.1f", - mFrameCenterPosition + mFrameCenterToBorderDistance), - leftX, - topY - frameTextOffset, mFrameTextPaint - ); - canvas.drawText( - String.format(mDefaultLocale, "%.1f", mFrameCenterPosition), - leftX, - middleY - frameTextOffset, mFrameTextPaint - ); - canvas.drawText( - String.format(mDefaultLocale, "%.1f", - mFrameCenterPosition - mFrameCenterToBorderDistance), - leftX, - bottomY - frameTextOffset, mFrameTextPaint - ); - - // If there are no graph values to be drawn, stop here. - if (mGraphValues.getSize() == 0) { - return; - } - - // Draw the graph using the times and positions. - // We start at the most recent value (which should be drawn at the right) and move - // to the older values (which should be drawn to the left of more recent ones). Negative - // indices are handled by circuling back to the end of the buffer. - final long mostRecentTime = mGraphValues.getLast().mTime; - float prevCoordX = 0; - float prevCoordY = 0; - float prevAge = 0; - for (Iterator<GraphValue> iter = mGraphValues.reverseIterator(); iter.hasNext();) { - final GraphValue value = iter.next(); - - final int age = (int) (mostRecentTime - value.mTime); - final float pos = value.mPos; - - // We get the horizontal coordinate in time units from left to right with - // (MAX_SHOWN_TIME_INTERVAL - age). Then, we rescale it to match the canvas - // units by dividing it by the time-domain length (MAX_SHOWN_TIME_INTERVAL) - // and by multiplying it by the canvas length (rightX - leftX). Finally, we - // offset the coordinate by adding it to leftX. - final float coordX = leftX + ((float) (MAX_SHOWN_TIME_INTERVAL - age) - / MAX_SHOWN_TIME_INTERVAL) * (rightX - leftX); - - // We get the vertical coordinate in position units from middle to top with - // (pos - mFrameCenterPosition). Then, we rescale it to match the canvas - // units by dividing it by half of the position-domain length - // (mFrameCenterToBorderDistance) and by multiplying it by half of the canvas - // length (middleY - topY). Finally, we offset the coordinate by subtracting - // it from middleY (we can't "add" here because the coordinate grows from top - // to bottom). - final float coordY = middleY - ((pos - mFrameCenterPosition) - / mFrameCenterToBorderDistance) * (middleY - topY); - - // Draw a point for this value. - canvas.drawPoint(coordX, coordY, mGraphPointPaint); - - // If this value is part of the same gesture as the previous one, draw a line - // between them. We ignore the first value (with age = 0). - if (age != 0 && (age - prevAge) <= MAX_GESTURE_TIME) { - canvas.drawLine(prevCoordX, prevCoordY, coordX, coordY, mGraphLinePaint); - } - - prevCoordX = coordX; - prevCoordY = coordY; - prevAge = age; - } - } - - @VisibleForTesting - float getFrameCenterPosition() { - return mFrameCenterPosition; - } - - /** - * Holds data needed to draw each entry in the graph. - */ - private static class GraphValue { - /** Position. */ - float mPos; - /** Time when this value was added. */ - long mTime; - - GraphValue(float pos, long time) { - this.mPos = pos; - this.mTime = time; - } - } - - /** - * Holds the graph values as a cyclic buffer. It has a fixed capacity, and it replaces the - * old values with new ones to avoid creating new objects. - */ - private static class CyclicBuffer { - private final GraphValue[] mValues; - private final int mCapacity; - private int mSize = 0; - private int mLastIndex = 0; - - // The iteration index and counter are here to make it easier to reset them. - /** Determines the value currently pointed by the iterator. */ - private int mIteratorIndex; - /** Counts how many values have been iterated through. */ - private int mIteratorCount; - - /** Used traverse the values in reverse order. */ - private final Iterator<GraphValue> mReverseIterator = new Iterator<GraphValue>() { - @Override - public boolean hasNext() { - return mIteratorCount <= mSize; - } - - @Override - public GraphValue next() { - // Returns the value currently pointed by the iterator and moves the iterator to - // the previous one. - mIteratorCount++; - return mValues[(mIteratorIndex-- + mCapacity) % mCapacity]; - } - }; - - CyclicBuffer(int capacity) { - mCapacity = capacity; - mValues = new GraphValue[capacity]; - } - - /** - * Add new graph value. If there is an existing object, we replace its data with the - * new one. With this, we re-use old objects instead of creating new ones. - */ - void add(float pos, long time) { - mLastIndex = (mLastIndex + 1) % mCapacity; - if (mValues[mLastIndex] == null) { - mValues[mLastIndex] = new GraphValue(pos, time); - } else { - final GraphValue oldValue = mValues[mLastIndex]; - oldValue.mPos = pos; - oldValue.mTime = time; - } - - // If needed, account for new value in the buffer size. - if (mSize != mCapacity) { - mSize++; - } - } - - int getSize() { - return mSize; - } - - GraphValue getFirst() { - final int distanceBetweenLastAndFirst = (mCapacity - mSize) + 1; - final int firstIndex = (mLastIndex + distanceBetweenLastAndFirst) % mCapacity; - return mValues[firstIndex]; - } - - GraphValue getLast() { - return mValues[mLastIndex]; - } - - void removeFirst() { - mSize--; - } - - /** Returns an iterator pointing at the last value. */ - Iterator<GraphValue> reverseIterator() { - mIteratorIndex = mLastIndex; - mIteratorCount = 1; - return mReverseIterator; - } - } - } } diff --git a/services/core/java/com/android/server/input/debug/RotaryInputGraphView.java b/services/core/java/com/android/server/input/debug/RotaryInputGraphView.java new file mode 100644 index 0000000000000000000000000000000000000000..95635d925855386c4bd5d9a1f3d596c834e763f4 --- /dev/null +++ b/services/core/java/com/android/server/input/debug/RotaryInputGraphView.java @@ -0,0 +1,342 @@ +/* + * Copyright 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.input.debug; + +import static android.util.TypedValue.COMPLEX_UNIT_SP; + +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.util.DisplayMetrics; +import android.util.TypedValue; +import android.view.View; +import android.view.ViewConfiguration; + +import java.util.Iterator; +import java.util.Locale; +import java.util.concurrent.TimeUnit; + +/** + * Shows a graph with the rotary input values as a function of time. + * The graph gets reset if no action is received for a certain amount of time. + */ +public class RotaryInputGraphView extends View { + + private static final int FRAME_COLOR = 0xbf741b47; + private static final int FRAME_WIDTH_SP = 2; + private static final int FRAME_BORDER_GAP_SP = 10; + private static final int FRAME_TEXT_SIZE_SP = 10; + private static final int FRAME_TEXT_OFFSET_SP = 2; + private static final int GRAPH_COLOR = 0xffff00ff; + private static final int GRAPH_LINE_WIDTH_SP = 1; + private static final int GRAPH_POINT_RADIUS_SP = 4; + private static final long MAX_SHOWN_TIME_INTERVAL = TimeUnit.SECONDS.toMillis(5); + private static final float DEFAULT_FRAME_CENTER_POSITION = 0; + private static final int MAX_GRAPH_VALUES_SIZE = 400; + /** Maximum time between values so that they are considered part of the same gesture. */ + private static final long MAX_GESTURE_TIME = TimeUnit.SECONDS.toMillis(1); + + private final DisplayMetrics mDm; + /** + * Distance in position units (amount scrolled in display pixels) from the center to the + * top/bottom frame lines. + */ + private final float mFrameCenterToBorderDistance; + private final float mScaledVerticalScrollFactor; + private final Locale mDefaultLocale = Locale.getDefault(); + private final Paint mFramePaint = new Paint(); + private final Paint mFrameTextPaint = new Paint(); + private final Paint mGraphLinePaint = new Paint(); + private final Paint mGraphPointPaint = new Paint(); + + private final CyclicBuffer mGraphValues = new CyclicBuffer(MAX_GRAPH_VALUES_SIZE); + /** Position at which graph values are placed at the center of the graph. */ + private float mFrameCenterPosition = DEFAULT_FRAME_CENTER_POSITION; + + public RotaryInputGraphView(Context c) { + super(c); + + mDm = mContext.getResources().getDisplayMetrics(); + // This makes the center-to-border distance equivalent to the display height, meaning + // that the total height of the graph is equivalent to 2x the display height. + mFrameCenterToBorderDistance = mDm.heightPixels; + mScaledVerticalScrollFactor = ViewConfiguration.get(c).getScaledVerticalScrollFactor(); + + mFramePaint.setColor(FRAME_COLOR); + mFramePaint.setStrokeWidth(applyDimensionSp(FRAME_WIDTH_SP, mDm)); + + mFrameTextPaint.setColor(GRAPH_COLOR); + mFrameTextPaint.setTextSize(applyDimensionSp(FRAME_TEXT_SIZE_SP, mDm)); + + mGraphLinePaint.setColor(GRAPH_COLOR); + mGraphLinePaint.setStrokeWidth(applyDimensionSp(GRAPH_LINE_WIDTH_SP, mDm)); + mGraphLinePaint.setStrokeCap(Paint.Cap.ROUND); + mGraphLinePaint.setStrokeJoin(Paint.Join.ROUND); + + mGraphPointPaint.setColor(GRAPH_COLOR); + mGraphPointPaint.setStrokeWidth(applyDimensionSp(GRAPH_POINT_RADIUS_SP, mDm)); + mGraphPointPaint.setStrokeCap(Paint.Cap.ROUND); + mGraphPointPaint.setStrokeJoin(Paint.Join.ROUND); + } + + /** + * Reads new scroll axis value and updates the list accordingly. Old positions are + * kept at the front (what you would get with getFirst), while the recent positions are + * kept at the back (what you would get with getLast). Also updates the frame center + * position to handle out-of-bounds cases. + */ + public void addValue(float scrollAxisValue, long eventTime) { + // Remove values that are too old. + while (mGraphValues.getSize() > 0 + && (eventTime - mGraphValues.getFirst().mTime) > MAX_SHOWN_TIME_INTERVAL) { + mGraphValues.removeFirst(); + } + + // If there are no recent values, reset the frame center. + if (mGraphValues.getSize() == 0) { + mFrameCenterPosition = DEFAULT_FRAME_CENTER_POSITION; + } + + // Handle new value. We multiply the scroll axis value by the scaled scroll factor to + // get the amount of pixels to be scrolled. We also compute the accumulated position + // by adding the current value to the last one (if not empty). + final float displacement = scrollAxisValue * mScaledVerticalScrollFactor; + final float prevPos = (mGraphValues.getSize() == 0 ? 0 : mGraphValues.getLast().mPos); + final float pos = prevPos + displacement; + + mGraphValues.add(pos, eventTime); + + // The difference between the distance of the most recent position from the center + // frame (pos - mFrameCenterPosition) and the maximum allowed distance from the center + // frame (mFrameCenterToBorderDistance). + final float verticalDiff = Math.abs(pos - mFrameCenterPosition) + - mFrameCenterToBorderDistance; + // If needed, translate frame. + if (verticalDiff > 0) { + final int sign = pos - mFrameCenterPosition < 0 ? -1 : 1; + // Here, we update the center frame position by the exact amount needed for us to + // stay within the maximum allowed distance from the center frame. + mFrameCenterPosition += sign * verticalDiff; + } + + // Redraw canvas. + invalidate(); + } + + @Override + protected void onDraw(Canvas canvas) { + super.onDraw(canvas); + + // Note: vertical coordinates in Canvas go from top to bottom, + // that is bottomY > middleY > topY. + final int verticalMargin = applyDimensionSp(FRAME_BORDER_GAP_SP, mDm); + final int topY = verticalMargin; + final int bottomY = getHeight() - verticalMargin; + final int middleY = (topY + bottomY) / 2; + + // Note: horizontal coordinates in Canvas go from left to right, + // that is rightX > leftX. + final int leftX = 0; + final int rightX = getWidth(); + + // Draw the frame, which includes 3 lines that show the maximum, + // minimum and middle positions of the graph. + canvas.drawLine(leftX, topY, rightX, topY, mFramePaint); + canvas.drawLine(leftX, middleY, rightX, middleY, mFramePaint); + canvas.drawLine(leftX, bottomY, rightX, bottomY, mFramePaint); + + // Draw the position that each frame line corresponds to. + final int frameTextOffset = applyDimensionSp(FRAME_TEXT_OFFSET_SP, mDm); + canvas.drawText( + String.format(mDefaultLocale, "%.1f", + mFrameCenterPosition + mFrameCenterToBorderDistance), + leftX, + topY - frameTextOffset, mFrameTextPaint + ); + canvas.drawText( + String.format(mDefaultLocale, "%.1f", mFrameCenterPosition), + leftX, + middleY - frameTextOffset, mFrameTextPaint + ); + canvas.drawText( + String.format(mDefaultLocale, "%.1f", + mFrameCenterPosition - mFrameCenterToBorderDistance), + leftX, + bottomY - frameTextOffset, mFrameTextPaint + ); + + // If there are no graph values to be drawn, stop here. + if (mGraphValues.getSize() == 0) { + return; + } + + // Draw the graph using the times and positions. + // We start at the most recent value (which should be drawn at the right) and move + // to the older values (which should be drawn to the left of more recent ones). Negative + // indices are handled by circuling back to the end of the buffer. + final long mostRecentTime = mGraphValues.getLast().mTime; + float prevCoordX = 0; + float prevCoordY = 0; + float prevAge = 0; + for (Iterator<GraphValue> iter = mGraphValues.reverseIterator(); iter.hasNext();) { + final GraphValue value = iter.next(); + + final int age = (int) (mostRecentTime - value.mTime); + final float pos = value.mPos; + + // We get the horizontal coordinate in time units from left to right with + // (MAX_SHOWN_TIME_INTERVAL - age). Then, we rescale it to match the canvas + // units by dividing it by the time-domain length (MAX_SHOWN_TIME_INTERVAL) + // and by multiplying it by the canvas length (rightX - leftX). Finally, we + // offset the coordinate by adding it to leftX. + final float coordX = leftX + ((float) (MAX_SHOWN_TIME_INTERVAL - age) + / MAX_SHOWN_TIME_INTERVAL) * (rightX - leftX); + + // We get the vertical coordinate in position units from middle to top with + // (pos - mFrameCenterPosition). Then, we rescale it to match the canvas + // units by dividing it by half of the position-domain length + // (mFrameCenterToBorderDistance) and by multiplying it by half of the canvas + // length (middleY - topY). Finally, we offset the coordinate by subtracting + // it from middleY (we can't "add" here because the coordinate grows from top + // to bottom). + final float coordY = middleY - ((pos - mFrameCenterPosition) + / mFrameCenterToBorderDistance) * (middleY - topY); + + // Draw a point for this value. + canvas.drawPoint(coordX, coordY, mGraphPointPaint); + + // If this value is part of the same gesture as the previous one, draw a line + // between them. We ignore the first value (with age = 0). + if (age != 0 && (age - prevAge) <= MAX_GESTURE_TIME) { + canvas.drawLine(prevCoordX, prevCoordY, coordX, coordY, mGraphLinePaint); + } + + prevCoordX = coordX; + prevCoordY = coordY; + prevAge = age; + } + } + + public float getFrameCenterPosition() { + return mFrameCenterPosition; + } + + /** + * Converts a dimension in scaled pixel units to integer display pixels. + */ + private static int applyDimensionSp(int dimensionSp, DisplayMetrics dm) { + return (int) TypedValue.applyDimension(COMPLEX_UNIT_SP, dimensionSp, dm); + } + + /** + * Holds data needed to draw each entry in the graph. + */ + private static class GraphValue { + /** Position. */ + float mPos; + /** Time when this value was added. */ + long mTime; + + GraphValue(float pos, long time) { + this.mPos = pos; + this.mTime = time; + } + } + + /** + * Holds the graph values as a cyclic buffer. It has a fixed capacity, and it replaces the + * old values with new ones to avoid creating new objects. + */ + private static class CyclicBuffer { + private final GraphValue[] mValues; + private final int mCapacity; + private int mSize = 0; + private int mLastIndex = 0; + + // The iteration index and counter are here to make it easier to reset them. + /** Determines the value currently pointed by the iterator. */ + private int mIteratorIndex; + /** Counts how many values have been iterated through. */ + private int mIteratorCount; + + /** Used traverse the values in reverse order. */ + private final Iterator<GraphValue> mReverseIterator = new Iterator<GraphValue>() { + @Override + public boolean hasNext() { + return mIteratorCount <= mSize; + } + + @Override + public GraphValue next() { + // Returns the value currently pointed by the iterator and moves the iterator to + // the previous one. + mIteratorCount++; + return mValues[(mIteratorIndex-- + mCapacity) % mCapacity]; + } + }; + + CyclicBuffer(int capacity) { + mCapacity = capacity; + mValues = new GraphValue[capacity]; + } + + /** + * Add new graph value. If there is an existing object, we replace its data with the + * new one. With this, we re-use old objects instead of creating new ones. + */ + void add(float pos, long time) { + mLastIndex = (mLastIndex + 1) % mCapacity; + if (mValues[mLastIndex] == null) { + mValues[mLastIndex] = new GraphValue(pos, time); + } else { + final GraphValue oldValue = mValues[mLastIndex]; + oldValue.mPos = pos; + oldValue.mTime = time; + } + + // If needed, account for new value in the buffer size. + if (mSize != mCapacity) { + mSize++; + } + } + + int getSize() { + return mSize; + } + + GraphValue getFirst() { + final int distanceBetweenLastAndFirst = (mCapacity - mSize) + 1; + final int firstIndex = (mLastIndex + distanceBetweenLastAndFirst) % mCapacity; + return mValues[firstIndex]; + } + + GraphValue getLast() { + return mValues[mLastIndex]; + } + + void removeFirst() { + mSize--; + } + + /** Returns an iterator pointing at the last value. */ + Iterator<GraphValue> reverseIterator() { + mIteratorIndex = mLastIndex; + mIteratorCount = 1; + return mReverseIterator; + } + } +} diff --git a/services/core/java/com/android/server/input/debug/RotaryInputValueView.java b/services/core/java/com/android/server/input/debug/RotaryInputValueView.java new file mode 100644 index 0000000000000000000000000000000000000000..9fadac57cef941e7ba324e9e3ea63f2831634acb --- /dev/null +++ b/services/core/java/com/android/server/input/debug/RotaryInputValueView.java @@ -0,0 +1,103 @@ +/* + * Copyright 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.input.debug; + +import static android.util.TypedValue.COMPLEX_UNIT_SP; + +import android.content.Context; +import android.graphics.ColorFilter; +import android.graphics.ColorMatrixColorFilter; +import android.graphics.Typeface; +import android.util.DisplayMetrics; +import android.util.TypedValue; +import android.view.ViewConfiguration; +import android.widget.TextView; + +import com.android.internal.R; + +import java.util.Locale; + +/** + * Draws the most recent rotary input value and indicates whether the source is active. + */ +public class RotaryInputValueView extends TextView { + + private static final int INACTIVE_TEXT_COLOR = 0xffff00ff; + private static final int ACTIVE_TEXT_COLOR = 0xff420f28; + private static final int TEXT_SIZE_SP = 8; + private static final int SIDE_PADDING_SP = 4; + /** Determines how long the active status lasts. */ + private static final int ACTIVE_STATUS_DURATION = 250 /* milliseconds */; + private static final ColorFilter ACTIVE_BACKGROUND_FILTER = + new ColorMatrixColorFilter(new float[]{ + 0, 0, 0, 0, 255, // red + 0, 0, 0, 0, 0, // green + 0, 0, 0, 0, 255, // blue + 0, 0, 0, 0, 200 // alpha + }); + + private final Runnable mUpdateActivityStatusCallback = () -> updateActivityStatus(false); + private final float mScaledVerticalScrollFactor; + private final Locale mDefaultLocale = Locale.getDefault(); + + public RotaryInputValueView(Context c) { + super(c); + + DisplayMetrics dm = mContext.getResources().getDisplayMetrics(); + mScaledVerticalScrollFactor = ViewConfiguration.get(c).getScaledVerticalScrollFactor(); + + setText(getFormattedValue(0)); + setTextColor(INACTIVE_TEXT_COLOR); + setTextSize(applyDimensionSp(TEXT_SIZE_SP, dm)); + setPaddingRelative(applyDimensionSp(SIDE_PADDING_SP, dm), 0, + applyDimensionSp(SIDE_PADDING_SP, dm), 0); + setTypeface(null, Typeface.BOLD); + setBackgroundResource(R.drawable.focus_event_rotary_input_background); + } + + /** Updates the shown text with the formatted value. */ + public void updateValue(float value) { + removeCallbacks(mUpdateActivityStatusCallback); + + setText(getFormattedValue(value * mScaledVerticalScrollFactor)); + + updateActivityStatus(true); + postDelayed(mUpdateActivityStatusCallback, ACTIVE_STATUS_DURATION); + } + + /** Updates whether or not there's active rotary input. */ + public void updateActivityStatus(boolean active) { + if (active) { + setTextColor(ACTIVE_TEXT_COLOR); + getBackground().setColorFilter(ACTIVE_BACKGROUND_FILTER); + } else { + setTextColor(INACTIVE_TEXT_COLOR); + getBackground().clearColorFilter(); + } + } + + private String getFormattedValue(float value) { + return String.format(mDefaultLocale, "%s%.1f", value < 0 ? "-" : "+", Math.abs(value)); + } + + /** + * Converts a dimension in scaled pixel units to integer display pixels. + */ + private static int applyDimensionSp(int dimensionSp, DisplayMetrics dm) { + return (int) TypedValue.applyDimension(COMPLEX_UNIT_SP, dimensionSp, dm); + } +} diff --git a/services/core/java/com/android/server/inputmethod/HandwritingEventReceiverSurface.java b/services/core/java/com/android/server/inputmethod/HandwritingEventReceiverSurface.java index 7726f40fa2aef75843c19588fdc3a97865e52f5e..dbbbed31df769b6e223d36ad1fb0811cddfcaeb8 100644 --- a/services/core/java/com/android/server/inputmethod/HandwritingEventReceiverSurface.java +++ b/services/core/java/com/android/server/inputmethod/HandwritingEventReceiverSurface.java @@ -57,13 +57,13 @@ final class HandwritingEventReceiverSurface { InputConfig.NOT_FOCUSABLE | InputConfig.NOT_TOUCHABLE | InputConfig.SPY - | InputConfig.INTERCEPTS_STYLUS - | InputConfig.TRUSTED_OVERLAY; + | InputConfig.INTERCEPTS_STYLUS; // Configure the surface to receive stylus events across the entire display. mWindowHandle.replaceTouchableRegionWithCrop(null /* use this surface's bounds */); final SurfaceControl.Transaction t = new SurfaceControl.Transaction(); + mWindowHandle.setTrustedOverlay(t, mInputSurface, true); t.setInputWindowInfo(mInputSurface, mWindowHandle); t.setLayer(mInputSurface, InputManagerService.INPUT_OVERLAY_LAYER_HANDWRITING_SURFACE); t.setPosition(mInputSurface, 0, 0); diff --git a/services/core/java/com/android/server/notification/NotificationBitmapJobService.java b/services/core/java/com/android/server/notification/NotificationBitmapJobService.java index 4335a1dcfa75701c59c281261d8e03ddda37cafe..e1a07076cb2d8d16b96ba5a52a51dbcf77d14982 100644 --- a/services/core/java/com/android/server/notification/NotificationBitmapJobService.java +++ b/services/core/java/com/android/server/notification/NotificationBitmapJobService.java @@ -29,7 +29,12 @@ import android.util.Slog; import com.android.internal.annotations.VisibleForTesting; import com.android.server.LocalServices; -import java.util.Calendar; +import java.time.Duration; +import java.time.Instant; +import java.time.LocalDate; +import java.time.LocalTime; +import java.time.ZonedDateTime; +import java.time.ZoneId; /** * This service runs everyday at 2am local time to remove expired bitmaps. @@ -69,26 +74,25 @@ public class NotificationBitmapJobService extends JobService { * @return Milliseconds until the next time the job should run. */ private static long getRunAfterMs() { - Calendar cal = Calendar.getInstance(); // Uses local time zone - final long now = cal.getTimeInMillis(); + ZoneId zoneId = ZoneId.systemDefault(); + ZonedDateTime now = Instant.now().atZone(zoneId); - cal.set(Calendar.HOUR_OF_DAY, 2); - cal.set(Calendar.MINUTE, 0); - cal.set(Calendar.MILLISECOND, 0); - final long today2AM = cal.getTimeInMillis(); + LocalDate today = now.toLocalDate(); + LocalTime twoAM = LocalTime.of(/* hour= */ 2, /* minute= */ 0); - cal.add(Calendar.DAY_OF_YEAR, 1); - final long tomorrow2AM = cal.getTimeInMillis(); + ZonedDateTime today2AM = ZonedDateTime.of(today, twoAM, zoneId); + ZonedDateTime tomorrow2AM = today2AM.plusDays(1); return getTimeUntilRemoval(now, today2AM, tomorrow2AM); } @VisibleForTesting - static long getTimeUntilRemoval(long now, long today2AM, long tomorrow2AM) { - if (now < today2AM) { - return today2AM - now; + static long getTimeUntilRemoval(ZonedDateTime now, ZonedDateTime today2AM, + ZonedDateTime tomorrow2AM) { + if (Duration.between(now, today2AM).isNegative()) { + return Duration.between(now, tomorrow2AM).toMillis(); } - return tomorrow2AM - now; + return Duration.between(now, today2AM).toMillis(); } @Override diff --git a/services/core/java/com/android/server/notification/NotificationHistoryJobService.java b/services/core/java/com/android/server/notification/NotificationHistoryJobService.java index 3776ad7a0799d6b2bea580c2f6cc3dafa8e270d7..c9317d17be37a0eda4f60d06c5b26ae21f5a5898 100644 --- a/services/core/java/com/android/server/notification/NotificationHistoryJobService.java +++ b/services/core/java/com/android/server/notification/NotificationHistoryJobService.java @@ -27,6 +27,7 @@ import android.content.Context; import android.os.CancellationSignal; import android.util.Slog; +import com.android.internal.annotations.VisibleForTesting; import com.android.server.LocalServices; import java.util.concurrent.TimeUnit; @@ -77,5 +78,11 @@ public class NotificationHistoryJobService extends JobService { } return false; } + + @Override + @VisibleForTesting + protected void attachBaseContext(Context base) { + super.attachBaseContext(base); + } } diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index db69d93583d4c2a03d9ca5c278cc7d399abea499..87c30674bfb7bd7ea9b74001e02f7af525696766 100755 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -396,7 +396,7 @@ public class NotificationManagerService extends SystemService { static final int MESSAGE_FINISH_TOKEN_TIMEOUT = 7; static final int MESSAGE_ON_PACKAGE_CHANGED = 8; - static final long BITMAP_EXPIRATION_TIME_MS = TimeUnit.HOURS.toMillis(24); + static final Duration BITMAP_DURATION = Duration.ofHours(24); // ranking thread messages private static final int MESSAGE_RECONSIDER_RANKING = 1000; @@ -6705,7 +6705,7 @@ public class NotificationManagerService extends SystemService { final long timePostedMs = r.getSbn().getPostTime(); final long timeNowMs = System.currentTimeMillis(); - if (isBitmapExpired(timePostedMs, timeNowMs, BITMAP_EXPIRATION_TIME_MS)) { + if (isBitmapExpired(timePostedMs, timeNowMs, BITMAP_DURATION.toMillis())) { removeBitmapAndRepost(r); } } diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java index 82d3e9157986e1a41b0fa76cb75979bb1c006ae9..68a8e40d052829ae0a0b7c5e4e98ff7fecdad46e 100644 --- a/services/core/java/com/android/server/pm/UserManagerService.java +++ b/services/core/java/com/android/server/pm/UserManagerService.java @@ -286,6 +286,8 @@ public class UserManagerService extends IUserManager.Stub { private static final int USER_VERSION = 11; + private static final int MAX_USER_STRING_LENGTH = 500; + private static final long EPOCH_PLUS_30_YEARS = 30L * 365 * 24 * 60 * 60 * 1000L; // ms static final int WRITE_USER_MSG = 1; @@ -4374,15 +4376,17 @@ public class UserManagerService extends IUserManager.Stub { // Write seed data if (userData.persistSeedData) { if (userData.seedAccountName != null) { - serializer.attribute(null, ATTR_SEED_ACCOUNT_NAME, userData.seedAccountName); + serializer.attribute(null, ATTR_SEED_ACCOUNT_NAME, + truncateString(userData.seedAccountName)); } if (userData.seedAccountType != null) { - serializer.attribute(null, ATTR_SEED_ACCOUNT_TYPE, userData.seedAccountType); + serializer.attribute(null, ATTR_SEED_ACCOUNT_TYPE, + truncateString(userData.seedAccountType)); } } if (userInfo.name != null) { serializer.startTag(null, TAG_NAME); - serializer.text(userInfo.name); + serializer.text(truncateString(userInfo.name)); serializer.endTag(null, TAG_NAME); } synchronized (mRestrictionsLock) { @@ -4431,6 +4435,13 @@ public class UserManagerService extends IUserManager.Stub { serializer.endDocument(); } + private String truncateString(String original) { + if (original == null || original.length() <= MAX_USER_STRING_LENGTH) { + return original; + } + return original.substring(0, MAX_USER_STRING_LENGTH); + } + /* * Writes the user list file in this format: * @@ -4869,7 +4880,7 @@ public class UserManagerService extends IUserManager.Stub { @UserIdInt int parentId, boolean preCreate, @Nullable String[] disallowedPackages, @NonNull TimingsTraceAndSlog t, @Nullable Object token) throws UserManager.CheckedUserOperationException { - + String truncatedName = truncateString(name); final UserTypeDetails userTypeDetails = mUserTypes.get(userType); if (userTypeDetails == null) { throwCheckedUserOperationException( @@ -4904,8 +4915,8 @@ public class UserManagerService extends IUserManager.Stub { // Try to use a pre-created user (if available). if (!preCreate && parentId < 0 && isUserTypeEligibleForPreCreation(userTypeDetails)) { - final UserInfo preCreatedUser = convertPreCreatedUserIfPossible(userType, flags, name, - token); + final UserInfo preCreatedUser = convertPreCreatedUserIfPossible(userType, flags, + truncatedName, token); if (preCreatedUser != null) { return preCreatedUser; } @@ -5000,7 +5011,7 @@ public class UserManagerService extends IUserManager.Stub { flags |= UserInfo.FLAG_EPHEMERAL_ON_CREATE; } - userInfo = new UserInfo(userId, name, null, flags, userType); + userInfo = new UserInfo(userId, truncatedName, null, flags, userType); userInfo.serialNumber = mNextSerialNumber++; userInfo.creationTime = getCreationTime(); userInfo.partial = true; @@ -6456,8 +6467,8 @@ public class UserManagerService extends IUserManager.Stub { Slog.e(LOG_TAG, "No such user for settings seed data u=" + userId); return; } - userData.seedAccountName = accountName; - userData.seedAccountType = accountType; + userData.seedAccountName = truncateString(accountName); + userData.seedAccountType = truncateString(accountType); userData.seedAccountOptions = accountOptions; userData.persistSeedData = persist; } diff --git a/services/core/java/com/android/server/policy/AppOpsPolicy.java b/services/core/java/com/android/server/policy/AppOpsPolicy.java index ebc7163cd05ccdfebbc236ed7361f92d5d5a491b..b83421fe78d795f17d59d380d10b5b46eb4d6ed1 100644 --- a/services/core/java/com/android/server/policy/AppOpsPolicy.java +++ b/services/core/java/com/android/server/policy/AppOpsPolicy.java @@ -42,6 +42,7 @@ import android.os.PackageTagsList; import android.os.Process; import android.os.SystemProperties; import android.os.UserHandle; +import android.permission.flags.Flags; import android.service.voice.VoiceInteractionManagerInternal; import android.service.voice.VoiceInteractionManagerInternal.HotwordDetectionServiceIdentity; import android.text.TextUtils; @@ -75,9 +76,6 @@ public final class AppOpsPolicy implements AppOpsManagerInternal.CheckOpsDelegat private static final boolean SYSPROP_HOTWORD_DETECTION_SERVICE_REQUIRED = SystemProperties.getBoolean("ro.hotword.detection_service_required", false); - //TODO(b/289087412): import this from the flag value in set up in device config. - private static final boolean IS_VOICE_ACTIVATION_OP_ENABLED = false; - @NonNull private final Object mLock = new Object(); @@ -212,7 +210,7 @@ public final class AppOpsPolicy implements AppOpsManagerInternal.CheckOpsDelegat * @return the op that should be noted for the voice activations of the app by detected hotword. */ public static int getVoiceActivationOp() { - if (IS_VOICE_ACTIVATION_OP_ENABLED) { + if (Flags.voiceActivationPermissionApis()) { return OP_RECEIVE_SANDBOX_TRIGGER_AUDIO; } return OP_RECORD_AUDIO_HOTWORD; diff --git a/services/core/java/com/android/server/wm/ActivityStartController.java b/services/core/java/com/android/server/wm/ActivityStartController.java index c39b266a7701c498da73c8dea86b2ed118cf944f..4a5311b14397e45529f91a0ed04e02b193ec7aa1 100644 --- a/services/core/java/com/android/server/wm/ActivityStartController.java +++ b/services/core/java/com/android/server/wm/ActivityStartController.java @@ -577,7 +577,8 @@ public class ActivityStartController { .getRootTask(WINDOWING_MODE_UNDEFINED, activityType); if (rootTask == null) return false; final ActivityRecord r = rootTask.topRunningActivity(); - if (r == null || r.isVisibleRequested() || !r.attachedToProcess() + if (r == null || (r.isVisibleRequested() && rootTask.isTopRootTaskInDisplayArea()) + || !r.attachedToProcess() || !r.mActivityComponent.equals(intent.getComponent()) || !mService.isCallerRecents(r.getUid()) // Recents keeps invisible while device is locked. diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java index 61bae7153f6da7341670808e00971072d0339bd0..0b673211a1c9ced5b822726e24c311edf5edd663 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java @@ -6448,19 +6448,8 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { if (!restarting && hasVisibleActivities) { deferWindowLayout(); try { - final Task topTask = mRootWindowContainer.getTopDisplayFocusedRootTask(); - if (topTask != null - && topTask.topRunningActivity(true /* focusableOnly */) == null) { - topTask.adjustFocusToNextFocusableTask("handleAppDied"); - } - if (!mRootWindowContainer.resumeFocusedTasksTopActivities()) { - // If there was nothing to resume, and we are not already restarting - // this process, but there is a visible activity that is hosted by the - // process...then make sure all visible activities are running, taking - // care of restarting this process. - mRootWindowContainer.ensureActivitiesVisible(null, 0, - !PRESERVE_WINDOWS); - } + mRootWindowContainer.ensureVisibilityOnVisibleActivityDiedOrCrashed( + "handleAppDied"); } finally { continueWindowLayout(); } @@ -6901,7 +6890,18 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public int finishTopCrashedActivities(WindowProcessController crashedApp, String reason) { synchronized (mGlobalLock) { - return mRootWindowContainer.finishTopCrashedActivities(crashedApp, reason); + deferWindowLayout(); + try { + final Task finishedTask = mRootWindowContainer.finishTopCrashedActivities( + crashedApp, reason); + if (finishedTask != null) { + mRootWindowContainer.ensureVisibilityOnVisibleActivityDiedOrCrashed(reason); + return finishedTask.mTaskId; + } + return INVALID_TASK_ID; + } finally { + continueWindowLayout(); + } } } diff --git a/services/core/java/com/android/server/wm/DragState.java b/services/core/java/com/android/server/wm/DragState.java index 0f1a1053716e6d8d4c698c6c650f9de0d2f1a607..7af4aadb2f0e6a34ead5a6757c586acc73b41d7e 100644 --- a/services/core/java/com/android/server/wm/DragState.java +++ b/services/core/java/com/android/server/wm/DragState.java @@ -48,7 +48,6 @@ import android.hardware.input.InputManagerGlobal; import android.os.Binder; import android.os.Build; import android.os.IBinder; -import android.os.InputConfig; import android.os.RemoteException; import android.os.UserHandle; import android.os.UserManager; @@ -186,6 +185,10 @@ class DragState { // Crop the input surface to the display size. mTmpClipRect.set(0, 0, mDisplaySize.x, mDisplaySize.y); + // Make trusted overlay to not block any touches while D&D ongoing and allowing + // touches to pass through to windows underneath. This allows user to interact with the + // UI to navigate while dragging. + h.setTrustedOverlay(mTransaction, mInputSurface, true); mTransaction.show(mInputSurface) .setInputWindowInfo(mInputSurface, h) .setLayer(mInputSurface, Integer.MAX_VALUE) @@ -377,11 +380,6 @@ class DragState { mDragWindowHandle.ownerUid = MY_UID; mDragWindowHandle.scaleFactor = 1.0f; - // InputConfig.TRUSTED_OVERLAY: To not block any touches while D&D ongoing and allowing - // touches to pass through to windows underneath. This allows user to interact with the - // UI to navigate while dragging. - mDragWindowHandle.inputConfig = InputConfig.TRUSTED_OVERLAY; - // The drag window cannot receive new touches. mDragWindowHandle.touchableRegion.setEmpty(); diff --git a/services/core/java/com/android/server/wm/InputConsumerImpl.java b/services/core/java/com/android/server/wm/InputConsumerImpl.java index 39622c1c5aaf2d61e59d7898f5a9dc38362ea468..c21930dab5ebe68502ef07f27d32a091da849634 100644 --- a/services/core/java/com/android/server/wm/InputConsumerImpl.java +++ b/services/core/java/com/android/server/wm/InputConsumerImpl.java @@ -74,7 +74,7 @@ class InputConsumerImpl implements IBinder.DeathRecipient { mWindowHandle.ownerPid = WindowManagerService.MY_PID; mWindowHandle.ownerUid = WindowManagerService.MY_UID; mWindowHandle.scaleFactor = 1.0f; - mWindowHandle.inputConfig = InputConfig.NOT_FOCUSABLE | InputConfig.TRUSTED_OVERLAY; + mWindowHandle.inputConfig = InputConfig.NOT_FOCUSABLE; mInputSurface = mService.makeSurfaceBuilder( mService.mRoot.getDisplayContent(displayId).getSession()) @@ -129,12 +129,14 @@ class InputConsumerImpl implements IBinder.DeathRecipient { void show(SurfaceControl.Transaction t, WindowContainer w) { t.show(mInputSurface); + mWindowHandle.setTrustedOverlay(t, mInputSurface, true); t.setInputWindowInfo(mInputSurface, mWindowHandle); t.setRelativeLayer(mInputSurface, w.getSurfaceControl(), 1); } void show(SurfaceControl.Transaction t, int layer) { t.show(mInputSurface); + mWindowHandle.setTrustedOverlay(t, mInputSurface, true); t.setInputWindowInfo(mInputSurface, mWindowHandle); t.setLayer(mInputSurface, layer); } diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java index 825d38b3eed746bfa8177d7a5a6a608d4821e26c..af307ec3c2a9623c7fcf7ca51665fd04e59c4be1 100644 --- a/services/core/java/com/android/server/wm/InputMonitor.java +++ b/services/core/java/com/android/server/wm/InputMonitor.java @@ -675,6 +675,11 @@ final class InputMonitor { w.getKeyInterceptionInfo()); if (w.mWinAnimator.hasSurface()) { + // Update trusted overlay changes here because they are tied to input info. Input + // changes can be updated even if surfaces aren't. + inputWindowHandle.setTrustedOverlay(mInputTransaction, + w.mWinAnimator.mSurfaceController.mSurfaceControl, + w.isWindowTrustedOverlay()); populateInputWindowHandle(inputWindowHandle, w); setInputWindowInfoIfNeeded(mInputTransaction, w.mWinAnimator.mSurfaceController.mSurfaceControl, inputWindowHandle); @@ -732,7 +737,7 @@ final class InputMonitor { new InputWindowHandle(null /* inputApplicationHandle */, displayId)); inputWindowHandle.setName(name); inputWindowHandle.setLayoutParamsType(TYPE_SECURE_SYSTEM_OVERLAY); - inputWindowHandle.setTrustedOverlay(true); + inputWindowHandle.setTrustedOverlay(t, sc, true); populateOverlayInputInfo(inputWindowHandle); setInputWindowInfoIfNeeded(t, sc, inputWindowHandle); } diff --git a/services/core/java/com/android/server/wm/InputWindowHandleWrapper.java b/services/core/java/com/android/server/wm/InputWindowHandleWrapper.java index 64b7a6064e4578aea327f438c613a10b4c60b1ac..90d81bd82087251922f85c6ad5c3a5328415854f 100644 --- a/services/core/java/com/android/server/wm/InputWindowHandleWrapper.java +++ b/services/core/java/com/android/server/wm/InputWindowHandleWrapper.java @@ -195,6 +195,11 @@ class InputWindowHandleWrapper { mChanged = true; } + void setTrustedOverlay(SurfaceControl.Transaction t, SurfaceControl sc, + boolean trustedOverlay) { + mHandle.setTrustedOverlay(t, sc, trustedOverlay); + } + void setOwnerPid(int pid) { if (mHandle.ownerPid == pid) { return; diff --git a/services/core/java/com/android/server/wm/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java index c3977d6918e35fe83f2005c62ae7bda91bd92326..82d4b90d06be33ffa69bb086d656e1feae1aa327 100644 --- a/services/core/java/com/android/server/wm/RecentsAnimationController.java +++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java @@ -62,6 +62,7 @@ import android.window.PictureInPictureSurfaceTransaction; import android.window.TaskSnapshot; import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.os.IResultReceiver; import com.android.internal.protolog.common.ProtoLog; import com.android.server.LocalServices; import com.android.server.inputmethod.InputMethodManagerInternal; @@ -244,7 +245,8 @@ public class RecentsAnimationController implements DeathRecipient { } @Override - public void finish(boolean moveHomeToTop, boolean sendUserLeaveHint) { + public void finish(boolean moveHomeToTop, boolean sendUserLeaveHint, + IResultReceiver finishCb) { ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS, "finish(%b): mCanceled=%b", moveHomeToTop, mCanceled); final long token = Binder.clearCallingIdentity(); @@ -257,6 +259,13 @@ public class RecentsAnimationController implements DeathRecipient { } finally { Binder.restoreCallingIdentity(token); } + if (finishCb != null) { + try { + finishCb.send(0, new Bundle()); + } catch (RemoteException e) { + Slog.e(TAG, "Failed to report animation finished", e); + } + } } @Override diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java index a88aa2e3f78062870439ef5f06a11734978d955b..cf6a1feef5ee90c97481dffb8b4ef67084b7a941 100644 --- a/services/core/java/com/android/server/wm/RootWindowContainer.java +++ b/services/core/java/com/android/server/wm/RootWindowContainer.java @@ -2319,19 +2319,36 @@ class RootWindowContainer extends WindowContainer<DisplayContent> * * @param app The app that crashed. * @param reason Reason to perform this action. - * @return The task id that was finished in this root task, or INVALID_TASK_ID if none was - * finished. + * @return The finished task which was on top or visible, otherwise {@code null} if the crashed + * app doesn't have activity in visible task. */ - int finishTopCrashedActivities(WindowProcessController app, String reason) { + @Nullable + Task finishTopCrashedActivities(WindowProcessController app, String reason) { Task focusedRootTask = getTopDisplayFocusedRootTask(); final Task[] finishedTask = new Task[1]; forAllRootTasks(rootTask -> { + final boolean recordTopOrVisible = finishedTask[0] == null + && (focusedRootTask == rootTask || rootTask.isVisibleRequested()); final Task t = rootTask.finishTopCrashedActivityLocked(app, reason); - if (rootTask == focusedRootTask || finishedTask[0] == null) { + if (recordTopOrVisible) { finishedTask[0] = t; } }); - return finishedTask[0] != null ? finishedTask[0].mTaskId : INVALID_TASK_ID; + return finishedTask[0]; + } + + void ensureVisibilityOnVisibleActivityDiedOrCrashed(String reason) { + final Task topTask = getTopDisplayFocusedRootTask(); + if (topTask != null && topTask.topRunningActivity(true /* focusableOnly */) == null) { + // Move the next focusable task to front. + topTask.adjustFocusToNextFocusableTask(reason); + } + if (!resumeFocusedTasksTopActivities()) { + // It may be nothing to resume because there are pausing activities or all the top + // activities are resumed. Then it still needs to make sure all visible activities are + // running in case the tasks were reordered or there are non-top visible activities. + ensureActivitiesVisible(null /* starting */, 0 /* configChanges */, !PRESERVE_WINDOWS); + } } boolean resumeFocusedTasksTopActivities() { diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java index c6547a0c11b82250487d96f4726b96bf766708a2..882104a297efaa61a29a4ded588ea75f56120856 100644 --- a/services/core/java/com/android/server/wm/Transition.java +++ b/services/core/java/com/android/server/wm/Transition.java @@ -372,8 +372,7 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener { parent.forAllTasks(t -> { // Skip transient-launch task if (t == transientRootTask) return false; - if (t.isVisibleRequested() && !t.isAlwaysOnTop() - && !t.getWindowConfiguration().tasksAreFloating()) { + if (t.isVisibleRequested() && !t.isAlwaysOnTop()) { if (t.isRootTask()) { mTransientHideTasks.add(t); } diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 1996dd9068f29d7fa70dee66d816601230344c7e..074b4044fdaabfb398849c60eb3af8d1c130db85 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -2493,14 +2493,6 @@ public class WindowManagerService extends IWindowManager.Stub outInsetsState.set(win.getCompatInsetsState(), true /* copySources */); } - // TODO (b/298562855): Remove this after identifying the reason why the frame is empty. - if (win.mAttrs.providedInsets != null && win.getFrame().isEmpty()) { - Slog.w(TAG, "Empty frame of " + win - + " configChanged=" + configChanged - + " frame=" + win.getFrame().toShortString() - + " attrs=" + attrs); - } - ProtoLog.v(WM_DEBUG_FOCUS, "Relayout of %s: focusMayChange=%b", win, focusMayChange); @@ -8884,11 +8876,6 @@ public class WindowManagerService extends IWindowManager.Stub h.inputConfig |= InputConfig.NOT_FOCUSABLE; } - // Check private trusted overlay flag to set trustedOverlay field of input window handle. - if ((privateFlags & PRIVATE_FLAG_TRUSTED_OVERLAY) != 0) { - h.inputConfig |= InputConfig.TRUSTED_OVERLAY; - } - h.dispatchingTimeoutMillis = DEFAULT_DISPATCHING_TIMEOUT_MILLIS; h.ownerUid = callingUid; h.ownerPid = callingPid; @@ -8908,6 +8895,8 @@ public class WindowManagerService extends IWindowManager.Stub } final SurfaceControl.Transaction t = mTransactionFactory.get(); + // Check private trusted overlay flag to set trustedOverlay field of input window handle. + h.setTrustedOverlay(t, surface, (privateFlags & PRIVATE_FLAG_TRUSTED_OVERLAY) != 0); t.setInputWindowInfo(surface, h); t.apply(); t.close(); diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index ebef606a8d603bb05af60fb7f2d37c400dacdefc..4beec2bc79e6f1d380673bb65d59745a03975563 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -178,6 +178,7 @@ import static com.android.server.wm.WindowStateProto.UNRESTRICTED_KEEP_CLEAR_ARE import static com.android.server.wm.WindowStateProto.VIEW_VISIBILITY; import static com.android.server.wm.WindowStateProto.WINDOW_CONTAINER; import static com.android.server.wm.WindowStateProto.WINDOW_FRAMES; +import static com.android.window.flags.Flags.surfaceTrustedOverlay; import android.annotation.CallSuper; import android.annotation.NonNull; @@ -1110,7 +1111,9 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP mInputWindowHandle.setName(getName()); mInputWindowHandle.setPackageName(mAttrs.packageName); mInputWindowHandle.setLayoutParamsType(mAttrs.type); - mInputWindowHandle.setTrustedOverlay(shouldWindowHandleBeTrusted(s)); + if (!surfaceTrustedOverlay()) { + mInputWindowHandle.setTrustedOverlay(isWindowTrustedOverlay()); + } if (DEBUG) { Slog.v(TAG, "Window " + this + " client=" + c.asBinder() + " token=" + token + " (" + mAttrs.token + ")" + " params=" + a); @@ -1185,12 +1188,12 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP } } - boolean shouldWindowHandleBeTrusted(Session s) { + public boolean isWindowTrustedOverlay() { return InputMonitor.isTrustedOverlay(mAttrs.type) || ((mAttrs.privateFlags & PRIVATE_FLAG_TRUSTED_OVERLAY) != 0 - && s.mCanAddInternalSystemWindow) + && mSession.mCanAddInternalSystemWindow) || ((mAttrs.privateFlags & PRIVATE_FLAG_SYSTEM_APPLICATION_OVERLAY) != 0 - && s.mCanCreateSystemApplicationOverlay); + && mSession.mCanCreateSystemApplicationOverlay); } int getTouchOcclusionMode() { @@ -5187,6 +5190,9 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP updateFrameRateSelectionPriorityIfNeeded(); updateScaleIfNeeded(); mWinAnimator.prepareSurfaceLocked(getSyncTransaction()); + if (surfaceTrustedOverlay()) { + getSyncTransaction().setTrustedOverlay(mSurfaceControl, isWindowTrustedOverlay()); + } } super.prepareSurfaces(); } @@ -5939,7 +5945,13 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP } boolean isTrustedOverlay() { - return mInputWindowHandle.isTrustedOverlay(); + if (surfaceTrustedOverlay()) { + WindowState parentWindow = getParentWindow(); + return isWindowTrustedOverlay() || (parentWindow != null + && parentWindow.isWindowTrustedOverlay()); + } else { + return mInputWindowHandle.isTrustedOverlay(); + } } public boolean receiveFocusFromTapOutside() { 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 d0a9c458a20f7fa58603106c88fcde25761da398..debd891400b6d540f7d4ef5426a0005665d4ad39 100644 --- a/services/core/xsd/display-device-config/display-device-config.xsd +++ b/services/core/xsd/display-device-config/display-device-config.xsd @@ -46,6 +46,8 @@ <xs:annotation name="nonnull"/> <xs:annotation name="final"/> </xs:element> + <xs:element type="powerThrottlingConfig" name="powerThrottlingConfig" minOccurs="0" + maxOccurs="1"/> <xs:element type="luxThrottling" name="luxThrottling" minOccurs="0" maxOccurs="1"/> <xs:element type="highBrightnessMode" name="highBrightnessMode" minOccurs="0" @@ -350,6 +352,43 @@ </xs:sequence> </xs:complexType> + <xs:complexType name="powerThrottlingMap"> + <xs:sequence> + <xs:element name="powerThrottlingPoint" type="powerThrottlingPoint" maxOccurs="unbounded" minOccurs="1"> + <xs:annotation name="nonnull"/> + <xs:annotation name="final"/> + </xs:element> + </xs:sequence> + <xs:attribute name="id" type="xs:string"/> + </xs:complexType> + + <xs:complexType name="powerThrottlingPoint"> + <xs:sequence> + <xs:element type="thermalStatus" name="thermalStatus"> + <xs:annotation name="nonnull"/> + <xs:annotation name="final"/> + </xs:element> + <xs:element type="nonNegativeDecimal" name="powerQuotaMilliWatts"> + <xs:annotation name="nonnull"/> + <xs:annotation name="final"/> + </xs:element> + </xs:sequence> + </xs:complexType> + + <xs:complexType name="powerThrottlingConfig"> + <xs:element type="nonNegativeDecimal" name="brightnessLowestCapAllowed"> + <xs:annotation name="nonnull"/> + <xs:annotation name="final"/> + </xs:element> + <xs:element name="pollingWindowMillis" type="xs:nonNegativeInteger"> + <xs:annotation name="nonnull"/> + <xs:annotation name="final"/> + </xs:element> + <xs:element type="powerThrottlingMap" name="powerThrottlingMap" maxOccurs="unbounded"> + <xs:annotation name="final"/> + </xs:element> + </xs:complexType> + <xs:complexType name="nitsMap"> <xs:sequence> <xs:element name="point" type="point" maxOccurs="unbounded" minOccurs="2"> diff --git a/services/core/xsd/display-device-config/schema/current.txt b/services/core/xsd/display-device-config/schema/current.txt index 949b1f2cb74b955ef19a9f4e9b38363148f0be56..2d27f0c7966082bb94e29736396fbd728e0889a8 100644 --- a/services/core/xsd/display-device-config/schema/current.txt +++ b/services/core/xsd/display-device-config/schema/current.txt @@ -106,6 +106,7 @@ package com.android.server.display.config { method public final com.android.server.display.config.SensorDetails getLightSensor(); method public com.android.server.display.config.LuxThrottling getLuxThrottling(); method @Nullable public final String getName(); + method public com.android.server.display.config.PowerThrottlingConfig getPowerThrottlingConfig(); method public final com.android.server.display.config.SensorDetails getProxSensor(); method public com.android.server.display.config.DisplayQuirks getQuirks(); method public com.android.server.display.config.RefreshRateConfigs getRefreshRate(); @@ -138,6 +139,7 @@ package com.android.server.display.config { method public final void setLightSensor(com.android.server.display.config.SensorDetails); method public void setLuxThrottling(com.android.server.display.config.LuxThrottling); method public final void setName(@Nullable String); + method public void setPowerThrottlingConfig(com.android.server.display.config.PowerThrottlingConfig); method public final void setProxSensor(com.android.server.display.config.SensorDetails); method public void setQuirks(com.android.server.display.config.DisplayQuirks); method public void setRefreshRate(com.android.server.display.config.RefreshRateConfigs); @@ -246,6 +248,30 @@ package com.android.server.display.config { method public final void setValue(@NonNull java.math.BigDecimal); } + public class PowerThrottlingConfig { + ctor public PowerThrottlingConfig(); + method @NonNull public final java.math.BigDecimal getBrightnessLowestCapAllowed(); + method @NonNull public final java.math.BigInteger getPollingWindowMillis(); + method public final java.util.List<com.android.server.display.config.PowerThrottlingMap> getPowerThrottlingMap(); + method public final void setBrightnessLowestCapAllowed(@NonNull java.math.BigDecimal); + method public final void setPollingWindowMillis(@NonNull java.math.BigInteger); + } + + public class PowerThrottlingMap { + ctor public PowerThrottlingMap(); + method public String getId(); + method @NonNull public final java.util.List<com.android.server.display.config.PowerThrottlingPoint> getPowerThrottlingPoint(); + method public void setId(String); + } + + public class PowerThrottlingPoint { + ctor public PowerThrottlingPoint(); + method @NonNull public final java.math.BigDecimal getPowerQuotaMilliWatts(); + method @NonNull public final com.android.server.display.config.ThermalStatus getThermalStatus(); + method public final void setPowerQuotaMilliWatts(@NonNull java.math.BigDecimal); + method public final void setThermalStatus(@NonNull com.android.server.display.config.ThermalStatus); + } + public enum PredefinedBrightnessLimitNames { method public String getRawName(); enum_constant public static final com.android.server.display.config.PredefinedBrightnessLimitNames _default; diff --git a/services/core/xsd/display-layout-config/display-layout-config.xsd b/services/core/xsd/display-layout-config/display-layout-config.xsd index 57b5d00f75a0e72be51bf325afd14b27d810431c..4e954653bcbb7678ec8e4f01ec7d0ede2cbe9de7 100644 --- a/services/core/xsd/display-layout-config/display-layout-config.xsd +++ b/services/core/xsd/display-layout-config/display-layout-config.xsd @@ -52,6 +52,7 @@ <xs:element name="address" type="xs:nonNegativeInteger"/> <xs:element name="position" type="xs:string" minOccurs="0" maxOccurs="1" /> <xs:element name="brightnessThrottlingMapId" type="xs:string" minOccurs="0" maxOccurs="1" /> + <xs:element name="powerThrottlingMapId" type="xs:string" minOccurs="0" maxOccurs="1" /> <xs:element name="refreshRateThermalThrottlingMapId" type="xs:string" minOccurs="0" /> <xs:element name="leadDisplayAddress" type="xs:nonNegativeInteger" minOccurs="0" maxOccurs="1" /> </xs:sequence> diff --git a/services/core/xsd/display-layout-config/schema/current.txt b/services/core/xsd/display-layout-config/schema/current.txt index 2d4f7a428db127874dac2c4f1aca842e36236303..195cae5aee14e9156a6ba4a5440f64e7d49edb08 100644 --- a/services/core/xsd/display-layout-config/schema/current.txt +++ b/services/core/xsd/display-layout-config/schema/current.txt @@ -8,6 +8,7 @@ package com.android.server.display.config.layout { method public String getDisplayGroup(); method public java.math.BigInteger getLeadDisplayAddress(); method public String getPosition(); + method public String getPowerThrottlingMapId(); method public String getRefreshRateThermalThrottlingMapId(); method public String getRefreshRateZoneId(); method public boolean isDefaultDisplay(); @@ -19,6 +20,7 @@ package com.android.server.display.config.layout { method public void setEnabled(boolean); method public void setLeadDisplayAddress(java.math.BigInteger); method public void setPosition(String); + method public void setPowerThrottlingMapId(String); method public void setRefreshRateThermalThrottlingMapId(String); method public void setRefreshRateZoneId(String); } diff --git a/services/foldables/devicestateprovider/tests/Android.bp b/services/foldables/devicestateprovider/tests/Android.bp index a8db05e9917945e42e5c379526bb41ac0db18dd7..84a6df38e0a0c01f8ae9d9d348ca7bef32c1c95a 100644 --- a/services/foldables/devicestateprovider/tests/Android.bp +++ b/services/foldables/devicestateprovider/tests/Android.bp @@ -20,11 +20,11 @@ android_test { "foldable-device-state-provider", "androidx.test.rules", "junit", - "truth-prebuilt", + "truth", "mockito-target-extended-minus-junit4", "androidx.test.uiautomator_uiautomator", "androidx.test.ext.junit", "testables", ], - test_suites: ["device-tests"] + test_suites: ["device-tests"], } diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index 57fa12d20de510f35c5ef98269f04991642d46ed..49ad84a8e6d9954f799e34ee5f6973d9a414f67d 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -264,6 +264,8 @@ public final class SystemServer implements Dumpable { "com.android.server.backup.BackupManagerService$Lifecycle"; private static final String APPWIDGET_SERVICE_CLASS = "com.android.server.appwidget.AppWidgetService"; + private static final String ARC_SYSTEM_HEALTH_SERVICE = + "com.android.server.arc.health.ArcSystemHealthService"; private static final String VOICE_RECOGNITION_MANAGER_SERVICE_CLASS = "com.android.server.voiceinteraction.VoiceInteractionManagerService"; private static final String APP_HIBERNATION_SERVICE_CLASS = @@ -1287,6 +1289,12 @@ public final class SystemServer implements Dumpable { } } + if (Build.IS_ARC) { + t.traceBegin("StartArcSystemHealthService"); + mSystemServiceManager.startService(ARC_SYSTEM_HEALTH_SERVICE); + t.traceEnd(); + } + t.traceBegin("StartUserManagerService"); mSystemServiceManager.startService(UserManagerService.LifeCycle.class); t.traceEnd(); diff --git a/services/robotests/backup/Android.bp b/services/robotests/backup/Android.bp index e04dd688f2a2bcfc15fb86adbe05d165417c18a4..8b9efb312efe48c5a4c9b8fc40716f4efc446db7 100644 --- a/services/robotests/backup/Android.bp +++ b/services/robotests/backup/Android.bp @@ -59,7 +59,7 @@ android_robolectric_test { "mockito-robolectric-prebuilt", "platform-test-annotations", "testng", - "truth-prebuilt", + "truth", ], instrumentation_for: "BackupFrameworksServicesLib", diff --git a/services/tests/InputMethodSystemServerTests/Android.bp b/services/tests/InputMethodSystemServerTests/Android.bp index 36446f64bdce92fb2e0b7d7aa04c8a4810152fa2..ffe6dc5d1c63bae131f6687bb266513b9463a356 100644 --- a/services/tests/InputMethodSystemServerTests/Android.bp +++ b/services/tests/InputMethodSystemServerTests/Android.bp @@ -44,7 +44,7 @@ android_test { "service-permission.stubs.system_server", "servicestests-core-utils", "servicestests-utils-mockito-extended", - "truth-prebuilt", + "truth", ], libs: [ @@ -92,7 +92,7 @@ android_test { "service-permission.stubs.system_server", "servicestests-core-utils", "servicestests-utils-mockito-extended", - "truth-prebuilt", + "truth", "SimpleImeTestingLib", "SimpleImeImsLib", ], diff --git a/services/tests/PackageManager/packageinstaller/Android.bp b/services/tests/PackageManager/packageinstaller/Android.bp index 35d754b4adc5952bea0151655178ad2cbae9703f..e8fce8e72601e2e81ecd155fff181989462cb6ad 100644 --- a/services/tests/PackageManager/packageinstaller/Android.bp +++ b/services/tests/PackageManager/packageinstaller/Android.bp @@ -32,7 +32,7 @@ android_test { "androidx.test.runner", "junit", "kotlin-test", - "truth-prebuilt", + "truth", ], platform_apis: true, test_suites: ["device-tests"], diff --git a/services/tests/PackageManagerComponentOverrideTests/Android.bp b/services/tests/PackageManagerComponentOverrideTests/Android.bp index bc369701b2d443ee88d37cdfc8684b0308a5a13a..00850a5e5be0f4600dd611647ef8bd36bb4a1a60 100644 --- a/services/tests/PackageManagerComponentOverrideTests/Android.bp +++ b/services/tests/PackageManagerComponentOverrideTests/Android.bp @@ -38,7 +38,7 @@ android_test { "service-permission.stubs.system_server", "servicestests-utils-mockito-extended", "testng", // TODO: remove once Android migrates to JUnit 4.12, which provides assertThrows - "truth-prebuilt", + "truth", ], jni_libs: [ diff --git a/services/tests/PackageManagerServiceTests/appenumeration/Android.bp b/services/tests/PackageManagerServiceTests/appenumeration/Android.bp index 9c4e6fd66cebce24134c2cf0cc67f3635a6c4cc1..ad7af44d4089a95abc2da45e38add284e9edf0e3 100644 --- a/services/tests/PackageManagerServiceTests/appenumeration/Android.bp +++ b/services/tests/PackageManagerServiceTests/appenumeration/Android.bp @@ -29,7 +29,7 @@ android_test { static_libs: [ "compatibility-device-util-axt", "androidx.test.runner", - "truth-prebuilt", + "truth", "Harrier", ], platform_apis: true, diff --git a/services/tests/PackageManagerServiceTests/host/Android.bp b/services/tests/PackageManagerServiceTests/host/Android.bp index ce28682c0a2555232df5ea6ca095ea50c30d12ac..6eacef767042156486cb599ea050b97114c20e77 100644 --- a/services/tests/PackageManagerServiceTests/host/Android.bp +++ b/services/tests/PackageManagerServiceTests/host/Android.bp @@ -30,7 +30,7 @@ java_test_host { libs: [ "tradefed", "junit", - "truth-prebuilt", + "truth", ], static_libs: [ "ApexInstallHelper", diff --git a/services/tests/PackageManagerServiceTests/host/test-apps/DeviceSide/Android.bp b/services/tests/PackageManagerServiceTests/host/test-apps/DeviceSide/Android.bp index 462c5801e95290fb93a6534cce3384c367400e8c..cea9c599317de703eb3d7de3d479aaeb2b0a82a1 100644 --- a/services/tests/PackageManagerServiceTests/host/test-apps/DeviceSide/Android.bp +++ b/services/tests/PackageManagerServiceTests/host/test-apps/DeviceSide/Android.bp @@ -38,6 +38,6 @@ android_test_helper_app { "junit-params", "androidx.test.ext.junit", "androidx.test.rules", - "truth-prebuilt", + "truth", ], } diff --git a/services/tests/PackageManagerServiceTests/host/test-apps/OverlayActor/Android.bp b/services/tests/PackageManagerServiceTests/host/test-apps/OverlayActor/Android.bp index 57184748d074a3489d2e098ccd873fd6454fc31d..ed5f2b51b9ed3767396952d8e85654cc522a6a9a 100644 --- a/services/tests/PackageManagerServiceTests/host/test-apps/OverlayActor/Android.bp +++ b/services/tests/PackageManagerServiceTests/host/test-apps/OverlayActor/Android.bp @@ -28,6 +28,6 @@ android_test_helper_app { "androidx.test.runner", "junit", "kotlin-test", - "truth-prebuilt", + "truth", ], } diff --git a/services/tests/PackageManagerServiceTests/server/Android.bp b/services/tests/PackageManagerServiceTests/server/Android.bp index a1d846e0f426ada5482589380cbf7524b6c2ce4d..3aca1cafbf751a4e0c38967fbdc939d7815cbede 100644 --- a/services/tests/PackageManagerServiceTests/server/Android.bp +++ b/services/tests/PackageManagerServiceTests/server/Android.bp @@ -41,7 +41,7 @@ android_test { "mockito-target-minus-junit4", "platform-test-annotations", "ShortcutManagerTestUtils", - "truth-prebuilt", + "truth", "testables", "platformprotosnano", "framework-protos", @@ -51,7 +51,7 @@ android_test { "servicestests-utils", "service-permission.impl", "testng", - "truth-prebuilt", + "truth", "junit", "junit-params", "platform-compat-test-rules", diff --git a/services/tests/PackageManagerServiceTests/unit/Android.bp b/services/tests/PackageManagerServiceTests/unit/Android.bp index 9b3b8c35736c5be09759d9524cd0dc47391fd410..8505983894a827c2da616ade28952facd020d306 100644 --- a/services/tests/PackageManagerServiceTests/unit/Android.bp +++ b/services/tests/PackageManagerServiceTests/unit/Android.bp @@ -37,7 +37,7 @@ android_test { "services.core", "servicestests-utils", "servicestests-core-utils", - "truth-prebuilt", + "truth", ], jni_libs: [ "libdexmakerjvmtiagent", diff --git a/services/tests/RemoteProvisioningServiceTests/Android.bp b/services/tests/RemoteProvisioningServiceTests/Android.bp index fc2c0857146bfe0e0e937dc42962b9541f6c7585..19c913620760a110abac4529e41930b9f7ab0c98 100644 --- a/services/tests/RemoteProvisioningServiceTests/Android.bp +++ b/services/tests/RemoteProvisioningServiceTests/Android.bp @@ -30,8 +30,8 @@ android_test { "mockito-target", "service-rkp.impl", "services.core", - "truth-prebuilt", - "truth-java8-extension-jar", + "truth", + "truth-java8-extension", ], test_suites: [ "device-tests", diff --git a/services/tests/apexsystemservices/Android.bp b/services/tests/apexsystemservices/Android.bp index e724e804f4e7e24e29a9d79db45347e417224512..9dacfeabf1ef3b7ad36ccdceef0548caf6d903f4 100644 --- a/services/tests/apexsystemservices/Android.bp +++ b/services/tests/apexsystemservices/Android.bp @@ -34,7 +34,7 @@ java_test_host { "compatibility-host-util", "cts-install-lib-host", "frameworks-base-hostutils", - "truth-prebuilt", + "truth", "modules-utils-build-testing", ], test_suites: [ 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 6ef150c80037ca71719a9bae0d77ec67fbfe4af1..c37d21ae1cc05de3114a19f15cc1bca15482f261 100644 --- a/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceConfigTest.java +++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceConfigTest.java @@ -178,6 +178,89 @@ public final class DisplayDeviceConfigTest { assertEquals(mDisplayDeviceConfig.getHostUsiVersion().getMinorVersion(), 0); } + @Test + public void testPowerThrottlingConfigFromDisplayConfig() throws IOException { + setupDisplayDeviceConfigFromDisplayConfigFile(); + + DisplayDeviceConfig.PowerThrottlingConfigData powerThrottlingConfigData = + mDisplayDeviceConfig.getPowerThrottlingConfigData(); + assertNotNull(powerThrottlingConfigData); + assertEquals(0.1f, powerThrottlingConfigData.brightnessLowestCapAllowed, SMALL_DELTA); + assertEquals(10, powerThrottlingConfigData.pollingWindowMillis); + } + + @Test + public void testPowerThrottlingDataFromDisplayConfig() throws IOException { + setupDisplayDeviceConfigFromDisplayConfigFile(); + + List<DisplayDeviceConfig.PowerThrottlingData.ThrottlingLevel> + defaultThrottlingLevels = new ArrayList<>(); + defaultThrottlingLevels.add( + new DisplayDeviceConfig.PowerThrottlingData.ThrottlingLevel( + DisplayDeviceConfig.convertThermalStatus(ThermalStatus.light), 800f + )); + defaultThrottlingLevels.add( + new DisplayDeviceConfig.PowerThrottlingData.ThrottlingLevel( + DisplayDeviceConfig.convertThermalStatus(ThermalStatus.moderate), 600f + )); + defaultThrottlingLevels.add( + new DisplayDeviceConfig.PowerThrottlingData.ThrottlingLevel( + DisplayDeviceConfig.convertThermalStatus(ThermalStatus.severe), 400f + )); + defaultThrottlingLevels.add( + new DisplayDeviceConfig.PowerThrottlingData.ThrottlingLevel( + DisplayDeviceConfig.convertThermalStatus(ThermalStatus.critical), 200f + )); + defaultThrottlingLevels.add( + new DisplayDeviceConfig.PowerThrottlingData.ThrottlingLevel( + DisplayDeviceConfig.convertThermalStatus(ThermalStatus.emergency), 100f + )); + defaultThrottlingLevels.add( + new DisplayDeviceConfig.PowerThrottlingData.ThrottlingLevel( + DisplayDeviceConfig.convertThermalStatus(ThermalStatus.shutdown), 50f + )); + + DisplayDeviceConfig.PowerThrottlingData defaultThrottlingData = + new DisplayDeviceConfig.PowerThrottlingData(defaultThrottlingLevels); + + List<DisplayDeviceConfig.PowerThrottlingData.ThrottlingLevel> + concurrentThrottlingLevels = new ArrayList<>(); + concurrentThrottlingLevels.add( + new DisplayDeviceConfig.PowerThrottlingData.ThrottlingLevel( + DisplayDeviceConfig.convertThermalStatus(ThermalStatus.light), 800f + )); + concurrentThrottlingLevels.add( + new DisplayDeviceConfig.PowerThrottlingData.ThrottlingLevel( + DisplayDeviceConfig.convertThermalStatus(ThermalStatus.moderate), 600f + )); + concurrentThrottlingLevels.add( + new DisplayDeviceConfig.PowerThrottlingData.ThrottlingLevel( + DisplayDeviceConfig.convertThermalStatus(ThermalStatus.severe), 400f + )); + concurrentThrottlingLevels.add( + new DisplayDeviceConfig.PowerThrottlingData.ThrottlingLevel( + DisplayDeviceConfig.convertThermalStatus(ThermalStatus.critical), 200f + )); + concurrentThrottlingLevels.add( + new DisplayDeviceConfig.PowerThrottlingData.ThrottlingLevel( + DisplayDeviceConfig.convertThermalStatus(ThermalStatus.emergency), 100f + )); + concurrentThrottlingLevels.add( + new DisplayDeviceConfig.PowerThrottlingData.ThrottlingLevel( + DisplayDeviceConfig.convertThermalStatus(ThermalStatus.shutdown), 50f + )); + DisplayDeviceConfig.PowerThrottlingData concurrentThrottlingData = + new DisplayDeviceConfig.PowerThrottlingData(concurrentThrottlingLevels); + + HashMap<String, DisplayDeviceConfig.PowerThrottlingData> throttlingDataMap = + new HashMap<>(2); + throttlingDataMap.put("default", defaultThrottlingData); + throttlingDataMap.put("concurrent", concurrentThrottlingData); + + assertEquals(throttlingDataMap, + mDisplayDeviceConfig.getPowerThrottlingDataMapByThrottlingId()); + } + @Test public void testConfigValuesFromConfigResource() { setupDisplayDeviceConfigFromConfigResourceFile(); @@ -845,6 +928,64 @@ public final class DisplayDeviceConfigTest { + "</screenBrightnessRampSlowIncreaseIdle>\n"; } + private String getPowerThrottlingConfig() { + return "<powerThrottlingConfig >\n" + + "<brightnessLowestCapAllowed>0.1</brightnessLowestCapAllowed>\n" + + "<pollingWindowMillis>10</pollingWindowMillis>\n" + + "<powerThrottlingMap>\n" + + "<powerThrottlingPoint>\n" + + "<thermalStatus>light</thermalStatus>\n" + + "<powerQuotaMilliWatts>800</powerQuotaMilliWatts>\n" + + "</powerThrottlingPoint>\n" + + "<powerThrottlingPoint>\n" + + "<thermalStatus>moderate</thermalStatus>\n" + + "<powerQuotaMilliWatts>600</powerQuotaMilliWatts>\n" + + "</powerThrottlingPoint>\n" + + "<powerThrottlingPoint>\n" + + "<thermalStatus>severe</thermalStatus>\n" + + "<powerQuotaMilliWatts>400</powerQuotaMilliWatts>\n" + + "</powerThrottlingPoint>\n" + + "<powerThrottlingPoint>\n" + + "<thermalStatus>critical</thermalStatus>\n" + + "<powerQuotaMilliWatts>200</powerQuotaMilliWatts>\n" + + "</powerThrottlingPoint>\n" + + "<powerThrottlingPoint>\n" + + "<thermalStatus>emergency</thermalStatus>\n" + + "<powerQuotaMilliWatts>100</powerQuotaMilliWatts>\n" + + "</powerThrottlingPoint>\n" + + "<powerThrottlingPoint>\n" + + "<thermalStatus>shutdown</thermalStatus>\n" + + "<powerQuotaMilliWatts>50</powerQuotaMilliWatts>\n" + + "</powerThrottlingPoint>\n" + + "</powerThrottlingMap>\n" + + "<powerThrottlingMap id=\"concurrent\">\n" + + "<powerThrottlingPoint>\n" + + "<thermalStatus>light</thermalStatus>\n" + + "<powerQuotaMilliWatts>800</powerQuotaMilliWatts>\n" + + "</powerThrottlingPoint>\n" + + "<powerThrottlingPoint>\n" + + "<thermalStatus>moderate</thermalStatus>\n" + + "<powerQuotaMilliWatts>600</powerQuotaMilliWatts>\n" + + "</powerThrottlingPoint>\n" + + "<powerThrottlingPoint>\n" + + "<thermalStatus>severe</thermalStatus>\n" + + "<powerQuotaMilliWatts>400</powerQuotaMilliWatts>\n" + + "</powerThrottlingPoint>\n" + + "<powerThrottlingPoint>\n" + + "<thermalStatus>critical</thermalStatus>\n" + + "<powerQuotaMilliWatts>200</powerQuotaMilliWatts>\n" + + "</powerThrottlingPoint>\n" + + "<powerThrottlingPoint>\n" + + "<thermalStatus>emergency</thermalStatus>\n" + + "<powerQuotaMilliWatts>100</powerQuotaMilliWatts>\n" + + "</powerThrottlingPoint>\n" + + "<powerThrottlingPoint>\n" + + "<thermalStatus>shutdown</thermalStatus>\n" + + "<powerQuotaMilliWatts>50</powerQuotaMilliWatts>\n" + + "</powerThrottlingPoint>\n" + + "</powerThrottlingMap>\n" + + "</powerThrottlingConfig>\n"; + } private String getScreenBrightnessRampCapsIdle() { return "<screenBrightnessRampIncreaseMaxIdleMillis>" + "4000" @@ -915,6 +1056,7 @@ public final class DisplayDeviceConfigTest { + "</displayBrightnessPoint>\n" + "</displayBrightnessMapping>\n" + "</autoBrightness>\n" + + getPowerThrottlingConfig() + "<highBrightnessMode enabled=\"true\">\n" + "<transitionPoint>" + BRIGHTNESS[1] + "</transitionPoint>\n" + "<minimumLux>10000</minimumLux>\n" diff --git a/services/tests/inprocesstests/Android.bp b/services/tests/inprocesstests/Android.bp index 7c237ac6befb95f804734c66be5975478d79a586..086e84b86aca4a7bc52bb684dbabc1b6344d984b 100644 --- a/services/tests/inprocesstests/Android.bp +++ b/services/tests/inprocesstests/Android.bp @@ -14,7 +14,7 @@ android_test { "androidx.test.core", "androidx.test.rules", "services.core", - "truth-prebuilt", + "truth", "platform-test-annotations", ], test_suites: ["general-tests"], diff --git a/services/tests/mockingservicestests/Android.bp b/services/tests/mockingservicestests/Android.bp index 0813bb09fd52ab1f585b52eb9656a4200ded58a2..063af573e1f39562954518916de4db74d54f3ce3 100644 --- a/services/tests/mockingservicestests/Android.bp +++ b/services/tests/mockingservicestests/Android.bp @@ -68,7 +68,7 @@ android_test { "servicestests-core-utils", "servicestests-utils-mockito-extended", "testables", - "truth-prebuilt", + "truth", // TODO: remove once Android migrates to JUnit 4.12, which provides assertThrows "testng", "compatibility-device-util-axt", diff --git a/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java index 5b1508b8393be1e8eff82cb4c40610169d085849..be29163e7677be897877d69389b080735512bf74 100644 --- a/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java @@ -1290,7 +1290,8 @@ public class DeviceIdleControllerTest { } @Test - public void testLightStepIdleStateIdlingTimeIncreases() { + public void testLightStepIdleStateIdlingTimeIncreasesExponentially() { + mConstants.LIGHT_IDLE_INCREASE_LINEARLY = false; final long maintenanceTimeMs = 60_000L; mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET = maintenanceTimeMs; mConstants.LIGHT_IDLE_MAINTENANCE_MAX_BUDGET = maintenanceTimeMs; @@ -1335,13 +1336,88 @@ public class DeviceIdleControllerTest { eq(mInjector.nowElapsed + idlingTimeMs), anyLong(), anyString(), any(), any(Handler.class)); - for (int i = 0; i < 2; ++i) { + for (int i = 0; i < 10; ++i) { // IDLE->MAINTENANCE alarm mInjector.nowElapsed = mDeviceIdleController.getNextLightAlarmTimeForTesting(); alarmListener.onAlarm(); verifyLightStateConditions(LIGHT_STATE_IDLE_MAINTENANCE); long maintenanceExpiryTime = mInjector.nowElapsed + maintenanceTimeMs; idlingTimeMs *= mConstants.LIGHT_IDLE_FACTOR; + idlingTimeMs = Math.min(idlingTimeMs, mConstants.LIGHT_MAX_IDLE_TIMEOUT); + // Set MAINTENANCE->IDLE + alarmManagerInOrder.verify(mAlarmManager).setWindow( + eq(AlarmManager.ELAPSED_REALTIME_WAKEUP), + eq(maintenanceExpiryTime), + anyLong(), anyString(), any(), any(Handler.class)); + + // MAINTENANCE->IDLE alarm + mInjector.nowElapsed = mDeviceIdleController.getNextLightAlarmTimeForTesting(); + alarmListener.onAlarm(); + verifyLightStateConditions(LIGHT_STATE_IDLE); + // Set IDLE->MAINTENANCE again + alarmManagerInOrder.verify(mAlarmManager).setWindow( + eq(AlarmManager.ELAPSED_REALTIME_WAKEUP), + eq(mInjector.nowElapsed + idlingTimeMs), + anyLong(), anyString(), any(), any(Handler.class)); + } + } + + @Test + public void testLightStepIdleStateIdlingTimeIncreasesLinearly() { + mConstants.LIGHT_IDLE_INCREASE_LINEARLY = true; + final long maintenanceTimeMs = 60_000L; + mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET = maintenanceTimeMs; + mConstants.LIGHT_IDLE_MAINTENANCE_MAX_BUDGET = maintenanceTimeMs; + mConstants.LIGHT_IDLE_TIMEOUT = 5 * 60_000L; + mConstants.LIGHT_MAX_IDLE_TIMEOUT = 30 * 60_000L; + mConstants.LIGHT_IDLE_FACTOR = 2f; + mConstants.LIGHT_IDLE_LINEAR_INCREASE_FACTOR_MS = 2 * 60_000L; + + setNetworkConnected(true); + mDeviceIdleController.setJobsActive(false); + mDeviceIdleController.setAlarmsActive(false); + mDeviceIdleController.setActiveIdleOpsForTest(0); + + InOrder alarmManagerInOrder = inOrder(mAlarmManager); + + final ArgumentCaptor<AlarmManager.OnAlarmListener> alarmListenerCaptor = ArgumentCaptor + .forClass(AlarmManager.OnAlarmListener.class); + doNothing().when(mAlarmManager).setWindow(anyInt(), anyLong(), anyLong(), + eq("DeviceIdleController.light"), alarmListenerCaptor.capture(), any()); + + // Set state to INACTIVE. + mDeviceIdleController.becomeActiveLocked("testing", 0); + setChargingOn(false); + setScreenOn(false); + verifyLightStateConditions(LIGHT_STATE_INACTIVE); + long idlingTimeMs = mConstants.LIGHT_IDLE_TIMEOUT; + final long idleAfterInactiveExpiryTime = + mInjector.nowElapsed + mConstants.LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT; + alarmManagerInOrder.verify(mAlarmManager).setWindow( + eq(AlarmManager.ELAPSED_REALTIME_WAKEUP), + eq(idleAfterInactiveExpiryTime), + anyLong(), anyString(), any(), any(Handler.class)); + + final AlarmManager.OnAlarmListener alarmListener = + alarmListenerCaptor.getAllValues().get(0); + + // INACTIVE -> IDLE alarm + mInjector.nowElapsed = mDeviceIdleController.getNextLightAlarmTimeForTesting(); + alarmListener.onAlarm(); + verifyLightStateConditions(LIGHT_STATE_IDLE); + alarmManagerInOrder.verify(mAlarmManager).setWindow( + eq(AlarmManager.ELAPSED_REALTIME_WAKEUP), + eq(mInjector.nowElapsed + idlingTimeMs), + anyLong(), anyString(), any(), any(Handler.class)); + + for (int i = 0; i < 10; ++i) { + // IDLE->MAINTENANCE alarm + mInjector.nowElapsed = mDeviceIdleController.getNextLightAlarmTimeForTesting(); + alarmListener.onAlarm(); + verifyLightStateConditions(LIGHT_STATE_IDLE_MAINTENANCE); + long maintenanceExpiryTime = mInjector.nowElapsed + maintenanceTimeMs; + idlingTimeMs += mConstants.LIGHT_IDLE_LINEAR_INCREASE_FACTOR_MS; + idlingTimeMs = Math.min(idlingTimeMs, mConstants.LIGHT_MAX_IDLE_TIMEOUT); // Set MAINTENANCE->IDLE alarmManagerInOrder.verify(mAlarmManager).setWindow( eq(AlarmManager.ELAPSED_REALTIME_WAKEUP), diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/UserManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/pm/UserManagerServiceTest.java index 6304270f9a7674943fdbeef0b8e199e1c9205c46..305569edd2fa5d32d000703e9d4f1ce49acfa7ee 100644 --- a/services/tests/mockingservicestests/src/com/android/server/pm/UserManagerServiceTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/pm/UserManagerServiceTest.java @@ -308,7 +308,6 @@ public final class UserManagerServiceTest { addDefaultProfileAndParent(); mUms.setBootUser(PROFILE_USER_ID); - // Boot user not switchable so return most recently in foreground. assertWithMessage("getBootUser") .that(mUmi.getBootUser(/* waitUntilSet= */ false)).isEqualTo(OTHER_USER_ID); @@ -523,6 +522,24 @@ public final class UserManagerServiceTest { .isFalse(); } + @Test + public void testCreateUserWithLongName_TruncatesName() { + UserInfo user = mUms.createUserWithThrow(generateLongString(), USER_TYPE_FULL_SECONDARY, 0); + assertThat(user.name.length()).isEqualTo(500); + UserInfo user1 = mUms.createUserWithThrow("Test", USER_TYPE_FULL_SECONDARY, 0); + assertThat(user1.name.length()).isEqualTo(4); + } + + private String generateLongString() { + String partialString = "Test Name Test Name Test Name Test Name Test Name Test Name Test " + + "Name Test Name Test Name Test Name "; //String of length 100 + StringBuilder resultString = new StringBuilder(); + for (int i = 0; i < 660; i++) { + resultString.append(partialString); + } + return resultString.toString(); + } + private void removeNonSystemUsers() { for (UserInfo user : mUms.getUsers(true)) { if (!user.getUserHandle().isSystem()) { diff --git a/services/tests/powerstatstests/Android.bp b/services/tests/powerstatstests/Android.bp index 8ab45070a0172e0b0095d9cb520f2b8298502223..18a4f00689096cd0b3a35872df8a1d740dd291c0 100644 --- a/services/tests/powerstatstests/Android.bp +++ b/services/tests/powerstatstests/Android.bp @@ -16,7 +16,7 @@ android_test { "coretests-aidl", "platformprotosnano", "junit", - "truth-prebuilt", + "truth", "androidx.test.runner", "androidx.test.ext.junit", "androidx.test.ext.truth", diff --git a/services/tests/servicestests/Android.bp b/services/tests/servicestests/Android.bp index 71f7f577d038fda55789f231628eddbb1379c9a7..2ece8c74420c95aa4dba23c4e02522836c05e62e 100644 --- a/services/tests/servicestests/Android.bp +++ b/services/tests/servicestests/Android.bp @@ -61,7 +61,7 @@ android_test { "mockito-target-minus-junit4", "platform-test-annotations", "ShortcutManagerTestUtils", - "truth-prebuilt", + "truth", "testables", "androidx.test.uiautomator_uiautomator", "platformprotosnano", @@ -72,7 +72,7 @@ android_test { // TODO: remove once Android migrates to JUnit 4.12, // which provides assertThrows "testng", - "truth-prebuilt", + "truth", "junit", "junit-params", "ActivityContext", diff --git a/services/tests/servicestests/src/com/android/server/am/AnrTimerTest.java b/services/tests/servicestests/src/com/android/server/am/AnrTimerTest.java index 9fdbdda38c75deaff17418bbc1f7e490fbf987b2..70527ce2ad328141e747f15e16ba373df219f2f8 100644 --- a/services/tests/servicestests/src/com/android/server/am/AnrTimerTest.java +++ b/services/tests/servicestests/src/com/android/server/am/AnrTimerTest.java @@ -228,6 +228,7 @@ public class AnrTimerTest { TestHandler mTestHandler; TestInjector(int skip, boolean immediate) { + super(mHandler); mTracker = new TestTracker(skip); mImmediate = immediate; } @@ -249,9 +250,16 @@ public class AnrTimerTest { return mTestHandler; } + @Override AnrTimer.CpuTracker getTracker() { return mTracker; } + + /** For test purposes, always enable the feature. */ + @Override + boolean getFeatureEnabled() { + return true; + } } // Tests @@ -261,7 +269,6 @@ public class AnrTimerTest { // 4. Start a couple of timers. Verify max active timers. Discard one and verify the active // count drops by 1. Accept one and verify the active count drops by 1. - @Test public void testSimpleTimeout() throws Exception { // Create an immediate TestHandler. diff --git a/services/tests/uiservicestests/Android.bp b/services/tests/uiservicestests/Android.bp index 1d37f9da8d7a633894eddf994f71a87880d52ec9..d1f4961ab7e53f22ca43bcf0b8f9a23bfe1a4667 100644 --- a/services/tests/uiservicestests/Android.bp +++ b/services/tests/uiservicestests/Android.bp @@ -39,7 +39,7 @@ android_test { "hamcrest-library", "servicestests-utils", "testables", - "truth-prebuilt", + "truth", // TODO: remove once Android migrates to JUnit 4.12, // which provides assertThrows "testng", diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationBitmapJobServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationBitmapJobServiceTest.java index 312057ee922d607d83f5a6534151e95d5c65d295..348d1bfd44dfcca53addc641ebcd95d27349e40d 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationBitmapJobServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationBitmapJobServiceTest.java @@ -44,6 +44,12 @@ import org.mockito.Captor; import org.mockito.Mock; import java.lang.reflect.Field; +import java.time.Duration; +import java.time.Instant; +import java.time.LocalDate; +import java.time.LocalTime; +import java.time.ZonedDateTime; +import java.time.ZoneId; @RunWith(AndroidTestingRunner.class) public class NotificationBitmapJobServiceTest extends UiServiceTestCase { @@ -103,17 +109,39 @@ public class NotificationBitmapJobServiceTest extends UiServiceTestCase { @Test public void testGetTimeUntilRemoval_beforeToday2am_returnTimeUntilToday2am() { - final long timeUntilRemoval = mJobService.getTimeUntilRemoval(/* now= */ 1, - /* today2AM= */ 2, /* tomorrow2AM= */ 26); + ZoneId zoneId = ZoneId.systemDefault(); + ZonedDateTime now = Instant.now().atZone(zoneId); + LocalDate today = now.toLocalDate(); - assertThat(timeUntilRemoval).isEqualTo(1); + LocalTime oneAM = LocalTime.of(/* hour= */ 1, /* minute= */ 0); + LocalTime twoAM = LocalTime.of(/* hour= */ 2, /* minute= */ 0); + + ZonedDateTime today1AM = ZonedDateTime.of(today, oneAM, zoneId); + ZonedDateTime today2AM = ZonedDateTime.of(today, twoAM, zoneId); + ZonedDateTime tomorrow2AM = today2AM.plusDays(1); + + final long msUntilRemoval = mJobService.getTimeUntilRemoval( + /* now= */ today1AM, today2AM, tomorrow2AM); + + assertThat(msUntilRemoval).isEqualTo(Duration.ofHours(1).toMillis()); } @Test public void testGetTimeUntilRemoval_afterToday2am_returnTimeUntilTomorrow2am() { - final long timeUntilRemoval = mJobService.getTimeUntilRemoval(/* now= */ 3, - /* today2AM= */ 2, /* tomorrow2AM= */ 26); + ZoneId zoneId = ZoneId.systemDefault(); + ZonedDateTime now = Instant.now().atZone(zoneId); + LocalDate today = now.toLocalDate(); + + LocalTime threeAM = LocalTime.of(/* hour= */ 3, /* minute= */ 0); + LocalTime twoAM = LocalTime.of(/* hour= */ 2, /* minute= */ 0); + + ZonedDateTime today3AM = ZonedDateTime.of(today, threeAM, zoneId); + ZonedDateTime today2AM = ZonedDateTime.of(today, twoAM, zoneId); + ZonedDateTime tomorrow2AM = today2AM.plusDays(1); + + final long msUntilRemoval = mJobService.getTimeUntilRemoval(/* now= */ today3AM, + today2AM, tomorrow2AM); - assertThat(timeUntilRemoval).isEqualTo(23); + assertThat(msUntilRemoval).isEqualTo(Duration.ofHours(23).toMillis()); } } \ No newline at end of file diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationHistoryJobServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationHistoryJobServiceTest.java index d758e71c62a208c4073666fa32c9f464667b5654..3499a12f5954322140076abb6f414457e1165183 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationHistoryJobServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationHistoryJobServiceTest.java @@ -71,10 +71,10 @@ public class NotificationHistoryJobServiceTest extends UiServiceTestCase { @Before public void setUp() throws Exception { mJobService = new NotificationHistoryJobService(); + mJobService.attachBaseContext(mContext); + mJobService.onCreate(); + mJobService.onBind(/* intent= */ null); // Create JobServiceEngine within JobService. - final Field field = JobService.class.getDeclaredField("mEngine"); - field.setAccessible(true); - field.set(mJobService, mock(JobServiceEngine.class)); mContext.addMockSystemService(JobScheduler.class, mMockJobScheduler); // add NotificationManagerInternal to LocalServices diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java index c98d2359b2f935185ba4c4b2552a5d7d9b52cd02..91129a14ecab32dd0760f796807008f3436ebfeb 100755 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java @@ -91,7 +91,7 @@ import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STR import static com.android.server.am.PendingIntentRecord.FLAG_ACTIVITY_SENDER; import static com.android.server.am.PendingIntentRecord.FLAG_BROADCAST_SENDER; import static com.android.server.am.PendingIntentRecord.FLAG_SERVICE_SENDER; -import static com.android.server.notification.NotificationManagerService.BITMAP_EXPIRATION_TIME_MS; +import static com.android.server.notification.NotificationManagerService.BITMAP_DURATION; import static com.android.server.notification.NotificationManagerService.DEFAULT_MAX_NOTIFICATION_ENQUEUE_RATE; import static com.android.server.notification.NotificationRecordLogger.NotificationReportedEvent.NOTIFICATION_ADJUSTED; import static com.android.server.notification.NotificationRecordLogger.NotificationReportedEvent.NOTIFICATION_POSTED; @@ -11381,7 +11381,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { long timePostedMs = System.currentTimeMillis(); if (isExpired) { - timePostedMs -= BITMAP_EXPIRATION_TIME_MS; + timePostedMs -= BITMAP_DURATION.toMillis(); } StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 8, "tag", mUid, 0, notification, UserHandle.getUserHandleForUid(mUid), null, timePostedMs); diff --git a/services/tests/voiceinteractiontests/Android.bp b/services/tests/voiceinteractiontests/Android.bp index e704ebf32270feb7bff5dbce96fb18f64b322bda..744cb63f72b3d924f6b4c823599c7210d178e2ec 100644 --- a/services/tests/voiceinteractiontests/Android.bp +++ b/services/tests/voiceinteractiontests/Android.bp @@ -43,7 +43,7 @@ android_test { "services.soundtrigger", "servicestests-core-utils", "servicestests-utils-mockito-extended", - "truth-prebuilt", + "truth", ], libs: [ diff --git a/services/tests/wmtests/Android.bp b/services/tests/wmtests/Android.bp index c2812a14a3eb3c5cf434edf4afd908567b259bcb..af39b2f027eecdfd2de9bff6df1c5262ced56643 100644 --- a/services/tests/wmtests/Android.bp +++ b/services/tests/wmtests/Android.bp @@ -57,12 +57,14 @@ android_test { "platform-test-annotations", "servicestests-utils", "testng", - "truth-prebuilt", + "truth", "testables", "hamcrest-library", "platform-compat-test-rules", "CtsSurfaceValidatorLib", "service-sdksandbox.impl", + "com.android.window.flags.window-aconfig-java", + "flag-junit", ], libs: [ diff --git a/services/tests/wmtests/AndroidManifest.xml b/services/tests/wmtests/AndroidManifest.xml index 42e3383987d61a775371da0afe0cbf121ddc8cd8..762e23c8e2883e9c98a64aaea3c6a02274568cd9 100644 --- a/services/tests/wmtests/AndroidManifest.xml +++ b/services/tests/wmtests/AndroidManifest.xml @@ -47,6 +47,8 @@ <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.MANAGE_MEDIA_PROJECTION"/> + <uses-permission android:name="android.permission.INTERNAL_SYSTEM_WINDOW"/> + <uses-permission android:name="android.permission.MONITOR_INPUT"/> <!-- TODO: Remove largeHeap hack when memory leak is fixed (b/123984854) --> <application android:debuggable="true" @@ -104,6 +106,11 @@ android:showWhenLocked="true" android:turnScreenOn="true" /> + <activity android:name="android.app.Activity" + android:exported="true" + android:showWhenLocked="true" + android:turnScreenOn="true" /> + <activity android:name="androidx.test.core.app.InstrumentationActivityInvoker$EmptyActivity" android:exported="true"> diff --git a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java index 3bc6450ae5910eaf2e13d76e845c2dfc16afd63f..c241033c69d3accf018fe750e45ba71b8db951ee 100644 --- a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java @@ -549,10 +549,12 @@ public class RootWindowContainerTests extends WindowTestsBase { // Let's pretend that the app has crashed. firstActivity.app.setThread(null); - mRootWindowContainer.finishTopCrashedActivities(firstActivity.app, "test"); + final Task finishedTask = mRootWindowContainer.finishTopCrashedActivities( + firstActivity.app, "test"); // Verify that the root task was removed. assertEquals(originalRootTaskCount, defaultTaskDisplayArea.getRootTaskCount()); + assertEquals(rootTask, finishedTask); } /** diff --git a/services/tests/wmtests/src/com/android/server/wm/TrustedOverlayTests.java b/services/tests/wmtests/src/com/android/server/wm/TrustedOverlayTests.java new file mode 100644 index 0000000000000000000000000000000000000000..ac498397eb390b2b81f33619ed3a784b01e5c7ea --- /dev/null +++ b/services/tests/wmtests/src/com/android/server/wm/TrustedOverlayTests.java @@ -0,0 +1,217 @@ +/* + * Copyright 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.wm; + +import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY; +import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_PANEL; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import android.app.Activity; +import android.app.Instrumentation; +import android.os.IBinder; +import android.platform.test.annotations.Presubmit; +import android.platform.test.annotations.RequiresFlagsDisabled; +import android.platform.test.annotations.RequiresFlagsEnabled; +import android.platform.test.flag.junit.CheckFlagsRule; +import android.platform.test.flag.junit.DeviceFlagsValueProvider; +import android.server.wm.BuildUtils; +import android.server.wm.CtsWindowInfoUtils; +import android.view.View; +import android.view.ViewTreeObserver; +import android.view.WindowManager; + +import androidx.test.ext.junit.rules.ActivityScenarioRule; +import androidx.test.platform.app.InstrumentationRegistry; + +import com.android.window.flags.Flags; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestName; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +@Presubmit +public class TrustedOverlayTests { + private static final String TAG = "TrustedOverlayTests"; + private static final long TIMEOUT_S = 5L * BuildUtils.HW_TIMEOUT_MULTIPLIER; + + @Rule + public final CheckFlagsRule mCheckFlagsRule = + DeviceFlagsValueProvider.createCheckFlagsRule(); + + @Rule + public TestName mName = new TestName(); + + @Rule + public final ActivityScenarioRule<Activity> mActivityRule = new ActivityScenarioRule<>( + Activity.class); + + private Instrumentation mInstrumentation; + private Activity mActivity; + + @Before + public void setup() { + mInstrumentation = InstrumentationRegistry.getInstrumentation(); + mActivityRule.getScenario().onActivity(activity -> { + mActivity = activity; + }); + } + + @RequiresFlagsDisabled(Flags.FLAG_SURFACE_TRUSTED_OVERLAY) + @Test + public void setTrustedOverlayInputWindow() throws InterruptedException { + testTrustedOverlayChildHelper(false); + } + + @Test + @RequiresFlagsEnabled(Flags.FLAG_SURFACE_TRUSTED_OVERLAY) + public void setTrustedOverlayChildLayer() throws InterruptedException { + testTrustedOverlayChildHelper(true); + } + + /** + * b/300659960 where setting spy window and trusted overlay were not happening in the same + * transaction causing the system to crash. This ensures there are no synchronization issues + * setting both spy window and trusted overlay. + */ + @Test + public void setSpyWindowDoesntCrash() throws InterruptedException { + IBinder[] tokens = new IBinder[1]; + CountDownLatch hostTokenReady = new CountDownLatch(1); + mInstrumentation.runOnMainSync(() -> { + WindowManager.LayoutParams params = mActivity.getWindow().getAttributes(); + params.inputFeatures |= WindowManager.LayoutParams.INPUT_FEATURE_SPY; + params.privateFlags |= PRIVATE_FLAG_TRUSTED_OVERLAY; + mActivity.getWindow().setAttributes(params); + + View rootView = mActivity.getWindow().getDecorView(); + if (rootView.isAttachedToWindow()) { + tokens[0] = rootView.getWindowToken(); + hostTokenReady.countDown(); + } else { + rootView.getViewTreeObserver().addOnWindowAttachListener( + new ViewTreeObserver.OnWindowAttachListener() { + @Override + public void onWindowAttached() { + tokens[0] = rootView.getWindowToken(); + hostTokenReady.countDown(); + } + + @Override + public void onWindowDetached() { + } + }); + } + }); + + assertTrue("Failed to wait for host to get added", + hostTokenReady.await(TIMEOUT_S, TimeUnit.SECONDS)); + + boolean[] foundTrusted = new boolean[1]; + CtsWindowInfoUtils.waitForWindowInfos( + windowInfos -> { + for (var windowInfo : windowInfos) { + if (windowInfo.windowToken == tokens[0] && windowInfo.isTrustedOverlay) { + foundTrusted[0] = true; + return true; + } + } + return false; + }, TIMEOUT_S, TimeUnit.SECONDS); + + if (!foundTrusted[0]) { + CtsWindowInfoUtils.dumpWindowsOnScreen(TAG, mName.getMethodName()); + } + + assertTrue("Failed to find window or was not marked trusted", foundTrusted[0]); + } + + private void testTrustedOverlayChildHelper(boolean expectedTrustedChild) + throws InterruptedException { + IBinder[] tokens = new IBinder[2]; + CountDownLatch hostTokenReady = new CountDownLatch(1); + mInstrumentation.runOnMainSync(() -> { + mActivity.getWindow().addPrivateFlags(PRIVATE_FLAG_TRUSTED_OVERLAY); + View rootView = mActivity.getWindow().getDecorView(); + if (rootView.isAttachedToWindow()) { + tokens[0] = rootView.getWindowToken(); + hostTokenReady.countDown(); + } else { + rootView.getViewTreeObserver().addOnWindowAttachListener( + new ViewTreeObserver.OnWindowAttachListener() { + @Override + public void onWindowAttached() { + tokens[0] = rootView.getWindowToken(); + hostTokenReady.countDown(); + } + + @Override + public void onWindowDetached() { + } + }); + } + }); + + assertTrue("Failed to wait for host to get added", + hostTokenReady.await(TIMEOUT_S, TimeUnit.SECONDS)); + + mInstrumentation.runOnMainSync(() -> { + WindowManager wm = mActivity.getSystemService(WindowManager.class); + + View childView = new View(mActivity) { + @Override + protected void onAttachedToWindow() { + super.onAttachedToWindow(); + tokens[1] = getWindowToken(); + } + }; + WindowManager.LayoutParams params = new WindowManager.LayoutParams(); + params.token = tokens[0]; + params.type = TYPE_APPLICATION_PANEL; + wm.addView(childView, params); + }); + + boolean[] foundTrusted = new boolean[2]; + + CtsWindowInfoUtils.waitForWindowInfos( + windowInfos -> { + for (var windowInfo : windowInfos) { + if (windowInfo.windowToken == tokens[0] + && windowInfo.isTrustedOverlay) { + foundTrusted[0] = true; + } else if (windowInfo.windowToken == tokens[1] + && windowInfo.isTrustedOverlay) { + foundTrusted[1] = true; + } + } + return foundTrusted[0] && foundTrusted[1]; + }, TIMEOUT_S, TimeUnit.SECONDS); + + if (!foundTrusted[0] || !foundTrusted[1]) { + CtsWindowInfoUtils.dumpWindowsOnScreen(TAG, mName.getMethodName()); + } + + assertTrue("Failed to find parent window or was not marked trusted", foundTrusted[0]); + assertEquals("Failed to find child window or was not marked trusted", expectedTrustedChild, + foundTrusted[1]); + } +} diff --git a/services/usage/java/com/android/server/usage/UsageStatsHandlerThread.java b/services/usage/java/com/android/server/usage/UsageStatsHandlerThread.java deleted file mode 100644 index 6801c940253890583a0c5d74242540ebd86972c2..0000000000000000000000000000000000000000 --- a/services/usage/java/com/android/server/usage/UsageStatsHandlerThread.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (C) 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.usage; - -import android.os.Handler; -import android.os.HandlerExecutor; -import android.os.HandlerThread; -import android.os.Looper; -import android.os.Process; -import android.os.Trace; - -import java.util.concurrent.Executor; - -/** - * Shared singleton default priority thread for usage stats message handling. - * - * @see com.android.internal.os.BackgroundThread - */ -public final class UsageStatsHandlerThread extends HandlerThread { - private static final long SLOW_DISPATCH_THRESHOLD_MS = 10_000; - private static final long SLOW_DELIVERY_THRESHOLD_MS = 30_000; - private static UsageStatsHandlerThread sInstance; - private static Handler sHandler; - private static Executor sHandlerExecutor; - - private UsageStatsHandlerThread() { - super("usagestats.default", Process.THREAD_PRIORITY_DEFAULT); - } - - private static void ensureThreadLocked() { - if (sInstance == null) { - sInstance = new UsageStatsHandlerThread(); - sInstance.start(); - final Looper looper = sInstance.getLooper(); - looper.setTraceTag(Trace.TRACE_TAG_SYSTEM_SERVER); - looper.setSlowLogThresholdMs( - SLOW_DISPATCH_THRESHOLD_MS, SLOW_DELIVERY_THRESHOLD_MS); - sHandler = new Handler(sInstance.getLooper()); - sHandlerExecutor = new HandlerExecutor(sHandler); - } - } - - /** Returns the UsageStatsHandlerThread singleton */ - public static UsageStatsHandlerThread get() { - synchronized (UsageStatsHandlerThread.class) { - ensureThreadLocked(); - return sInstance; - } - } - - /** Returns the singleton handler for UsageStatsHandlerThread */ - public static Handler getHandler() { - synchronized (UsageStatsHandlerThread.class) { - ensureThreadLocked(); - return sHandler; - } - } - - /** Returns the singleton handler executor for UsageStatsHandlerThread */ - public static Executor getExecutor() { - synchronized (UsageStatsHandlerThread.class) { - ensureThreadLocked(); - return sHandlerExecutor; - } - } -} diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java index 9956faaa2eb16dba34b2a6d09b34bc268c91488f..6cebe0af7a3587e13cd4d10266a8eb69bd100423 100644 --- a/services/usage/java/com/android/server/usage/UsageStatsService.java +++ b/services/usage/java/com/android/server/usage/UsageStatsService.java @@ -106,7 +106,6 @@ import com.android.internal.util.CollectionUtils; import com.android.internal.util.DumpUtils; import com.android.internal.util.FrameworkStatsLog; import com.android.internal.util.IndentingPrintWriter; -import com.android.server.IoThread; import com.android.server.LocalServices; import com.android.server.SystemService; import com.android.server.usage.AppStandbyInternal.AppIdleStateChangeListener; @@ -202,8 +201,7 @@ public class UsageStatsService extends SystemService implements static final int MSG_NOTIFY_ESTIMATED_LAUNCH_TIMES_CHANGED = 9; private final Object mLock = new Object(); - private Handler mHandler; - private Handler mIoHandler; + Handler mHandler; AppOpsManager mAppOps; UserManager mUserManager; PackageManager mPackageManager; @@ -235,7 +233,7 @@ public class UsageStatsService extends SystemService implements private final SparseArray<LinkedList<Event>> mReportedEvents = new SparseArray<>(); final SparseArray<ArraySet<String>> mUsageReporters = new SparseArray(); final SparseArray<ActivityData> mVisibleActivities = new SparseArray(); - @GuardedBy("mLaunchTimeAlarmQueues") // Don't hold the main lock + @GuardedBy("mLock") private final SparseArray<LaunchTimeAlarmQueue> mLaunchTimeAlarmQueues = new SparseArray<>(); @GuardedBy("mUsageEventListeners") // Don't hold the main lock when calling out private final ArraySet<UsageStatsManagerInternal.UsageEventListener> mUsageEventListeners = @@ -281,38 +279,6 @@ public class UsageStatsService extends SystemService implements } } - private final Handler.Callback mIoHandlerCallback = (msg) -> { - switch (msg.what) { - case MSG_UID_STATE_CHANGED: { - final int uid = msg.arg1; - final int procState = msg.arg2; - - final int newCounter = (procState <= ActivityManager.PROCESS_STATE_TOP) ? 0 : 1; - synchronized (mUidToKernelCounter) { - final int oldCounter = mUidToKernelCounter.get(uid, 0); - if (newCounter != oldCounter) { - mUidToKernelCounter.put(uid, newCounter); - try { - FileUtils.stringToFile(KERNEL_COUNTER_FILE, uid + " " + newCounter); - } catch (IOException e) { - Slog.w(TAG, "Failed to update counter set: " + e); - } - } - } - return true; - } - case MSG_HANDLE_LAUNCH_TIME_ON_USER_UNLOCK: { - final int userId = msg.arg1; - Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, - "usageStatsHandleEstimatedLaunchTimesOnUser(" + userId + ")"); - handleEstimatedLaunchTimesOnUserUnlock(userId); - Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); - return true; - } - } - return false; - }; - private final Injector mInjector; public UsageStatsService(Context context) { @@ -332,9 +298,7 @@ public class UsageStatsService extends SystemService implements mUserManager = (UserManager) getContext().getSystemService(Context.USER_SERVICE); mPackageManager = getContext().getPackageManager(); mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class); - - mHandler = new H(UsageStatsHandlerThread.get().getLooper()); - mIoHandler = new Handler(IoThread.get().getLooper(), mIoHandlerCallback); + mHandler = new H(BackgroundThread.get().getLooper()); mAppStandby = mInjector.getAppStandbyController(getContext()); mResponseStatsTracker = new BroadcastResponseStatsTracker(mAppStandby, getContext()); @@ -460,9 +424,6 @@ public class UsageStatsService extends SystemService implements } mUserUnlockedStates.remove(userId); mUserState.put(userId, null); // release the service (mainly for GC) - } - - synchronized (mLaunchTimeAlarmQueues) { LaunchTimeAlarmQueue alarmQueue = mLaunchTimeAlarmQueues.get(userId); if (alarmQueue != null) { alarmQueue.removeAllAlarms(); @@ -518,12 +479,10 @@ public class UsageStatsService extends SystemService implements } reportEvent(unlockEvent, userId); - mIoHandler.obtainMessage(MSG_HANDLE_LAUNCH_TIME_ON_USER_UNLOCK, - userId, 0).sendToTarget(); + mHandler.obtainMessage(MSG_HANDLE_LAUNCH_TIME_ON_USER_UNLOCK, userId, 0).sendToTarget(); // Remove all the stats stored in system DE. deleteRecursively(new File(Environment.getDataSystemDeDirectory(userId), "usagestats")); - // Force a flush to disk for the current user to ensure important events are persisted. // Note: there is a very very small chance that the system crashes between deleting // the stats above from DE and persisting them to CE here in which case we will lose @@ -642,7 +601,7 @@ public class UsageStatsService extends SystemService implements private final IUidObserver mUidObserver = new UidObserver() { @Override public void onUidStateChanged(int uid, int procState, long procStateSeq, int capability) { - mIoHandler.obtainMessage(MSG_UID_STATE_CHANGED, uid, procState).sendToTarget(); + mHandler.obtainMessage(MSG_UID_STATE_CHANGED, uid, procState).sendToTarget(); } @Override @@ -714,18 +673,16 @@ public class UsageStatsService extends SystemService implements callingPid, callingUid) == PackageManager.PERMISSION_GRANTED); } - private static void deleteRecursively(final File path) { - if (path.isDirectory()) { - final File[] files = path.listFiles(); - if (files != null) { - for (File subFile : files) { - deleteRecursively(subFile); - } + private static void deleteRecursively(File f) { + File[] files = f.listFiles(); + if (files != null) { + for (File subFile : files) { + deleteRecursively(subFile); } } - if (path.exists() && !path.delete()) { - Slog.e(TAG, "Failed to delete " + path); + if (f.exists() && !f.delete()) { + Slog.e(TAG, "Failed to delete " + f); } } @@ -1287,9 +1244,6 @@ public class UsageStatsService extends SystemService implements Slog.i(TAG, "Removing user " + userId + " and all data."); mUserState.remove(userId); mAppTimeLimit.onUserRemoved(userId); - } - - synchronized (mLaunchTimeAlarmQueues) { final LaunchTimeAlarmQueue alarmQueue = mLaunchTimeAlarmQueues.get(userId); if (alarmQueue != null) { alarmQueue.removeAllAlarms(); @@ -1320,13 +1274,6 @@ public class UsageStatsService extends SystemService implements } } - synchronized (mLaunchTimeAlarmQueues) { - final LaunchTimeAlarmQueue alarmQueue = mLaunchTimeAlarmQueues.get(userId); - if (alarmQueue != null) { - alarmQueue.removeAlarmForKey(packageName); - } - } - final int tokenRemoved; synchronized (mLock) { final long timeRemoved = System.currentTimeMillis(); @@ -1335,7 +1282,10 @@ public class UsageStatsService extends SystemService implements // when the user service is initialized and package manager is queried. return; } - + final LaunchTimeAlarmQueue alarmQueue = mLaunchTimeAlarmQueues.get(userId); + if (alarmQueue != null) { + alarmQueue.removeAlarmForKey(packageName); + } final UserUsageStatsService userService = mUserState.get(userId); if (userService == null) { return; @@ -1545,63 +1495,60 @@ public class UsageStatsService extends SystemService implements estimatedLaunchTime = calculateEstimatedPackageLaunchTime(userId, packageName); mAppStandby.setEstimatedLaunchTime(packageName, userId, estimatedLaunchTime); - getOrCreateLaunchTimeAlarmQueue(userId).addAlarm(packageName, - SystemClock.elapsedRealtime() + (estimatedLaunchTime - now)); - } - return estimatedLaunchTime; - } - - private LaunchTimeAlarmQueue getOrCreateLaunchTimeAlarmQueue(int userId) { - synchronized (mLaunchTimeAlarmQueues) { - LaunchTimeAlarmQueue alarmQueue = mLaunchTimeAlarmQueues.get(userId); - if (alarmQueue == null) { - alarmQueue = new LaunchTimeAlarmQueue( - userId, getContext(), BackgroundThread.get().getLooper()); - mLaunchTimeAlarmQueues.put(userId, alarmQueue); + synchronized (mLock) { + LaunchTimeAlarmQueue alarmQueue = mLaunchTimeAlarmQueues.get(userId); + if (alarmQueue == null) { + alarmQueue = new LaunchTimeAlarmQueue( + userId, getContext(), BackgroundThread.get().getLooper()); + mLaunchTimeAlarmQueues.put(userId, alarmQueue); + } + alarmQueue.addAlarm(packageName, + SystemClock.elapsedRealtime() + (estimatedLaunchTime - now)); } - - return alarmQueue; } + return estimatedLaunchTime; } @CurrentTimeMillisLong private long calculateEstimatedPackageLaunchTime(int userId, String packageName) { - final long endTime = System.currentTimeMillis(); - final long beginTime = endTime - ONE_WEEK; - final long unknownTime = endTime + UNKNOWN_LAUNCH_TIME_DELAY_MS; - final UsageEvents events = queryEarliestEventsForPackage( - userId, beginTime, endTime, packageName, Event.ACTIVITY_RESUMED); - if (events == null) { - if (DEBUG) { - Slog.d(TAG, "No events for " + userId + ":" + packageName); - } - return unknownTime; - } - final UsageEvents.Event event = new UsageEvents.Event(); - final boolean hasMoreThan24HoursOfHistory; - if (events.getNextEvent(event)) { - hasMoreThan24HoursOfHistory = endTime - event.getTimeStamp() > ONE_DAY; - if (DEBUG) { - Slog.d(TAG, userId + ":" + packageName + " history > 24 hours=" - + hasMoreThan24HoursOfHistory); - } - } else { - if (DEBUG) { - Slog.d(TAG, userId + ":" + packageName + " has no events"); + synchronized (mLock) { + final long endTime = System.currentTimeMillis(); + final long beginTime = endTime - ONE_WEEK; + final long unknownTime = endTime + UNKNOWN_LAUNCH_TIME_DELAY_MS; + final UsageEvents events = queryEarliestEventsForPackage( + userId, beginTime, endTime, packageName, Event.ACTIVITY_RESUMED); + if (events == null) { + if (DEBUG) { + Slog.d(TAG, "No events for " + userId + ":" + packageName); + } + return unknownTime; } + final UsageEvents.Event event = new UsageEvents.Event(); + final boolean hasMoreThan24HoursOfHistory; + if (events.getNextEvent(event)) { + hasMoreThan24HoursOfHistory = endTime - event.getTimeStamp() > ONE_DAY; + if (DEBUG) { + Slog.d(TAG, userId + ":" + packageName + " history > 24 hours=" + + hasMoreThan24HoursOfHistory); + } + } else { + if (DEBUG) { + Slog.d(TAG, userId + ":" + packageName + " has no events"); + } + return unknownTime; + } + do { + if (event.getEventType() == Event.ACTIVITY_RESUMED) { + final long timestamp = event.getTimeStamp(); + final long nextLaunch = + calculateNextLaunchTime(hasMoreThan24HoursOfHistory, timestamp); + if (nextLaunch > endTime) { + return nextLaunch; + } + } + } while (events.getNextEvent(event)); return unknownTime; } - do { - if (event.getEventType() == Event.ACTIVITY_RESUMED) { - final long timestamp = event.getTimeStamp(); - final long nextLaunch = - calculateNextLaunchTime(hasMoreThan24HoursOfHistory, timestamp); - if (nextLaunch > endTime) { - return nextLaunch; - } - } - } while (events.getNextEvent(event)); - return unknownTime; } @CurrentTimeMillisLong @@ -1622,54 +1569,61 @@ public class UsageStatsService extends SystemService implements } private void handleEstimatedLaunchTimesOnUserUnlock(int userId) { - final long nowElapsed = SystemClock.elapsedRealtime(); - final long now = System.currentTimeMillis(); - final long beginTime = now - ONE_WEEK; - final UsageEvents events = queryEarliestAppEvents( - userId, beginTime, now, Event.ACTIVITY_RESUMED); - if (events == null) { - return; - } - final ArrayMap<String, Boolean> hasMoreThan24HoursOfHistory = new ArrayMap<>(); - final UsageEvents.Event event = new UsageEvents.Event(); - boolean changedTimes = false; - final LaunchTimeAlarmQueue alarmQueue = getOrCreateLaunchTimeAlarmQueue(userId); - for (boolean unprocessedEvent = events.getNextEvent(event); unprocessedEvent; - unprocessedEvent = events.getNextEvent(event)) { - final String packageName = event.getPackageName(); - if (!hasMoreThan24HoursOfHistory.containsKey(packageName)) { - boolean hasHistory = now - event.getTimeStamp() > ONE_DAY; - if (DEBUG) { - Slog.d(TAG, - userId + ":" + packageName + " history > 24 hours=" + hasHistory); - } - hasMoreThan24HoursOfHistory.put(packageName, hasHistory); - } - if (event.getEventType() == Event.ACTIVITY_RESUMED) { - long estimatedLaunchTime = - mAppStandby.getEstimatedLaunchTime(packageName, userId); - if (estimatedLaunchTime < now || estimatedLaunchTime == Long.MAX_VALUE) { - //noinspection ConstantConditions - estimatedLaunchTime = calculateNextLaunchTime( - hasMoreThan24HoursOfHistory.get(packageName), event.getTimeStamp()); - mAppStandby.setEstimatedLaunchTime( - packageName, userId, estimatedLaunchTime); - } - if (estimatedLaunchTime < now + ONE_WEEK) { - // Before a user is unlocked, we don't know when the app will be launched, - // so we give callers the UNKNOWN time. Now that we have a better estimate, - // we should notify them of the change. + synchronized (mLock) { + final long nowElapsed = SystemClock.elapsedRealtime(); + final long now = System.currentTimeMillis(); + final long beginTime = now - ONE_WEEK; + final UsageEvents events = queryEarliestAppEvents( + userId, beginTime, now, Event.ACTIVITY_RESUMED); + if (events == null) { + return; + } + final ArrayMap<String, Boolean> hasMoreThan24HoursOfHistory = new ArrayMap<>(); + final UsageEvents.Event event = new UsageEvents.Event(); + LaunchTimeAlarmQueue alarmQueue = mLaunchTimeAlarmQueues.get(userId); + if (alarmQueue == null) { + alarmQueue = new LaunchTimeAlarmQueue( + userId, getContext(), BackgroundThread.get().getLooper()); + mLaunchTimeAlarmQueues.put(userId, alarmQueue); + } + boolean changedTimes = false; + for (boolean unprocessedEvent = events.getNextEvent(event); unprocessedEvent; + unprocessedEvent = events.getNextEvent(event)) { + final String packageName = event.getPackageName(); + if (!hasMoreThan24HoursOfHistory.containsKey(packageName)) { + boolean hasHistory = now - event.getTimeStamp() > ONE_DAY; if (DEBUG) { - Slog.d(TAG, "User " + userId + " unlock resulting in" - + " estimated launch time change for " + packageName); + Slog.d(TAG, + userId + ":" + packageName + " history > 24 hours=" + hasHistory); } - changedTimes |= stageChangedEstimatedLaunchTime(userId, packageName); + hasMoreThan24HoursOfHistory.put(packageName, hasHistory); + } + if (event.getEventType() == Event.ACTIVITY_RESUMED) { + long estimatedLaunchTime = + mAppStandby.getEstimatedLaunchTime(packageName, userId); + if (estimatedLaunchTime < now || estimatedLaunchTime == Long.MAX_VALUE) { + //noinspection ConstantConditions + estimatedLaunchTime = calculateNextLaunchTime( + hasMoreThan24HoursOfHistory.get(packageName), event.getTimeStamp()); + mAppStandby.setEstimatedLaunchTime( + packageName, userId, estimatedLaunchTime); + } + if (estimatedLaunchTime < now + ONE_WEEK) { + // Before a user is unlocked, we don't know when the app will be launched, + // so we give callers the UNKNOWN time. Now that we have a better estimate, + // we should notify them of the change. + if (DEBUG) { + Slog.d(TAG, "User " + userId + " unlock resulting in" + + " estimated launch time change for " + packageName); + } + changedTimes |= stageChangedEstimatedLaunchTime(userId, packageName); + } + alarmQueue.addAlarm(packageName, nowElapsed + (estimatedLaunchTime - now)); } - alarmQueue.addAlarm(packageName, nowElapsed + (estimatedLaunchTime - now)); } - } - if (changedTimes) { - mHandler.sendEmptyMessage(MSG_NOTIFY_ESTIMATED_LAUNCH_TIMES_CHANGED); + if (changedTimes) { + mHandler.sendEmptyMessage(MSG_NOTIFY_ESTIMATED_LAUNCH_TIMES_CHANGED); + } } } @@ -2041,11 +1995,37 @@ public class UsageStatsService extends SystemService implements case MSG_PACKAGE_REMOVED: onPackageRemoved(msg.arg1, (String) msg.obj); break; + case MSG_UID_STATE_CHANGED: { + final int uid = msg.arg1; + final int procState = msg.arg2; + + final int newCounter = (procState <= ActivityManager.PROCESS_STATE_TOP) ? 0 : 1; + synchronized (mUidToKernelCounter) { + final int oldCounter = mUidToKernelCounter.get(uid, 0); + if (newCounter != oldCounter) { + mUidToKernelCounter.put(uid, newCounter); + try { + FileUtils.stringToFile(KERNEL_COUNTER_FILE, uid + " " + newCounter); + } catch (IOException e) { + Slog.w(TAG, "Failed to update counter set: " + e); + } + } + } + break; + } case MSG_ON_START: synchronized (mLock) { loadGlobalComponentUsageLocked(); } break; + case MSG_HANDLE_LAUNCH_TIME_ON_USER_UNLOCK: { + final int userId = msg.arg1; + Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, + "usageStatsHandleEstimatedLaunchTimesOnUser(" + userId + ")"); + handleEstimatedLaunchTimesOnUserUnlock(userId); + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); + } + break; case MSG_NOTIFY_ESTIMATED_LAUNCH_TIMES_CHANGED: { removeMessages(MSG_NOTIFY_ESTIMATED_LAUNCH_TIMES_CHANGED); diff --git a/tests/BatteryStatsPerfTest/Android.bp b/tests/BatteryStatsPerfTest/Android.bp index 5233a5b8654e94afe5cc859a2f857202289ea5f8..c2a70151fa13dc44ceebaf09402c306968e9c19d 100644 --- a/tests/BatteryStatsPerfTest/Android.bp +++ b/tests/BatteryStatsPerfTest/Android.bp @@ -27,7 +27,7 @@ android_test { static_libs: [ "androidx.test.rules", "apct-perftests-utils", - "truth-prebuilt", + "truth", ], platform_apis: true, certificate: "platform", diff --git a/tests/BinaryTransparencyHostTest/Android.bp b/tests/BinaryTransparencyHostTest/Android.bp index 615990f22e3c48c940364097baaca1922d4933e2..38cb9869f1659155a4aaf6472a376ecf84de155d 100644 --- a/tests/BinaryTransparencyHostTest/Android.bp +++ b/tests/BinaryTransparencyHostTest/Android.bp @@ -30,7 +30,7 @@ java_test_host { "compatibility-host-util", ], static_libs: [ - "truth-prebuilt", + "truth", ], data: [ ":BinaryTransparencyTestApp", diff --git a/tests/BlobStoreTestUtils/Android.bp b/tests/BlobStoreTestUtils/Android.bp index c4faf7f4fb1150ef320447dd15dafec9c90936e4..1fb73e2c0967e96e1c551a36aa67af16d31ddea1 100644 --- a/tests/BlobStoreTestUtils/Android.bp +++ b/tests/BlobStoreTestUtils/Android.bp @@ -22,12 +22,12 @@ package { } java_library { - name: "BlobStoreTestUtils", - srcs: ["src/**/*.java"], - static_libs: [ - "truth-prebuilt", - "androidx.test.uiautomator_uiautomator", - "androidx.test.ext.junit", - ], - sdk_version: "test_current", + name: "BlobStoreTestUtils", + srcs: ["src/**/*.java"], + static_libs: [ + "truth", + "androidx.test.uiautomator_uiautomator", + "androidx.test.ext.junit", + ], + sdk_version: "test_current", } diff --git a/tests/ChoreographerTests/Android.bp b/tests/ChoreographerTests/Android.bp index ca3026705c635d089d315cb54a3c363af22bc11a..5d49120ee702ae9d9e93c175b905561097a59cbd 100644 --- a/tests/ChoreographerTests/Android.bp +++ b/tests/ChoreographerTests/Android.bp @@ -34,7 +34,7 @@ android_test { "androidx.test.rules", "compatibility-device-util-axt", "com.google.android.material_material", - "truth-prebuilt", + "truth", ], jni_libs: [ "libchoreographertests_jni", diff --git a/tests/CtsSurfaceControlTestsStaging/Android.bp b/tests/CtsSurfaceControlTestsStaging/Android.bp index 680952157fdcc3f5f6c5792c8e8e619678a7bdb5..96e4a9ea43006133dac2be810e95144499d07cb1 100644 --- a/tests/CtsSurfaceControlTestsStaging/Android.bp +++ b/tests/CtsSurfaceControlTestsStaging/Android.bp @@ -37,7 +37,7 @@ android_test { "compatibility-device-util-axt", "com.google.android.material_material", "SurfaceFlingerProperties", - "truth-prebuilt", + "truth", ], resource_dirs: ["src/main/res"], certificate: "platform", diff --git a/tests/DynamicCodeLoggerIntegrationTests/Android.bp b/tests/DynamicCodeLoggerIntegrationTests/Android.bp index 448d46fe5e4e7eda6e6fc50739243ce01598d0c2..3f2c8083156594af689109e57eff790787d8d85f 100644 --- a/tests/DynamicCodeLoggerIntegrationTests/Android.bp +++ b/tests/DynamicCodeLoggerIntegrationTests/Android.bp @@ -47,7 +47,7 @@ android_test { static_libs: [ "androidx.test.rules", - "truth-prebuilt", + "truth", ], compile_multilib: "both", diff --git a/tests/FlickerTests/Android.bp b/tests/FlickerTests/Android.bp index a2ae56eaeadcf4aa8079701e060c090325743525..82aa85d55e4c6ca845097257cb67777c4a7179bb 100644 --- a/tests/FlickerTests/Android.bp +++ b/tests/FlickerTests/Android.bp @@ -236,7 +236,7 @@ java_library { static_libs: [ "flickerlib", "flickerlib-helpers", - "truth-prebuilt", + "truth", "app-helpers-core", ], } @@ -255,7 +255,7 @@ java_library { "flickerlib", "flickerlib-apphelpers", "flickerlib-helpers", - "truth-prebuilt", + "truth", "app-helpers-core", "wm-flicker-window-extensions", ], diff --git a/tests/FsVerityTest/TEST_MAPPING b/tests/FsVerityTest/TEST_MAPPING index 39944bed3f60ca3be9373901361c8f72e5a7e3ac..7d59d77651836f8290cfdc885595c6b7194ab76a 100644 --- a/tests/FsVerityTest/TEST_MAPPING +++ b/tests/FsVerityTest/TEST_MAPPING @@ -1,12 +1,7 @@ { - "postsubmit": [ + "presubmit": [ { "name": "FsVerityTest" - }, - // nextgen test only runs during postsubmit. - { - "name": "FsVerityTest", - "keywords": ["nextgen"] } ] } diff --git a/tests/Input/Android.bp b/tests/Input/Android.bp index 365e00e2b6522e2211fff0ad452ce7ef4444dbc9..f910b8b5f02a8432a5647c216598816b4f8324e1 100644 --- a/tests/Input/Android.bp +++ b/tests/Input/Android.bp @@ -35,7 +35,7 @@ android_test { "services.core.unboosted", "testables", "testng", - "truth-prebuilt", + "truth", ], libs: [ "android.test.mock", diff --git a/tests/Input/src/com/android/server/input/FocusEventDebugViewTest.java b/tests/Input/src/com/android/server/input/debug/FocusEventDebugViewTest.java similarity index 58% rename from tests/Input/src/com/android/server/input/FocusEventDebugViewTest.java rename to tests/Input/src/com/android/server/input/debug/FocusEventDebugViewTest.java index 1b98887199e3f7bc8757346bebda2e66a07d0758..ae7fb3b29f6ce413c2a338477a72cd09d95e6885 100644 --- a/tests/Input/src/com/android/server/input/FocusEventDebugViewTest.java +++ b/tests/Input/src/com/android/server/input/debug/FocusEventDebugViewTest.java @@ -14,15 +14,16 @@ * limitations under the License. */ -package com.android.server.input; +package com.android.server.input.debug; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.anyFloat; import static org.mockito.Mockito.anyInt; +import static org.mockito.Mockito.anyLong; import static org.mockito.Mockito.anyString; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.content.Context; @@ -31,11 +32,12 @@ import android.view.InputDevice; import android.view.MotionEvent; import android.view.MotionEvent.PointerCoords; import android.view.MotionEvent.PointerProperties; -import android.view.ViewConfiguration; import androidx.test.InstrumentationRegistry; import androidx.test.runner.AndroidJUnit4; +import com.android.server.input.InputManagerService; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -48,76 +50,50 @@ import org.junit.runner.RunWith; public class FocusEventDebugViewTest { private FocusEventDebugView mFocusEventDebugView; - private FocusEventDebugView.RotaryInputValueView mRotaryInputValueView; - private FocusEventDebugView.RotaryInputGraphView mRotaryInputGraphView; - private float mScaledVerticalScrollFactor; + private RotaryInputValueView mRotaryInputValueView; + private RotaryInputGraphView mRotaryInputGraphView; @Before public void setUp() throws Exception { Context context = InstrumentationRegistry.getContext(); - mScaledVerticalScrollFactor = - ViewConfiguration.get(context).getScaledVerticalScrollFactor(); InputManagerService mockService = mock(InputManagerService.class); when(mockService.monitorInput(anyString(), anyInt())) .thenReturn(InputChannel.openInputChannelPair("FocusEventDebugViewTest")[1]); - mRotaryInputValueView = new FocusEventDebugView.RotaryInputValueView(context); - mRotaryInputGraphView = new FocusEventDebugView.RotaryInputGraphView(context); + mRotaryInputValueView = spy(new RotaryInputValueView(context)); + mRotaryInputGraphView = spy(new RotaryInputGraphView(context)); mFocusEventDebugView = new FocusEventDebugView(context, mockService, () -> mRotaryInputValueView, () -> mRotaryInputGraphView); } @Test - public void startsRotaryInputValueViewWithDefaultValue() { - assertEquals("+0.0", mRotaryInputValueView.getText()); - } - - @Test - public void startsRotaryInputGraphViewWithDefaultFrameCenter() { - assertEquals(0, mRotaryInputGraphView.getFrameCenterPosition(), 0.01); - } - - @Test - public void handleRotaryInput_updatesRotaryInputValueViewWithScrollValue() { - mFocusEventDebugView.handleUpdateShowRotaryInput(true); - - mFocusEventDebugView.handleRotaryInput(createRotaryMotionEvent(0.5f)); - - assertEquals(String.format("+%.1f", 0.5f * mScaledVerticalScrollFactor), - mRotaryInputValueView.getText()); - } - - @Test - public void handleRotaryInput_translatesRotaryInputGraphViewWithHighScrollValue() { + public void handleRotaryInput_sendsMotionEventWhenEnabled() { mFocusEventDebugView.handleUpdateShowRotaryInput(true); - mFocusEventDebugView.handleRotaryInput(createRotaryMotionEvent(1000f)); + mFocusEventDebugView.handleRotaryInput(createRotaryMotionEvent(0.5f, 10L)); - assertTrue(mRotaryInputGraphView.getFrameCenterPosition() > 0); + verify(mRotaryInputGraphView).addValue(0.5f, 10L); + verify(mRotaryInputValueView).updateValue(0.5f); } @Test - public void updateActivityStatus_setsAndRemovesColorFilter() { - // It should not be active initially. - assertNull(mRotaryInputValueView.getBackground().getColorFilter()); + public void handleRotaryInput_doesNotSendMotionEventWhenDisabled() { + mFocusEventDebugView.handleUpdateShowRotaryInput(false); - mRotaryInputValueView.updateActivityStatus(true); - // It should be active after rotary input. - assertNotNull(mRotaryInputValueView.getBackground().getColorFilter()); + mFocusEventDebugView.handleRotaryInput(createRotaryMotionEvent(0.5f, 10L)); - mRotaryInputValueView.updateActivityStatus(false); - // It should not be active after waiting for mUpdateActivityStatusCallback. - assertNull(mRotaryInputValueView.getBackground().getColorFilter()); + verify(mRotaryInputGraphView, never()).addValue(anyFloat(), anyLong()); + verify(mRotaryInputValueView, never()).updateValue(anyFloat()); } - private MotionEvent createRotaryMotionEvent(float scrollAxisValue) { + private MotionEvent createRotaryMotionEvent(float scrollAxisValue, long eventTime) { PointerCoords pointerCoords = new PointerCoords(); pointerCoords.setAxisValue(MotionEvent.AXIS_SCROLL, scrollAxisValue); PointerProperties pointerProperties = new PointerProperties(); return MotionEvent.obtain( /* downTime */ 0, - /* eventTime */ 0, + /* eventTime */ eventTime, /* action */ MotionEvent.ACTION_SCROLL, /* pointerCount */ 1, /* pointerProperties */ new PointerProperties[] {pointerProperties}, diff --git a/tests/Input/src/com/android/server/input/debug/RotaryInputGraphViewTest.java b/tests/Input/src/com/android/server/input/debug/RotaryInputGraphViewTest.java new file mode 100644 index 0000000000000000000000000000000000000000..af6ece414fd162909c99b09bac7d9dbbfc034274 --- /dev/null +++ b/tests/Input/src/com/android/server/input/debug/RotaryInputGraphViewTest.java @@ -0,0 +1,61 @@ +/* + * Copyright 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.input.debug; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import android.content.Context; + +import androidx.test.InstrumentationRegistry; +import androidx.test.runner.AndroidJUnit4; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +/** + * Build/Install/Run: + * atest RotaryInputGraphViewTest + */ +@RunWith(AndroidJUnit4.class) +public class RotaryInputGraphViewTest { + + private RotaryInputGraphView mRotaryInputGraphView; + + @Before + public void setUp() throws Exception { + Context context = InstrumentationRegistry.getContext(); + + mRotaryInputGraphView = new RotaryInputGraphView(context); + } + + @Test + public void startsWithDefaultFrameCenter() { + assertEquals(0, mRotaryInputGraphView.getFrameCenterPosition(), 0.01); + } + + @Test + public void addValue_translatesRotaryInputGraphViewWithHighScrollValue() { + final float scrollAxisValue = 1000f; + final long eventTime = 0; + + mRotaryInputGraphView.addValue(scrollAxisValue, eventTime); + + assertTrue(mRotaryInputGraphView.getFrameCenterPosition() > 0); + } +} diff --git a/tests/Input/src/com/android/server/input/debug/RotaryInputValueViewTest.java b/tests/Input/src/com/android/server/input/debug/RotaryInputValueViewTest.java new file mode 100644 index 0000000000000000000000000000000000000000..e5e3852dc3183d6b6f44d1998615ae0843ed468c --- /dev/null +++ b/tests/Input/src/com/android/server/input/debug/RotaryInputValueViewTest.java @@ -0,0 +1,85 @@ +/* + * Copyright 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.input.debug; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; + +import android.content.Context; +import android.view.ViewConfiguration; + +import androidx.test.InstrumentationRegistry; +import androidx.test.runner.AndroidJUnit4; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.util.Locale; + +/** + * Build/Install/Run: + * atest RotaryInputValueViewTest + */ +@RunWith(AndroidJUnit4.class) +public class RotaryInputValueViewTest { + + private final Locale mDefaultLocale = Locale.getDefault(); + + private RotaryInputValueView mRotaryInputValueView; + private float mScaledVerticalScrollFactor; + + @Before + public void setUp() throws Exception { + Context context = InstrumentationRegistry.getContext(); + mScaledVerticalScrollFactor = + ViewConfiguration.get(context).getScaledVerticalScrollFactor(); + + mRotaryInputValueView = new RotaryInputValueView(context); + } + + @Test + public void startsWithDefaultValue() { + assertEquals("+0.0", mRotaryInputValueView.getText().toString()); + } + + @Test + public void updateValue_updatesTextWithScrollValue() { + final float scrollAxisValue = 1000f; + final String expectedText = String.format(mDefaultLocale, "+%.1f", + scrollAxisValue * mScaledVerticalScrollFactor); + + mRotaryInputValueView.updateValue(scrollAxisValue); + + assertEquals(expectedText, mRotaryInputValueView.getText().toString()); + } + + @Test + public void updateActivityStatus_setsAndRemovesColorFilter() { + // It should not be active initially. + assertNull(mRotaryInputValueView.getBackground().getColorFilter()); + + mRotaryInputValueView.updateActivityStatus(true); + // It should be active after rotary input. + assertNotNull(mRotaryInputValueView.getBackground().getColorFilter()); + + mRotaryInputValueView.updateActivityStatus(false); + // It should not be active after waiting for mUpdateActivityStatusCallback. + assertNull(mRotaryInputValueView.getBackground().getColorFilter()); + } +} diff --git a/tests/InputMethodStressTest/Android.bp b/tests/InputMethodStressTest/Android.bp index 84845c69fb27e438659e0335b0095303f5df7ab1..58ceb3f3edf4fbe7fcac7f8f9677881c73852640 100644 --- a/tests/InputMethodStressTest/Android.bp +++ b/tests/InputMethodStressTest/Android.bp @@ -26,7 +26,7 @@ android_test { "compatibility-device-util-axt", "platform-test-annotations", "platform-test-rules", - "truth-prebuilt", + "truth", ], test_suites: [ "general-tests", diff --git a/tests/InputScreenshotTest/Android.bp b/tests/InputScreenshotTest/Android.bp index eee486f997487272a4bb7bed27308408de4cab73..15aaa463cce7294e42e5af927a8b257a4d5dc4ab 100644 --- a/tests/InputScreenshotTest/Android.bp +++ b/tests/InputScreenshotTest/Android.bp @@ -29,7 +29,7 @@ android_test { "androidx.lifecycle_lifecycle-livedata-ktx", "androidx.lifecycle_lifecycle-runtime-compose", "androidx.navigation_navigation-compose", - "truth-prebuilt", + "truth", "androidx.compose.runtime_runtime", "androidx.test.core", "androidx.test.ext.junit", @@ -47,7 +47,7 @@ android_test { "services.core.unboosted", "testables", "testng", - "truth-prebuilt", + "truth", ], libs: [ "android.test.mock", diff --git a/tests/Internal/Android.bp b/tests/Internal/Android.bp index ef45864dd93be7f39d123d955ba1d84488d407f0..ddec8fa1d70a2494e88f5621c981fe3712b88981 100644 --- a/tests/Internal/Android.bp +++ b/tests/Internal/Android.bp @@ -19,7 +19,7 @@ android_test { "junit", "androidx.test.rules", "mockito-target-minus-junit4", - "truth-prebuilt", + "truth", "platform-test-annotations", ], java_resource_dirs: ["res"], diff --git a/tests/LocalizationTest/Android.bp b/tests/LocalizationTest/Android.bp index 4e0b0a89d972d9849723726a211b6c44ca7e2926..909ca5972552ff8c7b9af0f4fc4c481516742afa 100644 --- a/tests/LocalizationTest/Android.bp +++ b/tests/LocalizationTest/Android.bp @@ -34,7 +34,7 @@ android_test { "androidx.test.ext.junit", "androidx.test.rules", "mockito-target-extended-minus-junit4", - "truth-prebuilt", + "truth", ], jni_libs: [ // For mockito extended diff --git a/tests/MidiTests/Android.bp b/tests/MidiTests/Android.bp index 254770d21818d49fc73cce9582e3f42b2ad5c401..fcacab3fb13c032da5964fd3f0ba01ebe29a2113 100644 --- a/tests/MidiTests/Android.bp +++ b/tests/MidiTests/Android.bp @@ -31,7 +31,7 @@ android_test { "mockito-target-inline-minus-junit4", "platform-test-annotations", "services.midi", - "truth-prebuilt", + "truth", ], jni_libs: ["libdexmakerjvmtiagent"], certificate: "platform", diff --git a/tests/PackageWatchdog/Android.bp b/tests/PackageWatchdog/Android.bp index 1e1dc84585605175ef8b26d462bee13bd29f8225..e0e6c4c43b166f71b506be527fd1347728770189 100644 --- a/tests/PackageWatchdog/Android.bp +++ b/tests/PackageWatchdog/Android.bp @@ -32,7 +32,7 @@ android_test { "androidx.test.rules", "services.core", "services.net", - "truth-prebuilt", + "truth", ], libs: ["android.test.runner"], jni_libs: [ diff --git a/tests/PlatformCompatGating/Android.bp b/tests/PlatformCompatGating/Android.bp index f0f9c4bdd721f9082bafadf0b0d9ca8f6c6f2060..fd992cf415cfdf0b5d303bc2735c575a18fd14c0 100644 --- a/tests/PlatformCompatGating/Android.bp +++ b/tests/PlatformCompatGating/Android.bp @@ -38,7 +38,7 @@ android_test { "androidx.test.ext.junit", "mockito-target-minus-junit4", "testng", - "truth-prebuilt", + "truth", "platform-compat-test-rules", ], } diff --git a/tests/PlatformCompatGating/test-rules/Android.bp b/tests/PlatformCompatGating/test-rules/Android.bp index 5f91f9d0e505e3c3123b103f5382d39bbccebd64..f6a41c2f44b7a2bb66426aba6bcaf4dedfd49a97 100644 --- a/tests/PlatformCompatGating/test-rules/Android.bp +++ b/tests/PlatformCompatGating/test-rules/Android.bp @@ -29,7 +29,7 @@ java_library { static_libs: [ "junit", "androidx.test.core", - "truth-prebuilt", - "core-compat-test-rules" + "truth", + "core-compat-test-rules", ], } diff --git a/tests/SurfaceViewBufferTests/Android.bp b/tests/SurfaceViewBufferTests/Android.bp index 38313f85c31dfcde8bcedfc5c8e81c5aefb40b51..055d6258d1ac7c1c048ccba05e79cca2c8966846 100644 --- a/tests/SurfaceViewBufferTests/Android.bp +++ b/tests/SurfaceViewBufferTests/Android.bp @@ -45,7 +45,7 @@ android_test { "kotlinx-coroutines-android", "flickerlib", "flickerlib-trace_processor_shell", - "truth-prebuilt", + "truth", "cts-wm-util", "CtsSurfaceValidatorLib", ], diff --git a/tests/TaskOrganizerTest/Android.bp b/tests/TaskOrganizerTest/Android.bp index bf12f423f145afccffba7fe9a622e267b82b65a0..d2ade34148e2793528d6fabfe0d51ded3290de9a 100644 --- a/tests/TaskOrganizerTest/Android.bp +++ b/tests/TaskOrganizerTest/Android.bp @@ -43,6 +43,6 @@ android_test { "kotlinx-coroutines-android", "flickerlib", "flickerlib-trace_processor_shell", - "truth-prebuilt", + "truth", ], } diff --git a/tests/TelephonyCommonTests/Android.bp b/tests/TelephonyCommonTests/Android.bp index 81ec265c2c291bfecbb1ff96a16995160e0b9d1c..b968e5d811486cc1da01fc21b3bfeffbf1fda48f 100644 --- a/tests/TelephonyCommonTests/Android.bp +++ b/tests/TelephonyCommonTests/Android.bp @@ -32,11 +32,11 @@ android_test { static_libs: [ "mockito-target-extended", "androidx.test.rules", - "truth-prebuilt", + "truth", "platform-test-annotations", "androidx.core_core", "androidx.fragment_fragment", - "androidx.test.ext.junit" + "androidx.test.ext.junit", ], jni_libs: ["libdexmakerjvmtiagent"], diff --git a/tests/TrustTests/Android.bp b/tests/TrustTests/Android.bp index c216bced81f00ebc3fb5356d9cda50a815d45366..4e75a1d02a4128b9a3a2176049e6f7c7adc81c9d 100644 --- a/tests/TrustTests/Android.bp +++ b/tests/TrustTests/Android.bp @@ -28,7 +28,7 @@ android_test { "flag-junit", "mockito-target-minus-junit4", "servicestests-utils", - "truth-prebuilt", + "truth", ], libs: [ "android.test.runner", diff --git a/tests/UpdatableSystemFontTest/Android.bp b/tests/UpdatableSystemFontTest/Android.bp index 9bfcc18ee3012bec96785e4fa1315e4bde60e5d6..ddb3649a83207138c9054fdd5513a5c4992cf952 100644 --- a/tests/UpdatableSystemFontTest/Android.bp +++ b/tests/UpdatableSystemFontTest/Android.bp @@ -30,7 +30,7 @@ android_test { "androidx.test.uiautomator_uiautomator", "compatibility-device-util-axt", "platform-test-annotations", - "truth-prebuilt", + "truth", ], test_suites: [ "general-tests", diff --git a/tests/UsbManagerTests/Android.bp b/tests/UsbManagerTests/Android.bp index 97fbf5b320351007fce0e0e7af42f194f3910ed3..c02d8e96abb0a90200e90672a5ab6d2081a8dc6a 100644 --- a/tests/UsbManagerTests/Android.bp +++ b/tests/UsbManagerTests/Android.bp @@ -31,7 +31,7 @@ android_test { "androidx.test.rules", "mockito-target-inline-minus-junit4", "platform-test-annotations", - "truth-prebuilt", + "truth", "UsbManagerTestLib", ], jni_libs: ["libdexmakerjvmtiagent"], diff --git a/tests/UsbManagerTests/lib/Android.bp b/tests/UsbManagerTests/lib/Android.bp index 994484cd63bf02b8feeeaea57a48572ee7100937..4e5a70fef0ca5907b38d088e2aaa4490d679f020 100644 --- a/tests/UsbManagerTests/lib/Android.bp +++ b/tests/UsbManagerTests/lib/Android.bp @@ -34,7 +34,7 @@ android_library { "services.core", "services.net", "services.usb", - "truth-prebuilt", + "truth", "androidx.core_core", ], libs: [ diff --git a/tests/UsbTests/Android.bp b/tests/UsbTests/Android.bp index c60c519ec4d42147853ee5bd55cbbe19a89dc6a0..92c271165ad7b974697dd85d6e4b594d45cb1c77 100644 --- a/tests/UsbTests/Android.bp +++ b/tests/UsbTests/Android.bp @@ -34,7 +34,7 @@ android_test { "services.core", "services.net", "services.usb", - "truth-prebuilt", + "truth", "UsbManagerTestLib", ], jni_libs: [ diff --git a/tests/componentalias/Android.bp b/tests/componentalias/Android.bp index 01d34e4ff645c346f50c2b98d7e87817a7cc5dd9..39037f22fdcb90ea2071ee5b745ba1b2a14d29ce 100644 --- a/tests/componentalias/Android.bp +++ b/tests/componentalias/Android.bp @@ -25,7 +25,7 @@ java_defaults { "androidx.test.rules", "compatibility-device-util-axt", "mockito-target-extended-minus-junit4", - "truth-prebuilt", + "truth", ], libs: ["android.test.base"], srcs: [ diff --git a/tools/hoststubgen/hoststubgen/test-framework/AndroidHostTest.bp b/tools/hoststubgen/hoststubgen/test-framework/AndroidHostTest.bp index e7fb2debfc4ea1514566c384def3c54c1236591f..b71e5c47c70e54bb9372f193e23903c6a4d5a1f5 100644 --- a/tools/hoststubgen/hoststubgen/test-framework/AndroidHostTest.bp +++ b/tools/hoststubgen/hoststubgen/test-framework/AndroidHostTest.bp @@ -24,7 +24,7 @@ java_library_host { ], static_libs: [ "junit", - "truth-prebuilt", + "truth", "mockito", // http://cs/h/googleplex-android/platform/superproject/main/+/main:platform_testing/libraries/annotations/src/android/platform/test/annotations/ diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/Android.bp b/tools/hoststubgen/hoststubgen/test-tiny-framework/Android.bp index 05d6a43cdb0f49bb5e245e30c5d87fe5e5e3416f..f9dc305a4e3e9f04281a74ba78fdde33359acfed 100644 --- a/tools/hoststubgen/hoststubgen/test-tiny-framework/Android.bp +++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/Android.bp @@ -104,7 +104,7 @@ java_library_host { ], static_libs: [ "junit", - "truth-prebuilt", + "truth", // http://cs/h/googleplex-android/platform/superproject/main/+/main:platform_testing/libraries/annotations/src/android/platform/test/annotations/ "platform-test-annotations", diff --git a/tools/processors/immutability/Android.bp b/tools/processors/immutability/Android.bp index a7d69039fcb0dbb00077158423736cfefbd3c232..ecc283b0b37ef4f89b6392305019f9ec475ba202 100644 --- a/tools/processors/immutability/Android.bp +++ b/tools/processors/immutability/Android.bp @@ -50,7 +50,7 @@ java_test_host { static_libs: [ "compile-testing-prebuilt", - "truth-prebuilt", + "truth", "junit", "kotlin-reflect", "ImmutabilityAnnotationProcessorHostLibrary", diff --git a/tools/processors/intdef_mappings/Android.bp b/tools/processors/intdef_mappings/Android.bp index 7059c52ddc76754f5ecd4a75e8d4c4e24395fb55..9c755b7d58c25833285ca41b93911f1ed0b408b1 100644 --- a/tools/processors/intdef_mappings/Android.bp +++ b/tools/processors/intdef_mappings/Android.bp @@ -38,7 +38,7 @@ java_test_host { static_libs: [ "compile-testing-prebuilt", - "truth-prebuilt", + "truth", "junit", "guava", "libintdef-annotation-processor", diff --git a/wifi/tests/Android.bp b/wifi/tests/Android.bp index 7a299694741a8d76fddff2ff8a1bb5eb88060001..5a0f742372d758786910ab40eb50372a316b3720 100644 --- a/wifi/tests/Android.bp +++ b/wifi/tests/Android.bp @@ -40,7 +40,7 @@ android_test { "frameworks-base-testutils", "guava", "mockito-target-minus-junit4", - "truth-prebuilt", + "truth", ], libs: [