Merge "Create SeekBar with icon buttons for common usage" into tm-qpr-dev
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index 3d5c34c..76475f2 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -649,8 +649,11 @@
return Uid.PROCESS_STATE_NONEXISTENT;
} else if (procState == ActivityManager.PROCESS_STATE_TOP) {
return Uid.PROCESS_STATE_TOP;
- } else if (ActivityManager.isForegroundService(procState)) {
- // State when app has put itself in the foreground.
+ } else if (procState == ActivityManager.PROCESS_STATE_BOUND_TOP) {
+ return Uid.PROCESS_STATE_BACKGROUND;
+ } else if (procState == ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
+ return Uid.PROCESS_STATE_FOREGROUND_SERVICE;
+ } else if (procState == ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
return Uid.PROCESS_STATE_FOREGROUND_SERVICE;
} else if (procState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
// Persistent and other foreground states go here.
diff --git a/core/java/android/os/UidBatteryConsumer.java b/core/java/android/os/UidBatteryConsumer.java
index 91d231e..787b609 100644
--- a/core/java/android/os/UidBatteryConsumer.java
+++ b/core/java/android/os/UidBatteryConsumer.java
@@ -51,8 +51,7 @@
}
/**
- * The state of an application when it is either running a foreground (top) activity
- * or a foreground service.
+ * The state of an application when it is either running a foreground (top) activity.
*/
public static final int STATE_FOREGROUND = 0;
@@ -64,7 +63,8 @@
* {@link android.app.ActivityManager#PROCESS_STATE_TRANSIENT_BACKGROUND},
* {@link android.app.ActivityManager#PROCESS_STATE_BACKUP},
* {@link android.app.ActivityManager#PROCESS_STATE_SERVICE},
- * {@link android.app.ActivityManager#PROCESS_STATE_RECEIVER}.
+ * {@link android.app.ActivityManager#PROCESS_STATE_RECEIVER},
+ * {@link android.app.ActivityManager#PROCESS_STATE_FOREGROUND_SERVICE}.
*/
public static final int STATE_BACKGROUND = 1;
diff --git a/core/java/android/service/dreams/DreamService.java b/core/java/android/service/dreams/DreamService.java
index 6a4710f..d79ea89 100644
--- a/core/java/android/service/dreams/DreamService.java
+++ b/core/java/android/service/dreams/DreamService.java
@@ -234,6 +234,7 @@
private boolean mCanDoze;
private boolean mDozing;
private boolean mWindowless;
+ private boolean mOverlayFinishing;
private int mDozeScreenState = Display.STATE_UNKNOWN;
private int mDozeScreenBrightness = PowerManager.BRIGHTNESS_DEFAULT;
@@ -1051,6 +1052,7 @@
// We must unbind from any overlay connection if we are unbound before finishing.
if (mOverlayConnection != null) {
mOverlayConnection.unbind();
+ mOverlayConnection = null;
}
return super.onUnbind(intent);
@@ -1067,7 +1069,9 @@
// If there is an active overlay connection, signal that the dream is ending before
// continuing. Note that the overlay cannot rely on the unbound state, since another dream
// might have bound to it in the meantime.
- if (mOverlayConnection != null) {
+ if (mOverlayConnection != null && !mOverlayFinishing) {
+ // Set mOverlayFinish to true to only allow this consumer to be added once.
+ mOverlayFinishing = true;
mOverlayConnection.addConsumer(overlay -> {
try {
overlay.endDream();
@@ -1300,9 +1304,10 @@
* Must run on mHandler.
*
* @param dreamToken Token for this dream service.
- * @param started A callback that will be invoked once onDreamingStarted has completed.
+ * @param started A callback that will be invoked once onDreamingStarted has completed.
*/
- private void attach(IBinder dreamToken, boolean canDoze, IRemoteCallback started) {
+ private void attach(IBinder dreamToken, boolean canDoze, boolean isPreviewMode,
+ IRemoteCallback started) {
if (mDreamToken != null) {
Slog.e(mTag, "attach() called when dream with token=" + mDreamToken
+ " already attached");
@@ -1350,7 +1355,8 @@
i.putExtra(DreamActivity.EXTRA_CALLBACK, new DreamActivityCallbacks(mDreamToken));
final ServiceInfo serviceInfo = fetchServiceInfo(this,
new ComponentName(this, getClass()));
- i.putExtra(DreamActivity.EXTRA_DREAM_TITLE, fetchDreamLabel(this, serviceInfo));
+ i.putExtra(DreamActivity.EXTRA_DREAM_TITLE,
+ fetchDreamLabel(this, serviceInfo, isPreviewMode));
try {
if (!ActivityTaskManager.getService().startDreamActivity(i)) {
@@ -1466,10 +1472,18 @@
@Nullable
private static CharSequence fetchDreamLabel(Context context,
- @Nullable ServiceInfo serviceInfo) {
- if (serviceInfo == null) return null;
+ @Nullable ServiceInfo serviceInfo,
+ boolean isPreviewMode) {
+ if (serviceInfo == null) {
+ return null;
+ }
final PackageManager pm = context.getPackageManager();
- return serviceInfo.loadLabel(pm);
+ final CharSequence dreamLabel = serviceInfo.loadLabel(pm);
+ if (!isPreviewMode || dreamLabel == null) {
+ return dreamLabel;
+ }
+ // When in preview mode, return a special label indicating the dream is in preview.
+ return context.getResources().getString(R.string.dream_preview_title, dreamLabel);
}
@Nullable
@@ -1525,8 +1539,9 @@
final class DreamServiceWrapper extends IDreamService.Stub {
@Override
public void attach(final IBinder dreamToken, final boolean canDoze,
- IRemoteCallback started) {
- mHandler.post(() -> DreamService.this.attach(dreamToken, canDoze, started));
+ final boolean isPreviewMode, IRemoteCallback started) {
+ mHandler.post(
+ () -> DreamService.this.attach(dreamToken, canDoze, isPreviewMode, started));
}
@Override
diff --git a/core/java/android/service/dreams/IDreamService.aidl b/core/java/android/service/dreams/IDreamService.aidl
index ce04354..8b5d875 100644
--- a/core/java/android/service/dreams/IDreamService.aidl
+++ b/core/java/android/service/dreams/IDreamService.aidl
@@ -22,7 +22,7 @@
* @hide
*/
oneway interface IDreamService {
- void attach(IBinder windowToken, boolean canDoze, IRemoteCallback started);
+ void attach(IBinder windowToken, boolean canDoze, boolean isPreviewMode, IRemoteCallback started);
void detach();
void wakeUp();
}
diff --git a/core/java/com/android/internal/os/BatteryUsageStatsProvider.java b/core/java/com/android/internal/os/BatteryUsageStatsProvider.java
index 09e409b..ac4976f 100644
--- a/core/java/com/android/internal/os/BatteryUsageStatsProvider.java
+++ b/core/java/com/android/internal/os/BatteryUsageStatsProvider.java
@@ -298,18 +298,16 @@
BatteryStats.Uid.PROCESS_STATE_FOREGROUND, realtimeUs,
BatteryStats.STATS_SINCE_CHARGED);
- totalForegroundDurationUs += uid.getProcessStateTime(
- BatteryStats.Uid.PROCESS_STATE_FOREGROUND_SERVICE, realtimeUs,
- BatteryStats.STATS_SINCE_CHARGED);
-
return totalForegroundDurationUs / 1000;
}
private long getProcessBackgroundTimeMs(BatteryStats.Uid uid, long realtimeUs) {
- return uid.getProcessStateTime(BatteryStats.Uid.PROCESS_STATE_BACKGROUND, realtimeUs,
- BatteryStats.STATS_SINCE_CHARGED) / 1000;
+ return (uid.getProcessStateTime(BatteryStats.Uid.PROCESS_STATE_BACKGROUND,
+ realtimeUs, BatteryStats.STATS_SINCE_CHARGED)
+ + uid.getProcessStateTime(BatteryStats.Uid.PROCESS_STATE_FOREGROUND_SERVICE,
+ realtimeUs, BatteryStats.STATS_SINCE_CHARGED))
+ / 1000;
}
-
private BatteryUsageStats getAggregatedBatteryUsageStats(BatteryUsageStatsQuery query) {
final boolean includePowerModels = (query.getFlags()
& BatteryUsageStatsQuery.FLAG_BATTERY_USAGE_STATS_INCLUDE_POWER_MODELS) != 0;
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index ba54183..2091c05 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -975,6 +975,11 @@
<!-- Description for the capability of an accessibility service to take screenshot. [CHAR LIMIT=NONE] -->
<string name="capability_desc_canTakeScreenshot">Can take a screenshot of the display.</string>
+ <!-- Dream -->
+
+ <!-- The title to use when a dream is opened in preview mode. [CHAR LIMIT=NONE] -->
+ <string name="dream_preview_title">Preview, <xliff:g id="dream_name" example="Clock">%1$s</xliff:g></string>
+
<!-- Permissions -->
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index ad5b9c0..9cc8aa8 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -4285,6 +4285,8 @@
<java-symbol type="string" name="capability_desc_canTakeScreenshot" />
<java-symbol type="string" name="capability_title_canTakeScreenshot" />
+ <java-symbol type="string" name="dream_preview_title" />
+
<java-symbol type="string" name="config_servicesExtensionPackage" />
<!-- For app process exit info tracking -->
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java
index 52feac5..4c9b2b7 100644
--- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java
@@ -360,6 +360,7 @@
// map of ActivityManager process states and how long to simulate run time in each state
Map<Integer, Integer> stateRuntimeMap = new HashMap<Integer, Integer>();
stateRuntimeMap.put(ActivityManager.PROCESS_STATE_TOP, 1111);
+ stateRuntimeMap.put(ActivityManager.PROCESS_STATE_BOUND_TOP, 7382);
stateRuntimeMap.put(ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE, 1234);
stateRuntimeMap.put(ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, 2468);
stateRuntimeMap.put(ActivityManager.PROCESS_STATE_TOP_SLEEPING, 7531);
@@ -396,7 +397,8 @@
actualRunTimeUs = uid.getProcessStateTime(BatteryStats.Uid.PROCESS_STATE_FOREGROUND_SERVICE,
elapsedTimeUs, STATS_SINCE_CHARGED);
- expectedRunTimeMs = stateRuntimeMap.get(ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
+ expectedRunTimeMs = stateRuntimeMap.get(ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE)
+ + stateRuntimeMap.get(ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE);
assertEquals(expectedRunTimeMs * 1000, actualRunTimeUs);
actualRunTimeUs = uid.getProcessStateTime(BatteryStats.Uid.PROCESS_STATE_TOP_SLEEPING,
@@ -406,8 +408,7 @@
actualRunTimeUs = uid.getProcessStateTime(BatteryStats.Uid.PROCESS_STATE_FOREGROUND,
elapsedTimeUs, STATS_SINCE_CHARGED);
- expectedRunTimeMs = stateRuntimeMap.get(ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND)
- + stateRuntimeMap.get(ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE);
+ expectedRunTimeMs = stateRuntimeMap.get(ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND);
assertEquals(expectedRunTimeMs * 1000, actualRunTimeUs);
actualRunTimeUs = uid.getProcessStateTime(BatteryStats.Uid.PROCESS_STATE_BACKGROUND,
@@ -415,7 +416,8 @@
expectedRunTimeMs = stateRuntimeMap.get(ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND)
+ stateRuntimeMap.get(ActivityManager.PROCESS_STATE_BACKUP)
+ stateRuntimeMap.get(ActivityManager.PROCESS_STATE_SERVICE)
- + stateRuntimeMap.get(ActivityManager.PROCESS_STATE_RECEIVER);
+ + stateRuntimeMap.get(ActivityManager.PROCESS_STATE_RECEIVER)
+ + stateRuntimeMap.get(ActivityManager.PROCESS_STATE_BOUND_TOP);
assertEquals(expectedRunTimeMs * 1000, actualRunTimeUs);
actualRunTimeUs = uid.getProcessStateTime(BatteryStats.Uid.PROCESS_STATE_CACHED,
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsProviderTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsProviderTest.java
index 354b937..2742861 100644
--- a/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsProviderTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsProviderTest.java
@@ -78,9 +78,9 @@
batteryUsageStats.getUidBatteryConsumers();
final UidBatteryConsumer uidBatteryConsumer = uidBatteryConsumers.get(0);
assertThat(uidBatteryConsumer.getTimeInStateMs(UidBatteryConsumer.STATE_FOREGROUND))
- .isEqualTo(60 * MINUTE_IN_MS);
+ .isEqualTo(20 * MINUTE_IN_MS);
assertThat(uidBatteryConsumer.getTimeInStateMs(UidBatteryConsumer.STATE_BACKGROUND))
- .isEqualTo(10 * MINUTE_IN_MS);
+ .isEqualTo(40 * MINUTE_IN_MS);
assertThat(uidBatteryConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_AUDIO))
.isWithin(PRECISION).of(2.0);
assertThat(
@@ -121,22 +121,44 @@
private BatteryStatsImpl prepareBatteryStats() {
BatteryStatsImpl batteryStats = mStatsRule.getBatteryStats();
- batteryStats.noteActivityResumedLocked(APP_UID,
- 10 * MINUTE_IN_MS, 10 * MINUTE_IN_MS);
- batteryStats.noteUidProcessStateLocked(APP_UID, ActivityManager.PROCESS_STATE_TOP,
- 10 * MINUTE_IN_MS, 10 * MINUTE_IN_MS);
- batteryStats.noteActivityPausedLocked(APP_UID,
- 30 * MINUTE_IN_MS, 30 * MINUTE_IN_MS);
- batteryStats.noteUidProcessStateLocked(APP_UID, ActivityManager.PROCESS_STATE_SERVICE,
- 30 * MINUTE_IN_MS, 30 * MINUTE_IN_MS);
- batteryStats.noteUidProcessStateLocked(APP_UID,
- ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE,
- 40 * MINUTE_IN_MS, 40 * MINUTE_IN_MS);
- batteryStats.noteUidProcessStateLocked(APP_UID,
- ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE,
- 50 * MINUTE_IN_MS, 50 * MINUTE_IN_MS);
- batteryStats.noteUidProcessStateLocked(APP_UID, ActivityManager.PROCESS_STATE_CACHED_EMPTY,
- 80 * MINUTE_IN_MS, 80 * MINUTE_IN_MS);
+ mStatsRule.setTime(10 * MINUTE_IN_MS, 10 * MINUTE_IN_MS);
+ synchronized (batteryStats) {
+ batteryStats.noteActivityResumedLocked(APP_UID);
+ }
+
+ mStatsRule.setTime(10 * MINUTE_IN_MS, 10 * MINUTE_IN_MS);
+ synchronized (batteryStats) {
+ batteryStats.noteUidProcessStateLocked(APP_UID, ActivityManager.PROCESS_STATE_TOP);
+ }
+ mStatsRule.setTime(30 * MINUTE_IN_MS, 30 * MINUTE_IN_MS);
+ synchronized (batteryStats) {
+ batteryStats.noteActivityPausedLocked(APP_UID);
+ }
+ mStatsRule.setTime(30 * MINUTE_IN_MS, 30 * MINUTE_IN_MS);
+ synchronized (batteryStats) {
+ batteryStats.noteUidProcessStateLocked(APP_UID,
+ ActivityManager.PROCESS_STATE_SERVICE);
+ }
+ mStatsRule.setTime(40 * MINUTE_IN_MS, 40 * MINUTE_IN_MS);
+ synchronized (batteryStats) {
+ batteryStats.noteUidProcessStateLocked(APP_UID,
+ ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
+ }
+ mStatsRule.setTime(50 * MINUTE_IN_MS, 50 * MINUTE_IN_MS);
+ synchronized (batteryStats) {
+ batteryStats.noteUidProcessStateLocked(APP_UID,
+ ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE);
+ }
+ mStatsRule.setTime(60 * MINUTE_IN_MS, 60 * MINUTE_IN_MS);
+ synchronized (batteryStats) {
+ batteryStats.noteUidProcessStateLocked(APP_UID,
+ ActivityManager.PROCESS_STATE_BOUND_TOP);
+ }
+ mStatsRule.setTime(70 * MINUTE_IN_MS, 70 * MINUTE_IN_MS);
+ synchronized (batteryStats) {
+ batteryStats.noteUidProcessStateLocked(APP_UID,
+ ActivityManager.PROCESS_STATE_CACHED_EMPTY);
+ }
batteryStats.noteFlashlightOnLocked(APP_UID, 1000, 1000);
batteryStats.noteFlashlightOffLocked(APP_UID, 5000, 5000);
diff --git a/errorprone/java/com/google/errorprone/bugpatterns/android/RequiresPermissionChecker.java b/errorprone/java/com/google/errorprone/bugpatterns/android/RequiresPermissionChecker.java
index fa173072..d39d4b4 100644
--- a/errorprone/java/com/google/errorprone/bugpatterns/android/RequiresPermissionChecker.java
+++ b/errorprone/java/com/google/errorprone/bugpatterns/android/RequiresPermissionChecker.java
@@ -412,11 +412,11 @@
private static ParsedRequiresPermission parseRequiresPermissionRecursively(
MethodInvocationTree tree, VisitorState state) {
- if (ENFORCE_VIA_CONTEXT.matches(tree, state)) {
+ if (ENFORCE_VIA_CONTEXT.matches(tree, state) && tree.getArguments().size() > 0) {
final ParsedRequiresPermission res = new ParsedRequiresPermission();
res.allOf.add(String.valueOf(ASTHelpers.constValue(tree.getArguments().get(0))));
return res;
- } else if (ENFORCE_VIA_CHECKER.matches(tree, state)) {
+ } else if (ENFORCE_VIA_CHECKER.matches(tree, state) && tree.getArguments().size() > 1) {
final ParsedRequiresPermission res = new ParsedRequiresPermission();
res.allOf.add(String.valueOf(ASTHelpers.constValue(tree.getArguments().get(1))));
return res;
diff --git a/errorprone/tests/java/com/google/errorprone/bugpatterns/android/RequiresPermissionCheckerTest.java b/errorprone/tests/java/com/google/errorprone/bugpatterns/android/RequiresPermissionCheckerTest.java
index 388988e..38831b1 100644
--- a/errorprone/tests/java/com/google/errorprone/bugpatterns/android/RequiresPermissionCheckerTest.java
+++ b/errorprone/tests/java/com/google/errorprone/bugpatterns/android/RequiresPermissionCheckerTest.java
@@ -415,4 +415,27 @@
"}")
.doTest();
}
+
+ @Test
+ public void testInvalidFunctions() {
+ compilationHelper
+ .addSourceFile("/android/annotation/RequiresPermission.java")
+ .addSourceFile("/android/annotation/SuppressLint.java")
+ .addSourceFile("/android/content/Context.java")
+ .addSourceLines("Example.java",
+ "import android.annotation.RequiresPermission;",
+ "import android.annotation.SuppressLint;",
+ "import android.content.Context;",
+ "class Foo extends Context {",
+ " private static final String RED = \"red\";",
+ " public void checkPermission() {",
+ " }",
+ " @RequiresPermission(RED)",
+ " // BUG: Diagnostic contains:",
+ " public void exampleScoped(Context context) {",
+ " checkPermission();",
+ " }",
+ "}")
+ .doTest();
+ }
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeController.java
index d850416..bc81710 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeController.java
@@ -22,6 +22,7 @@
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.view.WindowManager.TRANSIT_CHANGE;
+import static android.view.WindowManager.TRANSIT_NONE;
import static android.view.WindowManager.TRANSIT_OPEN;
import static android.view.WindowManager.TRANSIT_TO_FRONT;
@@ -256,10 +257,13 @@
WindowContainerTransaction wct = new WindowContainerTransaction();
bringDesktopAppsToFront(wct);
- if (Transitions.ENABLE_SHELL_TRANSITIONS) {
- mTransitions.startTransition(TRANSIT_TO_FRONT, wct, null /* handler */);
- } else {
- mShellTaskOrganizer.applyTransaction(wct);
+ if (!wct.isEmpty()) {
+ if (Transitions.ENABLE_SHELL_TRANSITIONS) {
+ // TODO(b/268662477): add animation for the transition
+ mTransitions.startTransition(TRANSIT_NONE, wct, null /* handler */);
+ } else {
+ mShellTaskOrganizer.applyTransaction(wct);
+ }
}
}
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 2303325..fce0138 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
@@ -27,6 +27,7 @@
import android.os.IBinder
import android.view.SurfaceControl
import android.view.WindowManager.TRANSIT_CHANGE
+import android.view.WindowManager.TRANSIT_NONE
import android.view.WindowManager.TRANSIT_OPEN
import android.view.WindowManager.TRANSIT_TO_FRONT
import android.window.TransitionInfo
@@ -89,7 +90,8 @@
// Execute transaction if there are pending operations
if (!wct.isEmpty) {
if (Transitions.ENABLE_SHELL_TRANSITIONS) {
- transitions.startTransition(TRANSIT_TO_FRONT, wct, null /* handler */)
+ // TODO(b/268662477): add animation for the transition
+ transitions.startTransition(TRANSIT_NONE, wct, null /* handler */)
} else {
shellTaskOrganizer.applyTransaction(wct)
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeControllerTest.java
index 7997a7e..43f8f7b 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeControllerTest.java
@@ -22,6 +22,7 @@
import static android.app.WindowConfiguration.WINDOW_CONFIG_BOUNDS;
import static android.view.WindowManager.TRANSIT_CHANGE;
import static android.view.WindowManager.TRANSIT_CLOSE;
+import static android.view.WindowManager.TRANSIT_NONE;
import static android.view.WindowManager.TRANSIT_OPEN;
import static android.view.WindowManager.TRANSIT_TO_FRONT;
import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REORDER;
@@ -446,7 +447,7 @@
final ArgumentCaptor<WindowContainerTransaction> arg = ArgumentCaptor.forClass(
WindowContainerTransaction.class);
if (Transitions.ENABLE_SHELL_TRANSITIONS) {
- verify(mTransitions).startTransition(eq(TRANSIT_TO_FRONT), arg.capture(), any());
+ verify(mTransitions).startTransition(eq(TRANSIT_NONE), arg.capture(), any());
} else {
verify(mShellTaskOrganizer).applyTransaction(arg.capture());
}
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 f16beee..95e78a8 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
@@ -26,6 +26,8 @@
import android.os.Binder
import android.testing.AndroidTestingRunner
import android.view.WindowManager
+import android.view.WindowManager.TRANSIT_CHANGE
+import android.view.WindowManager.TRANSIT_NONE
import android.view.WindowManager.TRANSIT_OPEN
import android.view.WindowManager.TRANSIT_TO_FRONT
import android.window.TransitionRequestInfo
@@ -55,6 +57,7 @@
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentCaptor
+import org.mockito.ArgumentMatchers.eq
import org.mockito.ArgumentMatchers.isNull
import org.mockito.Mock
import org.mockito.Mockito
@@ -141,7 +144,7 @@
controller.showDesktopApps()
- val wct = getLatestWct()
+ val wct = getLatestWct(expectTransition = TRANSIT_NONE)
assertThat(wct.hierarchyOps).hasSize(3)
// Expect order to be from bottom: home, task1, task2
wct.assertReorderAt(index = 0, homeTask)
@@ -159,7 +162,7 @@
controller.showDesktopApps()
- val wct = getLatestWct()
+ val wct = getLatestWct(expectTransition = TRANSIT_NONE)
assertThat(wct.hierarchyOps).hasSize(3)
// Expect order to be from bottom: home, task1, task2
wct.assertReorderAt(index = 0, homeTask)
@@ -177,7 +180,7 @@
controller.showDesktopApps()
- val wct = getLatestWct()
+ val wct = getLatestWct(expectTransition = TRANSIT_NONE)
assertThat(wct.hierarchyOps).hasSize(3)
// Expect order to be from bottom: home, task1, task2
wct.assertReorderAt(index = 0, homeTask)
@@ -191,7 +194,7 @@
controller.showDesktopApps()
- val wct = getLatestWct()
+ val wct = getLatestWct(expectTransition = TRANSIT_NONE)
assertThat(wct.hierarchyOps).hasSize(1)
wct.assertReorderAt(index = 0, homeTask)
}
@@ -221,7 +224,7 @@
fun moveToDesktop() {
val task = setUpFullscreenTask()
controller.moveToDesktop(task)
- val wct = getLatestWct()
+ val wct = getLatestWct(expectTransition = TRANSIT_CHANGE)
assertThat(wct.changes[task.token.asBinder()]?.windowingMode)
.isEqualTo(WINDOWING_MODE_FREEFORM)
}
@@ -241,7 +244,7 @@
controller.moveToDesktop(fullscreenTask)
- with(getLatestWct()) {
+ with(getLatestWct(expectTransition = TRANSIT_CHANGE)) {
assertThat(hierarchyOps).hasSize(3)
assertReorderSequence(homeTask, freeformTask, fullscreenTask)
assertThat(changes[fullscreenTask.token.asBinder()]?.windowingMode)
@@ -253,7 +256,7 @@
fun moveToFullscreen() {
val task = setUpFreeformTask()
controller.moveToFullscreen(task)
- val wct = getLatestWct()
+ val wct = getLatestWct(expectTransition = TRANSIT_CHANGE)
assertThat(wct.changes[task.token.asBinder()]?.windowingMode)
.isEqualTo(WINDOWING_MODE_FULLSCREEN)
}
@@ -415,10 +418,12 @@
desktopModeTaskRepository.updateVisibleFreeformTasks(task.taskId, visible = false)
}
- private fun getLatestWct(): WindowContainerTransaction {
+ private fun getLatestWct(
+ @WindowManager.TransitionType expectTransition: Int = TRANSIT_OPEN
+ ): WindowContainerTransaction {
val arg = ArgumentCaptor.forClass(WindowContainerTransaction::class.java)
if (ENABLE_SHELL_TRANSITIONS) {
- verify(transitions).startTransition(anyInt(), arg.capture(), isNull())
+ verify(transitions).startTransition(eq(expectTransition), arg.capture(), isNull())
} else {
verify(shellTaskOrganizer).applyTransaction(arg.capture())
}
diff --git a/libs/hwui/renderthread/DrawFrameTask.cpp b/libs/hwui/renderthread/DrawFrameTask.cpp
index 59c914f..4ceb13e 100644
--- a/libs/hwui/renderthread/DrawFrameTask.cpp
+++ b/libs/hwui/renderthread/DrawFrameTask.cpp
@@ -278,6 +278,11 @@
mSignal.signal();
}
+void DrawFrameTask::createHintSession(pid_t uiThreadId, pid_t renderThreadId) {
+ if (mHintSessionWrapper) return;
+ mHintSessionWrapper.emplace(uiThreadId, renderThreadId);
+}
+
DrawFrameTask::HintSessionWrapper::HintSessionWrapper(int32_t uiThreadId, int32_t renderThreadId) {
if (!Properties::useHintManager) return;
if (uiThreadId < 0 || renderThreadId < 0) return;
diff --git a/libs/hwui/renderthread/DrawFrameTask.h b/libs/hwui/renderthread/DrawFrameTask.h
index d6fc292..b135a21 100644
--- a/libs/hwui/renderthread/DrawFrameTask.h
+++ b/libs/hwui/renderthread/DrawFrameTask.h
@@ -90,6 +90,8 @@
void forceDrawNextFrame() { mForceDrawFrame = true; }
+ void createHintSession(pid_t uiThreadId, pid_t renderThreadId);
+
private:
class HintSessionWrapper {
public:
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index a44b498..d9b650c 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -38,11 +38,18 @@
RenderProxy::RenderProxy(bool translucent, RenderNode* rootRenderNode,
IContextFactory* contextFactory)
: mRenderThread(RenderThread::getInstance()), mContext(nullptr) {
- mContext = mRenderThread.queue().runSync([&]() -> CanvasContext* {
- return CanvasContext::create(mRenderThread, translucent, rootRenderNode, contextFactory);
+ pid_t uiThreadId = pthread_gettid_np(pthread_self());
+ pid_t renderThreadId = getRenderThreadTid();
+ mContext = mRenderThread.queue().runSync([=, this]() -> CanvasContext* {
+ CanvasContext* context =
+ CanvasContext::create(mRenderThread, translucent, rootRenderNode, contextFactory);
+ if (context != nullptr) {
+ mRenderThread.queue().post(
+ [=] { mDrawFrameTask.createHintSession(uiThreadId, renderThreadId); });
+ }
+ return context;
});
- mDrawFrameTask.setContext(&mRenderThread, mContext, rootRenderNode,
- pthread_gettid_np(pthread_self()), getRenderThreadTid());
+ mDrawFrameTask.setContext(&mRenderThread, mContext, rootRenderNode, uiThreadId, renderThreadId);
}
RenderProxy::~RenderProxy() {
diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp
index 2529157..ed62c5f 100644
--- a/packages/SystemUI/Android.bp
+++ b/packages/SystemUI/Android.bp
@@ -204,6 +204,45 @@
path: "tests/utils/src",
}
+filegroup {
+ name: "SystemUI-tests-robolectric-pilots",
+ srcs: [
+ // data
+ "tests/src/com/android/systemui/keyguard/data/quickaffordance/CameraQuickAffordanceConfigTest.kt",
+ "tests/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfigTest.kt",
+ "tests/src/com/android/systemui/keyguard/data/quickaffordance/FakeKeyguardQuickAffordanceConfig.kt",
+ "tests/src/com/android/systemui/keyguard/data/quickaffordance/FlashlightQuickAffordanceConfigTest.kt",
+ "tests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigTest.kt",
+ "tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLegacySettingSyncerTest.kt",
+ "tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManagerTest.kt",
+ "tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceRemoteUserSelectionManagerTest.kt",
+ "tests/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfigTest.kt",
+ "tests/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfigTest.kt",
+ "tests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt",
+ "tests/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryImplTest.kt",
+ // domain
+ "tests/src/com/android/systemui/keyguard/domain/interactor/AlternateBouncerInteractorTest.kt",
+ "tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorTest.kt",
+ "tests/src/com/android/systemui/keyguard/domain/interactor/AlternateBouncerInteractorTest.kt",
+ "tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorTest.kt",
+ "tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt",
+ "tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorTest.kt",
+ "tests/src/com/android/systemui/keyguard/domain/interactor/LightRevealScrimInteractorTest.kt",
+ "tests/src/com/android/systemui/keyguard/domain/quickaffordance/FakeKeyguardQuickAffordanceRegistry.kt",
+ "tests/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractorWithCoroutinesTest.kt",
+ "tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorTest.kt",
+ "tests/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractorWithCoroutinesTest.kt",
+ // ui
+ "tests/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModelTest.kt",
+ "tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBouncerViewModelTest.kt",
+ "tests/src/com/android/systemui/keyguard/ui/viewmodel/GoneToDreamingTransitionViewModelTest.kt",
+ "tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingTransitionViewModelTest.kt",
+ "tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModelTest.kt",
+ "tests/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModelTest.kt",
+ ],
+ path: "tests/src",
+}
+
java_library {
name: "SystemUI-tests-concurrency",
srcs: [
@@ -315,8 +354,16 @@
defaults: [
"platform_app_defaults",
"SystemUI_app_defaults",
+ "SystemUI_compose_defaults",
],
manifest: "tests/AndroidManifest-base.xml",
+
+ srcs: [
+ "src/**/*.kt",
+ "src/**/*.java",
+ "src/**/I*.aidl",
+ ":ReleaseJavaFiles",
+ ],
static_libs: [
"SystemUI-tests-base",
],
@@ -330,6 +377,9 @@
certificate: "platform",
privileged: true,
resource_dirs: [],
+ kotlincflags: ["-Xjvm-default=all"],
+
+ plugins: ["dagger2-compiler"],
}
android_robolectric_test {
@@ -337,6 +387,13 @@
srcs: [
"tests/robolectric/src/**/*.kt",
"tests/robolectric/src/**/*.java",
+ ":SystemUI-tests-utils",
+ ":SystemUI-tests-robolectric-pilots",
+ ],
+ static_libs: [
+ "androidx.test.uiautomator_uiautomator",
+ "androidx.test.ext.junit",
+ "inline-mockito-robolectric-prebuilt",
],
libs: [
"android.test.runner",
@@ -344,7 +401,9 @@
"android.test.mock",
"truth-prebuilt",
],
- kotlincflags: ["-Xjvm-default=enable"],
+
+ upstream: true,
+
instrumentation_for: "SystemUIRobo-stub",
java_resource_dirs: ["tests/robolectric/config"],
}
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockRegistry.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockRegistry.kt
index a523cf1..ed6e619 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockRegistry.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockRegistry.kt
@@ -13,11 +13,13 @@
*/
package com.android.systemui.shared.clocks
+import android.app.ActivityManager
+import android.app.UserSwitchObserver
import android.content.Context
import android.database.ContentObserver
import android.graphics.drawable.Drawable
import android.net.Uri
-import android.os.Handler
+import android.os.UserHandle
import android.provider.Settings
import android.util.Log
import androidx.annotation.OpenForTesting
@@ -29,17 +31,23 @@
import com.android.systemui.plugins.ClockSettings
import com.android.systemui.plugins.PluginListener
import com.android.systemui.plugins.PluginManager
+import com.android.systemui.util.Assert
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.launch
-private val TAG = ClockRegistry::class.simpleName
+private val TAG = ClockRegistry::class.simpleName!!
private const val DEBUG = true
/** ClockRegistry aggregates providers and plugins */
open class ClockRegistry(
val context: Context,
val pluginManager: PluginManager,
- val handler: Handler,
+ val scope: CoroutineScope,
+ val mainDispatcher: CoroutineDispatcher,
+ val bgDispatcher: CoroutineDispatcher,
val isEnabled: Boolean,
- userHandle: Int,
+ val handleAllUsers: Boolean,
defaultClockProvider: ClockProvider,
val fallbackClockId: ClockId = DEFAULT_CLOCK_ID,
) {
@@ -50,66 +58,132 @@
private val availableClocks = mutableMapOf<ClockId, ClockInfo>()
private val clockChangeListeners = mutableListOf<ClockChangeListener>()
- private val settingObserver = object : ContentObserver(handler) {
- override fun onChange(selfChange: Boolean, uris: Collection<Uri>, flags: Int, userId: Int) =
- clockChangeListeners.forEach { it.onClockChanged() }
- }
+ private val settingObserver =
+ object : ContentObserver(null) {
+ override fun onChange(
+ selfChange: Boolean,
+ uris: Collection<Uri>,
+ flags: Int,
+ userId: Int
+ ) {
+ scope.launch(bgDispatcher) { querySettings() }
+ }
+ }
- private val pluginListener = object : PluginListener<ClockProviderPlugin> {
- override fun onPluginConnected(plugin: ClockProviderPlugin, context: Context) =
- connectClocks(plugin)
+ private val pluginListener =
+ object : PluginListener<ClockProviderPlugin> {
+ override fun onPluginConnected(plugin: ClockProviderPlugin, context: Context) =
+ connectClocks(plugin)
- override fun onPluginDisconnected(plugin: ClockProviderPlugin) =
- disconnectClocks(plugin)
- }
+ override fun onPluginDisconnected(plugin: ClockProviderPlugin) =
+ disconnectClocks(plugin)
+ }
- open var settings: ClockSettings?
- get() {
+ private val userSwitchObserver =
+ object : UserSwitchObserver() {
+ override fun onUserSwitchComplete(newUserId: Int) {
+ scope.launch(bgDispatcher) { querySettings() }
+ }
+ }
+
+ // TODO(b/267372164): Migrate to flows
+ var settings: ClockSettings? = null
+ get() = field
+ protected set(value) {
+ if (field != value) {
+ field = value
+ scope.launch(mainDispatcher) { onClockChanged() }
+ }
+ }
+
+ var isRegistered: Boolean = false
+ private set
+
+ @OpenForTesting
+ open fun querySettings() {
+ assertNotMainThread()
+ val result =
try {
- val json = Settings.Secure.getString(
- context.contentResolver,
- Settings.Secure.LOCK_SCREEN_CUSTOM_CLOCK_FACE
- )
- if (json == null || json.isEmpty()) {
- return null
- }
- return ClockSettings.deserialize(json)
+ val json =
+ if (handleAllUsers) {
+ Settings.Secure.getStringForUser(
+ context.contentResolver,
+ Settings.Secure.LOCK_SCREEN_CUSTOM_CLOCK_FACE,
+ ActivityManager.getCurrentUser()
+ )
+ } else {
+ Settings.Secure.getString(
+ context.contentResolver,
+ Settings.Secure.LOCK_SCREEN_CUSTOM_CLOCK_FACE
+ )
+ }
+
+ ClockSettings.deserialize(json)
} catch (ex: Exception) {
Log.e(TAG, "Failed to parse clock settings", ex)
- return null
+ null
}
- }
- protected set(value) {
- try {
- val json = if (value != null) {
- value._applied_timestamp = System.currentTimeMillis()
- ClockSettings.serialize(value)
- } else {
- ""
- }
+ settings = result
+ }
+ @OpenForTesting
+ open fun applySettings(value: ClockSettings?) {
+ assertNotMainThread()
+
+ try {
+ value?._applied_timestamp = System.currentTimeMillis()
+ val json = ClockSettings.serialize(value)
+
+ if (handleAllUsers) {
+ Settings.Secure.putStringForUser(
+ context.contentResolver,
+ Settings.Secure.LOCK_SCREEN_CUSTOM_CLOCK_FACE,
+ json,
+ ActivityManager.getCurrentUser()
+ )
+ } else {
Settings.Secure.putString(
context.contentResolver,
- Settings.Secure.LOCK_SCREEN_CUSTOM_CLOCK_FACE, json
+ Settings.Secure.LOCK_SCREEN_CUSTOM_CLOCK_FACE,
+ json
)
- } catch (ex: Exception) {
- Log.e(TAG, "Failed to set clock settings", ex)
}
+ } catch (ex: Exception) {
+ Log.e(TAG, "Failed to set clock settings", ex)
}
+ settings = value
+ }
- private fun mutateSetting(mutator: (ClockSettings) -> Unit) {
- val settings = this.settings ?: ClockSettings()
- mutator(settings)
- this.settings = settings
+ @OpenForTesting
+ protected open fun assertMainThread() {
+ Assert.isMainThread()
+ }
+
+ @OpenForTesting
+ protected open fun assertNotMainThread() {
+ Assert.isNotMainThread()
+ }
+
+ private fun onClockChanged() {
+ assertMainThread()
+ clockChangeListeners.forEach { it.onClockChanged() }
+ }
+
+ private fun mutateSetting(mutator: (ClockSettings) -> ClockSettings) {
+ scope.launch(bgDispatcher) { applySettings(mutator(settings ?: ClockSettings())) }
}
var currentClockId: ClockId
get() = settings?.clockId ?: fallbackClockId
- set(value) { mutateSetting { it.clockId = value } }
+ set(value) {
+ mutateSetting { it.copy(clockId = value) }
+ }
var seedColor: Int?
get() = settings?.seedColor
- set(value) { mutateSetting { it.seedColor = value } }
+ set(value) {
+ mutateSetting { it.copy(seedColor = value) }
+ }
init {
connectClocks(defaultClockProvider)
@@ -118,19 +192,51 @@
"$defaultClockProvider did not register clock at $DEFAULT_CLOCK_ID"
)
}
+ }
- if (isEnabled) {
- pluginManager.addPluginListener(
- pluginListener,
- ClockProviderPlugin::class.java,
- /*allowMultiple=*/ true
- )
+ fun registerListeners() {
+ if (!isEnabled || isRegistered) {
+ return
+ }
+
+ isRegistered = true
+
+ pluginManager.addPluginListener(
+ pluginListener,
+ ClockProviderPlugin::class.java,
+ /*allowMultiple=*/ true
+ )
+
+ scope.launch(bgDispatcher) { querySettings() }
+ if (handleAllUsers) {
context.contentResolver.registerContentObserver(
Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_CUSTOM_CLOCK_FACE),
/*notifyForDescendants=*/ false,
settingObserver,
- userHandle
+ UserHandle.USER_ALL
)
+
+ ActivityManager.getService().registerUserSwitchObserver(userSwitchObserver, TAG)
+ } else {
+ context.contentResolver.registerContentObserver(
+ Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_CUSTOM_CLOCK_FACE),
+ /*notifyForDescendants=*/ false,
+ settingObserver
+ )
+ }
+ }
+
+ fun unregisterListeners() {
+ if (!isRegistered) {
+ return
+ }
+
+ isRegistered = false
+
+ pluginManager.removePluginListener(pluginListener)
+ context.contentResolver.unregisterContentObserver(settingObserver)
+ if (handleAllUsers) {
+ ActivityManager.getService().unregisterUserSwitchObserver(userSwitchObserver)
}
}
@@ -157,7 +263,7 @@
if (DEBUG) {
Log.i(TAG, "Current clock ($currentId) was connected")
}
- clockChangeListeners.forEach { it.onClockChanged() }
+ onClockChanged()
}
}
}
@@ -172,13 +278,12 @@
if (currentId == clock.clockId) {
Log.w(TAG, "Current clock ($currentId) was disconnected")
- clockChangeListeners.forEach { it.onClockChanged() }
+ onClockChanged()
}
}
}
- @OpenForTesting
- open fun getClocks(): List<ClockMetadata> {
+ fun getClocks(): List<ClockMetadata> {
if (!isEnabled) {
return listOf(availableClocks[DEFAULT_CLOCK_ID]!!.metadata)
}
@@ -213,16 +318,16 @@
return createClock(DEFAULT_CLOCK_ID)!!
}
- private fun createClock(clockId: ClockId): ClockController? {
- val settings = this.settings ?: ClockSettings()
- if (clockId != settings.clockId) {
- settings.clockId = clockId
+ private fun createClock(targetClockId: ClockId): ClockController? {
+ var settings = this.settings ?: ClockSettings()
+ if (targetClockId != settings.clockId) {
+ settings = settings.copy(clockId = targetClockId)
}
- return availableClocks[clockId]?.provider?.createClock(settings)
+ return availableClocks[targetClockId]?.provider?.createClock(settings)
}
private data class ClockInfo(
val metadata: ClockMetadata,
- val provider: ClockProvider
+ val provider: ClockProvider,
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/util/Assert.java b/packages/SystemUI/customization/src/com/android/systemui/util/Assert.java
similarity index 100%
rename from packages/SystemUI/src/com/android/systemui/util/Assert.java
rename to packages/SystemUI/customization/src/com/android/systemui/util/Assert.java
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 590015d..1c2f38b 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockProviderPlugin.kt
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockProviderPlugin.kt
@@ -45,7 +45,7 @@
/** Initializes and returns the target clock design */
@Deprecated("Use overload with ClockSettings")
fun createClock(id: ClockId): ClockController {
- return createClock(ClockSettings(id, null, null))
+ return createClock(ClockSettings(id, null))
}
/** Initializes and returns the target clock design */
@@ -186,16 +186,21 @@
/** Structure for keeping clock-specific settings */
@Keep
data class ClockSettings(
- var clockId: ClockId? = null,
- var seedColor: Int? = null,
- var _applied_timestamp: Long? = null,
+ val clockId: ClockId? = null,
+ val seedColor: Int? = null,
) {
+ var _applied_timestamp: Long? = null
+
companion object {
private val KEY_CLOCK_ID = "clockId"
private val KEY_SEED_COLOR = "seedColor"
private val KEY_TIMESTAMP = "_applied_timestamp"
- fun serialize(setting: ClockSettings): String {
+ fun serialize(setting: ClockSettings?): String {
+ if (setting == null) {
+ return ""
+ }
+
return JSONObject()
.put(KEY_CLOCK_ID, setting.clockId)
.put(KEY_SEED_COLOR, setting.seedColor)
@@ -203,13 +208,21 @@
.toString()
}
- fun deserialize(jsonStr: String): ClockSettings {
+ fun deserialize(jsonStr: String?): ClockSettings? {
+ if (jsonStr.isNullOrEmpty()) {
+ return null
+ }
+
val json = JSONObject(jsonStr)
- return ClockSettings(
- json.getString(KEY_CLOCK_ID),
- if (!json.isNull(KEY_SEED_COLOR)) json.getInt(KEY_SEED_COLOR) else null,
- if (!json.isNull(KEY_TIMESTAMP)) json.getLong(KEY_TIMESTAMP) else null
- )
+ val result =
+ ClockSettings(
+ json.getString(KEY_CLOCK_ID),
+ if (!json.isNull(KEY_SEED_COLOR)) json.getInt(KEY_SEED_COLOR) else null
+ )
+ if (!json.isNull(KEY_TIMESTAMP)) {
+ result._applied_timestamp = json.getLong(KEY_TIMESTAMP)
+ }
+ return result
}
}
}
diff --git a/packages/SystemUI/res/xml/media_session_collapsed.xml b/packages/SystemUI/res/xml/media_session_collapsed.xml
index d9c81af..5129fc0 100644
--- a/packages/SystemUI/res/xml/media_session_collapsed.xml
+++ b/packages/SystemUI/res/xml/media_session_collapsed.xml
@@ -73,11 +73,12 @@
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/qs_media_info_spacing"
android:layout_marginBottom="@dimen/qs_media_padding"
- android:layout_marginTop="0dp"
+ android:layout_marginTop="@dimen/qs_media_icon_offset"
app:layout_constraintStart_toStartOf="@id/header_title"
app:layout_constraintEnd_toStartOf="@id/header_artist"
app:layout_constraintTop_toTopOf="@id/header_artist"
- app:layout_constraintBottom_toTopOf="@id/media_action_barrier_top"
+ app:layout_constraintBottom_toBottomOf="@id/header_artist"
+ app:layout_constraintVertical_bias="0"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintHorizontal_chainStyle="packed" />
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
index 4acbb0a..0326b6d 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
@@ -209,7 +209,6 @@
if (!animate) {
out.setAlpha(0f);
- out.setVisibility(INVISIBLE);
in.setAlpha(1f);
in.setVisibility(VISIBLE);
mStatusArea.setTranslationY(statusAreaYTranslation);
@@ -225,10 +224,7 @@
direction * -mClockSwitchYAmount));
mClockOutAnim.addListener(new AnimatorListenerAdapter() {
public void onAnimationEnd(Animator animation) {
- if (mClockOutAnim == animation) {
- out.setVisibility(INVISIBLE);
- mClockOutAnim = null;
- }
+ mClockOutAnim = null;
}
});
@@ -242,9 +238,7 @@
mClockInAnim.setStartDelay(CLOCK_OUT_MILLIS / 2);
mClockInAnim.addListener(new AnimatorListenerAdapter() {
public void onAnimationEnd(Animator animation) {
- if (mClockInAnim == animation) {
- mClockInAnim = null;
- }
+ mClockInAnim = null;
}
});
@@ -257,9 +251,7 @@
mStatusAreaAnim.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
mStatusAreaAnim.addListener(new AnimatorListenerAdapter() {
public void onAnimationEnd(Animator animation) {
- if (mStatusAreaAnim == animation) {
- mStatusAreaAnim = null;
- }
+ mStatusAreaAnim = null;
}
});
mStatusAreaAnim.start();
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
index 879a95c..baaeb2a 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
@@ -404,6 +404,10 @@
int clockHeight = clock.getLargeClock().getView().getHeight();
return frameHeight / 2 + clockHeight / 2 + mKeyguardLargeClockTopMargin / -2;
} else {
+ // This is only called if we've never shown the large clock as the frame is inflated
+ // with 'gone', but then the visibility is never set when it is animated away by
+ // KeyguardClockSwitch, instead it is removed from the view hierarchy.
+ // TODO(b/261755021): Cleanup Large Frame Visibility
int clockHeight = clock.getSmallClock().getView().getHeight();
return clockHeight + statusBarHeaderHeight + mKeyguardSmallClockTopMargin;
}
@@ -421,11 +425,15 @@
if (mLargeClockFrame.getVisibility() == View.VISIBLE) {
return clock.getLargeClock().getView().getHeight();
} else {
+ // Is not called except in certain edge cases, see comment in getClockBottom
+ // TODO(b/261755021): Cleanup Large Frame Visibility
return clock.getSmallClock().getView().getHeight();
}
}
boolean isClockTopAligned() {
+ // Returns false except certain edge cases, see comment in getClockBottom
+ // TODO(b/261755021): Cleanup Large Frame Visibility
return mLargeClockFrame.getVisibility() != View.VISIBLE;
}
diff --git a/packages/SystemUI/src/com/android/keyguard/dagger/ClockRegistryModule.java b/packages/SystemUI/src/com/android/keyguard/dagger/ClockRegistryModule.java
index 676979c..b1a83fb 100644
--- a/packages/SystemUI/src/com/android/keyguard/dagger/ClockRegistryModule.java
+++ b/packages/SystemUI/src/com/android/keyguard/dagger/ClockRegistryModule.java
@@ -18,13 +18,12 @@
import android.content.Context;
import android.content.res.Resources;
-import android.os.Handler;
-import android.os.UserHandle;
import android.view.LayoutInflater;
import com.android.systemui.R;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Application;
+import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.flags.Flags;
@@ -34,6 +33,8 @@
import dagger.Module;
import dagger.Provides;
+import kotlinx.coroutines.CoroutineDispatcher;
+import kotlinx.coroutines.CoroutineScope;
/** Dagger Module for clocks. */
@Module
@@ -44,17 +45,23 @@
public static ClockRegistry getClockRegistry(
@Application Context context,
PluginManager pluginManager,
- @Main Handler handler,
+ @Application CoroutineScope scope,
+ @Main CoroutineDispatcher mainDispatcher,
+ @Background CoroutineDispatcher bgDispatcher,
FeatureFlags featureFlags,
@Main Resources resources,
LayoutInflater layoutInflater) {
- return new ClockRegistry(
+ ClockRegistry registry = new ClockRegistry(
context,
pluginManager,
- handler,
+ scope,
+ mainDispatcher,
+ bgDispatcher,
featureFlags.isEnabled(Flags.LOCKSCREEN_CUSTOM_CLOCKS),
- UserHandle.USER_ALL,
+ /* handleAllUsers= */ true,
new DefaultClockProvider(context, layoutInflater, resources),
context.getString(R.string.lockscreen_clock_id_fallback));
+ registry.registerListeners();
+ return registry;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintIconController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintIconController.kt
index 1f6f6d9..3ea3cd1 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintIconController.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintIconController.kt
@@ -18,6 +18,7 @@
import android.annotation.RawRes
import android.content.Context
+import android.content.Context.FINGERPRINT_SERVICE
import android.content.res.Configuration
import android.hardware.fingerprint.FingerprintManager
import android.view.DisplayInfo
@@ -66,16 +67,11 @@
R.dimen.biometric_dialog_fingerprint_icon_width),
context.resources.getDimensionPixelSize(
R.dimen.biometric_dialog_fingerprint_icon_height))
- var sideFps = false
- (context.getSystemService(Context.FINGERPRINT_SERVICE)
- as FingerprintManager?)?.let { fpm ->
- for (prop in fpm.sensorPropertiesInternal) {
- if (prop.isAnySidefpsType) {
- sideFps = true
- }
- }
- }
- isSideFps = sideFps
+ isSideFps =
+ (context.getSystemService(FINGERPRINT_SERVICE) as FingerprintManager?)?.let { fpm ->
+ fpm.sensorPropertiesInternal.any { it.isAnySidefpsType }
+ } ?: false
+ preloadAssets(context)
val displayInfo = DisplayInfo()
context.display?.getDisplayInfo(displayInfo)
if (isSideFps && getRotationFromDefault(displayInfo.rotation) == Surface.ROTATION_180) {
@@ -329,6 +325,40 @@
else -> null
}
+ private fun preloadAssets(context: Context) {
+ if (isSideFps) {
+ cacheLottieAssetsInContext(
+ context,
+ R.raw.biometricprompt_fingerprint_to_error_landscape,
+ R.raw.biometricprompt_folded_base_bottomright,
+ R.raw.biometricprompt_folded_base_default,
+ R.raw.biometricprompt_folded_base_topleft,
+ R.raw.biometricprompt_landscape_base,
+ R.raw.biometricprompt_portrait_base_bottomright,
+ R.raw.biometricprompt_portrait_base_topleft,
+ R.raw.biometricprompt_symbol_error_to_fingerprint_landscape,
+ R.raw.biometricprompt_symbol_error_to_fingerprint_portrait_bottomright,
+ R.raw.biometricprompt_symbol_error_to_fingerprint_portrait_topleft,
+ R.raw.biometricprompt_symbol_error_to_success_landscape,
+ R.raw.biometricprompt_symbol_error_to_success_portrait_bottomright,
+ R.raw.biometricprompt_symbol_error_to_success_portrait_topleft,
+ R.raw.biometricprompt_symbol_fingerprint_to_error_portrait_bottomright,
+ R.raw.biometricprompt_symbol_fingerprint_to_error_portrait_topleft,
+ R.raw.biometricprompt_symbol_fingerprint_to_success_landscape,
+ R.raw.biometricprompt_symbol_fingerprint_to_success_portrait_bottomright,
+ R.raw.biometricprompt_symbol_fingerprint_to_success_portrait_topleft
+ )
+ } else {
+ cacheLottieAssetsInContext(
+ context,
+ R.raw.fingerprint_dialogue_error_to_fingerprint_lottie,
+ R.raw.fingerprint_dialogue_error_to_success_lottie,
+ R.raw.fingerprint_dialogue_fingerprint_to_error_lottie,
+ R.raw.fingerprint_dialogue_fingerprint_to_success_lottie
+ )
+ }
+ }
+
override fun onFoldUpdated(isFolded: Boolean) {
isDeviceFolded = isFolded
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricIconController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthIconController.kt
similarity index 86%
rename from packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricIconController.kt
rename to packages/SystemUI/src/com/android/systemui/biometrics/AuthIconController.kt
index b3b6fa2..d6ad4da 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricIconController.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthIconController.kt
@@ -24,14 +24,15 @@
import android.graphics.drawable.Drawable
import android.util.Log
import com.airbnb.lottie.LottieAnimationView
+import com.airbnb.lottie.LottieCompositionFactory
import com.android.systemui.biometrics.AuthBiometricView.BiometricState
private const val TAG = "AuthIconController"
/** Controller for animating the BiometricPrompt icon/affordance. */
abstract class AuthIconController(
- protected val context: Context,
- protected val iconView: LottieAnimationView
+ protected val context: Context,
+ protected val iconView: LottieAnimationView
) : Animatable2.AnimationCallback() {
/** If this controller should ignore events and pause. */
@@ -94,4 +95,12 @@
open fun handleAnimationEnd(drawable: Drawable) {}
open fun onConfigurationChanged(newConfig: Configuration) {}
+
+ // TODO(b/251476085): Migrate this to an extension at the appropriate level?
+ /** Load the given [rawResources] immediately so they are cached for use in the [context]. */
+ protected fun cacheLottieAssetsInContext(context: Context, vararg rawResources: Int) {
+ for (res in rawResources) {
+ LottieCompositionFactory.fromRawRes(context, res)
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemPropertiesFlagsModule.kt b/packages/SystemUI/src/com/android/systemui/dagger/SystemPropertiesFlagsModule.kt
new file mode 100644
index 0000000..c6f833b
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemPropertiesFlagsModule.kt
@@ -0,0 +1,30 @@
+/*
+ * 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.dagger
+
+import com.android.internal.config.sysui.SystemUiSystemPropertiesFlags
+import dagger.Module
+import dagger.Provides
+
+/** A module which provides access to the default [SystemUiSystemPropertiesFlags.FlagResolver] */
+@Module
+object SystemPropertiesFlagsModule {
+ /** provide the default FlagResolver. */
+ @Provides
+ fun provideFlagResolver(): SystemUiSystemPropertiesFlags.FlagResolver =
+ SystemUiSystemPropertiesFlags.getResolver()
+}
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
index 6274a26..c3ee9be 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
@@ -139,6 +139,7 @@
DemoModeModule.class,
FalsingModule.class,
FlagsModule.class,
+ SystemPropertiesFlagsModule.class,
FooterActionsModule.class,
LogModule.class,
MediaProjectionModule.class,
diff --git a/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsDebug.java b/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsDebug.java
index 4bac697..58fe094 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsDebug.java
+++ b/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsDebug.java
@@ -40,7 +40,6 @@
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.util.settings.GlobalSettings;
-import com.android.systemui.util.settings.SecureSettings;
import org.jetbrains.annotations.NotNull;
@@ -74,7 +73,6 @@
private final FlagManager mFlagManager;
private final Context mContext;
private final GlobalSettings mGlobalSettings;
- private final SecureSettings mSecureSettings;
private final Resources mResources;
private final SystemPropertiesHelper mSystemProperties;
private final ServerFlagReader mServerFlagReader;
@@ -87,8 +85,9 @@
private final ServerFlagReader.ChangeListener mOnPropertiesChanged =
new ServerFlagReader.ChangeListener() {
@Override
- public void onChange() {
- mRestarter.restartSystemUI();
+ public void onChange(Flag<?> flag) {
+ mRestarter.restartSystemUI(
+ "Server flag change: " + flag.getNamespace() + "." + flag.getName());
}
};
@@ -97,7 +96,6 @@
FlagManager flagManager,
Context context,
GlobalSettings globalSettings,
- SecureSettings secureSettings,
SystemPropertiesHelper systemProperties,
@Main Resources resources,
ServerFlagReader serverFlagReader,
@@ -106,7 +104,6 @@
mFlagManager = flagManager;
mContext = context;
mGlobalSettings = globalSettings;
- mSecureSettings = secureSettings;
mResources = resources;
mSystemProperties = systemProperties;
mServerFlagReader = serverFlagReader;
@@ -119,7 +116,8 @@
IntentFilter filter = new IntentFilter();
filter.addAction(ACTION_SET_FLAG);
filter.addAction(ACTION_GET_FLAGS);
- mFlagManager.setOnSettingsChangedAction(this::restartSystemUI);
+ mFlagManager.setOnSettingsChangedAction(
+ suppressRestart -> restartSystemUI(suppressRestart, "Settings changed"));
mFlagManager.setClearCacheAction(this::removeFromCache);
mContext.registerReceiver(mReceiver, filter, null, null,
Context.RECEIVER_EXPORTED_UNAUDITED);
@@ -233,6 +231,10 @@
Boolean result = readBooleanFlagOverride(flag.getName());
if (result == null) {
result = readBooleanFlagOverride(flag.getId());
+ if (result != null) {
+ // Move overrides from id to name
+ setFlagValueInternal(flag.getName(), result, BooleanFlagSerializer.INSTANCE);
+ }
}
boolean hasServerOverride = mServerFlagReader.hasOverride(
flag.getNamespace(), flag.getName());
@@ -305,25 +307,38 @@
requireNonNull(value, "Cannot set a null value");
T currentValue = readFlagValueInternal(name, serializer);
if (Objects.equals(currentValue, value)) {
- Log.i(TAG, "Flag id " + name + " is already " + value);
+ Log.i(TAG, "Flag \"" + name + "\" is already " + value);
return;
}
+ setFlagValueInternal(name, value, serializer);
+ Log.i(TAG, "Set flag \"" + name + "\" to " + value);
+ removeFromCache(name);
+ mFlagManager.dispatchListenersAndMaybeRestart(
+ name,
+ suppressRestart -> restartSystemUI(
+ suppressRestart, "Flag \"" + name + "\" changed to " + value));
+ }
+
+ private <T> void setFlagValueInternal(
+ String name, @NonNull T value, FlagSerializer<T> serializer) {
final String data = serializer.toSettingsData(value);
if (data == null) {
- Log.w(TAG, "Failed to set id " + name + " to " + value);
+ Log.w(TAG, "Failed to set flag " + name + " to " + value);
return;
}
mGlobalSettings.putStringForUser(mFlagManager.nameToSettingsKey(name), data,
UserHandle.USER_CURRENT);
- Log.i(TAG, "Set id " + name + " to " + value);
- removeFromCache(name);
- mFlagManager.dispatchListenersAndMaybeRestart(name, this::restartSystemUI);
}
<T> void eraseFlag(Flag<T> flag) {
if (flag instanceof SysPropFlag) {
- mSystemProperties.erase(((SysPropFlag<T>) flag).getName());
- dispatchListenersAndMaybeRestart(flag.getName(), this::restartAndroid);
+ mSystemProperties.erase(flag.getName());
+ dispatchListenersAndMaybeRestart(
+ flag.getName(),
+ suppressRestart -> restartSystemUI(
+ suppressRestart,
+ "SysProp Flag \"" + flag.getNamespace() + "."
+ + flag.getName() + "\" reset to default."));
} else {
eraseFlag(flag.getName());
}
@@ -333,7 +348,10 @@
private void eraseFlag(String name) {
eraseInternal(name);
removeFromCache(name);
- dispatchListenersAndMaybeRestart(name, this::restartSystemUI);
+ dispatchListenersAndMaybeRestart(
+ name,
+ suppressRestart -> restartSystemUI(
+ suppressRestart, "Flag \"" + name + "\" reset to default"));
}
private void dispatchListenersAndMaybeRestart(String name, Consumer<Boolean> restartAction) {
@@ -367,20 +385,20 @@
mFlagManager.removeListener(listener);
}
- private void restartSystemUI(boolean requestSuppress) {
+ private void restartSystemUI(boolean requestSuppress, String reason) {
if (requestSuppress) {
Log.i(TAG, "SystemUI Restart Suppressed");
return;
}
- mRestarter.restartSystemUI();
+ mRestarter.restartSystemUI(reason);
}
- private void restartAndroid(boolean requestSuppress) {
+ private void restartAndroid(boolean requestSuppress, String reason) {
if (requestSuppress) {
Log.i(TAG, "Android Restart Suppressed");
return;
}
- mRestarter.restartAndroid();
+ mRestarter.restartAndroid(reason);
}
void setBooleanFlagInternal(Flag<?> flag, boolean value) {
@@ -391,8 +409,11 @@
} else if (flag instanceof SysPropBooleanFlag) {
// Store SysProp flags in SystemProperties where they can read by outside parties.
mSystemProperties.setBoolean(((SysPropBooleanFlag) flag).getName(), value);
- dispatchListenersAndMaybeRestart(flag.getName(),
- FeatureFlagsDebug.this::restartAndroid);
+ dispatchListenersAndMaybeRestart(
+ flag.getName(),
+ suppressRestart -> restartSystemUI(
+ suppressRestart,
+ "Flag \"" + flag.getName() + "\" changed to " + value));
} else {
throw new IllegalArgumentException("Unknown flag type");
}
diff --git a/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsDebugRestarter.kt b/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsDebugRestarter.kt
index 069e612..a6956a4 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsDebugRestarter.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsDebugRestarter.kt
@@ -29,6 +29,7 @@
) : Restarter {
private var androidRestartRequested = false
+ private var pendingReason = ""
val observer =
object : WakefulnessLifecycle.Observer {
@@ -38,18 +39,20 @@
}
}
- override fun restartSystemUI() {
+ override fun restartSystemUI(reason: String) {
Log.d(FeatureFlagsDebug.TAG, "SystemUI Restart requested. Restarting on next screen off.")
- scheduleRestart()
+ Log.i(FeatureFlagsDebug.TAG, reason)
+ scheduleRestart(reason)
}
- override fun restartAndroid() {
+ override fun restartAndroid(reason: String) {
Log.d(FeatureFlagsDebug.TAG, "Android Restart requested. Restarting on next screen off.")
androidRestartRequested = true
- scheduleRestart()
+ scheduleRestart(reason)
}
- fun scheduleRestart() {
+ fun scheduleRestart(reason: String) {
+ pendingReason = reason
if (wakefulnessLifecycle.wakefulness == WakefulnessLifecycle.WAKEFULNESS_ASLEEP) {
restartNow()
} else {
@@ -59,9 +62,9 @@
private fun restartNow() {
if (androidRestartRequested) {
- systemExitRestarter.restartAndroid()
+ systemExitRestarter.restartAndroid(pendingReason)
} else {
- systemExitRestarter.restartSystemUI()
+ systemExitRestarter.restartSystemUI(pendingReason)
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsRelease.java b/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsRelease.java
index 7e14237..9859ff6 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsRelease.java
+++ b/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsRelease.java
@@ -57,8 +57,9 @@
private final ServerFlagReader.ChangeListener mOnPropertiesChanged =
new ServerFlagReader.ChangeListener() {
@Override
- public void onChange() {
- mRestarter.restartSystemUI();
+ public void onChange(Flag<?> flag) {
+ mRestarter.restartSystemUI(
+ "Server flag change: " + flag.getNamespace() + "." + flag.getName());
}
};
diff --git a/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsReleaseRestarter.kt b/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsReleaseRestarter.kt
index 7ff3876..c08266c 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsReleaseRestarter.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsReleaseRestarter.kt
@@ -36,41 +36,43 @@
) : Restarter {
var listenersAdded = false
var pendingRestart: Runnable? = null
+ private var pendingReason = ""
var androidRestartRequested = false
val observer =
object : WakefulnessLifecycle.Observer {
override fun onFinishedGoingToSleep() {
- scheduleRestart()
+ scheduleRestart(pendingReason)
}
}
val batteryCallback =
object : BatteryController.BatteryStateChangeCallback {
override fun onBatteryLevelChanged(level: Int, pluggedIn: Boolean, charging: Boolean) {
- scheduleRestart()
+ scheduleRestart(pendingReason)
}
}
- override fun restartSystemUI() {
+ override fun restartSystemUI(reason: String) {
Log.d(
FeatureFlagsDebug.TAG,
"SystemUI Restart requested. Restarting when plugged in and idle."
)
- scheduleRestart()
+ scheduleRestart(reason)
}
- override fun restartAndroid() {
+ override fun restartAndroid(reason: String) {
Log.d(
FeatureFlagsDebug.TAG,
"Android Restart requested. Restarting when plugged in and idle."
)
androidRestartRequested = true
- scheduleRestart()
+ scheduleRestart(reason)
}
- private fun scheduleRestart() {
+ private fun scheduleRestart(reason: String) {
// Don't bother adding listeners twice.
+ pendingReason = reason
if (!listenersAdded) {
listenersAdded = true
wakefulnessLifecycle.addObserver(observer)
@@ -91,9 +93,9 @@
private fun restartNow() {
Log.d(FeatureFlagsRelease.TAG, "Restarting due to systemui flag change")
if (androidRestartRequested) {
- systemExitRestarter.restartAndroid()
+ systemExitRestarter.restartAndroid(pendingReason)
} else {
- systemExitRestarter.restartSystemUI()
+ systemExitRestarter.restartSystemUI(pendingReason)
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/flags/Restarter.kt b/packages/SystemUI/src/com/android/systemui/flags/Restarter.kt
index ce8b821..9c67795 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/Restarter.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/Restarter.kt
@@ -16,7 +16,7 @@
package com.android.systemui.flags
interface Restarter {
- fun restartSystemUI()
+ fun restartSystemUI(reason: String)
- fun restartAndroid()
+ fun restartAndroid(reason: String)
}
diff --git a/packages/SystemUI/src/com/android/systemui/flags/ServerFlagReader.kt b/packages/SystemUI/src/com/android/systemui/flags/ServerFlagReader.kt
index a02b795..e225b10 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/ServerFlagReader.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/ServerFlagReader.kt
@@ -17,8 +17,10 @@
package com.android.systemui.flags
import android.provider.DeviceConfig
+import android.util.Log
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.dagger.qualifiers.TestHarness
import com.android.systemui.util.DeviceConfigProxy
import dagger.Module
import dagger.Provides
@@ -35,21 +37,27 @@
fun listenForChanges(values: Collection<Flag<*>>, listener: ChangeListener)
interface ChangeListener {
- fun onChange()
+ fun onChange(flag: Flag<*>)
}
}
class ServerFlagReaderImpl @Inject constructor(
private val namespace: String,
private val deviceConfig: DeviceConfigProxy,
- @Background private val executor: Executor
+ @Background private val executor: Executor,
+ @TestHarness private val isTestHarness: Boolean
) : ServerFlagReader {
+ private val TAG = "ServerFlagReader"
+
private val listeners =
mutableListOf<Pair<ServerFlagReader.ChangeListener, Collection<Flag<*>>>>()
private val onPropertiesChangedListener = object : DeviceConfig.OnPropertiesChangedListener {
override fun onPropertiesChanged(properties: DeviceConfig.Properties) {
+ if (isTestHarness) {
+ Log.w(TAG, "Ignore server flag changes in Test Harness mode.")
+ }
if (properties.namespace != namespace) {
return
}
@@ -59,7 +67,7 @@
propLoop@ for (propName in properties.keyset) {
for (flag in flags) {
if (propName == getServerOverrideName(flag.id) || propName == flag.name) {
- listener.onChange()
+ listener.onChange(flag)
break@propLoop
}
}
@@ -111,10 +119,11 @@
@SysUISingleton
fun bindsReader(
deviceConfig: DeviceConfigProxy,
- @Background executor: Executor
+ @Background executor: Executor,
+ @TestHarness isTestHarness: Boolean
): ServerFlagReader {
return ServerFlagReaderImpl(
- SYSUI_NAMESPACE, deviceConfig, executor
+ SYSUI_NAMESPACE, deviceConfig, executor, isTestHarness
)
}
}
@@ -139,7 +148,7 @@
for ((listener, flags) in listeners) {
flagLoop@ for (flag in flags) {
if (name == flag.name) {
- listener.onChange()
+ listener.onChange(flag)
break@flagLoop
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/flags/SystemExitRestarter.kt b/packages/SystemUI/src/com/android/systemui/flags/SystemExitRestarter.kt
index 89daa64..46e28a7 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/SystemExitRestarter.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/SystemExitRestarter.kt
@@ -16,6 +16,7 @@
package com.android.systemui.flags
+import android.util.Log
import com.android.internal.statusbar.IStatusBarService
import javax.inject.Inject
@@ -24,11 +25,13 @@
constructor(
private val barService: IStatusBarService,
) : Restarter {
- override fun restartAndroid() {
+ override fun restartAndroid(reason: String) {
+ Log.d(FeatureFlagsDebug.TAG, "Restarting Android: " + reason)
barService.restart()
}
- override fun restartSystemUI() {
+ override fun restartSystemUI(reason: String) {
+ Log.d(FeatureFlagsDebug.TAG, "Restarting SystemUI: " + reason)
System.exit(0)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaViewController.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaViewController.kt
index 1e6002c..b9b0459 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaViewController.kt
@@ -311,16 +311,15 @@
}
// media player
- val controlsTop =
- calculateWidgetGroupAlphaForSquishiness(
- controlIds,
- squishedViewState.measureHeight.toFloat(),
- squishedViewState,
- squishFraction
- )
+ calculateWidgetGroupAlphaForSquishiness(
+ controlIds,
+ squishedViewState.measureHeight.toFloat(),
+ squishedViewState,
+ squishFraction
+ )
calculateWidgetGroupAlphaForSquishiness(
detailIds,
- controlsTop,
+ squishedViewState.measureHeight.toFloat(),
squishedViewState,
squishFraction
)
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaDataUtils.java b/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaDataUtils.java
index 85282a1..e95106e 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaDataUtils.java
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaDataUtils.java
@@ -16,6 +16,7 @@
package com.android.systemui.media.controls.util;
+import android.annotation.Nullable;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
@@ -61,8 +62,9 @@
* @param extras
* @return the progress value between 0-1 inclusive if prsent, otherwise null
*/
- public static Double getDescriptionProgress(Bundle extras) {
- if (!extras.containsKey(MediaConstants.DESCRIPTION_EXTRAS_KEY_COMPLETION_STATUS)) {
+ public static Double getDescriptionProgress(@Nullable Bundle extras) {
+ if (extras == null
+ || !extras.containsKey(MediaConstants.DESCRIPTION_EXTRAS_KEY_COMPLETION_STATUS)) {
return null;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
index 56c34a0..8f1e0a1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
@@ -23,6 +23,7 @@
import android.content.res.Resources;
import android.graphics.Rect;
import android.util.AttributeSet;
+import android.util.IndentingPrintWriter;
import android.util.MathUtils;
import android.view.View;
import android.view.ViewGroup;
@@ -52,6 +53,9 @@
import com.android.systemui.statusbar.notification.stack.StackScrollAlgorithm;
import com.android.systemui.statusbar.notification.stack.ViewState;
import com.android.systemui.statusbar.phone.NotificationIconContainer;
+import com.android.systemui.util.DumpUtilsKt;
+
+import java.io.PrintWriter;
/**
* A notification shelf view that is placed inside the notification scroller. It manages the
@@ -86,7 +90,6 @@
private boolean mInteractive;
private boolean mAnimationsEnabled = true;
private boolean mShowNotificationShelf;
- private float mFirstElementRoundness;
private Rect mClipRect = new Rect();
private int mIndexOfFirstViewInShelf = -1;
private float mCornerAnimationDistance;
@@ -263,8 +266,7 @@
final float actualWidth = mAmbientState.isOnKeyguard()
? MathUtils.lerp(shortestWidth, getWidth(), fractionToShade)
: getWidth();
- ActivatableNotificationView anv = (ActivatableNotificationView) this;
- anv.setBackgroundWidth((int) actualWidth);
+ setBackgroundWidth((int) actualWidth);
if (mShelfIcons != null) {
mShelfIcons.setActualLayoutWidth((int) actualWidth);
}
@@ -365,9 +367,7 @@
boolean expandingAnimated = mAmbientState.isExpansionChanging()
&& !mAmbientState.isPanelTracking();
int baseZHeight = mAmbientState.getBaseZHeight();
- int backgroundTop = 0;
int clipTopAmount = 0;
- float firstElementRoundness = 0.0f;
for (int i = 0; i < mHostLayoutController.getChildCount(); i++) {
ExpandableView child = mHostLayoutController.getChildAt(i);
@@ -420,18 +420,6 @@
if (notGoneIndex != 0 || !aboveShelf) {
expandableRow.setAboveShelf(false);
}
- if (notGoneIndex == 0) {
- StatusBarIconView icon = expandableRow.getEntry().getIcons().getShelfIcon();
- NotificationIconContainer.IconState iconState = getIconState(icon);
- // The icon state might be null in rare cases where the notification is actually
- // added to the layout, but not to the shelf. An example are replied messages,
- // since they don't show up on AOD
- if (iconState != null && iconState.clampedAppearAmount == 1.0f) {
- // only if the first icon is fully in the shelf we want to clip to it!
- backgroundTop = (int) (child.getTranslationY() - getTranslationY());
- firstElementRoundness = expandableRow.getTopRoundness();
- }
- }
previousColor = ownColorUntinted;
notGoneIndex++;
@@ -467,8 +455,6 @@
// TODO(b/172289889) transition last icon in shelf to notification icon and vice versa.
setVisibility(isHidden ? View.INVISIBLE : View.VISIBLE);
- setBackgroundTop(backgroundTop);
- setFirstElementRoundness(firstElementRoundness);
mShelfIcons.setSpeedBumpIndex(mHostLayoutController.getSpeedBumpIndex());
mShelfIcons.calculateIconXTranslations();
mShelfIcons.applyIconStates();
@@ -570,12 +556,6 @@
}
}
- private void setFirstElementRoundness(float firstElementRoundness) {
- if (mFirstElementRoundness != firstElementRoundness) {
- mFirstElementRoundness = firstElementRoundness;
- }
- }
-
private void updateIconClipAmount(ExpandableNotificationRow row) {
float maxTop = row.getTranslationY();
if (getClipTopAmount() != 0) {
@@ -1011,6 +991,18 @@
expandableView.requestRoundnessReset(LegacySourceType.OnScroll);
}
+ @Override
+ public void dump(PrintWriter pwOriginal, String[] args) {
+ IndentingPrintWriter pw = DumpUtilsKt.asIndenting(pwOriginal);
+ super.dump(pw, args);
+ if (DUMP_VERBOSE) {
+ DumpUtilsKt.withIncreasedIndent(pw, () -> {
+ pw.println("mActualWidth: " + mActualWidth);
+ pw.println("mStatusBarHeight: " + mStatusBarHeight);
+ });
+ }
+ }
+
public class ShelfState extends ExpandableViewState {
private boolean hasItemsInStableShelf;
private ExpandableView firstViewInShelf;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotifPipelineFlags.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotifPipelineFlags.kt
index 4856759..fc89be2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotifPipelineFlags.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotifPipelineFlags.kt
@@ -17,13 +17,16 @@
package com.android.systemui.statusbar.notification
import android.content.Context
+import com.android.internal.config.sysui.SystemUiSystemPropertiesFlags.FlagResolver
+import com.android.internal.config.sysui.SystemUiSystemPropertiesFlags.NotificationFlags
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags
import javax.inject.Inject
class NotifPipelineFlags @Inject constructor(
val context: Context,
- val featureFlags: FeatureFlags
+ val featureFlags: FeatureFlags,
+ val sysPropFlags: FlagResolver,
) {
init {
featureFlags.addListener(Flags.DISABLE_FSI) { event -> event.requestNoRestart() }
@@ -39,11 +42,21 @@
fun disableFsi(): Boolean = featureFlags.isEnabled(Flags.DISABLE_FSI)
- val shouldFilterUnseenNotifsOnKeyguard: Boolean by lazy {
- featureFlags.isEnabled(Flags.FILTER_UNSEEN_NOTIFS_ON_KEYGUARD)
- }
+ fun forceDemoteFsi(): Boolean =
+ sysPropFlags.isEnabled(NotificationFlags.FSI_FORCE_DEMOTE)
- val isNoHunForOldWhenEnabled: Boolean by lazy {
- featureFlags.isEnabled(Flags.NO_HUN_FOR_OLD_WHEN)
- }
+ fun showStickyHunForDeniedFsi(): Boolean =
+ sysPropFlags.isEnabled(NotificationFlags.SHOW_STICKY_HUN_FOR_DENIED_FSI)
+
+ fun allowDismissOngoing(): Boolean =
+ sysPropFlags.isEnabled(NotificationFlags.ALLOW_DISMISS_ONGOING)
+
+ fun isOtpRedactionEnabled(): Boolean =
+ sysPropFlags.isEnabled(NotificationFlags.OTP_REDACTION)
+
+ val shouldFilterUnseenNotifsOnKeyguard: Boolean
+ get() = featureFlags.isEnabled(Flags.FILTER_UNSEEN_NOTIFS_ON_KEYGUARD)
+
+ val isNoHunForOldWhenEnabled: Boolean
+ get() = featureFlags.isEnabled(Flags.NO_HUN_FOR_OLD_WHEN)
}
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 7addc8f..68ad49be 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
@@ -23,6 +23,7 @@
import android.graphics.Canvas;
import android.graphics.Point;
import android.util.AttributeSet;
+import android.util.IndentingPrintWriter;
import android.util.MathUtils;
import android.view.Choreographer;
import android.view.MotionEvent;
@@ -43,7 +44,9 @@
import com.android.systemui.statusbar.notification.SourceType;
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
+import com.android.systemui.util.DumpUtilsKt;
+import java.io.PrintWriter;
import java.util.HashSet;
import java.util.Set;
@@ -651,11 +654,6 @@
mBackgroundNormal.setRadius(topRadius, bottomRadius);
}
- @Override
- protected void setBackgroundTop(int backgroundTop) {
- mBackgroundNormal.setBackgroundTop(backgroundTop);
- }
-
protected abstract View getContentView();
public int calculateBgColor() {
@@ -819,6 +817,22 @@
mOnDetachResetRoundness.add(sourceType);
}
+ @Override
+ public void dump(PrintWriter pwOriginal, String[] args) {
+ IndentingPrintWriter pw = DumpUtilsKt.asIndenting(pwOriginal);
+ super.dump(pw, args);
+ if (DUMP_VERBOSE) {
+ DumpUtilsKt.withIncreasedIndent(pw, () -> {
+ pw.println("mBackgroundNormal: " + mBackgroundNormal);
+ if (mBackgroundNormal != null) {
+ DumpUtilsKt.withIncreasedIndent(pw, () -> {
+ mBackgroundNormal.dump(pw, args);
+ });
+ }
+ });
+ }
+ }
+
public interface OnActivatedListener {
void onActivated(ActivatableNotificationView view);
void onActivationReset(ActivatableNotificationView view);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableOutlineView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableOutlineView.java
index 2041245..197caa2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableOutlineView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableOutlineView.java
@@ -24,12 +24,16 @@
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.AttributeSet;
+import android.util.IndentingPrintWriter;
import android.view.View;
import android.view.ViewOutlineProvider;
import com.android.systemui.R;
import com.android.systemui.statusbar.notification.RoundableState;
import com.android.systemui.statusbar.notification.stack.NotificationChildrenContainer;
+import com.android.systemui.util.DumpUtilsKt;
+
+import java.io.PrintWriter;
/**
* Like {@link ExpandableView}, but setting an outline for the height and clipping.
@@ -43,7 +47,6 @@
private float mOutlineAlpha = -1f;
private boolean mAlwaysRoundBothCorners;
private Path mTmpPath = new Path();
- private int mBackgroundTop;
/**
* {@code false} if the children views of the {@link ExpandableOutlineView} are translated when
@@ -59,7 +62,7 @@
// Only when translating just the contents, does the outline need to be shifted.
int translation = !mDismissUsingRowTranslationX ? (int) getTranslation() : 0;
int left = Math.max(translation, 0);
- int top = mClipTopAmount + mBackgroundTop;
+ int top = mClipTopAmount;
int right = getWidth() + Math.min(translation, 0);
int bottom = Math.max(getActualHeight() - mClipBottomAmount, top);
outline.setRect(left, top, right, bottom);
@@ -92,7 +95,7 @@
? (int) getTranslation() : 0;
int halfExtraWidth = (int) (mExtraWidthForClipping / 2.0f);
left = Math.max(translation, 0) - halfExtraWidth;
- top = mClipTopAmount + mBackgroundTop;
+ top = mClipTopAmount;
right = getWidth() + halfExtraWidth + Math.min(translation, 0);
// If the top is rounded we want the bottom to be at most at the top roundness, in order
// to avoid the shadow changing when scrolling up.
@@ -228,13 +231,6 @@
super.applyRoundnessAndInvalidate();
}
- protected void setBackgroundTop(int backgroundTop) {
- if (mBackgroundTop != backgroundTop) {
- mBackgroundTop = backgroundTop;
- invalidateOutline();
- }
- }
-
public void onDensityOrFontScaleChanged() {
initDimens();
applyRoundnessAndInvalidate();
@@ -350,4 +346,18 @@
public Path getCustomClipPath(View child) {
return null;
}
+
+ @Override
+ public void dump(PrintWriter pwOriginal, String[] args) {
+ IndentingPrintWriter pw = DumpUtilsKt.asIndenting(pwOriginal);
+ super.dump(pw, args);
+ DumpUtilsKt.withIncreasedIndent(pw, () -> {
+ pw.println("Roundness: " + getRoundableState().debugString());
+ if (DUMP_VERBOSE) {
+ pw.println("mCustomOutline: " + mCustomOutline + " mOutlineRect: " + mOutlineRect);
+ pw.println("mOutlineAlpha: " + mOutlineAlpha);
+ pw.println("mAlwaysRoundBothCorners: " + mAlwaysRoundBothCorners);
+ }
+ });
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java
index 955d7c1..25c7264 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java
@@ -51,6 +51,8 @@
*/
public abstract class ExpandableView extends FrameLayout implements Dumpable, Roundable {
private static final String TAG = "ExpandableView";
+ /** whether the dump() for this class should include verbose details */
+ protected static final boolean DUMP_VERBOSE = false;
private RoundableState mRoundableState = null;
protected OnHeightChangedListener mOnHeightChangedListener;
@@ -825,6 +827,14 @@
viewState.dump(pw, args);
pw.println();
}
+ if (DUMP_VERBOSE) {
+ pw.println("mClipTopAmount: " + mClipTopAmount);
+ pw.println("mClipBottomAmount " + mClipBottomAmount);
+ pw.println("mClipToActualHeight: " + mClipToActualHeight);
+ pw.println("mExtraWidthForClipping: " + mExtraWidthForClipping);
+ pw.println("mMinimumHeightForClipping: " + mMinimumHeightForClipping);
+ pw.println("getClipBounds(): " + getClipBounds());
+ }
});
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java
index 5171569..da8d2d5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java
@@ -28,12 +28,16 @@
import android.view.View;
import com.android.internal.util.ArrayUtils;
+import com.android.systemui.Dumpable;
import com.android.systemui.R;
+import java.io.PrintWriter;
+import java.util.Arrays;
+
/**
* A view that can be used for both the dimmed and normal background of an notification.
*/
-public class NotificationBackgroundView extends View {
+public class NotificationBackgroundView extends View implements Dumpable {
private final boolean mDontModifyCorners;
private Drawable mBackground;
@@ -42,7 +46,6 @@
private int mTintColor;
private final float[] mCornerRadii = new float[8];
private boolean mBottomIsRounded;
- private int mBackgroundTop;
private boolean mBottomAmountClips = true;
private int mActualHeight = -1;
private int mActualWidth = -1;
@@ -60,8 +63,7 @@
@Override
protected void onDraw(Canvas canvas) {
- if (mClipTopAmount + mClipBottomAmount < getActualHeight() - mBackgroundTop
- || mExpandAnimationRunning) {
+ if (mClipTopAmount + mClipBottomAmount < getActualHeight() || mExpandAnimationRunning) {
canvas.save();
if (!mExpandAnimationRunning) {
canvas.clipRect(0, mClipTopAmount, getWidth(),
@@ -74,7 +76,7 @@
private void draw(Canvas canvas, Drawable drawable) {
if (drawable != null) {
- int top = mBackgroundTop;
+ int top = 0;
int bottom = getActualHeight();
if (mBottomIsRounded
&& mBottomAmountClips
@@ -261,11 +263,6 @@
}
}
- public void setBackgroundTop(int backgroundTop) {
- mBackgroundTop = backgroundTop;
- invalidate();
- }
-
/** Set the current expand animation size. */
public void setExpandAnimationSize(int width, int height) {
mExpandAnimationHeight = height;
@@ -291,4 +288,16 @@
public void setPressedAllowed(boolean allowed) {
mIsPressedAllowed = allowed;
}
+
+ @Override
+ public void dump(PrintWriter pw, String[] args) {
+ pw.println("mDontModifyCorners: " + mDontModifyCorners);
+ pw.println("mClipTopAmount: " + mClipTopAmount);
+ pw.println("mClipBottomAmount: " + mClipBottomAmount);
+ pw.println("mCornerRadii: " + Arrays.toString(mCornerRadii));
+ pw.println("mBottomIsRounded: " + mBottomIsRounded);
+ pw.println("mBottomAmountClips: " + mBottomAmountClips);
+ pw.println("mActualWidth: " + mActualWidth);
+ pw.println("mActualHeight: " + mActualHeight);
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java
index 8dc1e8f..254f953 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java
@@ -16,7 +16,6 @@
package com.android.keyguard;
-import static android.view.View.INVISIBLE;
import static android.view.View.VISIBLE;
import static com.android.keyguard.KeyguardClockSwitch.LARGE;
@@ -190,7 +189,6 @@
assertThat(mLargeClockFrame.getAlpha()).isEqualTo(1);
assertThat(mLargeClockFrame.getVisibility()).isEqualTo(VISIBLE);
assertThat(mSmallClockFrame.getAlpha()).isEqualTo(0);
- assertThat(mSmallClockFrame.getVisibility()).isEqualTo(INVISIBLE);
}
@Test
@@ -200,7 +198,6 @@
assertThat(mLargeClockFrame.getAlpha()).isEqualTo(1);
assertThat(mLargeClockFrame.getVisibility()).isEqualTo(VISIBLE);
assertThat(mSmallClockFrame.getAlpha()).isEqualTo(0);
- assertThat(mSmallClockFrame.getVisibility()).isEqualTo(INVISIBLE);
}
@Test
@@ -215,7 +212,6 @@
// only big clock is removed at switch
assertThat(mLargeClockFrame.getParent()).isNull();
assertThat(mLargeClockFrame.getAlpha()).isEqualTo(0);
- assertThat(mLargeClockFrame.getVisibility()).isEqualTo(INVISIBLE);
}
@Test
@@ -227,7 +223,6 @@
// only big clock is removed at switch
assertThat(mLargeClockFrame.getParent()).isNull();
assertThat(mLargeClockFrame.getAlpha()).isEqualTo(0);
- assertThat(mLargeClockFrame.getVisibility()).isEqualTo(INVISIBLE);
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsDebugRestarterTest.kt b/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsDebugRestarterTest.kt
index ed16721..686782f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsDebugRestarterTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsDebugRestarterTest.kt
@@ -20,6 +20,7 @@
import com.android.systemui.keyguard.WakefulnessLifecycle
import com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_ASLEEP
import com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_AWAKE
+import com.android.systemui.util.mockito.any
import org.junit.Before
import org.junit.Test
import org.mockito.ArgumentCaptor
@@ -48,22 +49,22 @@
@Test
fun testRestart_ImmediateWhenAsleep() {
whenever(wakefulnessLifecycle.wakefulness).thenReturn(WAKEFULNESS_ASLEEP)
- restarter.restartSystemUI()
- verify(systemExitRestarter).restartSystemUI()
+ restarter.restartSystemUI("Restart for test")
+ verify(systemExitRestarter).restartSystemUI(any())
}
@Test
fun testRestart_WaitsForSceenOff() {
whenever(wakefulnessLifecycle.wakefulness).thenReturn(WAKEFULNESS_AWAKE)
- restarter.restartSystemUI()
- verify(systemExitRestarter, never()).restartSystemUI()
+ restarter.restartSystemUI("Restart for test")
+ verify(systemExitRestarter, never()).restartSystemUI(any())
val captor = ArgumentCaptor.forClass(WakefulnessLifecycle.Observer::class.java)
verify(wakefulnessLifecycle).addObserver(captor.capture())
captor.value.onFinishedGoingToSleep()
- verify(systemExitRestarter).restartSystemUI()
+ verify(systemExitRestarter).restartSystemUI(any())
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsDebugTest.kt b/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsDebugTest.kt
index d8bbd04..2bcd75b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsDebugTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsDebugTest.kt
@@ -28,7 +28,6 @@
import com.android.systemui.util.mockito.nullable
import com.android.systemui.util.mockito.withArgCaptor
import com.android.systemui.util.settings.GlobalSettings
-import com.android.systemui.util.settings.SecureSettings
import com.google.common.truth.Truth.assertThat
import org.junit.Assert
import org.junit.Before
@@ -63,8 +62,6 @@
@Mock
private lateinit var globalSettings: GlobalSettings
@Mock
- private lateinit var secureSettings: SecureSettings
- @Mock
private lateinit var systemProperties: SystemPropertiesHelper
@Mock
private lateinit var resources: Resources
@@ -92,7 +89,6 @@
flagManager,
mockContext,
globalSettings,
- secureSettings,
systemProperties,
resources,
serverFlagReader,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsReleaseRestarterTest.kt b/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsReleaseRestarterTest.kt
index 7d807e2..6060afe 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsReleaseRestarterTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsReleaseRestarterTest.kt
@@ -22,6 +22,7 @@
import com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_AWAKE
import com.android.systemui.statusbar.policy.BatteryController
import com.android.systemui.util.concurrency.FakeExecutor
+import com.android.systemui.util.mockito.any
import com.android.systemui.util.time.FakeSystemClock
import com.google.common.truth.Truth.assertThat
import org.junit.Before
@@ -63,7 +64,7 @@
whenever(batteryController.isPluggedIn).thenReturn(true)
assertThat(executor.numPending()).isEqualTo(0)
- restarter.restartSystemUI()
+ restarter.restartSystemUI("Restart for test")
assertThat(executor.numPending()).isEqualTo(1)
}
@@ -72,11 +73,11 @@
whenever(wakefulnessLifecycle.wakefulness).thenReturn(WAKEFULNESS_ASLEEP)
whenever(batteryController.isPluggedIn).thenReturn(true)
- restarter.restartSystemUI()
- verify(systemExitRestarter, never()).restartSystemUI()
+ restarter.restartSystemUI("Restart for test")
+ verify(systemExitRestarter, never()).restartSystemUI("Restart for test")
executor.advanceClockToLast()
executor.runAllReady()
- verify(systemExitRestarter).restartSystemUI()
+ verify(systemExitRestarter).restartSystemUI(any())
}
@Test
@@ -85,7 +86,7 @@
whenever(batteryController.isPluggedIn).thenReturn(true)
assertThat(executor.numPending()).isEqualTo(0)
- restarter.restartSystemUI()
+ restarter.restartSystemUI("Restart for test")
assertThat(executor.numPending()).isEqualTo(0)
}
@@ -95,7 +96,7 @@
whenever(batteryController.isPluggedIn).thenReturn(false)
assertThat(executor.numPending()).isEqualTo(0)
- restarter.restartSystemUI()
+ restarter.restartSystemUI("Restart for test")
assertThat(executor.numPending()).isEqualTo(0)
}
@@ -105,8 +106,8 @@
whenever(batteryController.isPluggedIn).thenReturn(true)
assertThat(executor.numPending()).isEqualTo(0)
- restarter.restartSystemUI()
- restarter.restartSystemUI()
+ restarter.restartSystemUI("Restart for test")
+ restarter.restartSystemUI("Restart for test")
assertThat(executor.numPending()).isEqualTo(1)
}
@@ -115,7 +116,7 @@
whenever(wakefulnessLifecycle.wakefulness).thenReturn(WAKEFULNESS_AWAKE)
whenever(batteryController.isPluggedIn).thenReturn(true)
assertThat(executor.numPending()).isEqualTo(0)
- restarter.restartSystemUI()
+ restarter.restartSystemUI("Restart for test")
val captor = ArgumentCaptor.forClass(WakefulnessLifecycle.Observer::class.java)
verify(wakefulnessLifecycle).addObserver(captor.capture())
@@ -131,7 +132,7 @@
whenever(wakefulnessLifecycle.wakefulness).thenReturn(WAKEFULNESS_ASLEEP)
whenever(batteryController.isPluggedIn).thenReturn(false)
assertThat(executor.numPending()).isEqualTo(0)
- restarter.restartSystemUI()
+ restarter.restartSystemUI("Restart for test")
val captor =
ArgumentCaptor.forClass(BatteryController.BatteryStateChangeCallback::class.java)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/flags/ServerFlagReaderImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/flags/ServerFlagReaderImplTest.kt
index 1633912..4ebf974 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/flags/ServerFlagReaderImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/flags/ServerFlagReaderImplTest.kt
@@ -45,7 +45,7 @@
fun setup() {
MockitoAnnotations.initMocks(this)
- serverFlagReader = ServerFlagReaderImpl(NAMESPACE, deviceConfig, executor)
+ serverFlagReader = ServerFlagReaderImpl(NAMESPACE, deviceConfig, executor, false)
}
@Test
@@ -56,6 +56,6 @@
deviceConfig.setProperty(NAMESPACE, "flag_override_1", "1", false)
executor.runAllReady()
- verify(changeListener).onChange()
+ verify(changeListener).onChange(flag)
}
}
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 58cdec4..db18ba6 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
@@ -20,6 +20,7 @@
import android.app.StatusBarManager
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.SysuiTestCase
import com.android.systemui.camera.CameraGestureHelper
@@ -31,14 +32,13 @@
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
import org.mockito.Mock
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
class CameraQuickAffordanceConfigTest : SysuiTestCase() {
@Mock private lateinit var cameraGestureHelper: CameraGestureHelper
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 15b85de..64839e2 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
@@ -22,6 +22,7 @@
import android.provider.Settings.Global.ZEN_MODE_OFF
import android.provider.Settings.Secure.ZEN_DURATION_FOREVER
import android.provider.Settings.Secure.ZEN_DURATION_PROMPT
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.settingslib.notification.EnableZenModeDialog
import com.android.systemui.R
@@ -51,7 +52,6 @@
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
import org.mockito.ArgumentCaptor
import org.mockito.Captor
import org.mockito.Mock
@@ -60,7 +60,7 @@
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
class DoNotDisturbQuickAffordanceConfigTest : SysuiTestCase() {
@Mock private lateinit var zenModeController: ZenModeController
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 9fa7db1..31391ee 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
@@ -18,6 +18,7 @@
package com.android.systemui.keyguard.data.quickaffordance
import android.content.Context
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.R
import com.android.systemui.common.shared.model.Icon
@@ -35,13 +36,12 @@
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
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
class FlashlightQuickAffordanceConfigTest : LeakCheckedTest() {
@Mock private lateinit var context: Context
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 659c1e5..2c1c04c 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
@@ -17,6 +17,7 @@
package com.android.systemui.keyguard.data.quickaffordance
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.R
import com.android.systemui.SysuiTestCase
@@ -34,13 +35,12 @@
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
import org.mockito.Mock
import org.mockito.Mockito.`when` as whenever
import org.mockito.MockitoAnnotations
@SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
class HomeControlsKeyguardQuickAffordanceConfigTest : SysuiTestCase() {
@Mock private lateinit var component: ControlsComponent
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 3b0169d..3bae7f7 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
@@ -20,6 +20,7 @@
import android.content.Context
import android.content.res.Resources
import android.provider.Settings
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.R
import com.android.systemui.SysuiTestCase
@@ -40,7 +41,6 @@
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
import org.mockito.ArgumentMatchers.anyInt
import org.mockito.ArgumentMatchers.anyString
import org.mockito.Mock
@@ -48,7 +48,7 @@
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
class KeyguardQuickAffordanceLegacySettingSyncerTest : SysuiTestCase() {
@Mock private lateinit var sharedPrefs: FakeSharedPreferences
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 3d65713..1259b47 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
@@ -20,6 +20,7 @@
import android.content.Intent
import android.content.SharedPreferences
import android.content.pm.UserInfo
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.R
import com.android.systemui.SysuiTestCase
@@ -40,7 +41,6 @@
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
import org.mockito.ArgumentMatchers.anyInt
import org.mockito.ArgumentMatchers.anyString
import org.mockito.Mock
@@ -51,7 +51,7 @@
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
class KeyguardQuickAffordanceLocalUserSelectionManagerTest : SysuiTestCase() {
@Mock private lateinit var userFileManager: UserFileManager
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 b21cec9..c08ef42 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
@@ -19,6 +19,7 @@
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.SysuiTestCase
import com.android.systemui.settings.FakeUserTracker
@@ -37,13 +38,12 @@
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
import org.mockito.Mock
import org.mockito.MockitoAnnotations
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
class KeyguardQuickAffordanceRemoteUserSelectionManagerTest : SysuiTestCase() {
@Mock private lateinit var userHandle: UserHandle
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceCoreStartableTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceCoreStartableTest.kt
index 34f3ed8..facc747 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceCoreStartableTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceCoreStartableTest.kt
@@ -21,6 +21,7 @@
import android.media.AudioManager
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Observer
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.flags.FeatureFlags
@@ -47,7 +48,6 @@
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
import org.mockito.Mock
import org.mockito.Mockito.verify
import org.mockito.Mockito.verifyZeroInteractions
@@ -55,8 +55,8 @@
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
-@RunWith(JUnit4::class)
-class MuteQuickAffordanceCoreStartableTest : SysuiTestCase() {
+@RunWith(AndroidJUnit4::class)
+class MuteQuickAffordanceCoreStartableTest : SysuiTestCase() {
@Mock
private lateinit var featureFlags: FeatureFlags
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 9d2ddff..1adf808 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
@@ -18,6 +18,7 @@
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.SysuiTestCase
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceConfig.OnTriggeredResult
@@ -33,13 +34,12 @@
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
import org.mockito.Mock
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
@SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
class QrCodeScannerKeyguardQuickAffordanceConfigTest : SysuiTestCase() {
@Mock private lateinit var controller: QRCodeScannerController
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 8f56b95..752963f 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
@@ -20,6 +20,7 @@
import android.graphics.drawable.Drawable
import android.service.quickaccesswallet.GetWalletCardsResponse
import android.service.quickaccesswallet.QuickAccessWalletClient
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.R
import com.android.systemui.SysuiTestCase
@@ -41,14 +42,13 @@
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
import org.mockito.Mock
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
class QuickAccessWalletKeyguardQuickAffordanceConfigTest : SysuiTestCase() {
@Mock private lateinit var walletController: QuickAccessWalletController
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 805dcec..5bd86bd 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
@@ -17,6 +17,7 @@
package com.android.systemui.keyguard.data.quickaffordance
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.ActivityIntentHelper
import com.android.systemui.SysuiTestCase
@@ -32,7 +33,6 @@
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
import org.mockito.ArgumentMatchers.anyBoolean
import org.mockito.ArgumentMatchers.anyInt
import org.mockito.Mock
@@ -40,7 +40,7 @@
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
class VideoCameraQuickAffordanceConfigTest : SysuiTestCase() {
@Mock private lateinit var activityIntentHelper: ActivityIntentHelper
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardBouncerRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardBouncerRepositoryTest.kt
index 444a2a7..ff22f1e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardBouncerRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardBouncerRepositoryTest.kt
@@ -16,6 +16,7 @@
package com.android.systemui.keyguard.data.repository
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.keyguard.ViewMediatorCallback
import com.android.systemui.SysuiTestCase
@@ -26,13 +27,12 @@
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
import org.mockito.Mock
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
@SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
class KeyguardBouncerRepositoryTest : SysuiTestCase() {
@Mock private lateinit var systemClock: SystemClock
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 6099f01..86e8c9a 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
@@ -19,9 +19,11 @@
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.R
import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.keyguard.data.quickaffordance.FakeKeyguardQuickAffordanceConfig
import com.android.systemui.keyguard.data.quickaffordance.FakeKeyguardQuickAffordanceProviderClientFactory
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceConfig
@@ -39,23 +41,19 @@
import com.android.systemui.util.mockito.whenever
import com.android.systemui.util.settings.FakeSettings
import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.flow.launchIn
-import kotlinx.coroutines.flow.onEach
-import kotlinx.coroutines.runBlocking
-import kotlinx.coroutines.yield
+import kotlinx.coroutines.test.StandardTestDispatcher
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
import org.mockito.ArgumentMatchers.anyInt
import org.mockito.ArgumentMatchers.anyString
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
class KeyguardQuickAffordanceRepositoryTest : SysuiTestCase() {
private lateinit var underTest: KeyguardQuickAffordanceRepository
@@ -65,12 +63,14 @@
private lateinit var userTracker: FakeUserTracker
private lateinit var client1: FakeCustomizationProviderClient
private lateinit var client2: FakeCustomizationProviderClient
+ private lateinit var testScope: TestScope
@Before
fun setUp() {
config1 = FakeKeyguardQuickAffordanceConfig(FakeCustomizationProviderClient.AFFORDANCE_1)
config2 = FakeKeyguardQuickAffordanceConfig(FakeCustomizationProviderClient.AFFORDANCE_2)
- val scope = CoroutineScope(IMMEDIATE)
+ val testDispatcher = StandardTestDispatcher()
+ testScope = TestScope(testDispatcher)
userTracker = FakeUserTracker()
val localUserSelectionManager =
KeyguardQuickAffordanceLocalUserSelectionManager(
@@ -93,7 +93,7 @@
client2 = FakeCustomizationProviderClient()
val remoteUserSelectionManager =
KeyguardQuickAffordanceRemoteUserSelectionManager(
- scope = scope,
+ scope = testScope.backgroundScope,
userTracker = userTracker,
clientFactory =
FakeKeyguardQuickAffordanceProviderClientFactory(
@@ -116,14 +116,14 @@
underTest =
KeyguardQuickAffordanceRepository(
appContext = context,
- scope = scope,
+ scope = testScope.backgroundScope,
localUserSelectionManager = localUserSelectionManager,
remoteUserSelectionManager = remoteUserSelectionManager,
userTracker = userTracker,
legacySettingSyncer =
KeyguardQuickAffordanceLegacySettingSyncer(
- scope = scope,
- backgroundDispatcher = IMMEDIATE,
+ scope = testScope.backgroundScope,
+ backgroundDispatcher = testDispatcher,
secureSettings = FakeSettings(),
selectionsManager = localUserSelectionManager,
),
@@ -135,15 +135,14 @@
@Test
fun setSelections() =
- runBlocking(IMMEDIATE) {
- var configsBySlotId: Map<String, List<KeyguardQuickAffordanceConfig>>? = null
- val job = underTest.selections.onEach { configsBySlotId = it }.launchIn(this)
+ testScope.runTest {
+ val configsBySlotId = collectLastValue(underTest.selections)
val slotId1 = "slot1"
val slotId2 = "slot2"
underTest.setSelections(slotId1, listOf(config1.key))
assertSelections(
- configsBySlotId,
+ configsBySlotId(),
mapOf(
slotId1 to listOf(config1),
),
@@ -151,7 +150,7 @@
underTest.setSelections(slotId2, listOf(config2.key))
assertSelections(
- configsBySlotId,
+ configsBySlotId(),
mapOf(
slotId1 to listOf(config1),
slotId2 to listOf(config2),
@@ -161,19 +160,17 @@
underTest.setSelections(slotId1, emptyList())
underTest.setSelections(slotId2, listOf(config1.key))
assertSelections(
- configsBySlotId,
+ configsBySlotId(),
mapOf(
slotId1 to emptyList(),
slotId2 to listOf(config1),
),
)
-
- job.cancel()
}
@Test
fun getAffordancePickerRepresentations() =
- runBlocking(IMMEDIATE) {
+ testScope.runTest {
assertThat(underTest.getAffordancePickerRepresentations())
.isEqualTo(
listOf(
@@ -226,7 +223,7 @@
@Test
fun `selections for secondary user`() =
- runBlocking(IMMEDIATE) {
+ testScope.runTest {
userTracker.set(
userInfos =
listOf(
@@ -252,12 +249,10 @@
slotId = KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START,
affordanceId = FakeCustomizationProviderClient.AFFORDANCE_2,
)
- val observed = mutableListOf<Map<String, List<KeyguardQuickAffordanceConfig>>>()
- val job = underTest.selections.onEach { observed.add(it) }.launchIn(this)
- yield()
+ val observed = collectLastValue(underTest.selections)
assertSelections(
- observed = observed.last(),
+ observed = observed(),
expected =
mapOf(
KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START to
@@ -266,8 +261,6 @@
),
)
)
-
- job.cancel()
}
private fun assertSelections(
@@ -283,7 +276,6 @@
}
companion object {
- private val IMMEDIATE = Dispatchers.Main.immediate
private const val SECONDARY_USER_1 = UserHandle.MIN_SECONDARY_USER_ID + 1
private const val SECONDARY_USER_2 = UserHandle.MIN_SECONDARY_USER_ID + 2
}
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 f997d18..8bb6a85 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
@@ -18,6 +18,7 @@
import android.graphics.Point
import android.hardware.biometrics.BiometricSourceType
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.keyguard.KeyguardUpdateMonitor
import com.android.keyguard.KeyguardUpdateMonitorCallback
@@ -54,13 +55,12 @@
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
import org.mockito.Mock
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
@SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
class KeyguardRepositoryImplTest : SysuiTestCase() {
@Mock private lateinit var statusBarStateController: StatusBarStateController
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepositoryTest.kt
index 32cec09..ae227b4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepositoryTest.kt
@@ -20,6 +20,7 @@
import android.util.Log
import android.util.Log.TerribleFailure
import android.util.Log.TerribleFailureHandler
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.animation.Interpolators
@@ -43,10 +44,9 @@
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
@SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
class KeyguardTransitionRepositoryTest : SysuiTestCase() {
private lateinit var underTest: KeyguardTransitionRepository
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 4b06905..a181137 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
@@ -18,6 +18,7 @@
import android.app.trust.TrustManager
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.SysuiTestCase
@@ -33,7 +34,6 @@
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
import org.mockito.ArgumentCaptor
import org.mockito.Captor
import org.mockito.Mock
@@ -43,7 +43,7 @@
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
class TrustRepositoryTest : SysuiTestCase() {
@Mock private lateinit var trustManager: TrustManager
@Captor private lateinit var listenerCaptor: ArgumentCaptor<TrustManager.TrustListener>
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/AlternateBouncerInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/AlternateBouncerInteractorTest.kt
index 8caf60f..7ded354 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/AlternateBouncerInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/AlternateBouncerInteractorTest.kt
@@ -16,6 +16,7 @@
package com.android.systemui.keyguard.domain.interactor
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.keyguard.KeyguardUpdateMonitor
import com.android.keyguard.ViewMediatorCallback
@@ -36,14 +37,13 @@
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
import org.mockito.Mock
import org.mockito.Mockito.mock
import org.mockito.MockitoAnnotations
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
class AlternateBouncerInteractorTest : SysuiTestCase() {
private lateinit var underTest: AlternateBouncerInteractor
private lateinit var bouncerRepository: KeyguardBouncerRepository
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 d938243..7d4861b 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
@@ -19,6 +19,7 @@
import android.app.StatusBarManager
import android.content.Context
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
@@ -36,12 +37,12 @@
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
import org.mockito.Mockito.mock
+import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
@SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
class KeyguardInteractorTest : SysuiTestCase() {
private lateinit var commandQueue: FakeCommandQueue
private lateinit var featureFlags: FakeFeatureFlags
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 9d60b16..51988ef 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
@@ -18,6 +18,7 @@
package com.android.systemui.keyguard.domain.interactor
import android.content.Intent
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.internal.logging.UiEventLogger
import com.android.systemui.SysuiTestCase
@@ -39,7 +40,6 @@
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
import org.mockito.ArgumentMatchers.anyBoolean
import org.mockito.Mock
import org.mockito.Mockito.never
@@ -48,7 +48,7 @@
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
class KeyguardLongPressInteractorTest : SysuiTestCase() {
@Mock private lateinit var activityStarter: ActivityStarter
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 8cff0ae..ec70857 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
@@ -18,6 +18,7 @@
package com.android.systemui.keyguard.domain.interactor
import android.os.UserHandle
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.internal.widget.LockPatternUtils
import com.android.systemui.R
@@ -60,7 +61,6 @@
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
import org.mockito.ArgumentMatchers.anyInt
import org.mockito.ArgumentMatchers.anyString
import org.mockito.Mock
@@ -68,7 +68,7 @@
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
class KeyguardQuickAffordanceInteractorTest : SysuiTestCase() {
@Mock private lateinit var lockPatternUtils: LockPatternUtils
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 6333b24..3d13d80 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
@@ -17,6 +17,7 @@
package com.android.systemui.keyguard.domain.interactor
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
@@ -29,17 +30,17 @@
import com.android.systemui.keyguard.shared.model.TransitionState.STARTED
import com.android.systemui.keyguard.shared.model.TransitionStep
import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.test.UnconfinedTestDispatcher
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
-import kotlinx.coroutines.runBlocking
+import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
@SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
+@kotlinx.coroutines.ExperimentalCoroutinesApi
class KeyguardTransitionInteractorTest : SysuiTestCase() {
private lateinit var underTest: KeyguardTransitionInteractor
@@ -53,7 +54,7 @@
@Test
fun `transition collectors receives only appropriate events`() =
- runBlocking(IMMEDIATE) {
+ runTest(UnconfinedTestDispatcher()) {
var lockscreenToAodSteps = mutableListOf<TransitionStep>()
val job1 =
underTest.lockscreenToAodTransition
@@ -87,10 +88,9 @@
@Test
fun dozeAmountTransitionTest() =
- runBlocking(IMMEDIATE) {
+ runTest(UnconfinedTestDispatcher()) {
var dozeAmountSteps = mutableListOf<TransitionStep>()
- val job =
- underTest.dozeAmountTransition.onEach { dozeAmountSteps.add(it) }.launchIn(this)
+ val job = underTest.dozeAmountTransition.onEach { dozeAmountSteps.add(it) }.launchIn(this)
val steps = mutableListOf<TransitionStep>()
@@ -119,10 +119,9 @@
@Test
fun keyguardStateTests() =
- runBlocking(IMMEDIATE) {
+ runTest(UnconfinedTestDispatcher()) {
var finishedSteps = mutableListOf<KeyguardState>()
- val job =
- underTest.finishedKeyguardState.onEach { finishedSteps.add(it) }.launchIn(this)
+ val job = underTest.finishedKeyguardState.onEach { finishedSteps.add(it) }.launchIn(this)
val steps = mutableListOf<TransitionStep>()
@@ -143,12 +142,10 @@
@Test
fun finishedKeyguardTransitionStepTests() =
- runBlocking(IMMEDIATE) {
+ runTest(UnconfinedTestDispatcher()) {
var finishedSteps = mutableListOf<TransitionStep>()
val job =
- underTest.finishedKeyguardTransitionStep
- .onEach { finishedSteps.add(it) }
- .launchIn(this)
+ underTest.finishedKeyguardTransitionStep.onEach { finishedSteps.add(it) }.launchIn(this)
val steps = mutableListOf<TransitionStep>()
@@ -169,12 +166,10 @@
@Test
fun startedKeyguardTransitionStepTests() =
- runBlocking(IMMEDIATE) {
+ runTest(UnconfinedTestDispatcher()) {
var startedSteps = mutableListOf<TransitionStep>()
val job =
- underTest.startedKeyguardTransitionStep
- .onEach { startedSteps.add(it) }
- .launchIn(this)
+ underTest.startedKeyguardTransitionStep.onEach { startedSteps.add(it) }.launchIn(this)
val steps = mutableListOf<TransitionStep>()
@@ -192,8 +187,4 @@
job.cancel()
}
-
- companion object {
- private val IMMEDIATE = Dispatchers.Main.immediate
- }
}
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 3166214..6236616 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
@@ -16,6 +16,7 @@
package com.android.systemui.keyguard.domain.interactor
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
@@ -33,11 +34,10 @@
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
import org.mockito.MockitoAnnotations
@SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
class LightRevealScrimInteractorTest : SysuiTestCase() {
private val fakeKeyguardTransitionRepository = FakeKeyguardTransitionRepository()
private val fakeLightRevealScrimRepository = FakeLightRevealScrimRepository()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerCallbackInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerCallbackInteractorTest.kt
index fbfeca9..f86ac79 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerCallbackInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerCallbackInteractorTest.kt
@@ -17,18 +17,18 @@
package com.android.systemui.keyguard.domain.interactor
import android.view.View
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
import org.mockito.Mock
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
@SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
class PrimaryBouncerCallbackInteractorTest : SysuiTestCase() {
private val mPrimaryBouncerCallbackInteractor = PrimaryBouncerCallbackInteractor()
@Mock
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractorWithCoroutinesTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractorWithCoroutinesTest.kt
index ea7bc91..75b74b0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractorWithCoroutinesTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractorWithCoroutinesTest.kt
@@ -17,6 +17,7 @@
package com.android.systemui.keyguard.domain.interactor
import android.os.Looper
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.keyguard.KeyguardSecurityModel
import com.android.keyguard.KeyguardUpdateMonitor
@@ -35,12 +36,11 @@
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
@SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
class PrimaryBouncerInteractorWithCoroutinesTest : SysuiTestCase() {
private lateinit var repository: FakeKeyguardBouncerRepository
@Mock private lateinit var bouncerView: BouncerView
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 06e397d..706154e 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
@@ -16,6 +16,7 @@
package com.android.systemui.keyguard.ui.viewmodel
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
@@ -33,10 +34,9 @@
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
@SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
class DreamingToLockscreenTransitionViewModelTest : SysuiTestCase() {
private lateinit var underTest: DreamingToLockscreenTransitionViewModel
private lateinit var repository: FakeKeyguardTransitionRepository
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 14c3b50..b15ce10 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
@@ -16,6 +16,7 @@
package com.android.systemui.keyguard.ui.viewmodel
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
@@ -32,10 +33,9 @@
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
@SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
class GoneToDreamingTransitionViewModelTest : SysuiTestCase() {
private lateinit var underTest: GoneToDreamingTransitionViewModel
private lateinit var repository: FakeKeyguardTransitionRepository
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBouncerViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBouncerViewModelTest.kt
index 3727134..586af62 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBouncerViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBouncerViewModelTest.kt
@@ -16,28 +16,29 @@
package com.android.systemui.keyguard.ui.viewmodel
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.keyguard.data.BouncerView
import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerInteractor
import com.android.systemui.keyguard.shared.model.BouncerShowMessageModel
import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
-import kotlinx.coroutines.runBlocking
+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.junit.runners.JUnit4
import org.mockito.Mock
import org.mockito.Mockito
import org.mockito.MockitoAnnotations
@SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
+@kotlinx.coroutines.ExperimentalCoroutinesApi
class KeyguardBouncerViewModelTest : SysuiTestCase() {
lateinit var underTest: KeyguardBouncerViewModel
@Mock lateinit var bouncerView: BouncerView
@@ -51,7 +52,7 @@
@Test
fun setMessage() =
- runBlocking(Dispatchers.Main.immediate) {
+ runTest {
val flow = MutableStateFlow<BouncerShowMessageModel?>(null)
var message: BouncerShowMessageModel? = null
Mockito.`when`(bouncerInteractor.showMessage)
@@ -62,6 +63,8 @@
flow.value = BouncerShowMessageModel(message = "abc", colorStateList = null)
val job = underTest.bouncerShowMessage.onEach { message = it }.launchIn(this)
+ // Run the tasks that are pending at this point of virtual time.
+ runCurrent()
assertThat(message?.message).isEqualTo("abc")
job.cancel()
}
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 ed31dc3..d94c108 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
@@ -16,6 +16,7 @@
package com.android.systemui.keyguard.ui.viewmodel
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
@@ -32,10 +33,9 @@
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
@SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
class LockscreenToDreamingTransitionViewModelTest : SysuiTestCase() {
private lateinit var underTest: LockscreenToDreamingTransitionViewModel
private lateinit var repository: FakeKeyguardTransitionRepository
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 458b315..12ec24d 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
@@ -16,6 +16,7 @@
package com.android.systemui.keyguard.ui.viewmodel
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
@@ -32,10 +33,9 @@
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
@SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
class LockscreenToOccludedTransitionViewModelTest : SysuiTestCase() {
private lateinit var underTest: LockscreenToOccludedTransitionViewModel
private lateinit var repository: FakeKeyguardTransitionRepository
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 a36214e..0c4e845 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
@@ -16,6 +16,7 @@
package com.android.systemui.keyguard.ui.viewmodel
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
@@ -32,10 +33,9 @@
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
@SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
class OccludedToLockscreenTransitionViewModelTest : SysuiTestCase() {
private lateinit var underTest: OccludedToLockscreenTransitionViewModel
private lateinit var repository: FakeKeyguardTransitionRepository
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/pipeline/MediaDataManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/pipeline/MediaDataManagerTest.kt
index 6f1b42b..9f12329 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/pipeline/MediaDataManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/pipeline/MediaDataManagerTest.kt
@@ -827,6 +827,24 @@
}
@Test
+ fun testAddResumptionControls_hasNoExtras() {
+ whenever(mediaFlags.isResumeProgressEnabled()).thenReturn(true)
+
+ // WHEN resumption controls are added that do not have any extras
+ val desc =
+ MediaDescription.Builder().run {
+ setTitle(SESSION_TITLE)
+ build()
+ }
+ addResumeControlAndLoad(desc)
+
+ // Resume progress is null
+ val data = mediaDataCaptor.value
+ assertThat(data.resumption).isTrue()
+ assertThat(data.resumeProgress).isEqualTo(null)
+ }
+
+ @Test
fun testResumptionDisabled_dismissesResumeControls() {
// WHEN there are resume controls and resumption is switched off
val desc =
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaViewControllerTest.kt
index 2f7eac2..af91cdb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaViewControllerTest.kt
@@ -33,6 +33,7 @@
import org.junit.runner.RunWith
import org.mockito.ArgumentMatchers.floatThat
import org.mockito.Mock
+import org.mockito.Mockito.times
import org.mockito.Mockito.verify
import org.mockito.Mockito.`when` as whenever
import org.mockito.MockitoAnnotations
@@ -139,14 +140,12 @@
whenever(controlWidgetState.y).thenReturn(150F)
whenever(controlWidgetState.height).thenReturn(20)
// in current beizer, when the progress reach 0.38, the result will be 0.5
- mediaViewController.squishViewState(mockViewState, 119F / 200F)
- verify(detailWidgetState).alpha = floatThat { kotlin.math.abs(it - 0.5F) < delta }
- mediaViewController.squishViewState(mockViewState, 150F / 200F)
- verify(detailWidgetState).alpha = floatThat { kotlin.math.abs(it - 1.0F) < delta }
mediaViewController.squishViewState(mockViewState, 181.4F / 200F)
verify(controlWidgetState).alpha = floatThat { kotlin.math.abs(it - 0.5F) < delta }
+ verify(detailWidgetState).alpha = floatThat { kotlin.math.abs(it - 1.0F) < delta }
mediaViewController.squishViewState(mockViewState, 200F / 200F)
verify(controlWidgetState).alpha = floatThat { kotlin.math.abs(it - 1.0F) < delta }
+ verify(detailWidgetState, times(2)).alpha = floatThat { kotlin.math.abs(it - 1.0F) < delta }
}
@Test
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 78bebb9..d01edcc 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
@@ -18,8 +18,6 @@
import android.content.ContentResolver
import android.content.Context
import android.graphics.drawable.Drawable
-import android.os.Handler
-import android.os.UserHandle
import android.testing.AndroidTestingRunner
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
@@ -34,6 +32,9 @@
import com.android.systemui.util.mockito.eq
import junit.framework.Assert.assertEquals
import junit.framework.Assert.fail
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.test.StandardTestDispatcher
+import kotlinx.coroutines.test.TestScope
import org.json.JSONException
import org.junit.Before
import org.junit.Rule
@@ -49,19 +50,19 @@
class ClockRegistryTest : SysuiTestCase() {
@JvmField @Rule val mockito = MockitoJUnit.rule()
+ private lateinit var dispatcher: CoroutineDispatcher
+ private lateinit var scope: TestScope
+
@Mock private lateinit var mockContext: Context
@Mock private lateinit var mockPluginManager: PluginManager
@Mock private lateinit var mockClock: ClockController
@Mock private lateinit var mockDefaultClock: ClockController
@Mock private lateinit var mockThumbnail: Drawable
- @Mock private lateinit var mockHandler: Handler
@Mock private lateinit var mockContentResolver: ContentResolver
private lateinit var fakeDefaultProvider: FakeClockPlugin
private lateinit var pluginListener: PluginListener<ClockProviderPlugin>
private lateinit var registry: ClockRegistry
- private var settingValue: ClockSettings? = null
-
companion object {
private fun failFactory(): ClockController {
fail("Unexpected call to createClock")
@@ -99,6 +100,9 @@
@Before
fun setUp() {
+ dispatcher = StandardTestDispatcher()
+ scope = TestScope(dispatcher)
+
fakeDefaultProvider = FakeClockPlugin()
.addClock(DEFAULT_CLOCK_ID, DEFAULT_CLOCK_NAME, { mockDefaultClock }, { mockThumbnail })
whenever(mockContext.contentResolver).thenReturn(mockContentResolver)
@@ -107,15 +111,22 @@
registry = object : ClockRegistry(
mockContext,
mockPluginManager,
- mockHandler,
+ scope = scope.backgroundScope,
+ mainDispatcher = dispatcher,
+ bgDispatcher = dispatcher,
isEnabled = true,
- userHandle = UserHandle.USER_ALL,
- defaultClockProvider = fakeDefaultProvider
+ handleAllUsers = true,
+ defaultClockProvider = fakeDefaultProvider,
) {
- override var settings: ClockSettings?
- get() = settingValue
- set(value) { settingValue = value }
+ override fun querySettings() { }
+ override fun applySettings(value: ClockSettings?) {
+ settings = value
+ }
+ // Unit Test does not validate threading
+ override fun assertMainThread() {}
+ override fun assertNotMainThread() {}
}
+ registry.registerListeners()
verify(mockPluginManager)
.addPluginListener(captor.capture(), eq(ClockProviderPlugin::class.java), eq(true))
@@ -187,16 +198,16 @@
.addClock("clock_1", "clock 1")
.addClock("clock_2", "clock 2")
- settingValue = ClockSettings("clock_3", null, null)
val plugin2 = FakeClockPlugin()
.addClock("clock_3", "clock 3", { mockClock })
.addClock("clock_4", "clock 4")
+ registry.applySettings(ClockSettings("clock_3", null))
pluginListener.onPluginConnected(plugin1, mockContext)
pluginListener.onPluginConnected(plugin2, mockContext)
val clock = registry.createCurrentClock()
- assertEquals(clock, mockClock)
+ assertEquals(mockClock, clock)
}
@Test
@@ -205,11 +216,11 @@
.addClock("clock_1", "clock 1")
.addClock("clock_2", "clock 2")
- settingValue = ClockSettings("clock_3", null, null)
val plugin2 = FakeClockPlugin()
.addClock("clock_3", "clock 3")
.addClock("clock_4", "clock 4")
+ registry.applySettings(ClockSettings("clock_3", null))
pluginListener.onPluginConnected(plugin1, mockContext)
pluginListener.onPluginConnected(plugin2, mockContext)
pluginListener.onPluginDisconnected(plugin2)
@@ -224,11 +235,11 @@
.addClock("clock_1", "clock 1")
.addClock("clock_2", "clock 2")
- settingValue = ClockSettings("clock_3", null, null)
val plugin2 = FakeClockPlugin()
.addClock("clock_3", "clock 3", { mockClock })
.addClock("clock_4", "clock 4")
+ registry.applySettings(ClockSettings("clock_3", null))
pluginListener.onPluginConnected(plugin1, mockContext)
pluginListener.onPluginConnected(plugin2, mockContext)
@@ -244,7 +255,7 @@
@Test
fun jsonDeserialization_gotExpectedObject() {
- val expected = ClockSettings("ID", null, 500)
+ val expected = ClockSettings("ID", null).apply { _applied_timestamp = 500 }
val actual = ClockSettings.deserialize("""{
"clockId":"ID",
"_applied_timestamp":500
@@ -254,14 +265,14 @@
@Test
fun jsonDeserialization_noTimestamp_gotExpectedObject() {
- val expected = ClockSettings("ID", null, null)
+ val expected = ClockSettings("ID", null)
val actual = ClockSettings.deserialize("{\"clockId\":\"ID\"}")
assertEquals(expected, actual)
}
@Test
fun jsonDeserialization_nullTimestamp_gotExpectedObject() {
- val expected = ClockSettings("ID", null, null)
+ val expected = ClockSettings("ID", null)
val actual = ClockSettings.deserialize("""{
"clockId":"ID",
"_applied_timestamp":null
@@ -271,7 +282,7 @@
@Test(expected = JSONException::class)
fun jsonDeserialization_noId_threwException() {
- val expected = ClockSettings("ID", null, 500)
+ val expected = ClockSettings(null, null).apply { _applied_timestamp = 500 }
val actual = ClockSettings.deserialize("{\"_applied_timestamp\":500}")
assertEquals(expected, actual)
}
@@ -279,14 +290,15 @@
@Test
fun jsonSerialization_gotExpectedString() {
val expected = "{\"clockId\":\"ID\",\"_applied_timestamp\":500}"
- val actual = ClockSettings.serialize(ClockSettings("ID", null, 500))
+ val actual = ClockSettings.serialize(ClockSettings("ID", null)
+ .apply { _applied_timestamp = 500 })
assertEquals(expected, actual)
}
@Test
fun jsonSerialization_noTimestamp_gotExpectedString() {
val expected = "{\"clockId\":\"ID\"}"
- val actual = ClockSettings.serialize(ClockSettings("ID", null, null))
+ val actual = ClockSettings.serialize(ClockSettings("ID", null))
assertEquals(expected, actual)
}
}
diff --git a/services/core/java/com/android/server/dreams/DreamController.java b/services/core/java/com/android/server/dreams/DreamController.java
index 61f7928..f74356d 100644
--- a/services/core/java/com/android/server/dreams/DreamController.java
+++ b/services/core/java/com/android/server/dreams/DreamController.java
@@ -270,7 +270,7 @@
try {
service.asBinder().linkToDeath(mCurrentDream, 0);
service.attach(mCurrentDream.mToken, mCurrentDream.mCanDoze,
- mCurrentDream.mDreamingStartedCallback);
+ mCurrentDream.mIsPreviewMode, mCurrentDream.mDreamingStartedCallback);
} catch (RemoteException ex) {
Slog.e(TAG, "The dream service died unexpectedly.", ex);
stopDream(true /*immediate*/, "attach failed");
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index faa219e..cbbee5d 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -4831,6 +4831,13 @@
Slog.w(TAG, "Ignoring setInputMethod of uid " + Binder.getCallingUid()
+ " token: " + token);
return;
+ } else {
+ // Called with current IME's token.
+ if (mMethodMap.get(id) != null
+ && mSettings.getEnabledInputMethodListWithFilterLocked(
+ (info) -> info.getId().equals(id)).isEmpty()) {
+ throw new IllegalStateException("Requested IME is not enabled: " + id);
+ }
}
final long ident = Binder.clearCallingIdentity();
diff --git a/services/tests/servicestests/src/com/android/server/dreams/DreamControllerTest.java b/services/tests/servicestests/src/com/android/server/dreams/DreamControllerTest.java
index 303a370..1ef1197 100644
--- a/services/tests/servicestests/src/com/android/server/dreams/DreamControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/dreams/DreamControllerTest.java
@@ -99,7 +99,24 @@
mLooper.dispatchAll();
// Verify that dream service is called to attach.
- verify(mIDreamService).attach(eq(mToken), eq(false) /*doze*/, any());
+ verify(mIDreamService).attach(eq(mToken), eq(false) /*doze*/,
+ eq(false) /*preview*/, any());
+ }
+
+ @Test
+ public void startDream_attachOnServiceConnectedInPreviewMode() throws RemoteException {
+ // Call dream controller to start dreaming.
+ mDreamController.startDream(mToken, mDreamName, true /*isPreview*/, false /*doze*/,
+ 0 /*userId*/, null /*wakeLock*/, mOverlayName, "test" /*reason*/);
+
+ // Mock service connected.
+ final ServiceConnection serviceConnection = captureServiceConnection();
+ serviceConnection.onServiceConnected(mDreamName, mIBinder);
+ mLooper.dispatchAll();
+
+ // Verify that dream service is called to attach.
+ verify(mIDreamService).attach(eq(mToken), eq(false) /*doze*/,
+ eq(true) /*preview*/, any());
}
@Test
@@ -129,7 +146,7 @@
// Mock second dream started.
verify(newDreamService).attach(eq(newToken), eq(false) /*doze*/,
- mRemoteCallbackCaptor.capture());
+ eq(false) /*preview*/, mRemoteCallbackCaptor.capture());
mRemoteCallbackCaptor.getValue().sendResult(null /*data*/);
mLooper.dispatchAll();
diff --git a/tests/testables/src/android/testing/TestableSettingsProvider.java b/tests/testables/src/android/testing/TestableSettingsProvider.java
index fd92c65..c6f18fd 100644
--- a/tests/testables/src/android/testing/TestableSettingsProvider.java
+++ b/tests/testables/src/android/testing/TestableSettingsProvider.java
@@ -49,14 +49,15 @@
}
void clearValuesAndCheck(Context context) {
- int userId = UserHandle.myUserId();
- mValues.put(key("global", MY_UNIQUE_KEY, userId), MY_UNIQUE_KEY);
- mValues.put(key("secure", MY_UNIQUE_KEY, userId), MY_UNIQUE_KEY);
- mValues.put(key("system", MY_UNIQUE_KEY, userId), MY_UNIQUE_KEY);
-
+ // Ensure we swapped over to use TestableSettingsProvider
Settings.Global.clearProviderForTest();
Settings.Secure.clearProviderForTest();
Settings.System.clearProviderForTest();
+
+ // putString will eventually invoking the mocked call() method and update mValues
+ Settings.Global.putString(context.getContentResolver(), MY_UNIQUE_KEY, MY_UNIQUE_KEY);
+ Settings.Secure.putString(context.getContentResolver(), MY_UNIQUE_KEY, MY_UNIQUE_KEY);
+ Settings.System.putString(context.getContentResolver(), MY_UNIQUE_KEY, MY_UNIQUE_KEY);
// Verify that if any test is using TestableContext, they all have the correct settings
// provider.
assertEquals("Incorrect settings provider, test using incorrect Context?", MY_UNIQUE_KEY,