Merge "Make Notification long clickable" into tm-qpr-dev
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index 2d1a41e..e27af17 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -170,6 +170,7 @@
Float.NEGATIVE_INFINITY);
private static final int NOTIFY_COLORS_RATE_LIMIT_MS = 1000;
+ private static final int PROCESS_LOCAL_COLORS_INTERVAL_MS = 1000;
private static final boolean ENABLE_WALLPAPER_DIMMING =
SystemProperties.getBoolean("persist.debug.enable_wallpaper_dimming", true);
@@ -275,9 +276,13 @@
MotionEvent mPendingMove;
boolean mIsInAmbientMode;
- // Needed for throttling onComputeColors.
+ // used to throttle onComputeColors
private long mLastColorInvalidation;
private final Runnable mNotifyColorsChanged = this::notifyColorsChanged;
+
+ // used to throttle processLocalColors
+ private long mLastProcessLocalColorsTimestamp;
+ private AtomicBoolean mProcessLocalColorsPending = new AtomicBoolean(false);
private final Supplier<Long> mClockFunction;
private final Handler mHandler;
@@ -1591,7 +1596,26 @@
processLocalColors(xOffset, xOffsetStep);
}
+ /**
+ * Thread-safe util to call {@link #processLocalColorsInternal} with a minimum interval of
+ * {@link #PROCESS_LOCAL_COLORS_INTERVAL_MS} between two calls.
+ */
private void processLocalColors(float xOffset, float xOffsetStep) {
+ if (mProcessLocalColorsPending.compareAndSet(false, true)) {
+ final long now = mClockFunction.get();
+ final long timeSinceLastColorProcess = now - mLastProcessLocalColorsTimestamp;
+ final long timeToWait = Math.max(0,
+ PROCESS_LOCAL_COLORS_INTERVAL_MS - timeSinceLastColorProcess);
+
+ mHandler.postDelayed(() -> {
+ mLastProcessLocalColorsTimestamp = now + timeToWait;
+ mProcessLocalColorsPending.set(false);
+ processLocalColorsInternal(xOffset, xOffsetStep);
+ }, timeToWait);
+ }
+ }
+
+ private void processLocalColorsInternal(float xOffset, float xOffsetStep) {
// implemented by the wallpaper
if (supportsLocalColorExtraction()) return;
if (DEBUG) {
@@ -1625,40 +1649,39 @@
float finalXOffsetStep = xOffsetStep;
float finalXOffset = xOffset;
- mHandler.post(() -> {
- Trace.beginSection("WallpaperService#processLocalColors");
- resetWindowPages();
- int xPage = xCurrentPage;
- EngineWindowPage current;
- if (mWindowPages.length == 0 || (mWindowPages.length != xPages)) {
- mWindowPages = new EngineWindowPage[xPages];
- initWindowPages(mWindowPages, finalXOffsetStep);
+
+ Trace.beginSection("WallpaperService#processLocalColors");
+ resetWindowPages();
+ int xPage = xCurrentPage;
+ EngineWindowPage current;
+ if (mWindowPages.length == 0 || (mWindowPages.length != xPages)) {
+ mWindowPages = new EngineWindowPage[xPages];
+ initWindowPages(mWindowPages, finalXOffsetStep);
+ }
+ if (mLocalColorsToAdd.size() != 0) {
+ for (RectF colorArea : mLocalColorsToAdd) {
+ if (!isValid(colorArea)) continue;
+ mLocalColorAreas.add(colorArea);
+ int colorPage = getRectFPage(colorArea, finalXOffsetStep);
+ EngineWindowPage currentPage = mWindowPages[colorPage];
+ currentPage.setLastUpdateTime(0);
+ currentPage.removeColor(colorArea);
}
- if (mLocalColorsToAdd.size() != 0) {
- for (RectF colorArea : mLocalColorsToAdd) {
- if (!isValid(colorArea)) continue;
- mLocalColorAreas.add(colorArea);
- int colorPage = getRectFPage(colorArea, finalXOffsetStep);
- EngineWindowPage currentPage = mWindowPages[colorPage];
- currentPage.setLastUpdateTime(0);
- currentPage.removeColor(colorArea);
- }
- mLocalColorsToAdd.clear();
+ mLocalColorsToAdd.clear();
+ }
+ if (xPage >= mWindowPages.length) {
+ if (DEBUG) {
+ Log.e(TAG, "error xPage >= mWindowPages.length page: " + xPage);
+ Log.e(TAG, "error on page " + xPage + " out of " + xPages);
+ Log.e(TAG,
+ "error on xOffsetStep " + finalXOffsetStep
+ + " xOffset " + finalXOffset);
}
- if (xPage >= mWindowPages.length) {
- if (DEBUG) {
- Log.e(TAG, "error xPage >= mWindowPages.length page: " + xPage);
- Log.e(TAG, "error on page " + xPage + " out of " + xPages);
- Log.e(TAG,
- "error on xOffsetStep " + finalXOffsetStep
- + " xOffset " + finalXOffset);
- }
- xPage = mWindowPages.length - 1;
- }
- current = mWindowPages[xPage];
- updatePage(current, xPage, xPages, finalXOffsetStep);
- Trace.endSection();
- });
+ xPage = mWindowPages.length - 1;
+ }
+ current = mWindowPages[xPage];
+ updatePage(current, xPage, xPages, finalXOffsetStep);
+ Trace.endSection();
}
private void initWindowPages(EngineWindowPage[] windowPages, float step) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
index 44e4a31..de5f2f4 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
@@ -250,25 +250,30 @@
@Override
public boolean onTouch(View v, MotionEvent e) {
- boolean isDrag = false;
final int id = v.getId();
if (id != R.id.caption_handle && id != R.id.desktop_mode_caption) {
return false;
}
- if (id == R.id.caption_handle) {
- isDrag = mDragDetector.onMotionEvent(e);
+ switch (e.getAction()) {
+ case MotionEvent.ACTION_DOWN:
+ mDragDetector.onMotionEvent(e);
+ final RunningTaskInfo taskInfo = mTaskOrganizer.getRunningTaskInfo(mTaskId);
+ if (taskInfo.isFocused) {
+ return mDragDetector.isDragEvent();
+ }
+ final WindowContainerTransaction wct = new WindowContainerTransaction();
+ wct.reorder(mTaskToken, true /* onTop */);
+ mSyncQueue.queue(wct);
+ return false;
+ case MotionEvent.ACTION_UP:
+ case MotionEvent.ACTION_CANCEL:
+ boolean res = mDragDetector.isDragEvent();
+ mDragDetector.onMotionEvent(e);
+ return res;
+ default:
+ mDragDetector.onMotionEvent(e);
+ return mDragDetector.isDragEvent();
}
- if (e.getAction() != MotionEvent.ACTION_DOWN) {
- return isDrag;
- }
- final RunningTaskInfo taskInfo = mTaskOrganizer.getRunningTaskInfo(mTaskId);
- if (taskInfo.isFocused) {
- return isDrag;
- }
- final WindowContainerTransaction wct = new WindowContainerTransaction();
- wct.reorder(mTaskToken, true /* onTop */);
- mSyncQueue.queue(wct);
- return true;
}
/**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragDetector.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragDetector.java
index 4fac843..cf1850b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragDetector.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragDetector.java
@@ -94,6 +94,10 @@
mTouchSlop = touchSlop;
}
+ boolean isDragEvent() {
+ return mIsDragEvent;
+ }
+
private void resetState() {
mIsDragEvent = false;
mInputDownPoint.set(0, 0);
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 ed6e619..ab36d58 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
@@ -51,9 +51,12 @@
defaultClockProvider: ClockProvider,
val fallbackClockId: ClockId = DEFAULT_CLOCK_ID,
) {
- // Usually this would be a typealias, but a SAM provides better java interop
- fun interface ClockChangeListener {
- fun onClockChanged()
+ interface ClockChangeListener {
+ // Called when the active clock changes
+ fun onCurrentClockChanged() {}
+
+ // Called when the list of available clocks changes
+ fun onAvailableClocksChanged() {}
}
private val availableClocks = mutableMapOf<ClockId, ClockInfo>()
@@ -92,7 +95,7 @@
protected set(value) {
if (field != value) {
field = value
- scope.launch(mainDispatcher) { onClockChanged() }
+ scope.launch(mainDispatcher) { onClockChanged { it.onCurrentClockChanged() } }
}
}
@@ -164,9 +167,9 @@
Assert.isNotMainThread()
}
- private fun onClockChanged() {
+ private fun onClockChanged(func: (ClockChangeListener) -> Unit) {
assertMainThread()
- clockChangeListeners.forEach { it.onClockChanged() }
+ clockChangeListeners.forEach(func)
}
private fun mutateSetting(mutator: (ClockSettings) -> ClockSettings) {
@@ -241,6 +244,7 @@
}
private fun connectClocks(provider: ClockProvider) {
+ var isAvailableChanged = false
val currentId = currentClockId
for (clock in provider.getClocks()) {
val id = clock.clockId
@@ -251,10 +255,11 @@
"Clock Id conflict: $id is registered by both " +
"${provider::class.simpleName} and ${current.provider::class.simpleName}"
)
- return
+ continue
}
availableClocks[id] = ClockInfo(clock, provider)
+ isAvailableChanged = true
if (DEBUG) {
Log.i(TAG, "Added ${clock.clockId}")
}
@@ -263,24 +268,35 @@
if (DEBUG) {
Log.i(TAG, "Current clock ($currentId) was connected")
}
- onClockChanged()
+ onClockChanged { it.onCurrentClockChanged() }
}
}
+
+ if (isAvailableChanged) {
+ onClockChanged { it.onAvailableClocksChanged() }
+ }
}
private fun disconnectClocks(provider: ClockProvider) {
+ var isAvailableChanged = false
val currentId = currentClockId
for (clock in provider.getClocks()) {
availableClocks.remove(clock.clockId)
+ isAvailableChanged = true
+
if (DEBUG) {
Log.i(TAG, "Removed ${clock.clockId}")
}
if (currentId == clock.clockId) {
Log.w(TAG, "Current clock ($currentId) was disconnected")
- onClockChanged()
+ onClockChanged { it.onCurrentClockChanged() }
}
}
+
+ if (isAvailableChanged) {
+ onClockChanged { it.onAvailableClocksChanged() }
+ }
}
fun getClocks(): List<ClockMetadata> {
diff --git a/packages/SystemUI/ktfmt_includes.txt b/packages/SystemUI/ktfmt_includes.txt
index 2215857..943d799 100644
--- a/packages/SystemUI/ktfmt_includes.txt
+++ b/packages/SystemUI/ktfmt_includes.txt
@@ -451,7 +451,6 @@
-packages/SystemUI/src/com/android/systemui/statusbar/phone/userswitcher/StatusBarUserSwitcherController.kt
-packages/SystemUI/src/com/android/systemui/statusbar/phone/userswitcher/StatusBarUserSwitcherFeatureController.kt
-packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt
--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ConnectivityPipelineLogger.kt
-packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryStateNotifier.kt
-packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceControlsController.kt
-packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceControlsControllerImpl.kt
@@ -736,7 +735,6 @@
-packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallLoggerTest.kt
-packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/panelstate/ShadeExpansionStateManagerTest.kt
-packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/userswitcher/StatusBarUserSwitcherControllerOldImplTest.kt
--packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ConnectivityPipelineLoggerTest.kt
-packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BatteryStateNotifierTest.kt
-packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ClockTest.kt
-packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/DeviceControlsControllerImplTest.kt
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 031d40e..3f84ddb 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -450,7 +450,7 @@
<integer name="watch_heap_limit">256000</integer>
<!-- SystemUI Plugins that can be loaded on user builds. -->
- <string-array name="config_pluginWhitelist" translatable="false">
+ <string-array name="config_pluginAllowlist" translatable="false">
<item>com.android.systemui</item>
</string-array>
@@ -829,7 +829,7 @@
<string name="config_wallpaperPickerPackage" translatable="false">
com.android.wallpaper
</string>
-
+
<!-- Whether the floating rotation button should be on the left/right in the device's natural
orientation -->
<bool name="floating_rotation_button_position_left">true</bool>
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
index baaeb2a..b85b2b8 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
@@ -151,8 +151,13 @@
mLogBuffer = logBuffer;
mView.setLogBuffer(mLogBuffer);
- mClockChangedListener = () -> {
- setClock(mClockRegistry.createCurrentClock());
+ mClockChangedListener = new ClockRegistry.ClockChangeListener() {
+ @Override
+ public void onCurrentClockChanged() {
+ setClock(mClockRegistry.createCurrentClock());
+ }
+ @Override
+ public void onAvailableClocksChanged() { }
};
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardFingerprintListenModel.kt b/packages/SystemUI/src/com/android/keyguard/KeyguardFingerprintListenModel.kt
index 998dc09..57130ed 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardFingerprintListenModel.kt
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardFingerprintListenModel.kt
@@ -27,6 +27,7 @@
override var userId: Int = 0,
override var listening: Boolean = false,
// keepSorted
+ var alternateBouncerShowing: Boolean = false,
var biometricEnabledForUser: Boolean = false,
var bouncerIsOrWillShow: Boolean = false,
var canSkipBouncer: Boolean = false,
@@ -57,6 +58,7 @@
userId.toString(),
listening.toString(),
// keep sorted
+ alternateBouncerShowing.toString(),
biometricEnabledForUser.toString(),
bouncerIsOrWillShow.toString(),
canSkipBouncer.toString(),
@@ -96,6 +98,7 @@
userId = model.userId
listening = model.listening
// keep sorted
+ alternateBouncerShowing = model.alternateBouncerShowing
biometricEnabledForUser = model.biometricEnabledForUser
bouncerIsOrWillShow = model.bouncerIsOrWillShow
canSkipBouncer = model.canSkipBouncer
@@ -141,6 +144,7 @@
"userId",
"listening",
// keep sorted
+ "alternateBouncerShowing",
"biometricAllowedForUser",
"bouncerIsOrWillShow",
"canSkipBouncer",
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index bb29a7e..e511365 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -2632,6 +2632,7 @@
ActiveUnlockConfig.ActiveUnlockRequestOrigin.UNLOCK_INTENT,
"alternateBouncer");
}
+ updateFingerprintListeningState(BIOMETRIC_ACTION_UPDATE);
}
private boolean shouldTriggerActiveUnlock() {
@@ -2716,7 +2717,7 @@
|| shouldListenForFingerprintAssistant
|| (mKeyguardOccluded && mIsDreaming)
|| (mKeyguardOccluded && userDoesNotHaveTrust
- && (mOccludingAppRequestingFp || isUdfps));
+ && (mOccludingAppRequestingFp || isUdfps || mAlternateBouncerShowing));
// Only listen if this KeyguardUpdateMonitor belongs to the primary user. There is an
// instance of KeyguardUpdateMonitor for each user but KeyguardUpdateMonitor is user-aware.
@@ -2757,6 +2758,7 @@
System.currentTimeMillis(),
user,
shouldListen,
+ mAlternateBouncerShowing,
biometricEnabledForUser,
mPrimaryBouncerIsOrWillBeShowing,
userCanSkipBouncer,
diff --git a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
index 8071a5d..0887b22 100644
--- a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
@@ -466,6 +466,17 @@
}
}
+ /**
+ * @return whether the userUnlockedWithBiometric state changed
+ */
+ private boolean updateUserUnlockedWithBiometric() {
+ final boolean wasUserUnlockedWithBiometric = mUserUnlockedWithBiometric;
+ mUserUnlockedWithBiometric =
+ mKeyguardUpdateMonitor.getUserUnlockedWithBiometric(
+ KeyguardUpdateMonitor.getCurrentUser());
+ return wasUserUnlockedWithBiometric != mUserUnlockedWithBiometric;
+ }
+
private StatusBarStateController.StateListener mStatusBarStateListener =
new StatusBarStateController.StateListener() {
@Override
@@ -503,11 +514,7 @@
@Override
public void onBiometricsCleared() {
- final boolean wasUserUnlockedWithBiometric = mUserUnlockedWithBiometric;
- mUserUnlockedWithBiometric =
- mKeyguardUpdateMonitor.getUserUnlockedWithBiometric(
- KeyguardUpdateMonitor.getCurrentUser());
- if (wasUserUnlockedWithBiometric != mUserUnlockedWithBiometric) {
+ if (updateUserUnlockedWithBiometric()) {
updateVisibility();
}
}
@@ -516,10 +523,8 @@
public void onBiometricRunningStateChanged(boolean running,
BiometricSourceType biometricSourceType) {
final boolean wasRunningFps = mRunningFPS;
- final boolean wasUserUnlockedWithBiometric = mUserUnlockedWithBiometric;
- mUserUnlockedWithBiometric =
- mKeyguardUpdateMonitor.getUserUnlockedWithBiometric(
- KeyguardUpdateMonitor.getCurrentUser());
+ final boolean userUnlockedWithBiometricChanged =
+ updateUserUnlockedWithBiometric();
if (biometricSourceType == FINGERPRINT) {
mRunningFPS = running;
@@ -537,8 +542,7 @@
}
}
- if (wasUserUnlockedWithBiometric != mUserUnlockedWithBiometric
- || wasRunningFps != mRunningFPS) {
+ if (userUnlockedWithBiometricChanged || wasRunningFps != mRunningFPS) {
updateVisibility();
}
}
@@ -549,6 +553,7 @@
@Override
public void onUnlockedChanged() {
mCanDismissLockScreen = mKeyguardStateController.canDismissLockScreen();
+ updateUserUnlockedWithBiometric();
updateKeyguardShowing();
updateVisibility();
}
@@ -566,9 +571,7 @@
updateKeyguardShowing();
if (mIsKeyguardShowing) {
- mUserUnlockedWithBiometric =
- mKeyguardUpdateMonitor.getUserUnlockedWithBiometric(
- KeyguardUpdateMonitor.getCurrentUser());
+ updateUserUnlockedWithBiometric();
}
updateVisibility();
}
diff --git a/packages/SystemUI/src/com/android/systemui/backup/BackupHelper.kt b/packages/SystemUI/src/com/android/systemui/backup/BackupHelper.kt
index 621b99d..6721c5d 100644
--- a/packages/SystemUI/src/com/android/systemui/backup/BackupHelper.kt
+++ b/packages/SystemUI/src/com/android/systemui/backup/BackupHelper.kt
@@ -31,6 +31,7 @@
import com.android.systemui.controls.controller.ControlsFavoritePersistenceWrapper
import com.android.systemui.keyguard.domain.backup.KeyguardQuickAffordanceBackupHelper
import com.android.systemui.people.widget.PeopleBackupHelper
+import com.android.systemui.settings.UserFileManagerImpl
/**
* Helper for backing up elements in SystemUI
@@ -58,17 +59,8 @@
override fun onCreate(userHandle: UserHandle, operationType: Int) {
super.onCreate()
- // The map in mapOf is guaranteed to be order preserving
- val controlsMap = mapOf(CONTROLS to getPPControlsFile(this))
- NoOverwriteFileBackupHelper(controlsDataLock, this, controlsMap).also {
- addHelper(NO_OVERWRITE_FILES_BACKUP_KEY, it)
- }
- // Conversations widgets backup only works for system user, because widgets' information is
- // stored in system user's SharedPreferences files and we can't open those from other users.
- if (!userHandle.isSystem) {
- return
- }
+ addControlsHelper(userHandle.identifier)
val keys = PeopleBackupHelper.getFilesToBackup()
addHelper(
@@ -95,6 +87,18 @@
sendBroadcastAsUser(intent, UserHandle.SYSTEM, PERMISSION_SELF)
}
+ private fun addControlsHelper(userId: Int) {
+ val file = UserFileManagerImpl.createFile(
+ userId = userId,
+ fileName = CONTROLS,
+ )
+ // The map in mapOf is guaranteed to be order preserving
+ val controlsMap = mapOf(file.getPath() to getPPControlsFile(this, userId))
+ NoOverwriteFileBackupHelper(controlsDataLock, this, controlsMap).also {
+ addHelper(NO_OVERWRITE_FILES_BACKUP_KEY, it)
+ }
+ }
+
/**
* Helper class for restoring files ONLY if they are not present.
*
@@ -136,17 +140,21 @@
}
}
-private fun getPPControlsFile(context: Context): () -> Unit {
+private fun getPPControlsFile(context: Context, userId: Int): () -> Unit {
return {
- val filesDir = context.filesDir
- val file = Environment.buildPath(filesDir, BackupHelper.CONTROLS)
+ val file = UserFileManagerImpl.createFile(
+ userId = userId,
+ fileName = BackupHelper.CONTROLS,
+ )
if (file.exists()) {
- val dest =
- Environment.buildPath(filesDir, AuxiliaryPersistenceWrapper.AUXILIARY_FILE_NAME)
+ val dest = UserFileManagerImpl.createFile(
+ userId = userId,
+ fileName = AuxiliaryPersistenceWrapper.AUXILIARY_FILE_NAME,
+ )
file.copyTo(dest)
val jobScheduler = context.getSystemService(JobScheduler::class.java)
jobScheduler?.schedule(
- AuxiliaryPersistenceWrapper.DeletionJobService.getJobForContext(context)
+ AuxiliaryPersistenceWrapper.DeletionJobService.getJobForContext(context, userId)
)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/controls/controller/AuxiliaryPersistenceWrapper.kt b/packages/SystemUI/src/com/android/systemui/controls/controller/AuxiliaryPersistenceWrapper.kt
index 0a6335e..b3c18fb 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/controller/AuxiliaryPersistenceWrapper.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/controller/AuxiliaryPersistenceWrapper.kt
@@ -21,8 +21,10 @@
import android.app.job.JobService
import android.content.ComponentName
import android.content.Context
+import android.os.PersistableBundle
import com.android.internal.annotations.VisibleForTesting
import com.android.systemui.backup.BackupHelper
+import com.android.systemui.settings.UserFileManagerImpl
import java.io.File
import java.util.concurrent.Executor
import java.util.concurrent.TimeUnit
@@ -33,14 +35,14 @@
* This file is a copy of the `controls_favorites.xml` file restored from a back up. It is used to
* keep track of controls that were restored but its corresponding app has not been installed yet.
*/
-class AuxiliaryPersistenceWrapper @VisibleForTesting internal constructor(
- wrapper: ControlsFavoritePersistenceWrapper
-) {
+class AuxiliaryPersistenceWrapper
+@VisibleForTesting
+internal constructor(wrapper: ControlsFavoritePersistenceWrapper) {
constructor(
file: File,
executor: Executor
- ): this(ControlsFavoritePersistenceWrapper(file, executor))
+ ) : this(ControlsFavoritePersistenceWrapper(file, executor))
companion object {
const val AUXILIARY_FILE_NAME = "aux_controls_favorites.xml"
@@ -48,9 +50,7 @@
private var persistenceWrapper: ControlsFavoritePersistenceWrapper = wrapper
- /**
- * Access the current list of favorites as tracked by the auxiliary file
- */
+ /** Access the current list of favorites as tracked by the auxiliary file */
var favorites: List<StructureInfo> = emptyList()
private set
@@ -73,18 +73,19 @@
* exist, it will be initialized to an empty list.
*/
fun initialize() {
- favorites = if (persistenceWrapper.fileExists) {
- persistenceWrapper.readFavorites()
- } else {
- emptyList()
- }
+ favorites =
+ if (persistenceWrapper.fileExists) {
+ persistenceWrapper.readFavorites()
+ } else {
+ emptyList()
+ }
}
/**
* Gets the list of favorite controls as persisted in the auxiliary file for a given component.
*
- * When the favorites for that application are returned, they will be removed from the
- * auxiliary file immediately, so they won't be retrieved again.
+ * When the favorites for that application are returned, they will be removed from the auxiliary
+ * file immediately, so they won't be retrieved again.
* @param componentName the name of the service that provided the controls
* @return a list of structures with favorites
*/
@@ -103,20 +104,20 @@
}
}
- /**
- * [JobService] to delete the auxiliary file after a week.
- */
+ /** [JobService] to delete the auxiliary file after a week. */
class DeletionJobService : JobService() {
companion object {
- @VisibleForTesting
- internal val DELETE_FILE_JOB_ID = 1000
+ @VisibleForTesting internal val DELETE_FILE_JOB_ID = 1000
+ @VisibleForTesting internal val USER = "USER"
private val WEEK_IN_MILLIS = TimeUnit.DAYS.toMillis(7)
- fun getJobForContext(context: Context): JobInfo {
+ fun getJobForContext(context: Context, targetUserId: Int): JobInfo {
val jobId = DELETE_FILE_JOB_ID + context.userId
val componentName = ComponentName(context, DeletionJobService::class.java)
+ val bundle = PersistableBundle().also { it.putInt(USER, targetUserId) }
return JobInfo.Builder(jobId, componentName)
.setMinimumLatency(WEEK_IN_MILLIS)
.setPersisted(true)
+ .setExtras(bundle)
.build()
}
}
@@ -127,8 +128,14 @@
}
override fun onStartJob(params: JobParameters): Boolean {
+ val userId = params.getExtras()?.getInt(USER, 0) ?: 0
synchronized(BackupHelper.controlsDataLock) {
- baseContext.deleteFile(AUXILIARY_FILE_NAME)
+ val file =
+ UserFileManagerImpl.createFile(
+ userId = userId,
+ fileName = AUXILIARY_FILE_NAME,
+ )
+ baseContext.deleteFile(file.getPath())
}
return false
}
@@ -137,4 +144,4 @@
return true // reschedule and try again if the job was stopped without completing
}
}
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt b/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt
index bddd8a7..947888b 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt
@@ -30,6 +30,7 @@
import com.android.systemui.dagger.qualifiers.PerUser
import com.android.systemui.dreams.DreamMonitor
import com.android.systemui.globalactions.GlobalActionsComponent
+import com.android.systemui.keyboard.PhysicalKeyboardCoreStartable
import com.android.systemui.keyboard.KeyboardUI
import com.android.systemui.keyguard.KeyguardViewMediator
import com.android.systemui.keyguard.data.quickaffordance.MuteQuickAffordanceCoreStartable
@@ -286,6 +287,11 @@
@ClassKey(StylusUsiPowerStartable::class)
abstract fun bindStylusUsiPowerStartable(sysui: StylusUsiPowerStartable): CoreStartable
+ @Binds
+ @IntoMap
+ @ClassKey(PhysicalKeyboardCoreStartable::class)
+ abstract fun bindKeyboardCoreStartable(listener: PhysicalKeyboardCoreStartable): CoreStartable
+
/** Inject into MuteQuickAffordanceCoreStartable*/
@Binds
@IntoMap
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
index 60fccef..5b4ce06 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
@@ -47,6 +47,7 @@
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.flags.FlagsModule;
import com.android.systemui.fragments.FragmentService;
+import com.android.systemui.keyboard.KeyboardModule;
import com.android.systemui.keyguard.data.BouncerViewModule;
import com.android.systemui.log.dagger.LogModule;
import com.android.systemui.mediaprojection.appselector.MediaProjectionModule;
@@ -150,6 +151,7 @@
SystemPropertiesFlagsModule.class,
FooterActionsModule.class,
GarbageMonitorModule.class,
+ KeyboardModule.class,
LogModule.class,
MediaProjectionModule.class,
MotionToolModule.class,
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/KeyboardModule.kt b/packages/SystemUI/src/com/android/systemui/keyboard/KeyboardModule.kt
new file mode 100644
index 0000000..e9b8908
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/KeyboardModule.kt
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.android.systemui.keyboard
+
+import dagger.Module
+
+@Module abstract class KeyboardModule
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/PhysicalKeyboardCoreStartable.kt b/packages/SystemUI/src/com/android/systemui/keyboard/PhysicalKeyboardCoreStartable.kt
new file mode 100644
index 0000000..b0f9c4e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/PhysicalKeyboardCoreStartable.kt
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.android.systemui.keyboard
+
+import com.android.systemui.CoreStartable
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.flags.Flags
+import javax.inject.Inject
+
+/** A [CoreStartable] that launches components interested in physical keyboard interaction. */
+@SysUISingleton
+class PhysicalKeyboardCoreStartable
+@Inject
+constructor(
+ private val featureFlags: FeatureFlags,
+) : CoreStartable {
+ override fun start() {
+ if (featureFlags.isEnabled(Flags.KEYBOARD_BACKLIGHT_INDICATOR)) {
+ // TODO(b/268645743) start listening for keyboard backlight brightness
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt
index 228320b..f964cb3 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt
@@ -933,7 +933,7 @@
}
// The smartspace is not visible if the bouncer is showing, so don't shared element it.
- if (keyguardStateController.isBouncerShowing) {
+ if (keyguardStateController.isPrimaryBouncerShowing) {
return false
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 09eaf75..6db1f89 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -1148,12 +1148,12 @@
private final KeyguardStateController.Callback mKeyguardStateControllerCallback =
new KeyguardStateController.Callback() {
@Override
- public void onBouncerShowingChanged() {
+ public void onPrimaryBouncerShowingChanged() {
synchronized (KeyguardViewMediator.this) {
- if (mKeyguardStateController.isBouncerShowing()) {
+ if (mKeyguardStateController.isPrimaryBouncerShowing()) {
mPendingPinLock = false;
}
- adjustStatusBarLocked(mKeyguardStateController.isBouncerShowing(), false);
+ adjustStatusBarLocked(mKeyguardStateController.isPrimaryBouncerShowing(), false);
}
}
};
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardBouncerRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardBouncerRepository.kt
index 091acad..4331fe6 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardBouncerRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardBouncerRepository.kt
@@ -68,8 +68,8 @@
val resourceUpdateRequests: StateFlow<Boolean>
val bouncerPromptReason: Int
val bouncerErrorMessage: CharSequence?
- val isAlternateBouncerVisible: StateFlow<Boolean>
- val isAlternateBouncerUIAvailable: StateFlow<Boolean>
+ val alternateBouncerVisible: StateFlow<Boolean>
+ val alternateBouncerUIAvailable: StateFlow<Boolean>
var lastAlternateBouncerVisibleTime: Long
fun setPrimaryScrimmed(isScrimmed: Boolean)
@@ -159,12 +159,12 @@
get() = viewMediatorCallback.consumeCustomMessage()
/** Values associated with the AlternateBouncer */
- private val _isAlternateBouncerVisible = MutableStateFlow(false)
- override val isAlternateBouncerVisible = _isAlternateBouncerVisible.asStateFlow()
+ private val _alternateBouncerVisible = MutableStateFlow(false)
+ override val alternateBouncerVisible = _alternateBouncerVisible.asStateFlow()
override var lastAlternateBouncerVisibleTime: Long = NOT_VISIBLE
- private val _isAlternateBouncerUIAvailable = MutableStateFlow(false)
- override val isAlternateBouncerUIAvailable: StateFlow<Boolean> =
- _isAlternateBouncerUIAvailable.asStateFlow()
+ private val _alternateBouncerUIAvailable = MutableStateFlow(false)
+ override val alternateBouncerUIAvailable: StateFlow<Boolean> =
+ _alternateBouncerUIAvailable.asStateFlow()
init {
setUpLogging()
@@ -179,16 +179,16 @@
}
override fun setAlternateVisible(isVisible: Boolean) {
- if (isVisible && !_isAlternateBouncerVisible.value) {
+ if (isVisible && !_alternateBouncerVisible.value) {
lastAlternateBouncerVisibleTime = clock.uptimeMillis()
} else if (!isVisible) {
lastAlternateBouncerVisibleTime = NOT_VISIBLE
}
- _isAlternateBouncerVisible.value = isVisible
+ _alternateBouncerVisible.value = isVisible
}
override fun setAlternateBouncerUIAvailable(isAvailable: Boolean) {
- _isAlternateBouncerUIAvailable.value = isAvailable
+ _alternateBouncerUIAvailable.value = isAvailable
}
override fun setPrimaryShow(keyguardBouncerModel: KeyguardBouncerModel?) {
@@ -290,7 +290,7 @@
resourceUpdateRequests
.logDiffsForTable(buffer, "", "ResourceUpdateRequests", false)
.launchIn(applicationScope)
- isAlternateBouncerUIAvailable
+ alternateBouncerUIAvailable
.logDiffsForTable(buffer, "", "IsAlternateBouncerUIAvailable", false)
.launchIn(applicationScope)
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepository.kt
index db95562..a3b3d0f 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepository.kt
@@ -86,9 +86,6 @@
/** Observable for the signal that keyguard is about to go away. */
val isKeyguardGoingAway: Flow<Boolean>
- /** Observable for whether the bouncer is showing. */
- val isBouncerShowing: Flow<Boolean>
-
/** Is the always-on display available to be used? */
val isAodAvailable: Flow<Boolean>
@@ -304,29 +301,6 @@
awaitClose { keyguardStateController.removeCallback(callback) }
}
- override val isBouncerShowing: Flow<Boolean> = conflatedCallbackFlow {
- val callback =
- object : KeyguardStateController.Callback {
- override fun onBouncerShowingChanged() {
- trySendWithFailureLogging(
- keyguardStateController.isBouncerShowing,
- TAG,
- "updated isBouncerShowing"
- )
- }
- }
-
- keyguardStateController.addCallback(callback)
- // Adding the callback does not send an initial update.
- trySendWithFailureLogging(
- keyguardStateController.isBouncerShowing,
- TAG,
- "initial isBouncerShowing"
- )
-
- awaitClose { keyguardStateController.removeCallback(callback) }
- }
-
override val isDozing: Flow<Boolean> =
conflatedCallbackFlow {
val callback =
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/backup/KeyguardQuickAffordanceBackupHelper.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/backup/KeyguardQuickAffordanceBackupHelper.kt
index 0e865ce..fa6efa5 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/backup/KeyguardQuickAffordanceBackupHelper.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/backup/KeyguardQuickAffordanceBackupHelper.kt
@@ -29,16 +29,9 @@
) :
SharedPreferencesBackupHelper(
context,
- if (UserFileManagerImpl.isPrimaryUser(userId)) {
- KeyguardQuickAffordanceSelectionManager.FILE_NAME
- } else {
- UserFileManagerImpl.secondaryUserFile(
- context = context,
- fileName = KeyguardQuickAffordanceSelectionManager.FILE_NAME,
- directoryName = UserFileManagerImpl.SHARED_PREFS,
- userId = userId,
- )
- .also { UserFileManagerImpl.ensureParentDirExists(it) }
- .toString()
- }
+ UserFileManagerImpl.createFile(
+ userId = userId,
+ fileName = KeyguardQuickAffordanceSelectionManager.FILE_NAME,
+ )
+ .getPath()
)
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/AlternateBouncerInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/AlternateBouncerInteractor.kt
index 6452e0e..dfe1038 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/AlternateBouncerInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/AlternateBouncerInteractor.kt
@@ -44,7 +44,7 @@
var legacyAlternateBouncer: LegacyAlternateBouncer? = null
var legacyAlternateBouncerVisibleTime: Long = NOT_VISIBLE
- val isVisible: Flow<Boolean> = bouncerRepository.isAlternateBouncerVisible
+ val isVisible: Flow<Boolean> = bouncerRepository.alternateBouncerVisible
/**
* Sets the correct bouncer states to show the alternate bouncer if it can show.
@@ -86,7 +86,7 @@
fun isVisibleState(): Boolean {
return if (isModernAlternateBouncerEnabled) {
- bouncerRepository.isAlternateBouncerVisible.value
+ bouncerRepository.alternateBouncerVisible.value
} else {
legacyAlternateBouncer?.isShowingAlternateBouncer ?: false
}
@@ -98,7 +98,7 @@
fun canShowAlternateBouncerForFingerprint(): Boolean {
return if (isModernAlternateBouncerEnabled) {
- bouncerRepository.isAlternateBouncerUIAvailable.value &&
+ bouncerRepository.alternateBouncerUIAvailable.value &&
biometricSettingsRepository.isFingerprintEnrolled.value &&
biometricSettingsRepository.isStrongBiometricAllowed.value &&
biometricSettingsRepository.isFingerprintEnabledByDevicePolicy.value &&
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractor.kt
new file mode 100644
index 0000000..310f44d
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractor.kt
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.keyguard.domain.interactor
+
+import android.animation.ValueAnimator
+import com.android.systemui.animation.Interpolators
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository
+import com.android.systemui.keyguard.shared.model.KeyguardState
+import com.android.systemui.keyguard.shared.model.TransitionInfo
+import com.android.systemui.keyguard.shared.model.WakefulnessState
+import com.android.systemui.util.kotlin.sample
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.onEach
+import kotlinx.coroutines.launch
+
+@SysUISingleton
+class FromAlternateBouncerTransitionInteractor
+@Inject
+constructor(
+ @Application private val scope: CoroutineScope,
+ private val keyguardInteractor: KeyguardInteractor,
+ private val keyguardTransitionRepository: KeyguardTransitionRepository,
+ private val keyguardTransitionInteractor: KeyguardTransitionInteractor,
+) : TransitionInteractor(FromAlternateBouncerTransitionInteractor::class.simpleName!!) {
+
+ override fun start() {
+ listenForAlternateBouncerToGone()
+ listenForAlternateBouncerToLockscreenAodOrDozing()
+ listenForAlternateBouncerToPrimaryBouncer()
+ }
+
+ private fun listenForAlternateBouncerToLockscreenAodOrDozing() {
+ scope.launch {
+ keyguardInteractor.alternateBouncerShowing
+ // Add a slight delay, as alternateBouncer and primaryBouncer showing event changes
+ // will arrive with a small gap in time. This prevents a transition to LOCKSCREEN
+ // happening prematurely.
+ .onEach { delay(50) }
+ .sample(
+ combine(
+ keyguardInteractor.primaryBouncerShowing,
+ keyguardTransitionInteractor.startedKeyguardTransitionStep,
+ keyguardInteractor.wakefulnessModel,
+ keyguardInteractor.isAodAvailable,
+ ::toQuad
+ ),
+ ::toQuint
+ )
+ .collect {
+ (
+ isAlternateBouncerShowing,
+ isPrimaryBouncerShowing,
+ lastStartedTransitionStep,
+ wakefulnessState,
+ isAodAvailable
+ ) ->
+ if (
+ !isAlternateBouncerShowing &&
+ !isPrimaryBouncerShowing &&
+ lastStartedTransitionStep.to == KeyguardState.ALTERNATE_BOUNCER
+ ) {
+ val to =
+ if (
+ wakefulnessState.state == WakefulnessState.STARTING_TO_SLEEP ||
+ wakefulnessState.state == WakefulnessState.ASLEEP
+ ) {
+ if (isAodAvailable) {
+ KeyguardState.AOD
+ } else {
+ KeyguardState.DOZING
+ }
+ } else {
+ KeyguardState.LOCKSCREEN
+ }
+ keyguardTransitionRepository.startTransition(
+ TransitionInfo(
+ ownerName = name,
+ from = KeyguardState.ALTERNATE_BOUNCER,
+ to = to,
+ animator = getAnimator(),
+ )
+ )
+ }
+ }
+ }
+ }
+
+ private fun listenForAlternateBouncerToGone() {
+ scope.launch {
+ keyguardInteractor.isKeyguardGoingAway
+ .sample(keyguardTransitionInteractor.finishedKeyguardState, ::Pair)
+ .collect { (isKeyguardGoingAway, keyguardState) ->
+ if (isKeyguardGoingAway && keyguardState == KeyguardState.ALTERNATE_BOUNCER) {
+ keyguardTransitionRepository.startTransition(
+ TransitionInfo(
+ ownerName = name,
+ from = KeyguardState.ALTERNATE_BOUNCER,
+ to = KeyguardState.GONE,
+ animator = getAnimator(),
+ )
+ )
+ }
+ }
+ }
+ }
+
+ private fun listenForAlternateBouncerToPrimaryBouncer() {
+ scope.launch {
+ keyguardInteractor.primaryBouncerShowing
+ .sample(keyguardTransitionInteractor.startedKeyguardTransitionStep, ::Pair)
+ .collect { (isPrimaryBouncerShowing, startedKeyguardState) ->
+ if (
+ isPrimaryBouncerShowing &&
+ startedKeyguardState.to == KeyguardState.ALTERNATE_BOUNCER
+ ) {
+ keyguardTransitionRepository.startTransition(
+ TransitionInfo(
+ ownerName = name,
+ from = KeyguardState.ALTERNATE_BOUNCER,
+ to = KeyguardState.PRIMARY_BOUNCER,
+ animator = getAnimator(),
+ )
+ )
+ }
+ }
+ }
+ }
+
+ private fun getAnimator(): ValueAnimator {
+ return ValueAnimator().apply {
+ interpolator = Interpolators.LINEAR
+ duration = TRANSITION_DURATION_MS
+ }
+ }
+
+ companion object {
+ private const val TRANSITION_DURATION_MS = 300L
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt
index 5674e2a..d01f489 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt
@@ -33,7 +33,6 @@
import kotlin.time.Duration
import kotlin.time.Duration.Companion.milliseconds
import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.launch
@@ -53,9 +52,10 @@
listenForLockscreenToOccluded()
listenForLockscreenToCamera()
listenForLockscreenToAodOrDozing()
- listenForLockscreenToBouncer()
+ listenForLockscreenToPrimaryBouncer()
listenForLockscreenToDreaming()
- listenForLockscreenToBouncerDragging()
+ listenForLockscreenToPrimaryBouncerDragging()
+ listenForLockscreenToAlternateBouncer()
}
private fun listenForLockscreenToDreaming() {
@@ -78,9 +78,9 @@
}
}
- private fun listenForLockscreenToBouncer() {
+ private fun listenForLockscreenToPrimaryBouncer() {
scope.launch {
- keyguardInteractor.isBouncerShowing
+ keyguardInteractor.primaryBouncerShowing
.sample(keyguardTransitionInteractor.startedKeyguardTransitionStep, ::Pair)
.collect { pair ->
val (isBouncerShowing, lastStartedTransitionStep) = pair
@@ -91,7 +91,30 @@
TransitionInfo(
ownerName = name,
from = KeyguardState.LOCKSCREEN,
- to = KeyguardState.BOUNCER,
+ to = KeyguardState.PRIMARY_BOUNCER,
+ animator = getAnimator(),
+ )
+ )
+ }
+ }
+ }
+ }
+
+ private fun listenForLockscreenToAlternateBouncer() {
+ scope.launch {
+ keyguardInteractor.alternateBouncerShowing
+ .sample(keyguardTransitionInteractor.startedKeyguardTransitionStep, ::Pair)
+ .collect { pair ->
+ val (isAlternateBouncerShowing, lastStartedTransitionStep) = pair
+ if (
+ isAlternateBouncerShowing &&
+ lastStartedTransitionStep.to == KeyguardState.LOCKSCREEN
+ ) {
+ keyguardTransitionRepository.startTransition(
+ TransitionInfo(
+ ownerName = name,
+ from = KeyguardState.LOCKSCREEN,
+ to = KeyguardState.ALTERNATE_BOUNCER,
animator = getAnimator(),
)
)
@@ -101,7 +124,7 @@
}
/* Starts transitions when manually dragging up the bouncer from the lockscreen. */
- private fun listenForLockscreenToBouncerDragging() {
+ private fun listenForLockscreenToPrimaryBouncerDragging() {
var transitionId: UUID? = null
scope.launch {
shadeRepository.shadeModel
@@ -144,7 +167,7 @@
keyguardTransitionRepository.startTransition(
TransitionInfo(
ownerName = name,
- from = KeyguardState.BOUNCER,
+ from = KeyguardState.PRIMARY_BOUNCER,
to = KeyguardState.LOCKSCREEN,
animator = getAnimator(0.milliseconds)
)
@@ -163,7 +186,7 @@
TransitionInfo(
ownerName = name,
from = KeyguardState.LOCKSCREEN,
- to = KeyguardState.BOUNCER,
+ to = KeyguardState.PRIMARY_BOUNCER,
animator = null,
)
)
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromBouncerTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractor.kt
similarity index 75%
rename from packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromBouncerTransitionInteractor.kt
rename to packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractor.kt
index 0e9c447..b59b413 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromBouncerTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractor.kt
@@ -24,62 +24,63 @@
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.shared.model.TransitionInfo
import com.android.systemui.keyguard.shared.model.WakefulnessState
-import com.android.systemui.shade.data.repository.ShadeRepository
import com.android.systemui.util.kotlin.sample
-import java.util.UUID
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.launch
@SysUISingleton
-class FromBouncerTransitionInteractor
+class FromPrimaryBouncerTransitionInteractor
@Inject
constructor(
@Application private val scope: CoroutineScope,
private val keyguardInteractor: KeyguardInteractor,
- private val shadeRepository: ShadeRepository,
private val keyguardTransitionRepository: KeyguardTransitionRepository,
private val keyguardTransitionInteractor: KeyguardTransitionInteractor
-) : TransitionInteractor(FromBouncerTransitionInteractor::class.simpleName!!) {
-
- private var transitionId: UUID? = null
+) : TransitionInteractor(FromPrimaryBouncerTransitionInteractor::class.simpleName!!) {
override fun start() {
- listenForBouncerToGone()
- listenForBouncerToLockscreenOrAod()
+ listenForPrimaryBouncerToGone()
+ listenForPrimaryBouncerToLockscreenAodOrDozing()
}
- private fun listenForBouncerToLockscreenOrAod() {
+ private fun listenForPrimaryBouncerToLockscreenAodOrDozing() {
scope.launch {
- keyguardInteractor.isBouncerShowing
+ keyguardInteractor.primaryBouncerShowing
.sample(
combine(
keyguardInteractor.wakefulnessModel,
keyguardTransitionInteractor.startedKeyguardTransitionStep,
- ::Pair
+ keyguardInteractor.isAodAvailable,
+ ::toTriple
),
- ::toTriple
+ ::toQuad
)
- .collect { triple ->
- val (isBouncerShowing, wakefulnessState, lastStartedTransitionStep) = triple
+ .collect {
+ (isBouncerShowing, wakefulnessState, lastStartedTransitionStep, isAodAvailable)
+ ->
if (
- !isBouncerShowing && lastStartedTransitionStep.to == KeyguardState.BOUNCER
+ !isBouncerShowing &&
+ lastStartedTransitionStep.to == KeyguardState.PRIMARY_BOUNCER
) {
val to =
if (
wakefulnessState.state == WakefulnessState.STARTING_TO_SLEEP ||
wakefulnessState.state == WakefulnessState.ASLEEP
) {
- KeyguardState.AOD
+ if (isAodAvailable) {
+ KeyguardState.AOD
+ } else {
+ KeyguardState.DOZING
+ }
} else {
KeyguardState.LOCKSCREEN
}
keyguardTransitionRepository.startTransition(
TransitionInfo(
ownerName = name,
- from = KeyguardState.BOUNCER,
+ from = KeyguardState.PRIMARY_BOUNCER,
to = to,
animator = getAnimator(),
)
@@ -89,17 +90,17 @@
}
}
- private fun listenForBouncerToGone() {
+ private fun listenForPrimaryBouncerToGone() {
scope.launch {
keyguardInteractor.isKeyguardGoingAway
- .sample(keyguardTransitionInteractor.finishedKeyguardState, { a, b -> Pair(a, b) })
+ .sample(keyguardTransitionInteractor.finishedKeyguardState) { a, b -> Pair(a, b) }
.collect { pair ->
val (isKeyguardGoingAway, keyguardState) = pair
- if (isKeyguardGoingAway && keyguardState == KeyguardState.BOUNCER) {
+ if (isKeyguardGoingAway && keyguardState == KeyguardState.PRIMARY_BOUNCER) {
keyguardTransitionRepository.startTransition(
TransitionInfo(
ownerName = name,
- from = KeyguardState.BOUNCER,
+ from = KeyguardState.PRIMARY_BOUNCER,
to = KeyguardState.GONE,
animator = getAnimator(),
)
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt
index 7e86a5d..d25aff0a 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt
@@ -24,6 +24,7 @@
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags
+import com.android.systemui.keyguard.data.repository.KeyguardBouncerRepository
import com.android.systemui.keyguard.data.repository.KeyguardRepository
import com.android.systemui.keyguard.shared.model.BiometricUnlockModel
import com.android.systemui.keyguard.shared.model.CameraLaunchSourceModel
@@ -56,6 +57,7 @@
private val repository: KeyguardRepository,
private val commandQueue: CommandQueue,
featureFlags: FeatureFlags,
+ bouncerRepository: KeyguardBouncerRepository,
) {
/**
* The amount of doze the system is in, where `1.0` is fully dozing and `0.0` is not dozing at
@@ -121,8 +123,10 @@
val isKeyguardOccluded: Flow<Boolean> = repository.isKeyguardOccluded
/** Whether the keyguard is going away. */
val isKeyguardGoingAway: Flow<Boolean> = repository.isKeyguardGoingAway
- /** Whether the bouncer is showing or not. */
- val isBouncerShowing: Flow<Boolean> = repository.isBouncerShowing
+ /** Whether the primary bouncer is showing or not. */
+ val primaryBouncerShowing: Flow<Boolean> = bouncerRepository.primaryBouncerVisible
+ /** Whether the alternate bouncer is showing or not. */
+ val alternateBouncerShowing: Flow<Boolean> = bouncerRepository.alternateBouncerVisible
/** The device wake/sleep state */
val wakefulnessModel: Flow<WakefulnessModel> = repository.wakefulness
/** Observable for the [StatusBarState] */
@@ -142,12 +146,12 @@
if (featureFlags.isEnabled(Flags.FACE_AUTH_REFACTOR)) {
combine(
isKeyguardVisible,
- repository.isBouncerShowing,
+ bouncerRepository.primaryBouncerVisible,
onCameraLaunchDetected,
- ) { isKeyguardVisible, isBouncerShowing, cameraLaunchEvent ->
+ ) { isKeyguardVisible, isPrimaryBouncerShowing, cameraLaunchEvent ->
when {
isKeyguardVisible -> false
- isBouncerShowing -> false
+ isPrimaryBouncerShowing -> false
else -> cameraLaunchEvent == CameraLaunchSourceModel.POWER_DOUBLE_TAP
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionAuditLogger.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionAuditLogger.kt
index d4e23499..51b0277 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionAuditLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionAuditLogger.kt
@@ -22,7 +22,6 @@
import com.android.systemui.plugins.log.LogLevel.VERBOSE
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
private val TAG = KeyguardTransitionAuditLogger::class.simpleName!!
@@ -46,8 +45,14 @@
}
scope.launch {
- keyguardInteractor.isBouncerShowing.collect {
- logger.log(TAG, VERBOSE, "Bouncer showing", it)
+ keyguardInteractor.primaryBouncerShowing.collect {
+ logger.log(TAG, VERBOSE, "Primary bouncer showing", it)
+ }
+ }
+
+ scope.launch {
+ keyguardInteractor.alternateBouncerShowing.collect {
+ logger.log(TAG, VERBOSE, "Alternate bouncer showing", it)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionCoreStartable.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionCoreStartable.kt
index fbed446..efc1bd0 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionCoreStartable.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionCoreStartable.kt
@@ -37,13 +37,14 @@
// exhaustive
val ret =
when (it) {
- is FromBouncerTransitionInteractor -> Log.d(TAG, "Started $it")
+ is FromPrimaryBouncerTransitionInteractor -> Log.d(TAG, "Started $it")
is FromAodTransitionInteractor -> Log.d(TAG, "Started $it")
is FromGoneTransitionInteractor -> Log.d(TAG, "Started $it")
is FromLockscreenTransitionInteractor -> Log.d(TAG, "Started $it")
is FromDreamingTransitionInteractor -> Log.d(TAG, "Started $it")
is FromOccludedTransitionInteractor -> Log.d(TAG, "Started $it")
is FromDozingTransitionInteractor -> Log.d(TAG, "Started $it")
+ is FromAlternateBouncerTransitionInteractor -> Log.d(TAG, "Started $it")
}
it.start()
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt
index 84bcdf9..1b7da5b 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt
@@ -21,13 +21,12 @@
import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.shared.model.KeyguardState.AOD
-import com.android.systemui.keyguard.shared.model.KeyguardState.BOUNCER
import com.android.systemui.keyguard.shared.model.KeyguardState.DREAMING
import com.android.systemui.keyguard.shared.model.KeyguardState.GONE
import com.android.systemui.keyguard.shared.model.KeyguardState.LOCKSCREEN
import com.android.systemui.keyguard.shared.model.KeyguardState.OCCLUDED
+import com.android.systemui.keyguard.shared.model.KeyguardState.PRIMARY_BOUNCER
import com.android.systemui.keyguard.shared.model.TransitionState
-import com.android.systemui.keyguard.shared.model.TransitionState.STARTED
import com.android.systemui.keyguard.shared.model.TransitionStep
import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
@@ -63,9 +62,9 @@
/** LOCKSCREEN->AOD transition information. */
val lockscreenToAodTransition: Flow<TransitionStep> = repository.transition(LOCKSCREEN, AOD)
- /** LOCKSCREEN->BOUNCER transition information. */
- val lockscreenToBouncerTransition: Flow<TransitionStep> =
- repository.transition(LOCKSCREEN, BOUNCER)
+ /** LOCKSCREEN->PRIMARY_BOUNCER transition information. */
+ val mLockscreenToPrimaryBouncerTransition: Flow<TransitionStep> =
+ repository.transition(LOCKSCREEN, PRIMARY_BOUNCER)
/** LOCKSCREEN->DREAMING transition information. */
val lockscreenToDreamingTransition: Flow<TransitionStep> =
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/LightRevealScrimInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/LightRevealScrimInteractor.kt
index a59c407..833eda7 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/LightRevealScrimInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/LightRevealScrimInteractor.kt
@@ -86,7 +86,8 @@
KeyguardState.DOZING -> false
KeyguardState.AOD -> false
KeyguardState.DREAMING -> true
- KeyguardState.BOUNCER -> true
+ KeyguardState.ALTERNATE_BOUNCER -> true
+ KeyguardState.PRIMARY_BOUNCER -> true
KeyguardState.LOCKSCREEN -> true
KeyguardState.GONE -> true
KeyguardState.OCCLUDED -> true
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractor.kt
index 96bf815..6610983 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractor.kt
@@ -164,7 +164,7 @@
} else {
DejankUtils.postAfterTraversal(showRunnable)
}
- keyguardStateController.notifyBouncerShowing(true)
+ keyguardStateController.notifyPrimaryBouncerShowing(true)
primaryBouncerCallbackInteractor.dispatchStartingToShow()
Trace.endSection()
}
@@ -181,7 +181,7 @@
}
falsingCollector.onBouncerHidden()
- keyguardStateController.notifyBouncerShowing(false /* showing */)
+ keyguardStateController.notifyPrimaryBouncerShowing(false /* showing */)
cancelShowRunnable()
repository.setPrimaryShowingSoon(false)
repository.setPrimaryVisible(false)
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/StartKeyguardTransitionModule.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/StartKeyguardTransitionModule.kt
index 81fa233..d9690b7 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/StartKeyguardTransitionModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/StartKeyguardTransitionModule.kt
@@ -32,7 +32,9 @@
@Binds
@IntoSet
- abstract fun fromBouncer(impl: FromBouncerTransitionInteractor): TransitionInteractor
+ abstract fun fromPrimaryBouncer(
+ impl: FromPrimaryBouncerTransitionInteractor
+ ): TransitionInteractor
@Binds
@IntoSet
@@ -53,4 +55,10 @@
@Binds
@IntoSet
abstract fun fromDozing(impl: FromDozingTransitionInteractor): TransitionInteractor
+
+ @Binds
+ @IntoSet
+ abstract fun fromAlternateBouncer(
+ impl: FromAlternateBouncerTransitionInteractor
+ ): TransitionInteractor
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/TransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/TransitionInteractor.kt
index 4d24c14..e3e3527 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/TransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/TransitionInteractor.kt
@@ -30,7 +30,26 @@
abstract fun start()
+ fun <A, B, C> toTriple(a: A, b: B, c: C) = Triple(a, b, c)
+
fun <A, B, C> toTriple(a: A, bc: Pair<B, C>) = Triple(a, bc.first, bc.second)
fun <A, B, C> toTriple(ab: Pair<A, B>, c: C) = Triple(ab.first, ab.second, c)
+
+ fun <A, B, C, D> toQuad(a: A, b: B, c: C, d: D) = Quad(a, b, c, d)
+
+ fun <A, B, C, D> toQuad(a: A, bcd: Triple<B, C, D>) = Quad(a, bcd.first, bcd.second, bcd.third)
+
+ fun <A, B, C, D, E> toQuint(a: A, bcde: Quad<B, C, D, E>) =
+ Quint(a, bcde.first, bcde.second, bcde.third, bcde.fourth)
}
+
+data class Quad<A, B, C, D>(val first: A, val second: B, val third: C, val fourth: D)
+
+data class Quint<A, B, C, D, E>(
+ val first: A,
+ val second: B,
+ val third: C,
+ val fourth: D,
+ val fifth: E
+)
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/KeyguardState.kt b/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/KeyguardState.kt
index c757986..87b4321 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/KeyguardState.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/KeyguardState.kt
@@ -42,10 +42,15 @@
*/
AOD,
/*
- * The security screen prompt UI, containing PIN, Password, Pattern, and all FPS
- * (Fingerprint Sensor) variations, for the user to verify their credentials
+ * The security screen prompt containing UI to prompt the user to use a biometric credential
+ * (ie: fingerprint). When supported, this may show before showing the primary bouncer.
*/
- BOUNCER,
+ ALTERNATE_BOUNCER,
+ /*
+ * The security screen prompt UI, containing PIN, Password, Pattern for the user to verify their
+ * credentials.
+ */
+ PRIMARY_BOUNCER,
/*
* Device is actively displaying keyguard UI and is not in low-power mode. Device may be
* unlocked if SWIPE security method is used, or if face lockscreen bypass is false.
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt
index 403576c..72b317c 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt
@@ -170,7 +170,12 @@
}
private fun setUpClock(parentView: ViewGroup) {
- val clockChangeListener = ClockRegistry.ClockChangeListener { onClockChanged(parentView) }
+ val clockChangeListener =
+ object : ClockRegistry.ClockChangeListener {
+ override fun onCurrentClockChanged() {
+ onClockChanged(parentView)
+ }
+ }
clockRegistry.registerClockChangeListener(clockChangeListener)
disposables.add(
DisposableHandle { clockRegistry.unregisterClockChangeListener(clockChangeListener) }
diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
index 4177480..5341cd5 100644
--- a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
+++ b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
@@ -265,16 +265,6 @@
return factory.create("MediaCarouselCtlrLog", 20);
}
- /**
- * Provides a {@link LogBuffer} for use in the status bar connectivity pipeline
- */
- @Provides
- @SysUISingleton
- @StatusBarConnectivityLog
- public static LogBuffer provideStatusBarConnectivityBuffer(LogBufferFactory factory) {
- return factory.create("SbConnectivity", 64);
- }
-
/** Allows logging buffers to be tweaked via adb on debug builds but not on prod builds. */
@Provides
@SysUISingleton
diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/StatusBarConnectivityLog.java b/packages/SystemUI/src/com/android/systemui/log/dagger/StatusBarConnectivityLog.java
deleted file mode 100644
index 67cdb72..0000000
--- a/packages/SystemUI/src/com/android/systemui/log/dagger/StatusBarConnectivityLog.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.log.dagger;
-
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import com.android.systemui.plugins.log.LogBuffer;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-
-import javax.inject.Qualifier;
-
-/**
- * A {@link LogBuffer} for status bar connectivity events.
- */
-@Qualifier
-@Documented
-@Retention(RUNTIME)
-public @interface StatusBarConnectivityLog {
-}
diff --git a/packages/SystemUI/src/com/android/systemui/plugins/PluginsModule.java b/packages/SystemUI/src/com/android/systemui/plugins/PluginsModule.java
index 146633d..95f1419 100644
--- a/packages/SystemUI/src/com/android/systemui/plugins/PluginsModule.java
+++ b/packages/SystemUI/src/com/android/systemui/plugins/PluginsModule.java
@@ -121,6 +121,6 @@
@Provides
@Named(PLUGIN_PRIVILEGED)
static List<String> providesPrivilegedPlugins(Context context) {
- return Arrays.asList(context.getResources().getStringArray(R.array.config_pluginWhitelist));
+ return Arrays.asList(context.getResources().getStringArray(R.array.config_pluginAllowlist));
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/settings/UserFileManagerImpl.kt b/packages/SystemUI/src/com/android/systemui/settings/UserFileManagerImpl.kt
index bfba6df..bb637dc 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/UserFileManagerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/settings/UserFileManagerImpl.kt
@@ -32,74 +32,62 @@
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.util.concurrency.DelayableExecutor
import java.io.File
+import java.io.FilenameFilter
import javax.inject.Inject
/**
- * Implementation for retrieving file paths for file storage of system and secondary users. Files
- * lie in {File Directory}/UserFileManager/{User Id} for secondary user. For system user, we use the
- * conventional {File Directory}
+ * Implementation for retrieving file paths for file storage of system and secondary users. For
+ * non-system users, files will be prepended by a special prefix containing the user id.
*/
@SysUISingleton
class UserFileManagerImpl
@Inject
constructor(
- // Context of system process and system user.
private val context: Context,
val userManager: UserManager,
val broadcastDispatcher: BroadcastDispatcher,
@Background val backgroundExecutor: DelayableExecutor
) : UserFileManager, CoreStartable {
companion object {
- private const val FILES = "files"
+ private const val PREFIX = "__USER_"
+ private const val TAG = "UserFileManagerImpl"
+ const val ROOT_DIR = "UserFileManager"
+ const val FILES = "files"
const val SHARED_PREFS = "shared_prefs"
- @VisibleForTesting internal const val ID = "UserFileManager"
-
- /** Returns `true` if the given user ID is that for the primary/system user. */
- fun isPrimaryUser(userId: Int): Boolean {
- return UserHandle(userId).isSystem
- }
/**
- * Returns a [File] pointing to the correct path for a secondary user ID.
- *
- * Note that there is no check for the type of user. This should only be called for
- * secondary users, never for the system user. For that, make sure to call [isPrimaryUser].
- *
- * Note also that there is no guarantee that the parent directory structure for the file
- * exists on disk. For that, call [ensureParentDirExists].
- *
- * @param context The context
- * @param fileName The name of the file
- * @param directoryName The name of the directory that would contain the file
- * @param userId The ID of the user to build a file path for
+ * Returns a File object with a relative path, built from the userId for non-system users
*/
- fun secondaryUserFile(
- context: Context,
- fileName: String,
- directoryName: String,
- userId: Int,
- ): File {
- return Environment.buildPath(
- context.filesDir,
- ID,
- userId.toString(),
- directoryName,
- fileName,
- )
- }
-
- /**
- * Checks to see if parent dir of the file exists. If it does not, we create the parent dirs
- * recursively.
- */
- fun ensureParentDirExists(file: File) {
- val parent = file.parentFile
- if (!parent.exists()) {
- if (!parent.mkdirs()) {
- Log.e(ID, "Could not create parent directory for file: ${file.absolutePath}")
- }
+ fun createFile(fileName: String, userId: Int): File {
+ return if (isSystemUser(userId)) {
+ File(fileName)
+ } else {
+ File(getFilePrefix(userId) + fileName)
}
}
+
+ fun createLegacyFile(context: Context, dir: String, fileName: String, userId: Int): File? {
+ return if (isSystemUser(userId)) {
+ null
+ } else {
+ return Environment.buildPath(
+ context.filesDir,
+ ROOT_DIR,
+ userId.toString(),
+ dir,
+ fileName
+ )
+ }
+ }
+
+ fun getFilePrefix(userId: Int): String {
+ return PREFIX + userId.toString() + "_"
+ }
+
+ /** Returns `true` if the given user ID is that for the system user. */
+ private fun isSystemUser(userId: Int): Boolean {
+ return UserHandle(userId).isSystem
+ }
}
private val broadcastReceiver =
@@ -119,64 +107,87 @@
broadcastDispatcher.registerReceiver(broadcastReceiver, filter, backgroundExecutor)
}
- /** Return the file based on current user. */
+ /**
+ * Return the file based on current user. Files for all users will exist in [context.filesDir],
+ * but non system user files will be prepended with [getFilePrefix].
+ */
override fun getFile(fileName: String, userId: Int): File {
- return if (isPrimaryUser(userId)) {
- Environment.buildPath(context.filesDir, fileName)
- } else {
- val secondaryFile =
- secondaryUserFile(
- context = context,
- userId = userId,
- directoryName = FILES,
- fileName = fileName,
- )
- ensureParentDirExists(secondaryFile)
- secondaryFile
- }
+ val file = File(context.filesDir, createFile(fileName, userId).path)
+ createLegacyFile(context, FILES, fileName, userId)?.run { migrate(file, this) }
+ return file
}
- /** Get shared preferences from user. */
+ /**
+ * Get shared preferences from user. Files for all users will exist in the shared_prefs dir, but
+ * non system user files will be prepended with [getFilePrefix].
+ */
override fun getSharedPreferences(
fileName: String,
@Context.PreferencesMode mode: Int,
userId: Int
): SharedPreferences {
- if (isPrimaryUser(userId)) {
- return context.getSharedPreferences(fileName, mode)
+ val file = createFile(fileName, userId)
+ createLegacyFile(context, SHARED_PREFS, "$fileName.xml", userId)?.run {
+ val path = Environment.buildPath(context.dataDir, SHARED_PREFS, "${file.path}.xml")
+ migrate(path, this)
}
-
- val secondaryUserDir =
- secondaryUserFile(
- context = context,
- fileName = fileName,
- directoryName = SHARED_PREFS,
- userId = userId,
- )
-
- ensureParentDirExists(secondaryUserDir)
- return context.getSharedPreferences(secondaryUserDir, mode)
+ return context.getSharedPreferences(file.path, mode)
}
- /** Remove dirs for deleted users. */
+ /** Remove files for deleted users. */
@VisibleForTesting
internal fun clearDeletedUserData() {
backgroundExecutor.execute {
- val file = Environment.buildPath(context.filesDir, ID)
- if (!file.exists()) return@execute
- val aliveUsers = userManager.aliveUsers.map { it.id.toString() }
- val dirsToDelete = file.list().filter { !aliveUsers.contains(it) }
+ deleteFiles(context.filesDir)
+ deleteFiles(File(context.dataDir, SHARED_PREFS))
+ }
+ }
- dirsToDelete.forEach { dir ->
+ private fun migrate(dest: File, source: File) {
+ if (source.exists()) {
+ try {
+ val parent = source.getParentFile()
+ source.renameTo(dest)
+
+ deleteParentDirsIfEmpty(parent)
+ } catch (e: Exception) {
+ Log.e(TAG, "Failed to rename and delete ${source.path}", e)
+ }
+ }
+ }
+
+ private fun deleteParentDirsIfEmpty(dir: File?) {
+ if (dir != null && dir.listFiles().size == 0) {
+ val priorParent = dir.parentFile
+ val isRoot = dir.name == ROOT_DIR
+ dir.delete()
+
+ if (!isRoot) {
+ deleteParentDirsIfEmpty(priorParent)
+ }
+ }
+ }
+
+ private fun deleteFiles(parent: File) {
+ val aliveUserFilePrefix = userManager.aliveUsers.map { getFilePrefix(it.id) }
+ val filesToDelete =
+ parent.listFiles(
+ FilenameFilter { _, name ->
+ name.startsWith(PREFIX) &&
+ aliveUserFilePrefix.filter { name.startsWith(it) }.isEmpty()
+ }
+ )
+
+ // This can happen in test environments
+ if (filesToDelete == null) {
+ Log.i(TAG, "Empty directory: ${parent.path}")
+ } else {
+ filesToDelete.forEach { file ->
+ Log.i(TAG, "Deleting file: ${file.path}")
try {
- val dirToDelete =
- Environment.buildPath(
- file,
- dir,
- )
- dirToDelete.deleteRecursively()
+ file.delete()
} catch (e: Exception) {
- Log.e(ID, "Deletion failed.", e)
+ Log.e(TAG, "Deletion failed.", e)
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt
index f565f3d..afa60fb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt
@@ -262,7 +262,6 @@
fun setStackScroller(nsslController: NotificationStackScrollLayoutController) {
this.nsslController = nsslController
- touchHelper.host = nsslController.view
touchHelper.expandCallback = nsslController.expandHelperCallback
}
@@ -736,14 +735,12 @@
private var dragDownAmountOnStart = 0.0f
lateinit var expandCallback: ExpandHelper.Callback
- lateinit var host: View
private var minDragDistance = 0
private var initialTouchX = 0f
private var initialTouchY = 0f
private var touchSlop = 0f
private var slopMultiplier = 0f
- private val temp2 = IntArray(2)
private var draggedFarEnough = false
private var startingChild: ExpandableView? = null
private var lastHeight = 0f
@@ -923,7 +920,6 @@
}
private fun findView(x: Float, y: Float): ExpandableView? {
- host.getLocationOnScreen(temp2)
- return expandCallback.getChildAtRawPosition(x + temp2[0], y + temp2[1])
+ return expandCallback.getChildAtRawPosition(x, y)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
index 6e63960..3170f34 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
@@ -870,7 +870,8 @@
}
for (int i = childCount - 1; i >= 0; i--) {
- updateChildZValue(i, algorithmState, ambientState, i == topHunIndex);
+ childrenOnTop = updateChildZValue(i, childrenOnTop,
+ algorithmState, ambientState, i == topHunIndex);
}
}
@@ -880,11 +881,15 @@
*
* @param isTopHun Whether the child is a top HUN. A top HUN means a HUN that shows on the
* vertically top of screen. Top HUNs should have drop shadows
+ * @param childrenOnTop It is greater than 0 when there's an existing HUN that is elevated
+ * @return childrenOnTop The decimal part represents the fraction of the elevated HUN's height
+ * that overlaps with QQS Panel. The integer part represents the count of
+ * previous HUNs whose Z positions are greater than 0.
*/
- protected void updateChildZValue(int i,
- StackScrollAlgorithmState algorithmState,
- AmbientState ambientState,
- boolean isTopHun) {
+ protected float updateChildZValue(int i, float childrenOnTop,
+ StackScrollAlgorithmState algorithmState,
+ AmbientState ambientState,
+ boolean isTopHun) {
ExpandableView child = algorithmState.visibleChildren.get(i);
ExpandableViewState childViewState = child.getViewState();
float baseZ = ambientState.getBaseZHeight();
@@ -898,16 +903,22 @@
// Handles HUN shadow when Shade is opened, and AmbientState.mScrollY > 0
// Calculate the HUN's z-value based on its overlapping fraction with QQS Panel.
// When scrolling down shade to make HUN back to in-position in Notification Panel,
- // the overlapFraction goes to 0, and the pinned HUN's shadows hides gradually.
- float overlap = ambientState.getTopPadding()
- + ambientState.getStackTranslation() - childViewState.getYTranslation();
-
- if (childViewState.height > 0) { // To avoid 0/0 problems
- // To prevent over-shadow
- float overlapFraction = MathUtils.saturate(overlap / childViewState.height);
- childViewState.setZTranslation(baseZ
- + overlapFraction * mPinnedZTranslationExtra);
+ // The over-lapping fraction goes to 0, and shadows hides gradually.
+ if (childrenOnTop != 0.0f) {
+ // To elevate the later HUN over previous HUN
+ childrenOnTop++;
+ } else {
+ float overlap = ambientState.getTopPadding()
+ + ambientState.getStackTranslation() - childViewState.getYTranslation();
+ // To prevent over-shadow during HUN entry
+ childrenOnTop += Math.min(
+ 1.0f,
+ overlap / childViewState.height
+ );
+ MathUtils.saturate(childrenOnTop);
}
+ childViewState.setZTranslation(baseZ
+ + childrenOnTop * mPinnedZTranslationExtra);
} else if (isTopHun) {
// In case this is a new view that has never been measured before, we don't want to
// elevate if we are currently expanded more than the notification
@@ -935,14 +946,15 @@
}
// Handles HUN shadow when shade is closed.
- // While shade is closed, and during HUN's entry: headerVisibleAmount stays 0, shadow stays.
- // While shade is closed, and HUN is showing: headerVisibleAmount stays 0, shadow stays.
+ // While HUN is showing and Shade is closed: headerVisibleAmount stays 0, shadow stays.
// During HUN-to-Shade (eg. dragging down HUN to open Shade): headerVisibleAmount goes
// gradually from 0 to 1, shadow hides gradually.
// Header visibility is a deprecated concept, we are using headerVisibleAmount only because
// this value nicely goes from 0 to 1 during the HUN-to-Shade process.
+
childViewState.setZTranslation(childViewState.getZTranslation()
+ (1.0f - child.getHeaderVisibleAmount()) * mPinnedZTranslationExtra);
+ return childrenOnTop;
}
public void setIsExpanded(boolean isExpanded) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/airplane/ui/viewmodel/AirplaneModeViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/airplane/ui/viewmodel/AirplaneModeViewModel.kt
index 4a5342e..5d5d562 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/airplane/ui/viewmodel/AirplaneModeViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/airplane/ui/viewmodel/AirplaneModeViewModel.kt
@@ -18,9 +18,10 @@
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.log.table.TableLogBuffer
+import com.android.systemui.log.table.logDiffsForTable
import com.android.systemui.statusbar.pipeline.airplane.domain.interactor.AirplaneModeInteractor
-import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger
-import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger.Companion.logOutputChange
+import com.android.systemui.statusbar.pipeline.dagger.AirplaneTableLog
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.SharingStarted
@@ -46,7 +47,7 @@
@Inject
constructor(
interactor: AirplaneModeInteractor,
- logger: ConnectivityPipelineLogger,
+ @AirplaneTableLog logger: TableLogBuffer,
@Application private val scope: CoroutineScope,
) : AirplaneModeViewModel {
override val isAirplaneModeIconVisible: StateFlow<Boolean> =
@@ -56,6 +57,11 @@
isAirplaneMode && !isAirplaneIconForceHidden
}
.distinctUntilChanged()
- .logOutputChange(logger, "isAirplaneModeIconVisible")
+ .logDiffsForTable(
+ logger,
+ columnPrefix = "",
+ columnName = "isAirplaneModeIconVisible",
+ initialValue = false,
+ )
.stateIn(scope, started = SharingStarted.WhileSubscribed(), initialValue = false)
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/MobileInputLog.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/MobileInputLog.kt
new file mode 100644
index 0000000..d1aa79e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/MobileInputLog.kt
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.pipeline.dagger
+
+import javax.inject.Qualifier
+
+/** Logs for inputs into the mobile pipeline. */
+@Qualifier
+@MustBeDocumented
+@kotlin.annotation.Retention(AnnotationRetention.RUNTIME)
+annotation class MobileInputLog
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/SharedConnectivityInputLog.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/SharedConnectivityInputLog.kt
new file mode 100644
index 0000000..5face22
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/SharedConnectivityInputLog.kt
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.pipeline.dagger
+
+import javax.inject.Qualifier
+
+/** Logs for connectivity-related inputs that are shared across wifi, mobile, etc. */
+@Qualifier
+@MustBeDocumented
+@kotlin.annotation.Retention(AnnotationRetention.RUNTIME)
+annotation class SharedConnectivityInputLog
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt
index 60de1a3..4464751 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt
@@ -19,8 +19,10 @@
import android.net.wifi.WifiManager
import com.android.systemui.CoreStartable
import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.log.LogBufferFactory
import com.android.systemui.log.table.TableLogBuffer
import com.android.systemui.log.table.TableLogBufferFactory
+import com.android.systemui.plugins.log.LogBuffer
import com.android.systemui.statusbar.pipeline.airplane.data.repository.AirplaneModeRepository
import com.android.systemui.statusbar.pipeline.airplane.data.repository.AirplaneModeRepositoryImpl
import com.android.systemui.statusbar.pipeline.airplane.ui.viewmodel.AirplaneModeViewModel
@@ -107,6 +109,13 @@
@Provides
@SysUISingleton
+ @WifiInputLog
+ fun provideWifiInputLogBuffer(factory: LogBufferFactory): LogBuffer {
+ return factory.create("WifiInputLog", 50)
+ }
+
+ @Provides
+ @SysUISingleton
@WifiTableLog
fun provideWifiTableLogBuffer(factory: TableLogBufferFactory): TableLogBuffer {
return factory.create("WifiTableLog", 100)
@@ -121,9 +130,23 @@
@Provides
@SysUISingleton
+ @SharedConnectivityInputLog
+ fun provideSharedConnectivityTableLogBuffer(factory: LogBufferFactory): LogBuffer {
+ return factory.create("SharedConnectivityInputLog", 30)
+ }
+
+ @Provides
+ @SysUISingleton
@MobileSummaryLog
fun provideMobileSummaryLogBuffer(factory: TableLogBufferFactory): TableLogBuffer {
return factory.create("MobileSummaryLog", 100)
}
+
+ @Provides
+ @SysUISingleton
+ @MobileInputLog
+ fun provideMobileInputLogBuffer(factory: LogBufferFactory): LogBuffer {
+ return factory.create("MobileInputLog", 100)
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/WifiInputLog.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/WifiInputLog.kt
new file mode 100644
index 0000000..6db6944
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/WifiInputLog.kt
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.pipeline.dagger
+
+import javax.inject.Qualifier
+
+/** Wifi logs for inputs into the wifi pipeline. */
+@Qualifier
+@MustBeDocumented
+@kotlin.annotation.Retention(AnnotationRetention.RUNTIME)
+annotation class WifiInputLog
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/CarrierConfigRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/CarrierConfigRepository.kt
index 5769f90..bb3b9b2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/CarrierConfigRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/CarrierConfigRepository.kt
@@ -31,7 +31,7 @@
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dump.DumpManager
import com.android.systemui.statusbar.pipeline.mobile.data.model.SystemUiCarrierConfig
-import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger
+import com.android.systemui.statusbar.pipeline.mobile.shared.MobileInputLogger
import java.io.PrintWriter
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
@@ -57,7 +57,7 @@
broadcastDispatcher: BroadcastDispatcher,
private val carrierConfigManager: CarrierConfigManager,
dumpManager: DumpManager,
- logger: ConnectivityPipelineLogger,
+ logger: MobileInputLogger,
@Application scope: CoroutineScope,
) : Dumpable {
private var isListening = false
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryImpl.kt
index dcce0ea..96b96f1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryImpl.kt
@@ -47,8 +47,8 @@
import com.android.systemui.statusbar.pipeline.mobile.data.repository.CarrierConfigRepository
import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository
import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository.Companion.DEFAULT_NUM_LEVELS
+import com.android.systemui.statusbar.pipeline.mobile.shared.MobileInputLogger
import com.android.systemui.statusbar.pipeline.mobile.util.MobileMappingsProxy
-import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger
import com.android.systemui.statusbar.pipeline.shared.data.model.toMobileDataActivityModel
import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher
@@ -85,7 +85,7 @@
broadcastDispatcher: BroadcastDispatcher,
private val mobileMappingsProxy: MobileMappingsProxy,
bgDispatcher: CoroutineDispatcher,
- logger: ConnectivityPipelineLogger,
+ logger: MobileInputLogger,
override val tableLogBuffer: TableLogBuffer,
scope: CoroutineScope,
) : MobileConnectionRepository {
@@ -291,7 +291,7 @@
private val broadcastDispatcher: BroadcastDispatcher,
private val context: Context,
private val telephonyManager: TelephonyManager,
- private val logger: ConnectivityPipelineLogger,
+ private val logger: MobileInputLogger,
private val carrierConfigRepository: CarrierConfigRepository,
private val mobileMappingsProxy: MobileMappingsProxy,
@Background private val bgDispatcher: CoroutineDispatcher,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryImpl.kt
index 73ce5e6..b3d5b1e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryImpl.kt
@@ -49,9 +49,8 @@
import com.android.systemui.statusbar.pipeline.mobile.data.model.NetworkNameModel
import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel
import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionsRepository
+import com.android.systemui.statusbar.pipeline.mobile.shared.MobileInputLogger
import com.android.systemui.statusbar.pipeline.mobile.util.MobileMappingsProxy
-import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger
-import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger.Companion.logInputChange
import com.android.systemui.statusbar.pipeline.wifi.data.repository.WifiRepository
import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiNetworkModel
import com.android.systemui.util.kotlin.pairwise
@@ -84,7 +83,7 @@
private val connectivityManager: ConnectivityManager,
private val subscriptionManager: SubscriptionManager,
private val telephonyManager: TelephonyManager,
- private val logger: ConnectivityPipelineLogger,
+ private val logger: MobileInputLogger,
@MobileSummaryLog private val tableLogger: TableLogBuffer,
mobileMappingsProxy: MobileMappingsProxy,
broadcastDispatcher: BroadcastDispatcher,
@@ -222,13 +221,13 @@
private val carrierConfigChangedEvent =
broadcastDispatcher
.broadcastFlow(IntentFilter(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED))
- .logInputChange(logger, "ACTION_CARRIER_CONFIG_CHANGED")
+ .onEach { logger.logActionCarrierConfigChanged() }
override val defaultDataSubRatConfig: StateFlow<Config> =
merge(defaultDataSubIdChangeEvent, carrierConfigChangedEvent)
.mapLatest { Config.readConfig(context) }
.distinctUntilChanged()
- .logInputChange(logger, "defaultDataSubRatConfig")
+ .onEach { logger.logDefaultDataSubRatConfig(it) }
.stateIn(
scope,
SharingStarted.WhileSubscribed(),
@@ -239,13 +238,13 @@
defaultDataSubRatConfig
.map { mobileMappingsProxy.mapIconSets(it) }
.distinctUntilChanged()
- .logInputChange(logger, "defaultMobileIconMapping")
+ .onEach { logger.logDefaultMobileIconMapping(it) }
override val defaultMobileIconGroup: Flow<MobileIconGroup> =
defaultDataSubRatConfig
.map { mobileMappingsProxy.getDefaultIcons(it) }
.distinctUntilChanged()
- .logInputChange(logger, "defaultMobileIconGroup")
+ .onEach { logger.logDefaultMobileIconGroup(it) }
override fun getRepoForSubId(subId: Int): FullMobileConnectionRepository {
if (!isValidSubId(subId)) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractor.kt
index 5a2e11e..142c372 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractor.kt
@@ -30,7 +30,6 @@
import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository
import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionsRepository
import com.android.systemui.statusbar.pipeline.mobile.data.repository.UserSetupRepository
-import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger
import com.android.systemui.statusbar.pipeline.shared.data.model.ConnectivitySlot
import com.android.systemui.statusbar.pipeline.shared.data.repository.ConnectivityRepository
import com.android.systemui.util.CarrierConfigTracker
@@ -111,7 +110,6 @@
constructor(
private val mobileConnectionsRepo: MobileConnectionsRepository,
private val carrierConfigTracker: CarrierConfigTracker,
- private val logger: ConnectivityPipelineLogger,
@MobileSummaryLog private val tableLogger: TableLogBuffer,
connectivityRepository: ConnectivityRepository,
userSetupRepo: UserSetupRepository,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/shared/MobileInputLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/shared/MobileInputLogger.kt
new file mode 100644
index 0000000..3cbd2b7
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/shared/MobileInputLogger.kt
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.pipeline.mobile.shared
+
+import android.net.Network
+import android.net.NetworkCapabilities
+import android.telephony.ServiceState
+import android.telephony.SignalStrength
+import android.telephony.TelephonyDisplayInfo
+import com.android.settingslib.SignalIcon
+import com.android.settingslib.mobile.MobileMappings
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.plugins.log.LogBuffer
+import com.android.systemui.plugins.log.LogLevel
+import com.android.systemui.statusbar.pipeline.dagger.MobileInputLog
+import com.android.systemui.statusbar.pipeline.shared.LoggerHelper
+import javax.inject.Inject
+
+/** Logs for inputs into the mobile pipeline. */
+@SysUISingleton
+class MobileInputLogger
+@Inject
+constructor(
+ @MobileInputLog private val buffer: LogBuffer,
+) {
+ fun logOnCapabilitiesChanged(
+ network: Network,
+ networkCapabilities: NetworkCapabilities,
+ isDefaultNetworkCallback: Boolean,
+ ) {
+ LoggerHelper.logOnCapabilitiesChanged(
+ buffer,
+ TAG,
+ network,
+ networkCapabilities,
+ isDefaultNetworkCallback,
+ )
+ }
+
+ fun logOnLost(network: Network) {
+ LoggerHelper.logOnLost(buffer, TAG, network)
+ }
+
+ fun logOnServiceStateChanged(serviceState: ServiceState, subId: Int) {
+ buffer.log(
+ TAG,
+ LogLevel.INFO,
+ {
+ int1 = subId
+ bool1 = serviceState.isEmergencyOnly
+ bool2 = serviceState.roaming
+ str1 = serviceState.operatorAlphaShort
+ },
+ {
+ "onServiceStateChanged: subId=$int1 emergencyOnly=$bool1 roaming=$bool2" +
+ " operator=$str1"
+ }
+ )
+ }
+
+ fun logOnSignalStrengthsChanged(signalStrength: SignalStrength, subId: Int) {
+ buffer.log(
+ TAG,
+ LogLevel.INFO,
+ {
+ int1 = subId
+ str1 = signalStrength.toString()
+ },
+ { "onSignalStrengthsChanged: subId=$int1 strengths=$str1" }
+ )
+ }
+
+ fun logOnDataConnectionStateChanged(dataState: Int, networkType: Int, subId: Int) {
+ buffer.log(
+ TAG,
+ LogLevel.INFO,
+ {
+ int1 = subId
+ int2 = dataState
+ str1 = networkType.toString()
+ },
+ { "onDataConnectionStateChanged: subId=$int1 dataState=$int2 networkType=$str1" },
+ )
+ }
+
+ fun logOnDataActivity(direction: Int, subId: Int) {
+ buffer.log(
+ TAG,
+ LogLevel.INFO,
+ {
+ int1 = subId
+ int2 = direction
+ },
+ { "onDataActivity: subId=$int1 direction=$int2" },
+ )
+ }
+
+ fun logOnCarrierNetworkChange(active: Boolean, subId: Int) {
+ buffer.log(
+ TAG,
+ LogLevel.INFO,
+ {
+ int1 = subId
+ bool1 = active
+ },
+ { "onCarrierNetworkChange: subId=$int1 active=$bool1" },
+ )
+ }
+
+ fun logOnDisplayInfoChanged(displayInfo: TelephonyDisplayInfo, subId: Int) {
+ buffer.log(
+ TAG,
+ LogLevel.INFO,
+ {
+ int1 = subId
+ str1 = displayInfo.toString()
+ },
+ { "onDisplayInfoChanged: subId=$int1 displayInfo=$str1" },
+ )
+ }
+
+ fun logUiAdapterSubIdsUpdated(subs: List<Int>) {
+ buffer.log(
+ TAG,
+ LogLevel.INFO,
+ { str1 = subs.toString() },
+ { "Sub IDs in MobileUiAdapter updated internally: $str1" },
+ )
+ }
+
+ fun logUiAdapterSubIdsSentToIconController(subs: List<Int>) {
+ buffer.log(
+ TAG,
+ LogLevel.INFO,
+ { str1 = subs.toString() },
+ { "Sub IDs in MobileUiAdapter being sent to icon controller: $str1" },
+ )
+ }
+
+ fun logCarrierConfigChanged(subId: Int) {
+ buffer.log(
+ TAG,
+ LogLevel.INFO,
+ { int1 = subId },
+ { "onCarrierConfigChanged: subId=$int1" },
+ )
+ }
+
+ fun logOnDataEnabledChanged(enabled: Boolean, subId: Int) {
+ buffer.log(
+ TAG,
+ LogLevel.INFO,
+ {
+ int1 = subId
+ bool1 = enabled
+ },
+ { "onDataEnabledChanged: subId=$int1 enabled=$bool1" },
+ )
+ }
+
+ fun logActionCarrierConfigChanged() {
+ buffer.log(TAG, LogLevel.INFO, {}, { "Intent received: ACTION_CARRIER_CONFIG_CHANGED" })
+ }
+
+ fun logDefaultDataSubRatConfig(config: MobileMappings.Config) {
+ buffer.log(
+ TAG,
+ LogLevel.INFO,
+ { str1 = config.toString() },
+ { "defaultDataSubRatConfig: $str1" }
+ )
+ }
+
+ fun logDefaultMobileIconMapping(mapping: Map<String, SignalIcon.MobileIconGroup>) {
+ buffer.log(
+ TAG,
+ LogLevel.INFO,
+ { str1 = mapping.toString() },
+ { "defaultMobileIconMapping: $str1" }
+ )
+ }
+
+ fun logDefaultMobileIconGroup(group: SignalIcon.MobileIconGroup) {
+ buffer.log(TAG, LogLevel.INFO, { str1 = group.name }, { "defaultMobileIconGroup: $str1" })
+ }
+}
+
+private const val TAG = "MobileInputLog"
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/MobileUiAdapter.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/MobileUiAdapter.kt
index ef75713..da63ab1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/MobileUiAdapter.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/MobileUiAdapter.kt
@@ -22,8 +22,8 @@
import com.android.systemui.statusbar.phone.StatusBarIconController
import com.android.systemui.statusbar.pipeline.StatusBarPipelineFlags
import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconsInteractor
+import com.android.systemui.statusbar.pipeline.mobile.shared.MobileInputLogger
import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.MobileIconsViewModel
-import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger
import java.io.PrintWriter
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
@@ -55,7 +55,7 @@
interactor: MobileIconsInteractor,
private val iconController: StatusBarIconController,
private val iconsViewModelFactory: MobileIconsViewModel.Factory,
- private val logger: ConnectivityPipelineLogger,
+ private val logger: MobileInputLogger,
@Application private val scope: CoroutineScope,
private val statusBarPipelineFlags: StatusBarPipelineFlags,
) : CoreStartable {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModel.kt
index 185b668..8cb52af 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModel.kt
@@ -25,7 +25,6 @@
import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconsInteractor
import com.android.systemui.statusbar.pipeline.mobile.ui.view.ModernStatusBarMobileView
import com.android.systemui.statusbar.pipeline.shared.ConnectivityConstants
-import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.StateFlow
@@ -42,7 +41,6 @@
val subscriptionIdsFlow: StateFlow<List<Int>>,
private val interactor: MobileIconsInteractor,
private val airplaneModeInteractor: AirplaneModeInteractor,
- private val logger: ConnectivityPipelineLogger,
private val constants: ConnectivityConstants,
@Application private val scope: CoroutineScope,
private val statusBarPipelineFlags: StatusBarPipelineFlags,
@@ -83,7 +81,6 @@
constructor(
private val interactor: MobileIconsInteractor,
private val airplaneModeInteractor: AirplaneModeInteractor,
- private val logger: ConnectivityPipelineLogger,
private val constants: ConnectivityConstants,
@Application private val scope: CoroutineScope,
private val statusBarPipelineFlags: StatusBarPipelineFlags,
@@ -93,7 +90,6 @@
subscriptionIdsFlow,
interactor,
airplaneModeInteractor,
- logger,
constants,
scope,
statusBarPipelineFlags,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ConnectivityConstants.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ConnectivityConstants.kt
index 0c9b86c..0fe5329 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ConnectivityConstants.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ConnectivityConstants.kt
@@ -22,7 +22,6 @@
import com.android.systemui.R
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dump.DumpManager
-import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger.Companion.SB_LOGGING_TAG
import java.io.PrintWriter
import javax.inject.Inject
@@ -40,7 +39,7 @@
telephonyManager: TelephonyManager,
) : Dumpable {
init {
- dumpManager.registerNormalDumpable("${SB_LOGGING_TAG}Constants", this)
+ dumpManager.registerNormalDumpable("ConnectivityConstants", this)
}
/** True if this device has the capability for data connections and false otherwise. */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ConnectivityInputLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ConnectivityInputLogger.kt
new file mode 100644
index 0000000..95548b8
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ConnectivityInputLogger.kt
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.pipeline.shared
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.plugins.log.LogBuffer
+import com.android.systemui.plugins.log.LogLevel
+import com.android.systemui.statusbar.pipeline.dagger.SharedConnectivityInputLog
+import javax.inject.Inject
+
+/** Logs for connectivity-related inputs that are shared across wifi, mobile, etc. */
+@SysUISingleton
+class ConnectivityInputLogger
+@Inject
+constructor(
+ @SharedConnectivityInputLog private val buffer: LogBuffer,
+) {
+ fun logTuningChanged(tuningList: String?) {
+ buffer.log(TAG, LogLevel.DEBUG, { str1 = tuningList }, { "onTuningChanged: $str1" })
+ }
+}
+
+private const val TAG = "ConnectivityInputLogger"
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ConnectivityPipelineLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ConnectivityPipelineLogger.kt
deleted file mode 100644
index 45036969..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ConnectivityPipelineLogger.kt
+++ /dev/null
@@ -1,285 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.statusbar.pipeline.shared
-
-import android.net.Network
-import android.net.NetworkCapabilities
-import android.telephony.ServiceState
-import android.telephony.SignalStrength
-import android.telephony.TelephonyDisplayInfo
-import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.log.dagger.StatusBarConnectivityLog
-import com.android.systemui.plugins.log.LogBuffer
-import com.android.systemui.plugins.log.LogLevel
-import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel
-import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger.Companion.toString
-import javax.inject.Inject
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.onEach
-
-@SysUISingleton
-class ConnectivityPipelineLogger
-@Inject
-constructor(
- @StatusBarConnectivityLog private val buffer: LogBuffer,
-) {
- /**
- * Logs a change in one of the **raw inputs** to the connectivity pipeline.
- *
- * Use this method for inputs that don't have any extra information besides their callback name.
- */
- fun logInputChange(callbackName: String) {
- buffer.log(SB_LOGGING_TAG, LogLevel.INFO, { str1 = callbackName }, { "Input: $str1" })
- }
-
- /** Logs a change in one of the **raw inputs** to the connectivity pipeline. */
- fun logInputChange(callbackName: String, changeInfo: String?) {
- buffer.log(
- SB_LOGGING_TAG,
- LogLevel.INFO,
- {
- str1 = callbackName
- str2 = changeInfo
- },
- { "Input: $str1: $str2" }
- )
- }
-
- /** Logs a **data transformation** that we performed within the connectivity pipeline. */
- fun logTransformation(transformationName: String, oldValue: Any?, newValue: Any?) {
- if (oldValue == newValue) {
- buffer.log(
- SB_LOGGING_TAG,
- LogLevel.INFO,
- {
- str1 = transformationName
- str2 = oldValue.toString()
- },
- { "Transform: $str1: $str2 (transformation didn't change it)" }
- )
- } else {
- buffer.log(
- SB_LOGGING_TAG,
- LogLevel.INFO,
- {
- str1 = transformationName
- str2 = oldValue.toString()
- str3 = newValue.toString()
- },
- { "Transform: $str1: $str2 -> $str3" }
- )
- }
- }
-
- /** Logs a change in one of the **outputs** to the connectivity pipeline. */
- fun logOutputChange(outputParamName: String, changeInfo: String) {
- buffer.log(
- SB_LOGGING_TAG,
- LogLevel.INFO,
- {
- str1 = outputParamName
- str2 = changeInfo
- },
- { "Output: $str1: $str2" }
- )
- }
-
- fun logOnCapabilitiesChanged(
- network: Network,
- networkCapabilities: NetworkCapabilities,
- isDefaultNetworkCallback: Boolean,
- ) {
- buffer.log(
- SB_LOGGING_TAG,
- LogLevel.INFO,
- {
- bool1 = isDefaultNetworkCallback
- int1 = network.getNetId()
- str1 = networkCapabilities.toString()
- },
- { "onCapabilitiesChanged[default=$bool1]: net=$int1 capabilities=$str1" }
- )
- }
-
- fun logOnLost(network: Network) {
- buffer.log(
- SB_LOGGING_TAG,
- LogLevel.INFO,
- { int1 = network.getNetId() },
- { "onLost: net=$int1" }
- )
- }
-
- fun logOnServiceStateChanged(serviceState: ServiceState, subId: Int) {
- buffer.log(
- SB_LOGGING_TAG,
- LogLevel.INFO,
- {
- int1 = subId
- bool1 = serviceState.isEmergencyOnly
- bool2 = serviceState.roaming
- str1 = serviceState.operatorAlphaShort
- },
- {
- "onServiceStateChanged: subId=$int1 emergencyOnly=$bool1 roaming=$bool2" +
- " operator=$str1"
- }
- )
- }
-
- fun logOnSignalStrengthsChanged(signalStrength: SignalStrength, subId: Int) {
- buffer.log(
- SB_LOGGING_TAG,
- LogLevel.INFO,
- {
- int1 = subId
- str1 = signalStrength.toString()
- },
- { "onSignalStrengthsChanged: subId=$int1 strengths=$str1" }
- )
- }
-
- fun logOnDataConnectionStateChanged(dataState: Int, networkType: Int, subId: Int) {
- buffer.log(
- SB_LOGGING_TAG,
- LogLevel.INFO,
- {
- int1 = subId
- int2 = dataState
- str1 = networkType.toString()
- },
- { "onDataConnectionStateChanged: subId=$int1 dataState=$int2 networkType=$str1" },
- )
- }
-
- fun logOnDataActivity(direction: Int, subId: Int) {
- buffer.log(
- SB_LOGGING_TAG,
- LogLevel.INFO,
- {
- int1 = subId
- int2 = direction
- },
- { "onDataActivity: subId=$int1 direction=$int2" },
- )
- }
-
- fun logOnCarrierNetworkChange(active: Boolean, subId: Int) {
- buffer.log(
- SB_LOGGING_TAG,
- LogLevel.INFO,
- {
- int1 = subId
- bool1 = active
- },
- { "onCarrierNetworkChange: subId=$int1 active=$bool1" },
- )
- }
-
- fun logOnDisplayInfoChanged(displayInfo: TelephonyDisplayInfo, subId: Int) {
- buffer.log(
- SB_LOGGING_TAG,
- LogLevel.INFO,
- {
- int1 = subId
- str1 = displayInfo.toString()
- },
- { "onDisplayInfoChanged: subId=$int1 displayInfo=$str1" },
- )
- }
-
- // TODO(b/238425913): We should split this class into mobile-specific and wifi-specific loggers.
-
- fun logUiAdapterSubIdsUpdated(subs: List<Int>) {
- buffer.log(
- SB_LOGGING_TAG,
- LogLevel.INFO,
- { str1 = subs.toString() },
- { "Sub IDs in MobileUiAdapter updated internally: $str1" },
- )
- }
-
- fun logUiAdapterSubIdsSentToIconController(subs: List<Int>) {
- buffer.log(
- SB_LOGGING_TAG,
- LogLevel.INFO,
- { str1 = subs.toString() },
- { "Sub IDs in MobileUiAdapter being sent to icon controller: $str1" },
- )
- }
-
- fun logCarrierConfigChanged(subId: Int) {
- buffer.log(
- SB_LOGGING_TAG,
- LogLevel.INFO,
- { int1 = subId },
- { "onCarrierConfigChanged: subId=$int1" },
- )
- }
-
- fun logOnDataEnabledChanged(enabled: Boolean, subId: Int) {
- buffer.log(
- SB_LOGGING_TAG,
- LogLevel.INFO,
- {
- int1 = subId
- bool1 = enabled
- },
- { "onDataEnabledChanged: subId=$int1 enabled=$bool1" },
- )
- }
-
- companion object {
- const val SB_LOGGING_TAG = "SbConnectivity"
-
- /** Log a change in one of the **inputs** to the connectivity pipeline. */
- fun Flow<Unit>.logInputChange(
- logger: ConnectivityPipelineLogger,
- inputParamName: String,
- ): Flow<Unit> {
- return this.onEach { logger.logInputChange(inputParamName) }
- }
-
- /**
- * Log a change in one of the **inputs** to the connectivity pipeline.
- *
- * @param prettyPrint an optional function to transform the value into a readable string.
- * [toString] is used if no custom function is provided.
- */
- fun <T> Flow<T>.logInputChange(
- logger: ConnectivityPipelineLogger,
- inputParamName: String,
- prettyPrint: (T) -> String = { it.toString() }
- ): Flow<T> {
- return this.onEach { logger.logInputChange(inputParamName, prettyPrint(it)) }
- }
-
- /**
- * Log a change in one of the **outputs** to the connectivity pipeline.
- *
- * @param prettyPrint an optional function to transform the value into a readable string.
- * [toString] is used if no custom function is provided.
- */
- fun <T> Flow<T>.logOutputChange(
- logger: ConnectivityPipelineLogger,
- outputParamName: String,
- prettyPrint: (T) -> String = { it.toString() }
- ): Flow<T> {
- return this.onEach { logger.logOutputChange(outputParamName, prettyPrint(it)) }
- }
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/LoggerHelper.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/LoggerHelper.kt
new file mode 100644
index 0000000..6f29e33
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/LoggerHelper.kt
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.pipeline.shared
+
+import android.net.Network
+import android.net.NetworkCapabilities
+import com.android.systemui.plugins.log.LogBuffer
+import com.android.systemui.plugins.log.LogLevel
+
+/** Helper object for logs that are shared between wifi and mobile. */
+object LoggerHelper {
+ fun logOnCapabilitiesChanged(
+ buffer: LogBuffer,
+ tag: String,
+ network: Network,
+ networkCapabilities: NetworkCapabilities,
+ isDefaultNetworkCallback: Boolean,
+ ) {
+ buffer.log(
+ tag,
+ LogLevel.INFO,
+ {
+ bool1 = isDefaultNetworkCallback
+ int1 = network.getNetId()
+ str1 = networkCapabilities.toString()
+ },
+ { "onCapabilitiesChanged[default=$bool1]: net=$int1 capabilities=$str1" }
+ )
+ }
+
+ fun logOnLost(buffer: LogBuffer, tag: String, network: Network) {
+ buffer.log(tag, LogLevel.INFO, { int1 = network.getNetId() }, { "onLost: net=$int1" })
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/data/repository/ConnectivityRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/data/repository/ConnectivityRepository.kt
index 45c6d46..5d9ba018 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/data/repository/ConnectivityRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/data/repository/ConnectivityRepository.kt
@@ -26,8 +26,7 @@
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dump.DumpManager
import com.android.systemui.statusbar.phone.StatusBarIconController
-import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger
-import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger.Companion.SB_LOGGING_TAG
+import com.android.systemui.statusbar.pipeline.shared.ConnectivityInputLogger
import com.android.systemui.statusbar.pipeline.shared.data.model.ConnectivitySlot
import com.android.systemui.statusbar.pipeline.shared.data.model.ConnectivitySlots
import com.android.systemui.tuner.TunerService
@@ -45,59 +44,61 @@
* types of connectivity (wifi, mobile, ethernet, etc.)
*/
interface ConnectivityRepository {
- /**
- * Observable for the current set of connectivity icons that should be force-hidden.
- */
+ /** Observable for the current set of connectivity icons that should be force-hidden. */
val forceHiddenSlots: StateFlow<Set<ConnectivitySlot>>
}
@OptIn(ExperimentalCoroutinesApi::class)
@SysUISingleton
-class ConnectivityRepositoryImpl @Inject constructor(
+class ConnectivityRepositoryImpl
+@Inject
+constructor(
private val connectivitySlots: ConnectivitySlots,
context: Context,
dumpManager: DumpManager,
- logger: ConnectivityPipelineLogger,
+ logger: ConnectivityInputLogger,
@Application scope: CoroutineScope,
tunerService: TunerService,
) : ConnectivityRepository, Dumpable {
init {
- dumpManager.registerDumpable("${SB_LOGGING_TAG}Repository", this)
+ dumpManager.registerDumpable("ConnectivityRepository", this)
}
// The default set of hidden icons to use if we don't get any from [TunerService].
private val defaultHiddenIcons: Set<ConnectivitySlot> =
- context.resources.getStringArray(DEFAULT_HIDDEN_ICONS_RESOURCE)
- .asList()
- .toSlotSet(connectivitySlots)
+ context.resources
+ .getStringArray(DEFAULT_HIDDEN_ICONS_RESOURCE)
+ .asList()
+ .toSlotSet(connectivitySlots)
- override val forceHiddenSlots: StateFlow<Set<ConnectivitySlot>> = conflatedCallbackFlow {
- val callback = object : TunerService.Tunable {
- override fun onTuningChanged(key: String, newHideList: String?) {
- if (key != HIDDEN_ICONS_TUNABLE_KEY) {
- return
- }
- logger.logInputChange("onTuningChanged", newHideList)
+ override val forceHiddenSlots: StateFlow<Set<ConnectivitySlot>> =
+ conflatedCallbackFlow {
+ val callback =
+ object : TunerService.Tunable {
+ override fun onTuningChanged(key: String, newHideList: String?) {
+ if (key != HIDDEN_ICONS_TUNABLE_KEY) {
+ return
+ }
+ logger.logTuningChanged(newHideList)
- val outputList = newHideList?.split(",")?.toSlotSet(connectivitySlots)
- ?: defaultHiddenIcons
- trySend(outputList)
+ val outputList =
+ newHideList?.split(",")?.toSlotSet(connectivitySlots)
+ ?: defaultHiddenIcons
+ trySend(outputList)
+ }
+ }
+ tunerService.addTunable(callback, HIDDEN_ICONS_TUNABLE_KEY)
+
+ awaitClose { tunerService.removeTunable(callback) }
}
- }
- tunerService.addTunable(callback, HIDDEN_ICONS_TUNABLE_KEY)
-
- awaitClose { tunerService.removeTunable(callback) }
- }
- .stateIn(
- scope,
- started = SharingStarted.WhileSubscribed(),
- initialValue = defaultHiddenIcons
- )
+ .stateIn(
+ scope,
+ started = SharingStarted.WhileSubscribed(),
+ initialValue = defaultHiddenIcons
+ )
override fun dump(pw: PrintWriter, args: Array<out String>) {
- pw.apply {
- println("defaultHiddenIcons=$defaultHiddenIcons")
- }
+ pw.apply { println("defaultHiddenIcons=$defaultHiddenIcons") }
}
companion object {
@@ -111,8 +112,7 @@
private fun List<String>.toSlotSet(
connectivitySlots: ConnectivitySlots
): Set<ConnectivitySlot> {
- return this
- .filter { it.isNotBlank() }
+ return this.filter { it.isNotBlank() }
.mapNotNull { connectivitySlots.getSlotFromName(it) }
.toSet()
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImpl.kt
index 7b486c1..ee58160 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImpl.kt
@@ -39,12 +39,11 @@
import com.android.systemui.log.table.TableLogBuffer
import com.android.systemui.log.table.logDiffsForTable
import com.android.systemui.statusbar.pipeline.dagger.WifiTableLog
-import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger
-import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger.Companion.logInputChange
import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel
import com.android.systemui.statusbar.pipeline.shared.data.model.toWifiDataActivityModel
import com.android.systemui.statusbar.pipeline.wifi.data.repository.RealWifiRepository
import com.android.systemui.statusbar.pipeline.wifi.data.repository.WifiRepository
+import com.android.systemui.statusbar.pipeline.wifi.shared.WifiInputLogger
import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiNetworkModel
import java.util.concurrent.Executor
import javax.inject.Inject
@@ -58,6 +57,7 @@
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.mapLatest
import kotlinx.coroutines.flow.merge
+import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.stateIn
/** Real implementation of [WifiRepository]. */
@@ -70,7 +70,7 @@
constructor(
broadcastDispatcher: BroadcastDispatcher,
connectivityManager: ConnectivityManager,
- logger: ConnectivityPipelineLogger,
+ logger: WifiInputLogger,
@WifiTableLog wifiTableLogBuffer: TableLogBuffer,
@Main mainExecutor: Executor,
@Application scope: CoroutineScope,
@@ -80,7 +80,7 @@
private val wifiStateChangeEvents: Flow<Unit> =
broadcastDispatcher
.broadcastFlow(IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION))
- .logInputChange(logger, "WIFI_STATE_CHANGED_ACTION intent")
+ .onEach { logger.logIntent("WIFI_STATE_CHANGED_ACTION") }
private val wifiNetworkChangeEvents: MutableSharedFlow<Unit> =
MutableSharedFlow(extraBufferCapacity = 1)
@@ -173,11 +173,6 @@
networkCapabilities,
wifiManager,
)
- logger.logTransformation(
- WIFI_NETWORK_CALLBACK_NAME,
- oldValue = currentWifi,
- newValue = wifiNetworkModel,
- )
currentWifi = wifiNetworkModel
trySend(wifiNetworkModel)
}
@@ -194,11 +189,6 @@
wifi.networkId == network.getNetId()
) {
val newNetworkModel = WifiNetworkModel.Inactive
- logger.logTransformation(
- WIFI_NETWORK_CALLBACK_NAME,
- oldValue = wifi,
- newValue = newNetworkModel,
- )
currentWifi = newNetworkModel
trySend(newNetworkModel)
}
@@ -228,7 +218,7 @@
override val wifiActivity: StateFlow<DataActivityModel> =
conflatedCallbackFlow {
val callback = TrafficStateCallback { state ->
- logger.logInputChange("onTrafficStateChange", prettyPrintActivity(state))
+ logger.logActivity(prettyPrintActivity(state))
trySend(state.toWifiDataActivityModel())
}
wifiManager.registerTrafficStateCallback(mainExecutor, callback)
@@ -336,8 +326,6 @@
.addTransportType(TRANSPORT_CELLULAR)
.build()
- private const val WIFI_NETWORK_CALLBACK_NAME = "wifiNetworkModel"
-
private const val CARRIER_MERGED_INVALID_SUB_ID_REASON =
"Wifi network was carrier merged but had invalid sub ID"
}
@@ -348,7 +336,7 @@
constructor(
private val broadcastDispatcher: BroadcastDispatcher,
private val connectivityManager: ConnectivityManager,
- private val logger: ConnectivityPipelineLogger,
+ private val logger: WifiInputLogger,
@WifiTableLog private val wifiTableLogBuffer: TableLogBuffer,
@Main private val mainExecutor: Executor,
@Application private val scope: CoroutineScope,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/shared/WifiConstants.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/shared/WifiConstants.kt
index 4f7fe28..8bea772 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/shared/WifiConstants.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/shared/WifiConstants.kt
@@ -21,7 +21,6 @@
import com.android.systemui.R
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dump.DumpManager
-import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger.Companion.SB_LOGGING_TAG
import java.io.PrintWriter
import javax.inject.Inject
@@ -30,12 +29,14 @@
* logging purposes.
*/
@SysUISingleton
-class WifiConstants @Inject constructor(
- context: Context,
- dumpManager: DumpManager,
+class WifiConstants
+@Inject
+constructor(
+ context: Context,
+ dumpManager: DumpManager,
) : Dumpable {
init {
- dumpManager.registerDumpable("${SB_LOGGING_TAG}WifiConstants", this)
+ dumpManager.registerNormalDumpable("WifiConstants", this)
}
/** True if we should always show the wifi icon when wifi is enabled and false otherwise. */
@@ -43,8 +44,6 @@
context.resources.getBoolean(R.bool.config_showWifiIndicatorWhenEnabled)
override fun dump(pw: PrintWriter, args: Array<out String>) {
- pw.apply {
- println("alwaysShowIconIfEnabled=$alwaysShowIconIfEnabled")
- }
+ pw.apply { println("alwaysShowIconIfEnabled=$alwaysShowIconIfEnabled") }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/shared/WifiInputLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/shared/WifiInputLogger.kt
new file mode 100644
index 0000000..a32e475
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/shared/WifiInputLogger.kt
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.pipeline.wifi.shared
+
+import android.net.Network
+import android.net.NetworkCapabilities
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.plugins.log.LogBuffer
+import com.android.systemui.plugins.log.LogLevel
+import com.android.systemui.statusbar.pipeline.dagger.WifiInputLog
+import com.android.systemui.statusbar.pipeline.shared.LoggerHelper
+import javax.inject.Inject
+
+/**
+ * Logger for all the wifi-related inputs (intents, callbacks, etc.) that the wifi repo receives.
+ */
+@SysUISingleton
+class WifiInputLogger
+@Inject
+constructor(
+ @WifiInputLog val buffer: LogBuffer,
+) {
+ fun logOnCapabilitiesChanged(
+ network: Network,
+ networkCapabilities: NetworkCapabilities,
+ isDefaultNetworkCallback: Boolean,
+ ) {
+ LoggerHelper.logOnCapabilitiesChanged(
+ buffer,
+ TAG,
+ network,
+ networkCapabilities,
+ isDefaultNetworkCallback,
+ )
+ }
+
+ fun logOnLost(network: Network) {
+ LoggerHelper.logOnLost(buffer, TAG, network)
+ }
+
+ fun logIntent(intentName: String) {
+ buffer.log(TAG, LogLevel.DEBUG, { str1 = intentName }, { "Intent received: $str1" })
+ }
+
+ fun logActivity(activity: String) {
+ buffer.log(TAG, LogLevel.DEBUG, { str1 = activity }, { "Activity: $str1" })
+ }
+}
+
+private const val TAG = "WifiInputLog"
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModel.kt
index 0f5ff91..1057231 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModel.kt
@@ -34,8 +34,6 @@
import com.android.systemui.statusbar.pipeline.airplane.ui.viewmodel.AirplaneModeViewModel
import com.android.systemui.statusbar.pipeline.dagger.WifiTableLog
import com.android.systemui.statusbar.pipeline.shared.ConnectivityConstants
-import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger
-import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger.Companion.logOutputChange
import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel
import com.android.systemui.statusbar.pipeline.wifi.domain.interactor.WifiInteractor
import com.android.systemui.statusbar.pipeline.wifi.shared.WifiConstants
@@ -69,7 +67,6 @@
airplaneModeViewModel: AirplaneModeViewModel,
connectivityConstants: ConnectivityConstants,
private val context: Context,
- logger: ConnectivityPipelineLogger,
@WifiTableLog wifiTableLogBuffer: TableLogBuffer,
interactor: WifiInteractor,
@Application private val scope: CoroutineScope,
@@ -143,29 +140,35 @@
)
/** The wifi activity status. Null if we shouldn't display the activity status. */
- private val activity: Flow<DataActivityModel?> =
+ private val activity: Flow<DataActivityModel> = run {
+ val default = DataActivityModel(hasActivityIn = false, hasActivityOut = false)
if (!connectivityConstants.shouldShowActivityConfig) {
- flowOf(null)
+ flowOf(default)
} else {
combine(interactor.activity, interactor.ssid) { activity, ssid ->
when (ssid) {
- null -> null
+ null -> default
else -> activity
}
}
}
.distinctUntilChanged()
- .logOutputChange(logger, "activity")
- .stateIn(scope, started = SharingStarted.WhileSubscribed(), initialValue = null)
+ .logDiffsForTable(
+ wifiTableLogBuffer,
+ columnPrefix = "VM.activity",
+ initialValue = default,
+ )
+ .stateIn(scope, started = SharingStarted.WhileSubscribed(), initialValue = default)
+ }
private val isActivityInViewVisible: Flow<Boolean> =
activity
- .map { it?.hasActivityIn == true }
+ .map { it.hasActivityIn }
.stateIn(scope, started = SharingStarted.WhileSubscribed(), initialValue = false)
private val isActivityOutViewVisible: Flow<Boolean> =
activity
- .map { it?.hasActivityOut == true }
+ .map { it.hasActivityOut }
.stateIn(scope, started = SharingStarted.WhileSubscribed(), initialValue = false)
private val isActivityContainerVisible: Flow<Boolean> =
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateController.java
index 1ae1eae..8929e02 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateController.java
@@ -56,7 +56,7 @@
/**
* Whether the bouncer (PIN/password entry) is currently visible.
*/
- boolean isBouncerShowing();
+ boolean isPrimaryBouncerShowing();
/**
* If swiping up will unlock without asking for a password.
@@ -196,7 +196,7 @@
/** **/
default void notifyKeyguardState(boolean showing, boolean occluded) {}
/** **/
- default void notifyBouncerShowing(boolean showing) {}
+ default void notifyPrimaryBouncerShowing(boolean showing) {}
/**
* Updates the keyguard state to reflect that it's in the process of being dismissed, either by
@@ -244,7 +244,7 @@
/**
* Called when the bouncer (PIN/password entry) is shown or hidden.
*/
- default void onBouncerShowingChanged() {}
+ default void onPrimaryBouncerShowingChanged() {}
/**
* Triggered when the device was just unlocked and the lock screen is being dismissed.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java
index 9ad36fd5..805368c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java
@@ -65,7 +65,7 @@
private boolean mCanDismissLockScreen;
private boolean mShowing;
- private boolean mBouncerShowing;
+ private boolean mPrimaryBouncerShowing;
private boolean mSecure;
private boolean mOccluded;
@@ -157,8 +157,8 @@
}
@Override
- public boolean isBouncerShowing() {
- return mBouncerShowing;
+ public boolean isPrimaryBouncerShowing() {
+ return mPrimaryBouncerShowing;
}
@Override
@@ -339,11 +339,11 @@
}
@Override
- public void notifyBouncerShowing(boolean showing) {
- if (mBouncerShowing != showing) {
- mBouncerShowing = showing;
+ public void notifyPrimaryBouncerShowing(boolean showing) {
+ if (mPrimaryBouncerShowing != showing) {
+ mPrimaryBouncerShowing = showing;
- new ArrayList<>(mCallbacks).forEach(Callback::onBouncerShowingChanged);
+ new ArrayList<>(mCallbacks).forEach(Callback::onPrimaryBouncerShowingChanged);
}
}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt
index f7fec80..480b8f9 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt
@@ -23,6 +23,7 @@
import com.android.systemui.SysuiTestCase
import com.android.systemui.broadcast.BroadcastDispatcher
import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
@@ -85,6 +86,7 @@
@Mock private lateinit var transitionRepository: KeyguardTransitionRepository
@Mock private lateinit var commandQueue: CommandQueue
private lateinit var repository: FakeKeyguardRepository
+ private lateinit var bouncerRepository: FakeKeyguardBouncerRepository
@Mock private lateinit var smallLogBuffer: LogBuffer
@Mock private lateinit var largeLogBuffer: LogBuffer
private lateinit var underTest: ClockEventController
@@ -103,11 +105,15 @@
whenever(largeClockEvents.tickRate).thenReturn(ClockTickRate.PER_MINUTE)
repository = FakeKeyguardRepository()
+ bouncerRepository = FakeKeyguardBouncerRepository()
underTest = ClockEventController(
- KeyguardInteractor(repository = repository,
- commandQueue = commandQueue,
- featureFlags = featureFlags),
+ KeyguardInteractor(
+ repository = repository,
+ commandQueue = commandQueue,
+ featureFlags = featureFlags,
+ bouncerRepository = bouncerRepository,
+ ),
KeyguardTransitionInteractor(repository = transitionRepository),
broadcastDispatcher,
batteryController,
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java
index ccc4e4a..a5f90f8 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java
@@ -241,7 +241,7 @@
mController.init();
verify(mClockRegistry).registerClockChangeListener(listenerArgumentCaptor.capture());
- listenerArgumentCaptor.getValue().onClockChanged();
+ listenerArgumentCaptor.getValue().onCurrentClockChanged();
verify(mView, times(2)).setClock(mClockController, StatusBarState.SHADE);
verify(mClockEventController, times(2)).setClock(mClockController);
}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
index 853d8ed..849d0bb 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -900,6 +900,25 @@
}
@Test
+ public void noFpListeningWhenKeyguardIsOccluded_unlessAlternateBouncerShowing() {
+ // GIVEN device is awake but occluded
+ mKeyguardUpdateMonitor.dispatchStartedWakingUp(PowerManager.WAKE_REASON_POWER_BUTTON);
+ mKeyguardUpdateMonitor.setKeyguardShowing(false, true);
+
+ // THEN fingerprint shouldn't listen
+ assertThat(mKeyguardUpdateMonitor.shouldListenForFingerprint(false)).isFalse();
+ verify(mFingerprintManager, never()).authenticate(any(), any(), any(), any(), anyInt(),
+ anyInt(), anyInt());
+
+ // WHEN alternate bouncer is shown
+ mKeyguardUpdateMonitor.setAlternateBouncerShowing(true);
+
+ // THEN make sure FP listening begins
+ verify(mFingerprintManager).authenticate(any(), any(), any(), any(), anyInt(), anyInt(),
+ anyInt());
+ }
+
+ @Test
public void testTriesToAuthenticate_whenTrustOnAgentKeyguard_ifBypass() {
mKeyguardUpdateMonitor.dispatchStartedWakingUp(PowerManager.WAKE_REASON_POWER_BUTTON);
mTestableLooper.processAllMessages();
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerBaseTest.java
index 3d0d036..456702b 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerBaseTest.java
@@ -43,6 +43,7 @@
import com.android.systemui.doze.util.BurnInHelperKt;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.flags.FeatureFlags;
+import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository;
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository;
import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository;
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor;
@@ -159,9 +160,12 @@
mAuthRippleController,
mResources,
new KeyguardTransitionInteractor(mTransitionRepository),
- new KeyguardInteractor(new FakeKeyguardRepository(),
+ new KeyguardInteractor(
+ new FakeKeyguardRepository(),
mCommandQueue,
- mFeatureFlags),
+ mFeatureFlags,
+ new FakeKeyguardBouncerRepository()
+ ),
mFeatureFlags
);
}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerTest.java
index b69491e..b7d0059 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerTest.java
@@ -284,4 +284,26 @@
// THEN the lock icon is shown
verify(mLockIconView).setContentDescription(LOCKED_LABEL);
}
+
+ @Test
+ public void lockIconShows_afterUnlockStateChanges() {
+ // GIVEN lock icon controller is initialized and view is attached
+ init(/* useMigrationFlag= */false);
+ captureKeyguardStateCallback();
+ captureKeyguardUpdateMonitorCallback();
+
+ // GIVEN user has unlocked with a biometric auth (ie: face auth)
+ // and biometric running state changes
+ when(mKeyguardUpdateMonitor.getUserUnlockedWithBiometric(anyInt())).thenReturn(true);
+ mKeyguardUpdateMonitorCallback.onBiometricRunningStateChanged(false,
+ BiometricSourceType.FACE);
+ reset(mLockIconView);
+
+ // WHEN the unlocked state changes
+ when(mKeyguardUpdateMonitor.getUserUnlockedWithBiometric(anyInt())).thenReturn(false);
+ mKeyguardStateCallback.onUnlockedChanged();
+
+ // THEN the lock icon is shown
+ verify(mLockIconView).setContentDescription(LOCKED_LABEL);
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/controller/DeletionJobServiceTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/controller/DeletionJobServiceTest.kt
index 4439586..2283746 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/controller/DeletionJobServiceTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/controller/DeletionJobServiceTest.kt
@@ -18,9 +18,13 @@
import android.app.job.JobParameters
import android.content.Context
+import android.os.PersistableBundle
import android.testing.AndroidTestingRunner
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
+import com.android.systemui.controls.controller.AuxiliaryPersistenceWrapper.DeletionJobService.Companion.USER
+import com.android.systemui.util.mockito.whenever
+import java.util.concurrent.TimeUnit
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
@@ -28,18 +32,15 @@
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
-import org.mockito.Mockito.`when`
import org.mockito.Mockito.mock
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
-import java.util.concurrent.TimeUnit
@SmallTest
@RunWith(AndroidTestingRunner::class)
class DeletionJobServiceTest : SysuiTestCase() {
- @Mock
- private lateinit var context: Context
+ @Mock private lateinit var context: Context
private lateinit var service: AuxiliaryPersistenceWrapper.DeletionJobService
@@ -53,6 +54,10 @@
@Test
fun testOnStartJob() {
+ val bundle = PersistableBundle().also { it.putInt(USER, 0) }
+ val params = mock(JobParameters::class.java)
+ whenever(params.getExtras()).thenReturn(bundle)
+
// false means job is terminated
assertFalse(service.onStartJob(mock(JobParameters::class.java)))
verify(context).deleteFile(AuxiliaryPersistenceWrapper.AUXILIARY_FILE_NAME)
@@ -67,13 +72,17 @@
@Test
fun testJobHasRightParameters() {
val userId = 10
- `when`(context.userId).thenReturn(userId)
- `when`(context.packageName).thenReturn(mContext.packageName)
+ whenever(context.userId).thenReturn(userId)
+ whenever(context.packageName).thenReturn(mContext.packageName)
- val jobInfo = AuxiliaryPersistenceWrapper.DeletionJobService.getJobForContext(context)
+ val jobInfo =
+ AuxiliaryPersistenceWrapper.DeletionJobService.getJobForContext(context, userId)
assertEquals(
- AuxiliaryPersistenceWrapper.DeletionJobService.DELETE_FILE_JOB_ID + userId, jobInfo.id)
+ AuxiliaryPersistenceWrapper.DeletionJobService.DELETE_FILE_JOB_ID + userId,
+ jobInfo.id
+ )
assertTrue(jobInfo.isPersisted)
+ assertEquals(userId, jobInfo.getExtras().getInt(USER))
assertEquals(TimeUnit.DAYS.toMillis(7), jobInfo.minLatencyMillis)
}
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/CustomizationProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/CustomizationProviderTest.kt
index 4415033..15a454b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/CustomizationProviderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/CustomizationProviderTest.kt
@@ -39,6 +39,7 @@
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceLegacySettingSyncer
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceLocalUserSelectionManager
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceRemoteUserSelectionManager
+import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
import com.android.systemui.keyguard.data.repository.KeyguardQuickAffordanceRepository
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
@@ -172,6 +173,7 @@
repository = FakeKeyguardRepository(),
commandQueue = commandQueue,
featureFlags = featureFlags,
+ bouncerRepository = FakeKeyguardBouncerRepository(),
),
registry = mock(),
lockPatternUtils = lockPatternUtils,
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 8bb6a85..0469e77 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
@@ -324,29 +324,6 @@
}
@Test
- fun isBouncerShowing() =
- runTest(UnconfinedTestDispatcher()) {
- whenever(keyguardStateController.isBouncerShowing).thenReturn(false)
- var latest: Boolean? = null
- val job = underTest.isBouncerShowing.onEach { latest = it }.launchIn(this)
-
- assertThat(latest).isFalse()
-
- val captor = argumentCaptor<KeyguardStateController.Callback>()
- verify(keyguardStateController).addCallback(captor.capture())
-
- whenever(keyguardStateController.isBouncerShowing).thenReturn(true)
- captor.value.onBouncerShowingChanged()
- assertThat(latest).isTrue()
-
- whenever(keyguardStateController.isBouncerShowing).thenReturn(false)
- captor.value.onBouncerShowingChanged()
- assertThat(latest).isFalse()
-
- job.cancel()
- }
-
- @Test
fun isKeyguardGoingAway() =
runTest(UnconfinedTestDispatcher()) {
whenever(keyguardStateController.isKeyguardGoingAway).thenReturn(false)
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 7ded354..18e80ea 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
@@ -130,7 +130,7 @@
givenCanShowAlternateBouncer()
assertTrue(underTest.show())
- assertTrue(bouncerRepository.isAlternateBouncerVisible.value)
+ assertTrue(bouncerRepository.alternateBouncerVisible.value)
}
@Test
@@ -138,7 +138,7 @@
givenCannotShowAlternateBouncer()
assertFalse(underTest.show())
- assertFalse(bouncerRepository.isAlternateBouncerVisible.value)
+ assertFalse(bouncerRepository.alternateBouncerVisible.value)
}
@Test
@@ -146,7 +146,7 @@
bouncerRepository.setAlternateVisible(true)
assertTrue(underTest.hide())
- assertFalse(bouncerRepository.isAlternateBouncerVisible.value)
+ assertFalse(bouncerRepository.alternateBouncerVisible.value)
}
@Test
@@ -154,7 +154,7 @@
bouncerRepository.setAlternateVisible(false)
assertFalse(underTest.hide())
- assertFalse(bouncerRepository.isAlternateBouncerVisible.value)
+ assertFalse(bouncerRepository.alternateBouncerVisible.value)
}
private fun givenCanShowAlternateBouncer() {
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 7d4861b..153439e 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
@@ -25,6 +25,7 @@
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.flags.FakeFeatureFlags
import com.android.systemui.flags.Flags.FACE_AUTH_REFACTOR
+import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
import com.android.systemui.keyguard.shared.model.CameraLaunchSourceModel
import com.android.systemui.settings.DisplayTracker
@@ -38,7 +39,6 @@
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mockito.mock
-import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
@SmallTest
@@ -50,6 +50,7 @@
private lateinit var underTest: KeyguardInteractor
private lateinit var repository: FakeKeyguardRepository
+ private lateinit var bouncerRepository: FakeKeyguardBouncerRepository
@Before
fun setUp() {
@@ -58,7 +59,14 @@
commandQueue = FakeCommandQueue(mock(Context::class.java), mock(DisplayTracker::class.java))
testScope = TestScope()
repository = FakeKeyguardRepository()
- underTest = KeyguardInteractor(repository, commandQueue, featureFlags)
+ bouncerRepository = FakeKeyguardBouncerRepository()
+ underTest =
+ KeyguardInteractor(
+ repository,
+ commandQueue,
+ featureFlags,
+ bouncerRepository,
+ )
}
@Test
@@ -137,7 +145,7 @@
repository.setKeyguardOccluded(true)
assertThat(secureCameraActive()).isTrue()
- repository.setBouncerShowing(true)
+ bouncerRepository.setPrimaryVisible(true)
assertThat(secureCameraActive()).isFalse()
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorParameterizedTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorParameterizedTest.kt
index 240af7b..23e06ec 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorParameterizedTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorParameterizedTest.kt
@@ -36,6 +36,7 @@
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceLegacySettingSyncer
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceLocalUserSelectionManager
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceRemoteUserSelectionManager
+import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
import com.android.systemui.keyguard.data.repository.KeyguardQuickAffordanceRepository
import com.android.systemui.keyguard.domain.quickaffordance.FakeKeyguardQuickAffordanceRegistry
@@ -298,6 +299,7 @@
repository = FakeKeyguardRepository(),
commandQueue = commandQueue,
featureFlags = featureFlags,
+ bouncerRepository = FakeKeyguardBouncerRepository(),
),
registry =
FakeKeyguardQuickAffordanceRegistry(
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 ec70857..1b8c627 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
@@ -36,6 +36,7 @@
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceLegacySettingSyncer
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceLocalUserSelectionManager
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceRemoteUserSelectionManager
+import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
import com.android.systemui.keyguard.data.repository.KeyguardQuickAffordanceRepository
import com.android.systemui.keyguard.domain.model.KeyguardQuickAffordanceModel
@@ -159,7 +160,8 @@
KeyguardInteractor(
repository = repository,
commandQueue = commandQueue,
- featureFlags = featureFlags
+ featureFlags = featureFlags,
+ bouncerRepository = FakeKeyguardBouncerRepository(),
),
registry =
FakeKeyguardQuickAffordanceRegistry(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt
index 46e4679..ae7a928 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt
@@ -22,7 +22,9 @@
import com.android.systemui.SysuiTestCase
import com.android.systemui.animation.Interpolators
import com.android.systemui.flags.FakeFeatureFlags
+import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags
+import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository
import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepositoryImpl
@@ -65,6 +67,7 @@
private lateinit var testScope: TestScope
private lateinit var keyguardRepository: FakeKeyguardRepository
+ private lateinit var bouncerRepository: FakeKeyguardBouncerRepository
private lateinit var shadeRepository: ShadeRepository
// Used to issue real transition steps for test input
@@ -81,6 +84,10 @@
private lateinit var fromOccludedTransitionInteractor: FromOccludedTransitionInteractor
private lateinit var fromGoneTransitionInteractor: FromGoneTransitionInteractor
private lateinit var fromAodTransitionInteractor: FromAodTransitionInteractor
+ private lateinit var fromAlternateBouncerTransitionInteractor:
+ FromAlternateBouncerTransitionInteractor
+ private lateinit var fromPrimaryBouncerTransitionInteractor:
+ FromPrimaryBouncerTransitionInteractor
@Before
fun setUp() {
@@ -88,6 +95,7 @@
testScope = TestScope()
keyguardRepository = FakeKeyguardRepository()
+ bouncerRepository = FakeKeyguardBouncerRepository()
shadeRepository = FakeShadeRepository()
/* Used to issue full transition steps, to better simulate a real device */
@@ -98,8 +106,7 @@
fromLockscreenTransitionInteractor =
FromLockscreenTransitionInteractor(
scope = testScope,
- keyguardInteractor =
- KeyguardInteractor(keyguardRepository, commandQueue, featureFlags),
+ keyguardInteractor = createKeyguardInteractor(featureFlags),
shadeRepository = shadeRepository,
keyguardTransitionRepository = mockTransitionRepository,
keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository),
@@ -109,8 +116,7 @@
fromDreamingTransitionInteractor =
FromDreamingTransitionInteractor(
scope = testScope,
- keyguardInteractor =
- KeyguardInteractor(keyguardRepository, commandQueue, featureFlags),
+ keyguardInteractor = createKeyguardInteractor(featureFlags),
keyguardTransitionRepository = mockTransitionRepository,
keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository),
)
@@ -119,8 +125,7 @@
fromAodTransitionInteractor =
FromAodTransitionInteractor(
scope = testScope,
- keyguardInteractor =
- KeyguardInteractor(keyguardRepository, commandQueue, featureFlags),
+ keyguardInteractor = createKeyguardInteractor(featureFlags),
keyguardTransitionRepository = mockTransitionRepository,
keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository),
)
@@ -129,8 +134,7 @@
fromGoneTransitionInteractor =
FromGoneTransitionInteractor(
scope = testScope,
- keyguardInteractor =
- KeyguardInteractor(keyguardRepository, commandQueue, featureFlags),
+ keyguardInteractor = createKeyguardInteractor(featureFlags),
keyguardTransitionRepository = mockTransitionRepository,
keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository),
)
@@ -139,8 +143,7 @@
fromDozingTransitionInteractor =
FromDozingTransitionInteractor(
scope = testScope,
- keyguardInteractor =
- KeyguardInteractor(keyguardRepository, commandQueue, featureFlags),
+ keyguardInteractor = createKeyguardInteractor(featureFlags),
keyguardTransitionRepository = mockTransitionRepository,
keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository),
)
@@ -149,12 +152,29 @@
fromOccludedTransitionInteractor =
FromOccludedTransitionInteractor(
scope = testScope,
- keyguardInteractor =
- KeyguardInteractor(keyguardRepository, commandQueue, featureFlags),
+ keyguardInteractor = createKeyguardInteractor(featureFlags),
keyguardTransitionRepository = mockTransitionRepository,
keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository),
)
fromOccludedTransitionInteractor.start()
+
+ fromAlternateBouncerTransitionInteractor =
+ FromAlternateBouncerTransitionInteractor(
+ scope = testScope,
+ keyguardInteractor = createKeyguardInteractor(featureFlags),
+ keyguardTransitionRepository = mockTransitionRepository,
+ keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository),
+ )
+ fromAlternateBouncerTransitionInteractor.start()
+
+ fromPrimaryBouncerTransitionInteractor =
+ FromPrimaryBouncerTransitionInteractor(
+ scope = testScope,
+ keyguardInteractor = createKeyguardInteractor(featureFlags),
+ keyguardTransitionRepository = mockTransitionRepository,
+ keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository),
+ )
+ fromPrimaryBouncerTransitionInteractor.start()
}
@Test
@@ -256,7 +276,7 @@
}
@Test
- fun `LOCKSCREEN to BOUNCER via bouncer showing call`() =
+ fun `LOCKSCREEN to PRIMARY_BOUNCER via bouncer showing call`() =
testScope.runTest {
// GIVEN a device that has at least woken up
keyguardRepository.setWakefulnessModel(startingToWake())
@@ -278,18 +298,18 @@
)
runCurrent()
- // WHEN the bouncer is set to show
- keyguardRepository.setBouncerShowing(true)
+ // WHEN the primary bouncer is set to show
+ bouncerRepository.setPrimaryVisible(true)
runCurrent()
val info =
withArgCaptor<TransitionInfo> {
verify(mockTransitionRepository).startTransition(capture())
}
- // THEN a transition to BOUNCER should occur
+ // THEN a transition to PRIMARY_BOUNCER should occur
assertThat(info.ownerName).isEqualTo("FromLockscreenTransitionInteractor")
assertThat(info.from).isEqualTo(KeyguardState.LOCKSCREEN)
- assertThat(info.to).isEqualTo(KeyguardState.BOUNCER)
+ assertThat(info.to).isEqualTo(KeyguardState.PRIMARY_BOUNCER)
assertThat(info.animator).isNotNull()
coroutineContext.cancelChildren()
@@ -695,6 +715,297 @@
coroutineContext.cancelChildren()
}
+ @Test
+ fun `ALTERNATE_BOUNCER to PRIMARY_BOUNCER`() =
+ testScope.runTest {
+ // GIVEN a prior transition has run to ALTERNATE_BOUNCER
+ runner.startTransition(
+ testScope,
+ TransitionInfo(
+ ownerName = "",
+ from = KeyguardState.LOCKSCREEN,
+ to = KeyguardState.ALTERNATE_BOUNCER,
+ animator =
+ ValueAnimator().apply {
+ duration = 10
+ interpolator = Interpolators.LINEAR
+ },
+ )
+ )
+ runCurrent()
+ reset(mockTransitionRepository)
+
+ // WHEN the alternateBouncer stops showing and then the primary bouncer shows
+ bouncerRepository.setPrimaryVisible(true)
+ runCurrent()
+
+ val info =
+ withArgCaptor<TransitionInfo> {
+ verify(mockTransitionRepository).startTransition(capture())
+ }
+ // THEN a transition to PRIMARY_BOUNCER should occur
+ assertThat(info.ownerName).isEqualTo("FromAlternateBouncerTransitionInteractor")
+ assertThat(info.from).isEqualTo(KeyguardState.ALTERNATE_BOUNCER)
+ assertThat(info.to).isEqualTo(KeyguardState.PRIMARY_BOUNCER)
+ assertThat(info.animator).isNotNull()
+
+ coroutineContext.cancelChildren()
+ }
+
+ @Test
+ fun `ALTERNATE_BOUNCER to AOD`() =
+ testScope.runTest {
+ // GIVEN a prior transition has run to ALTERNATE_BOUNCER
+ bouncerRepository.setAlternateVisible(true)
+ runner.startTransition(
+ testScope,
+ TransitionInfo(
+ ownerName = "",
+ from = KeyguardState.LOCKSCREEN,
+ to = KeyguardState.ALTERNATE_BOUNCER,
+ animator =
+ ValueAnimator().apply {
+ duration = 10
+ interpolator = Interpolators.LINEAR
+ },
+ )
+ )
+ runCurrent()
+ reset(mockTransitionRepository)
+
+ // GIVEN the primary bouncer isn't showing, aod available and starting to sleep
+ bouncerRepository.setPrimaryVisible(false)
+ keyguardRepository.setAodAvailable(true)
+ keyguardRepository.setWakefulnessModel(startingToSleep())
+
+ // WHEN the alternateBouncer stops showing
+ bouncerRepository.setAlternateVisible(false)
+ advanceUntilIdle()
+
+ val info =
+ withArgCaptor<TransitionInfo> {
+ verify(mockTransitionRepository).startTransition(capture())
+ }
+ // THEN a transition to AOD should occur
+ assertThat(info.ownerName).isEqualTo("FromAlternateBouncerTransitionInteractor")
+ assertThat(info.from).isEqualTo(KeyguardState.ALTERNATE_BOUNCER)
+ assertThat(info.to).isEqualTo(KeyguardState.AOD)
+ assertThat(info.animator).isNotNull()
+
+ coroutineContext.cancelChildren()
+ }
+
+ @Test
+ fun `ALTERNATE_BOUNCER to DOZING`() =
+ testScope.runTest {
+ // GIVEN a prior transition has run to ALTERNATE_BOUNCER
+ bouncerRepository.setAlternateVisible(true)
+ runner.startTransition(
+ testScope,
+ TransitionInfo(
+ ownerName = "",
+ from = KeyguardState.LOCKSCREEN,
+ to = KeyguardState.ALTERNATE_BOUNCER,
+ animator =
+ ValueAnimator().apply {
+ duration = 10
+ interpolator = Interpolators.LINEAR
+ },
+ )
+ )
+ runCurrent()
+ reset(mockTransitionRepository)
+
+ // GIVEN the primary bouncer isn't showing, aod not available and starting to sleep
+ // to sleep
+ bouncerRepository.setPrimaryVisible(false)
+ keyguardRepository.setAodAvailable(false)
+ keyguardRepository.setWakefulnessModel(startingToSleep())
+
+ // WHEN the alternateBouncer stops showing
+ bouncerRepository.setAlternateVisible(false)
+ advanceUntilIdle()
+
+ val info =
+ withArgCaptor<TransitionInfo> {
+ verify(mockTransitionRepository).startTransition(capture())
+ }
+ // THEN a transition to DOZING should occur
+ assertThat(info.ownerName).isEqualTo("FromAlternateBouncerTransitionInteractor")
+ assertThat(info.from).isEqualTo(KeyguardState.ALTERNATE_BOUNCER)
+ assertThat(info.to).isEqualTo(KeyguardState.DOZING)
+ assertThat(info.animator).isNotNull()
+
+ coroutineContext.cancelChildren()
+ }
+
+ @Test
+ fun `ALTERNATE_BOUNCER to LOCKSCREEN`() =
+ testScope.runTest {
+ // GIVEN a prior transition has run to ALTERNATE_BOUNCER
+ bouncerRepository.setAlternateVisible(true)
+ runner.startTransition(
+ testScope,
+ TransitionInfo(
+ ownerName = "",
+ from = KeyguardState.LOCKSCREEN,
+ to = KeyguardState.ALTERNATE_BOUNCER,
+ animator =
+ ValueAnimator().apply {
+ duration = 10
+ interpolator = Interpolators.LINEAR
+ },
+ )
+ )
+ runCurrent()
+ reset(mockTransitionRepository)
+
+ // GIVEN the primary bouncer isn't showing and device not sleeping
+ bouncerRepository.setPrimaryVisible(false)
+ keyguardRepository.setWakefulnessModel(startingToWake())
+
+ // WHEN the alternateBouncer stops showing
+ bouncerRepository.setAlternateVisible(false)
+ advanceUntilIdle()
+
+ val info =
+ withArgCaptor<TransitionInfo> {
+ verify(mockTransitionRepository).startTransition(capture())
+ }
+ // THEN a transition to LOCKSCREEN should occur
+ assertThat(info.ownerName).isEqualTo("FromAlternateBouncerTransitionInteractor")
+ assertThat(info.from).isEqualTo(KeyguardState.ALTERNATE_BOUNCER)
+ assertThat(info.to).isEqualTo(KeyguardState.LOCKSCREEN)
+ assertThat(info.animator).isNotNull()
+
+ coroutineContext.cancelChildren()
+ }
+
+ @Test
+ fun `PRIMARY_BOUNCER to AOD`() =
+ testScope.runTest {
+ // GIVEN a prior transition has run to PRIMARY_BOUNCER
+ bouncerRepository.setPrimaryVisible(true)
+ runner.startTransition(
+ testScope,
+ TransitionInfo(
+ ownerName = "",
+ from = KeyguardState.LOCKSCREEN,
+ to = KeyguardState.PRIMARY_BOUNCER,
+ animator =
+ ValueAnimator().apply {
+ duration = 10
+ interpolator = Interpolators.LINEAR
+ },
+ )
+ )
+ runCurrent()
+ reset(mockTransitionRepository)
+
+ // GIVEN aod available and starting to sleep
+ keyguardRepository.setAodAvailable(true)
+ keyguardRepository.setWakefulnessModel(startingToSleep())
+
+ // WHEN the primaryBouncer stops showing
+ bouncerRepository.setPrimaryVisible(false)
+ runCurrent()
+
+ val info =
+ withArgCaptor<TransitionInfo> {
+ verify(mockTransitionRepository).startTransition(capture())
+ }
+ // THEN a transition to AOD should occur
+ assertThat(info.ownerName).isEqualTo("FromPrimaryBouncerTransitionInteractor")
+ assertThat(info.from).isEqualTo(KeyguardState.PRIMARY_BOUNCER)
+ assertThat(info.to).isEqualTo(KeyguardState.AOD)
+ assertThat(info.animator).isNotNull()
+
+ coroutineContext.cancelChildren()
+ }
+
+ @Test
+ fun `PRIMARY_BOUNCER to DOZING`() =
+ testScope.runTest {
+ // GIVEN a prior transition has run to PRIMARY_BOUNCER
+ bouncerRepository.setPrimaryVisible(true)
+ runner.startTransition(
+ testScope,
+ TransitionInfo(
+ ownerName = "",
+ from = KeyguardState.LOCKSCREEN,
+ to = KeyguardState.PRIMARY_BOUNCER,
+ animator =
+ ValueAnimator().apply {
+ duration = 10
+ interpolator = Interpolators.LINEAR
+ },
+ )
+ )
+ runCurrent()
+ reset(mockTransitionRepository)
+
+ // GIVEN aod not available and starting to sleep to sleep
+ keyguardRepository.setAodAvailable(false)
+ keyguardRepository.setWakefulnessModel(startingToSleep())
+
+ // WHEN the primaryBouncer stops showing
+ bouncerRepository.setPrimaryVisible(false)
+ runCurrent()
+
+ val info =
+ withArgCaptor<TransitionInfo> {
+ verify(mockTransitionRepository).startTransition(capture())
+ }
+ // THEN a transition to DOZING should occur
+ assertThat(info.ownerName).isEqualTo("FromPrimaryBouncerTransitionInteractor")
+ assertThat(info.from).isEqualTo(KeyguardState.PRIMARY_BOUNCER)
+ assertThat(info.to).isEqualTo(KeyguardState.DOZING)
+ assertThat(info.animator).isNotNull()
+
+ coroutineContext.cancelChildren()
+ }
+
+ @Test
+ fun `PRIMARY_BOUNCER to LOCKSCREEN`() =
+ testScope.runTest {
+ // GIVEN a prior transition has run to PRIMARY_BOUNCER
+ bouncerRepository.setPrimaryVisible(true)
+ runner.startTransition(
+ testScope,
+ TransitionInfo(
+ ownerName = "",
+ from = KeyguardState.LOCKSCREEN,
+ to = KeyguardState.PRIMARY_BOUNCER,
+ animator =
+ ValueAnimator().apply {
+ duration = 10
+ interpolator = Interpolators.LINEAR
+ },
+ )
+ )
+ runCurrent()
+ reset(mockTransitionRepository)
+
+ // GIVEN device not sleeping
+ keyguardRepository.setWakefulnessModel(startingToWake())
+
+ // WHEN the alternateBouncer stops showing
+ bouncerRepository.setPrimaryVisible(false)
+ runCurrent()
+
+ val info =
+ withArgCaptor<TransitionInfo> {
+ verify(mockTransitionRepository).startTransition(capture())
+ }
+ // THEN a transition to LOCKSCREEN should occur
+ assertThat(info.ownerName).isEqualTo("FromPrimaryBouncerTransitionInteractor")
+ assertThat(info.from).isEqualTo(KeyguardState.PRIMARY_BOUNCER)
+ assertThat(info.to).isEqualTo(KeyguardState.LOCKSCREEN)
+ assertThat(info.animator).isNotNull()
+
+ coroutineContext.cancelChildren()
+ }
+
private fun startingToWake() =
WakefulnessModel(
WakefulnessState.STARTING_TO_WAKE,
@@ -710,4 +1021,13 @@
WakeSleepReason.OTHER,
WakeSleepReason.OTHER
)
+
+ private fun createKeyguardInteractor(featureFlags: FeatureFlags): KeyguardInteractor {
+ return KeyguardInteractor(
+ keyguardRepository,
+ commandQueue,
+ featureFlags,
+ bouncerRepository,
+ )
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractorTest.kt
index c5e0252..46ed829 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/PrimaryBouncerInteractorTest.kt
@@ -102,7 +102,7 @@
verify(repository).setPrimaryScrimmed(true)
verify(repository).setPanelExpansion(EXPANSION_VISIBLE)
verify(repository).setPrimaryShowingSoon(true)
- verify(keyguardStateController).notifyBouncerShowing(true)
+ verify(keyguardStateController).notifyPrimaryBouncerShowing(true)
verify(mPrimaryBouncerCallbackInteractor).dispatchStartingToShow()
verify(repository).setPrimaryVisible(true)
verify(repository).setPrimaryShow(any(KeyguardBouncerModel::class.java))
@@ -118,7 +118,7 @@
@Test
fun testShow_keyguardIsDone() {
`when`(bouncerView.delegate?.showNextSecurityScreenOrFinish()).thenReturn(true)
- verify(keyguardStateController, never()).notifyBouncerShowing(true)
+ verify(keyguardStateController, never()).notifyPrimaryBouncerShowing(true)
verify(mPrimaryBouncerCallbackInteractor, never()).dispatchStartingToShow()
}
@@ -126,7 +126,7 @@
fun testHide() {
underTest.hide()
verify(falsingCollector).onBouncerHidden()
- verify(keyguardStateController).notifyBouncerShowing(false)
+ verify(keyguardStateController).notifyPrimaryBouncerShowing(false)
verify(repository).setPrimaryShowingSoon(false)
verify(repository).setPrimaryVisible(false)
verify(repository).setPrimaryHide(true)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModelTest.kt
index 03a347e..6afeddd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModelTest.kt
@@ -35,6 +35,7 @@
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceLegacySettingSyncer
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceLocalUserSelectionManager
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceRemoteUserSelectionManager
+import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
import com.android.systemui.keyguard.data.repository.KeyguardQuickAffordanceRepository
import com.android.systemui.keyguard.domain.interactor.KeyguardBottomAreaInteractor
@@ -136,6 +137,7 @@
repository = repository,
commandQueue = commandQueue,
featureFlags = featureFlags,
+ bouncerRepository = FakeKeyguardBouncerRepository(),
)
whenever(userTracker.userHandle).thenReturn(mock())
whenever(lockPatternUtils.getStrongAuthForUser(anyInt()))
diff --git a/packages/SystemUI/tests/src/com/android/systemui/settings/UserFileManagerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/settings/UserFileManagerImplTest.kt
index 020a866..3fd19ff 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/settings/UserFileManagerImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/settings/UserFileManagerImplTest.kt
@@ -30,12 +30,14 @@
import com.android.systemui.util.mockito.eq
import com.android.systemui.util.time.FakeSystemClock
import com.google.common.truth.Truth.assertThat
+import java.io.File
+import java.nio.file.Files
import java.util.concurrent.Executor
-import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
+import org.mockito.Mockito.atLeastOnce
import org.mockito.Mockito.isNull
import org.mockito.Mockito.spy
import org.mockito.Mockito.verify
@@ -61,36 +63,83 @@
UserFileManagerImpl(context, userManager, broadcastDispatcher, backgroundExecutor)
}
- @After
- fun end() {
- val dir = Environment.buildPath(context.filesDir, UserFileManagerImpl.ID)
- dir.deleteRecursively()
- }
-
@Test
fun testGetFile() {
assertThat(userFileManager.getFile(TEST_FILE_NAME, 0).path)
.isEqualTo("${context.filesDir}/$TEST_FILE_NAME")
assertThat(userFileManager.getFile(TEST_FILE_NAME, 11).path)
- .isEqualTo("${context.filesDir}/${UserFileManagerImpl.ID}/11/files/$TEST_FILE_NAME")
+ .isEqualTo("${context.filesDir}/__USER_11_$TEST_FILE_NAME")
}
@Test
fun testGetSharedPreferences() {
+ val primarySharedPref = userFileManager.getSharedPreferences(TEST_FILE_NAME, 0, 0)
val secondarySharedPref = userFileManager.getSharedPreferences(TEST_FILE_NAME, 0, 11)
- val secondaryUserDir =
- Environment.buildPath(
- context.filesDir,
- UserFileManagerImpl.ID,
- "11",
- UserFileManagerImpl.SHARED_PREFS,
- TEST_FILE_NAME
- )
- assertThat(secondarySharedPref).isNotNull()
- assertThat(secondaryUserDir.exists())
- assertThat(userFileManager.getSharedPreferences(TEST_FILE_NAME, 0, 0))
- .isNotEqualTo(secondarySharedPref)
+ assertThat(primarySharedPref).isNotEqualTo(secondarySharedPref)
+
+ // Make sure these are different files
+ primarySharedPref.edit().putString("TEST", "ABC").commit()
+ assertThat(secondarySharedPref.getString("TEST", null)).isNull()
+
+ context.deleteSharedPreferences("TEST")
+ context.deleteSharedPreferences("__USER_11_TEST")
+ }
+
+ @Test
+ fun testMigrateFile() {
+ val userId = 12
+ val fileName = "myFile.txt"
+ val fileContents = "TestingFile"
+ val legacyFile =
+ UserFileManagerImpl.createLegacyFile(
+ context,
+ UserFileManagerImpl.FILES,
+ fileName,
+ userId
+ )!!
+
+ // Write file to legacy area
+ Files.createDirectories(legacyFile.getParentFile().toPath())
+ Files.write(legacyFile.toPath(), fileContents.toByteArray())
+ assertThat(legacyFile.exists()).isTrue()
+
+ // getFile() should migrate the legacy file to the new location
+ val file = userFileManager.getFile(fileName, userId)
+ val newContents = String(Files.readAllBytes(file.toPath()))
+
+ assertThat(newContents).isEqualTo(fileContents)
+ assertThat(legacyFile.exists()).isFalse()
+ assertThat(File(context.filesDir, UserFileManagerImpl.ROOT_DIR).exists()).isFalse()
+ }
+
+ @Test
+ fun testMigrateSharedPrefs() {
+ val userId = 13
+ val fileName = "myFile"
+ val contents = "TestingSharedPrefs"
+ val legacyFile =
+ UserFileManagerImpl.createLegacyFile(
+ context,
+ UserFileManagerImpl.SHARED_PREFS,
+ "$fileName.xml",
+ userId
+ )!!
+
+ // Write a valid shared prefs xml file to legacy area
+ val tmpPrefs = context.getSharedPreferences("tmp", Context.MODE_PRIVATE)
+ tmpPrefs.edit().putString(contents, contents).commit()
+ Files.createDirectories(legacyFile.getParentFile().toPath())
+ val tmpFile =
+ Environment.buildPath(context.dataDir, UserFileManagerImpl.SHARED_PREFS, "tmp.xml")
+ tmpFile.renameTo(legacyFile)
+ assertThat(legacyFile.exists()).isTrue()
+
+ // getSharedpreferences() should migrate the legacy file to the new location
+ val prefs = userFileManager.getSharedPreferences(fileName, Context.MODE_PRIVATE, userId)
+ assertThat(prefs.getString(contents, "")).isEqualTo(contents)
+ assertThat(legacyFile.exists()).isFalse()
+ assertThat(File(context.filesDir, UserFileManagerImpl.ROOT_DIR).exists()).isFalse()
}
@Test
@@ -111,44 +160,14 @@
@Test
fun testClearDeletedUserData() {
- val dir = Environment.buildPath(context.filesDir, UserFileManagerImpl.ID, "11", "files")
- dir.mkdirs()
- val file =
- Environment.buildPath(
- context.filesDir,
- UserFileManagerImpl.ID,
- "11",
- "files",
- TEST_FILE_NAME
- )
- val secondaryUserDir =
- Environment.buildPath(
- context.filesDir,
- UserFileManagerImpl.ID,
- "11",
- )
+ val file = userFileManager.getFile(TEST_FILE_NAME, 11)
file.createNewFile()
- assertThat(secondaryUserDir.exists()).isTrue()
+
assertThat(file.exists()).isTrue()
userFileManager.clearDeletedUserData()
assertThat(backgroundExecutor.runAllReady()).isGreaterThan(0)
- verify(userManager).aliveUsers
- assertThat(secondaryUserDir.exists()).isFalse()
- assertThat(file.exists()).isFalse()
- }
+ verify(userManager, atLeastOnce()).aliveUsers
- @Test
- fun testEnsureParentDirExists() {
- val file =
- Environment.buildPath(
- context.filesDir,
- UserFileManagerImpl.ID,
- "11",
- "files",
- TEST_FILE_NAME
- )
- assertThat(file.parentFile.exists()).isFalse()
- UserFileManagerImpl.ensureParentDirExists(file)
- assertThat(file.parentFile.exists()).isTrue()
+ assertThat(file.exists()).isFalse()
}
}
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 d01edcc..26eff61 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
@@ -230,7 +230,7 @@
}
@Test
- fun pluginRemoved_clockChanged() {
+ fun pluginRemoved_clockAndListChanged() {
val plugin1 = FakeClockPlugin()
.addClock("clock_1", "clock 1")
.addClock("clock_2", "clock 2")
@@ -239,20 +239,36 @@
.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)
var changeCallCount = 0
- registry.registerClockChangeListener { changeCallCount++ }
+ var listChangeCallCount = 0
+ registry.registerClockChangeListener(object : ClockRegistry.ClockChangeListener {
+ override fun onCurrentClockChanged() { changeCallCount++ }
+ override fun onAvailableClocksChanged() { listChangeCallCount++ }
+ })
+
+ registry.applySettings(ClockSettings("clock_3", null))
+ assertEquals(0, changeCallCount)
+ assertEquals(0, listChangeCallCount)
+
+ pluginListener.onPluginConnected(plugin1, mockContext)
+ assertEquals(0, changeCallCount)
+ assertEquals(1, listChangeCallCount)
+
+ pluginListener.onPluginConnected(plugin2, mockContext)
+ assertEquals(1, changeCallCount)
+ assertEquals(2, listChangeCallCount)
pluginListener.onPluginDisconnected(plugin1)
- assertEquals(0, changeCallCount)
+ assertEquals(1, changeCallCount)
+ assertEquals(3, listChangeCallCount)
pluginListener.onPluginDisconnected(plugin2)
- assertEquals(1, changeCallCount)
+ assertEquals(2, changeCallCount)
+ assertEquals(4, listChangeCallCount)
}
+
@Test
fun jsonDeserialization_gotExpectedObject() {
val expected = ClockSettings("ID", null).apply { _applied_timestamp = 500 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt
index 5832569..4d9db8c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt
@@ -518,7 +518,7 @@
val childHunView = createHunViewMock(
isShadeOpen = true,
fullyVisible = false,
- headerVisibleAmount = 1f,
+ headerVisibleAmount = 1f
)
val algorithmState = StackScrollAlgorithm.StackScrollAlgorithmState()
algorithmState.visibleChildren.add(childHunView)
@@ -526,6 +526,7 @@
// When: updateChildZValue() is called for the top HUN
stackScrollAlgorithm.updateChildZValue(
/* i= */ 0,
+ /* childrenOnTop= */ 0.0f,
/* StackScrollAlgorithmState= */ algorithmState,
/* ambientState= */ ambientState,
/* shouldElevateHun= */ true
@@ -545,7 +546,7 @@
val childHunView = createHunViewMock(
isShadeOpen = true,
fullyVisible = false,
- headerVisibleAmount = 1f,
+ headerVisibleAmount = 1f
)
// Use half of the HUN's height as overlap
childHunView.viewState.yTranslation = (childHunView.viewState.height + 1 shr 1).toFloat()
@@ -555,6 +556,7 @@
// When: updateChildZValue() is called for the top HUN
stackScrollAlgorithm.updateChildZValue(
/* i= */ 0,
+ /* childrenOnTop= */ 0.0f,
/* StackScrollAlgorithmState= */ algorithmState,
/* ambientState= */ ambientState,
/* shouldElevateHun= */ true
@@ -578,7 +580,7 @@
val childHunView = createHunViewMock(
isShadeOpen = true,
fullyVisible = true,
- headerVisibleAmount = 1f,
+ headerVisibleAmount = 1f
)
// HUN doesn't overlap with QQS Panel
childHunView.viewState.yTranslation = ambientState.topPadding +
@@ -589,6 +591,7 @@
// When: updateChildZValue() is called for the top HUN
stackScrollAlgorithm.updateChildZValue(
/* i= */ 0,
+ /* childrenOnTop= */ 0.0f,
/* StackScrollAlgorithmState= */ algorithmState,
/* ambientState= */ ambientState,
/* shouldElevateHun= */ true
@@ -608,7 +611,7 @@
val childHunView = createHunViewMock(
isShadeOpen = false,
fullyVisible = false,
- headerVisibleAmount = 0f,
+ headerVisibleAmount = 0f
)
childHunView.viewState.yTranslation = 0f
// Shade is closed, thus childHunView's headerVisibleAmount is 0
@@ -619,6 +622,7 @@
// When: updateChildZValue() is called for the top HUN
stackScrollAlgorithm.updateChildZValue(
/* i= */ 0,
+ /* childrenOnTop= */ 0.0f,
/* StackScrollAlgorithmState= */ algorithmState,
/* ambientState= */ ambientState,
/* shouldElevateHun= */ true
@@ -638,7 +642,7 @@
val childHunView = createHunViewMock(
isShadeOpen = false,
fullyVisible = false,
- headerVisibleAmount = 0.5f,
+ headerVisibleAmount = 0.5f
)
childHunView.viewState.yTranslation = 0f
// Shade is being opened, thus childHunView's headerVisibleAmount is between 0 and 1
@@ -650,6 +654,7 @@
// When: updateChildZValue() is called for the top HUN
stackScrollAlgorithm.updateChildZValue(
/* i= */ 0,
+ /* childrenOnTop= */ 0.0f,
/* StackScrollAlgorithmState= */ algorithmState,
/* ambientState= */ ambientState,
/* shouldElevateHun= */ true
@@ -664,7 +669,7 @@
private fun createHunViewMock(
isShadeOpen: Boolean,
fullyVisible: Boolean,
- headerVisibleAmount: Float,
+ headerVisibleAmount: Float
) =
mock<ExpandableNotificationRow>().apply {
val childViewStateMock = createHunChildViewState(isShadeOpen, fullyVisible)
@@ -675,10 +680,7 @@
}
- private fun createHunChildViewState(
- isShadeOpen: Boolean,
- fullyVisible: Boolean,
- ) =
+ private fun createHunChildViewState(isShadeOpen: Boolean, fullyVisible: Boolean) =
ExpandableViewState().apply {
// Mock the HUN's height with ambientState.topPadding +
// ambientState.stackTranslation
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/FakeKeyguardStateController.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/FakeKeyguardStateController.java
index a986777..c669c6f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/FakeKeyguardStateController.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/FakeKeyguardStateController.java
@@ -53,7 +53,7 @@
}
@Override
- public boolean isBouncerShowing() {
+ public boolean isPrimaryBouncerShowing() {
return false;
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/airplane/ui/viewmodel/AirplaneModeViewModelImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/airplane/ui/viewmodel/AirplaneModeViewModelImplTest.kt
index 5a6bb30..ab888f7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/airplane/ui/viewmodel/AirplaneModeViewModelImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/airplane/ui/viewmodel/AirplaneModeViewModelImplTest.kt
@@ -18,9 +18,9 @@
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
+import com.android.systemui.log.table.TableLogBuffer
import com.android.systemui.statusbar.pipeline.airplane.data.repository.FakeAirplaneModeRepository
import com.android.systemui.statusbar.pipeline.airplane.domain.interactor.AirplaneModeInteractor
-import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger
import com.android.systemui.statusbar.pipeline.shared.data.model.ConnectivitySlot
import com.android.systemui.statusbar.pipeline.shared.data.repository.FakeConnectivityRepository
import com.google.common.truth.Truth.assertThat
@@ -42,7 +42,7 @@
private lateinit var underTest: AirplaneModeViewModelImpl
- @Mock private lateinit var logger: ConnectivityPipelineLogger
+ @Mock private lateinit var logger: TableLogBuffer
private lateinit var airplaneModeRepository: FakeAirplaneModeRepository
private lateinit var connectivityRepository: FakeConnectivityRepository
private lateinit var interactor: AirplaneModeInteractor
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/CarrierConfigRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/CarrierConfigRepositoryTest.kt
index 521c67f..0145103 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/CarrierConfigRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/CarrierConfigRepositoryTest.kt
@@ -25,7 +25,7 @@
import com.android.systemui.SysuiTestCase
import com.android.systemui.dump.DumpManager
import com.android.systemui.statusbar.pipeline.mobile.data.model.SystemUiCarrierConfigTest.Companion.createTestConfig
-import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger
+import com.android.systemui.statusbar.pipeline.mobile.shared.MobileInputLogger
import com.android.systemui.util.mockito.whenever
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -53,7 +53,7 @@
private lateinit var mockitoSession: MockitoSession
private lateinit var carrierConfigCoreStartable: CarrierConfigCoreStartable
- @Mock private lateinit var logger: ConnectivityPipelineLogger
+ @Mock private lateinit var logger: MobileInputLogger
@Mock private lateinit var carrierConfigManager: CarrierConfigManager
@Mock private lateinit var dumpManager: DumpManager
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcherTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcherTest.kt
index 4da2104..17502f2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcherTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/MobileRepositorySwitcherTest.kt
@@ -33,8 +33,8 @@
import com.android.systemui.statusbar.pipeline.mobile.data.repository.demo.model.FakeNetworkEventModel
import com.android.systemui.statusbar.pipeline.mobile.data.repository.demo.validMobileEvent
import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.MobileConnectionsRepositoryImpl
+import com.android.systemui.statusbar.pipeline.mobile.shared.MobileInputLogger
import com.android.systemui.statusbar.pipeline.mobile.util.FakeMobileMappingsProxy
-import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger
import com.android.systemui.statusbar.pipeline.wifi.data.repository.FakeWifiRepository
import com.android.systemui.statusbar.pipeline.wifi.data.repository.demo.DemoModeWifiDataSource
import com.android.systemui.util.mockito.any
@@ -81,7 +81,7 @@
@Mock private lateinit var connectivityManager: ConnectivityManager
@Mock private lateinit var subscriptionManager: SubscriptionManager
@Mock private lateinit var telephonyManager: TelephonyManager
- @Mock private lateinit var logger: ConnectivityPipelineLogger
+ @Mock private lateinit var logger: MobileInputLogger
@Mock private lateinit var summaryLogger: TableLogBuffer
@Mock private lateinit var demoModeController: DemoModeController
@Mock private lateinit var dumpManager: DumpManager
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt
index a294088a..b2577e3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt
@@ -65,8 +65,8 @@
import com.android.systemui.statusbar.pipeline.mobile.data.model.toNetworkNameModel
import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeMobileConnectionsRepository
import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository.Companion.DEFAULT_NUM_LEVELS
+import com.android.systemui.statusbar.pipeline.mobile.shared.MobileInputLogger
import com.android.systemui.statusbar.pipeline.mobile.util.FakeMobileMappingsProxy
-import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger
import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel
import com.android.systemui.statusbar.pipeline.shared.data.model.toMobileDataActivityModel
import com.android.systemui.util.mockito.any
@@ -94,7 +94,7 @@
private lateinit var connectionsRepo: FakeMobileConnectionsRepository
@Mock private lateinit var telephonyManager: TelephonyManager
- @Mock private lateinit var logger: ConnectivityPipelineLogger
+ @Mock private lateinit var logger: MobileInputLogger
@Mock private lateinit var tableLogger: TableLogBuffer
private val scope = CoroutineScope(IMMEDIATE)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryTest.kt
index 8090205..09b7a66 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryTest.kt
@@ -42,8 +42,8 @@
import com.android.systemui.statusbar.pipeline.mobile.data.repository.CarrierConfigRepository
import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository
import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.FullMobileConnectionRepository.Factory.Companion.tableBufferLogName
+import com.android.systemui.statusbar.pipeline.mobile.shared.MobileInputLogger
import com.android.systemui.statusbar.pipeline.mobile.util.FakeMobileMappingsProxy
-import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger
import com.android.systemui.statusbar.pipeline.wifi.data.repository.FakeWifiRepository
import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiNetworkModel
import com.android.systemui.util.mockito.any
@@ -86,7 +86,7 @@
@Mock private lateinit var connectivityManager: ConnectivityManager
@Mock private lateinit var subscriptionManager: SubscriptionManager
@Mock private lateinit var telephonyManager: TelephonyManager
- @Mock private lateinit var logger: ConnectivityPipelineLogger
+ @Mock private lateinit var logger: MobileInputLogger
@Mock private lateinit var summaryLogger: TableLogBuffer
@Mock private lateinit var logBufferFactory: TableLogBufferFactory
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractorTest.kt
index bbca001..c51dbf1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractorTest.kt
@@ -85,7 +85,6 @@
MobileIconsInteractorImpl(
connectionsRepository,
carrierConfigTracker,
- logger = mock(),
tableLogger = mock(),
connectivityRepository,
userSetupRepository,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/shared/MobileInputLoggerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/shared/MobileInputLoggerTest.kt
new file mode 100644
index 0000000..86529dc
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/shared/MobileInputLoggerTest.kt
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.pipeline.mobile.shared
+
+import android.net.Network
+import android.net.NetworkCapabilities
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.dump.DumpManager
+import com.android.systemui.log.LogBufferFactory
+import com.android.systemui.plugins.log.LogcatEchoTracker
+import com.google.common.truth.Truth.assertThat
+import java.io.PrintWriter
+import java.io.StringWriter
+import org.junit.Test
+import org.mockito.Mockito
+import org.mockito.Mockito.mock
+
+@SmallTest
+class MobileInputLoggerTest : SysuiTestCase() {
+ private val buffer =
+ LogBufferFactory(DumpManager(), mock(LogcatEchoTracker::class.java)).create("buffer", 10)
+ private val logger = MobileInputLogger(buffer)
+
+ @Test
+ fun testLogNetworkCapsChange_bufferHasInfo() {
+ logger.logOnCapabilitiesChanged(NET_1, NET_1_CAPS, isDefaultNetworkCallback = true)
+
+ val stringWriter = StringWriter()
+ buffer.dump(PrintWriter(stringWriter), tailLength = 0)
+ val actualString = stringWriter.toString()
+
+ val expectedNetId = NET_1_ID.toString()
+ val expectedCaps = NET_1_CAPS.toString()
+
+ assertThat(actualString).contains("true")
+ assertThat(actualString).contains(expectedNetId)
+ assertThat(actualString).contains(expectedCaps)
+ }
+
+ @Test
+ fun testLogOnLost_bufferHasNetIdOfLostNetwork() {
+ logger.logOnLost(NET_1)
+
+ val stringWriter = StringWriter()
+ buffer.dump(PrintWriter(stringWriter), tailLength = 0)
+ val actualString = stringWriter.toString()
+
+ val expectedNetId = NET_1_ID.toString()
+
+ assertThat(actualString).contains(expectedNetId)
+ }
+
+ companion object {
+ private const val NET_1_ID = 100
+ private val NET_1 =
+ com.android.systemui.util.mockito.mock<Network>().also {
+ Mockito.`when`(it.getNetId()).thenReturn(NET_1_ID)
+ }
+ private val NET_1_CAPS =
+ NetworkCapabilities.Builder()
+ .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
+ .addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)
+ .build()
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModelTest.kt
index d9268a2..4628f84 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModelTest.kt
@@ -26,7 +26,6 @@
import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.FakeMobileIconsInteractor
import com.android.systemui.statusbar.pipeline.mobile.util.FakeMobileMappingsProxy
import com.android.systemui.statusbar.pipeline.shared.ConnectivityConstants
-import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger
import com.android.systemui.statusbar.pipeline.shared.data.repository.FakeConnectivityRepository
import com.android.systemui.util.mockito.mock
import com.google.common.truth.Truth.assertThat
@@ -51,7 +50,6 @@
private lateinit var airplaneModeInteractor: AirplaneModeInteractor
@Mock private lateinit var statusBarPipelineFlags: StatusBarPipelineFlags
- @Mock private lateinit var logger: ConnectivityPipelineLogger
@Mock private lateinit var constants: ConnectivityConstants
private val testDispatcher = UnconfinedTestDispatcher()
@@ -77,7 +75,6 @@
subscriptionIdsFlow,
interactor,
airplaneModeInteractor,
- logger,
constants,
testScope.backgroundScope,
statusBarPipelineFlags,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ConnectivityPipelineLoggerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ConnectivityPipelineLoggerTest.kt
deleted file mode 100644
index 3dccbbf..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ConnectivityPipelineLoggerTest.kt
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.statusbar.pipeline.shared
-
-import android.net.Network
-import android.net.NetworkCapabilities
-import androidx.test.filters.SmallTest
-import com.android.systemui.SysuiTestCase
-import com.android.systemui.dump.DumpManager
-import com.android.systemui.log.LogBufferFactory
-import com.android.systemui.plugins.log.LogcatEchoTracker
-import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger.Companion.logInputChange
-import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger.Companion.logOutputChange
-import com.google.common.truth.Truth.assertThat
-import java.io.PrintWriter
-import java.io.StringWriter
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.flowOf
-import kotlinx.coroutines.flow.launchIn
-import kotlinx.coroutines.runBlocking
-import org.junit.Test
-import org.mockito.Mockito
-import org.mockito.Mockito.mock
-
-@SmallTest
-class ConnectivityPipelineLoggerTest : SysuiTestCase() {
- private val buffer = LogBufferFactory(DumpManager(), mock(LogcatEchoTracker::class.java))
- .create("buffer", 10)
- private val logger = ConnectivityPipelineLogger(buffer)
-
- @Test
- fun testLogNetworkCapsChange_bufferHasInfo() {
- logger.logOnCapabilitiesChanged(NET_1, NET_1_CAPS, isDefaultNetworkCallback = true)
-
- val stringWriter = StringWriter()
- buffer.dump(PrintWriter(stringWriter), tailLength = 0)
- val actualString = stringWriter.toString()
-
- val expectedNetId = NET_1_ID.toString()
- val expectedCaps = NET_1_CAPS.toString()
-
- assertThat(actualString).contains("true")
- assertThat(actualString).contains(expectedNetId)
- assertThat(actualString).contains(expectedCaps)
- }
-
- @Test
- fun testLogOnLost_bufferHasNetIdOfLostNetwork() {
- logger.logOnLost(NET_1)
-
- val stringWriter = StringWriter()
- buffer.dump(PrintWriter(stringWriter), tailLength = 0)
- val actualString = stringWriter.toString()
-
- val expectedNetId = NET_1_ID.toString()
-
- assertThat(actualString).contains(expectedNetId)
- }
-
- @Test
- fun logOutputChange_printsValuesAndNulls() = runBlocking(IMMEDIATE) {
- val flow: Flow<Int?> = flowOf(1, null, 3)
-
- val job = flow
- .logOutputChange(logger, "testInts")
- .launchIn(this)
-
- val stringWriter = StringWriter()
- buffer.dump(PrintWriter(stringWriter), tailLength = 0)
- val actualString = stringWriter.toString()
-
- assertThat(actualString).contains("1")
- assertThat(actualString).contains("null")
- assertThat(actualString).contains("3")
-
- job.cancel()
- }
-
- @Test
- fun logInputChange_unit_printsInputName() = runBlocking(IMMEDIATE) {
- val flow: Flow<Unit> = flowOf(Unit, Unit)
-
- val job = flow
- .logInputChange(logger, "testInputs")
- .launchIn(this)
-
- val stringWriter = StringWriter()
- buffer.dump(PrintWriter(stringWriter), tailLength = 0)
- val actualString = stringWriter.toString()
-
- assertThat(actualString).contains("testInputs")
-
- job.cancel()
- }
-
- @Test
- fun logInputChange_any_printsValuesAndNulls() = runBlocking(IMMEDIATE) {
- val flow: Flow<Any?> = flowOf(null, 2, "threeString")
-
- val job = flow
- .logInputChange(logger, "testInputs")
- .launchIn(this)
-
- val stringWriter = StringWriter()
- buffer.dump(PrintWriter(stringWriter), tailLength = 0)
- val actualString = stringWriter.toString()
-
- assertThat(actualString).contains("null")
- assertThat(actualString).contains("2")
- assertThat(actualString).contains("threeString")
-
- job.cancel()
- }
-
- companion object {
- private const val NET_1_ID = 100
- private val NET_1 = com.android.systemui.util.mockito.mock<Network>().also {
- Mockito.`when`(it.getNetId()).thenReturn(NET_1_ID)
- }
- private val NET_1_CAPS = NetworkCapabilities.Builder()
- .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
- .addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)
- .build()
- private val IMMEDIATE = Dispatchers.Main.immediate
- }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/data/repository/ConnectivityRepositoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/data/repository/ConnectivityRepositoryImplTest.kt
index 6dbee2f..496f090 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/data/repository/ConnectivityRepositoryImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/data/repository/ConnectivityRepositoryImplTest.kt
@@ -19,7 +19,7 @@
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.dump.DumpManager
-import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger
+import com.android.systemui.statusbar.pipeline.shared.ConnectivityInputLogger
import com.android.systemui.statusbar.pipeline.shared.data.model.ConnectivitySlot
import com.android.systemui.statusbar.pipeline.shared.data.model.ConnectivitySlots
import com.android.systemui.statusbar.pipeline.shared.data.repository.ConnectivityRepositoryImpl.Companion.DEFAULT_HIDDEN_ICONS_RESOURCE
@@ -52,7 +52,7 @@
@Mock private lateinit var connectivitySlots: ConnectivitySlots
@Mock private lateinit var dumpManager: DumpManager
- @Mock private lateinit var logger: ConnectivityPipelineLogger
+ @Mock private lateinit var logger: ConnectivityInputLogger
private lateinit var scope: CoroutineScope
@Mock private lateinit var tunerService: TunerService
@@ -61,14 +61,15 @@
MockitoAnnotations.initMocks(this)
scope = CoroutineScope(IMMEDIATE)
- underTest = ConnectivityRepositoryImpl(
- connectivitySlots,
- context,
- dumpManager,
- logger,
- scope,
- tunerService,
- )
+ underTest =
+ ConnectivityRepositoryImpl(
+ connectivitySlots,
+ context,
+ dumpManager,
+ logger,
+ scope,
+ tunerService,
+ )
}
@After
@@ -77,199 +78,179 @@
}
@Test
- fun forceHiddenSlots_initiallyGetsDefault() = runBlocking(IMMEDIATE) {
- setUpEthernetWifiMobileSlotNames()
- context.getOrCreateTestableResources().addOverride(
- DEFAULT_HIDDEN_ICONS_RESOURCE,
- arrayOf(SLOT_WIFI, SLOT_ETHERNET)
- )
- // Re-create our [ConnectivityRepositoryImpl], since it fetches
- // config_statusBarIconsToExclude when it's first constructed
- underTest = ConnectivityRepositoryImpl(
- connectivitySlots,
- context,
- dumpManager,
- logger,
- scope,
- tunerService,
- )
+ fun forceHiddenSlots_initiallyGetsDefault() =
+ runBlocking(IMMEDIATE) {
+ setUpEthernetWifiMobileSlotNames()
+ context
+ .getOrCreateTestableResources()
+ .addOverride(DEFAULT_HIDDEN_ICONS_RESOURCE, arrayOf(SLOT_WIFI, SLOT_ETHERNET))
+ // Re-create our [ConnectivityRepositoryImpl], since it fetches
+ // config_statusBarIconsToExclude when it's first constructed
+ underTest =
+ ConnectivityRepositoryImpl(
+ connectivitySlots,
+ context,
+ dumpManager,
+ logger,
+ scope,
+ tunerService,
+ )
- var latest: Set<ConnectivitySlot>? = null
- val job = underTest
- .forceHiddenSlots
- .onEach { latest = it }
- .launchIn(this)
+ var latest: Set<ConnectivitySlot>? = null
+ val job = underTest.forceHiddenSlots.onEach { latest = it }.launchIn(this)
- assertThat(latest).containsExactly(ConnectivitySlot.ETHERNET, ConnectivitySlot.WIFI)
+ assertThat(latest).containsExactly(ConnectivitySlot.ETHERNET, ConnectivitySlot.WIFI)
- job.cancel()
- }
+ job.cancel()
+ }
@Test
- fun forceHiddenSlots_slotNamesAdded_flowHasSlots() = runBlocking(IMMEDIATE) {
- setUpEthernetWifiMobileSlotNames()
+ fun forceHiddenSlots_slotNamesAdded_flowHasSlots() =
+ runBlocking(IMMEDIATE) {
+ setUpEthernetWifiMobileSlotNames()
- var latest: Set<ConnectivitySlot>? = null
- val job = underTest
- .forceHiddenSlots
- .onEach { latest = it }
- .launchIn(this)
+ var latest: Set<ConnectivitySlot>? = null
+ val job = underTest.forceHiddenSlots.onEach { latest = it }.launchIn(this)
- getTunable().onTuningChanged(HIDDEN_ICONS_TUNABLE_KEY, SLOT_MOBILE)
+ getTunable().onTuningChanged(HIDDEN_ICONS_TUNABLE_KEY, SLOT_MOBILE)
- assertThat(latest).containsExactly(ConnectivitySlot.MOBILE)
+ assertThat(latest).containsExactly(ConnectivitySlot.MOBILE)
- job.cancel()
- }
+ job.cancel()
+ }
@Test
- fun forceHiddenSlots_wrongKey_doesNotUpdate() = runBlocking(IMMEDIATE) {
- setUpEthernetWifiMobileSlotNames()
+ fun forceHiddenSlots_wrongKey_doesNotUpdate() =
+ runBlocking(IMMEDIATE) {
+ setUpEthernetWifiMobileSlotNames()
- var latest: Set<ConnectivitySlot>? = null
- val job = underTest
- .forceHiddenSlots
- .onEach { latest = it }
- .launchIn(this)
+ var latest: Set<ConnectivitySlot>? = null
+ val job = underTest.forceHiddenSlots.onEach { latest = it }.launchIn(this)
- getTunable().onTuningChanged(HIDDEN_ICONS_TUNABLE_KEY, SLOT_MOBILE)
+ getTunable().onTuningChanged(HIDDEN_ICONS_TUNABLE_KEY, SLOT_MOBILE)
- // WHEN onTuningChanged with the wrong key
- getTunable().onTuningChanged("wrongKey", SLOT_WIFI)
- yield()
+ // WHEN onTuningChanged with the wrong key
+ getTunable().onTuningChanged("wrongKey", SLOT_WIFI)
+ yield()
- // THEN we didn't update our value and still have the old one
- assertThat(latest).containsExactly(ConnectivitySlot.MOBILE)
+ // THEN we didn't update our value and still have the old one
+ assertThat(latest).containsExactly(ConnectivitySlot.MOBILE)
- job.cancel()
- }
+ job.cancel()
+ }
@Test
- fun forceHiddenSlots_slotNamesAddedThenNull_flowHasDefault() = runBlocking(IMMEDIATE) {
- setUpEthernetWifiMobileSlotNames()
- context.getOrCreateTestableResources().addOverride(
- DEFAULT_HIDDEN_ICONS_RESOURCE,
- arrayOf(SLOT_WIFI, SLOT_ETHERNET)
- )
- // Re-create our [ConnectivityRepositoryImpl], since it fetches
- // config_statusBarIconsToExclude when it's first constructed
- underTest = ConnectivityRepositoryImpl(
- connectivitySlots,
- context,
- dumpManager,
- logger,
- scope,
- tunerService,
- )
+ fun forceHiddenSlots_slotNamesAddedThenNull_flowHasDefault() =
+ runBlocking(IMMEDIATE) {
+ setUpEthernetWifiMobileSlotNames()
+ context
+ .getOrCreateTestableResources()
+ .addOverride(DEFAULT_HIDDEN_ICONS_RESOURCE, arrayOf(SLOT_WIFI, SLOT_ETHERNET))
+ // Re-create our [ConnectivityRepositoryImpl], since it fetches
+ // config_statusBarIconsToExclude when it's first constructed
+ underTest =
+ ConnectivityRepositoryImpl(
+ connectivitySlots,
+ context,
+ dumpManager,
+ logger,
+ scope,
+ tunerService,
+ )
- var latest: Set<ConnectivitySlot>? = null
- val job = underTest
- .forceHiddenSlots
- .onEach { latest = it }
- .launchIn(this)
+ var latest: Set<ConnectivitySlot>? = null
+ val job = underTest.forceHiddenSlots.onEach { latest = it }.launchIn(this)
- // First, update the slots
- getTunable().onTuningChanged(HIDDEN_ICONS_TUNABLE_KEY, SLOT_MOBILE)
- assertThat(latest).containsExactly(ConnectivitySlot.MOBILE)
+ // First, update the slots
+ getTunable().onTuningChanged(HIDDEN_ICONS_TUNABLE_KEY, SLOT_MOBILE)
+ assertThat(latest).containsExactly(ConnectivitySlot.MOBILE)
- // WHEN we update to a null value
- getTunable().onTuningChanged(HIDDEN_ICONS_TUNABLE_KEY, null)
- yield()
+ // WHEN we update to a null value
+ getTunable().onTuningChanged(HIDDEN_ICONS_TUNABLE_KEY, null)
+ yield()
- // THEN we go back to our default value
- assertThat(latest).containsExactly(ConnectivitySlot.ETHERNET, ConnectivitySlot.WIFI)
+ // THEN we go back to our default value
+ assertThat(latest).containsExactly(ConnectivitySlot.ETHERNET, ConnectivitySlot.WIFI)
- job.cancel()
- }
+ job.cancel()
+ }
@Test
- fun forceHiddenSlots_someInvalidSlotNames_flowHasValidSlotsOnly() = runBlocking(IMMEDIATE) {
- var latest: Set<ConnectivitySlot>? = null
- val job = underTest
- .forceHiddenSlots
- .onEach { latest = it }
- .launchIn(this)
+ fun forceHiddenSlots_someInvalidSlotNames_flowHasValidSlotsOnly() =
+ runBlocking(IMMEDIATE) {
+ var latest: Set<ConnectivitySlot>? = null
+ val job = underTest.forceHiddenSlots.onEach { latest = it }.launchIn(this)
- whenever(connectivitySlots.getSlotFromName(SLOT_WIFI))
- .thenReturn(ConnectivitySlot.WIFI)
- whenever(connectivitySlots.getSlotFromName(SLOT_MOBILE)).thenReturn(null)
+ whenever(connectivitySlots.getSlotFromName(SLOT_WIFI)).thenReturn(ConnectivitySlot.WIFI)
+ whenever(connectivitySlots.getSlotFromName(SLOT_MOBILE)).thenReturn(null)
- getTunable().onTuningChanged(HIDDEN_ICONS_TUNABLE_KEY, "$SLOT_WIFI,$SLOT_MOBILE")
+ getTunable().onTuningChanged(HIDDEN_ICONS_TUNABLE_KEY, "$SLOT_WIFI,$SLOT_MOBILE")
- assertThat(latest).containsExactly(ConnectivitySlot.WIFI)
+ assertThat(latest).containsExactly(ConnectivitySlot.WIFI)
- job.cancel()
- }
+ job.cancel()
+ }
@Test
- fun forceHiddenSlots_someEmptySlotNames_flowHasValidSlotsOnly() = runBlocking(IMMEDIATE) {
- setUpEthernetWifiMobileSlotNames()
+ fun forceHiddenSlots_someEmptySlotNames_flowHasValidSlotsOnly() =
+ runBlocking(IMMEDIATE) {
+ setUpEthernetWifiMobileSlotNames()
- var latest: Set<ConnectivitySlot>? = null
- val job = underTest
- .forceHiddenSlots
- .onEach { latest = it }
- .launchIn(this)
+ var latest: Set<ConnectivitySlot>? = null
+ val job = underTest.forceHiddenSlots.onEach { latest = it }.launchIn(this)
- // WHEN there's empty and blank slot names
- getTunable().onTuningChanged(
- HIDDEN_ICONS_TUNABLE_KEY, "$SLOT_MOBILE, ,,$SLOT_WIFI"
- )
+ // WHEN there's empty and blank slot names
+ getTunable().onTuningChanged(HIDDEN_ICONS_TUNABLE_KEY, "$SLOT_MOBILE, ,,$SLOT_WIFI")
- // THEN we skip that slot but still process the other ones
- assertThat(latest).containsExactly(ConnectivitySlot.WIFI, ConnectivitySlot.MOBILE)
+ // THEN we skip that slot but still process the other ones
+ assertThat(latest).containsExactly(ConnectivitySlot.WIFI, ConnectivitySlot.MOBILE)
- job.cancel()
- }
+ job.cancel()
+ }
@Test
- fun forceHiddenSlots_allInvalidOrEmptySlotNames_flowHasEmpty() = runBlocking(IMMEDIATE) {
- var latest: Set<ConnectivitySlot>? = null
- val job = underTest
- .forceHiddenSlots
- .onEach { latest = it }
- .launchIn(this)
+ fun forceHiddenSlots_allInvalidOrEmptySlotNames_flowHasEmpty() =
+ runBlocking(IMMEDIATE) {
+ var latest: Set<ConnectivitySlot>? = null
+ val job = underTest.forceHiddenSlots.onEach { latest = it }.launchIn(this)
- whenever(connectivitySlots.getSlotFromName(SLOT_WIFI)).thenReturn(null)
- whenever(connectivitySlots.getSlotFromName(SLOT_ETHERNET)).thenReturn(null)
- whenever(connectivitySlots.getSlotFromName(SLOT_MOBILE)).thenReturn(null)
+ whenever(connectivitySlots.getSlotFromName(SLOT_WIFI)).thenReturn(null)
+ whenever(connectivitySlots.getSlotFromName(SLOT_ETHERNET)).thenReturn(null)
+ whenever(connectivitySlots.getSlotFromName(SLOT_MOBILE)).thenReturn(null)
- getTunable().onTuningChanged(
- HIDDEN_ICONS_TUNABLE_KEY, "$SLOT_MOBILE,,$SLOT_WIFI,$SLOT_ETHERNET,,,"
- )
+ getTunable()
+ .onTuningChanged(
+ HIDDEN_ICONS_TUNABLE_KEY,
+ "$SLOT_MOBILE,,$SLOT_WIFI,$SLOT_ETHERNET,,,"
+ )
- assertThat(latest).isEmpty()
+ assertThat(latest).isEmpty()
- job.cancel()
- }
+ job.cancel()
+ }
@Test
- fun forceHiddenSlots_newSubscriberGetsCurrentValue() = runBlocking(IMMEDIATE) {
- setUpEthernetWifiMobileSlotNames()
+ fun forceHiddenSlots_newSubscriberGetsCurrentValue() =
+ runBlocking(IMMEDIATE) {
+ setUpEthernetWifiMobileSlotNames()
- var latest1: Set<ConnectivitySlot>? = null
- val job1 = underTest
- .forceHiddenSlots
- .onEach { latest1 = it }
- .launchIn(this)
+ var latest1: Set<ConnectivitySlot>? = null
+ val job1 = underTest.forceHiddenSlots.onEach { latest1 = it }.launchIn(this)
- getTunable().onTuningChanged(HIDDEN_ICONS_TUNABLE_KEY, "$SLOT_WIFI,$SLOT_ETHERNET")
+ getTunable().onTuningChanged(HIDDEN_ICONS_TUNABLE_KEY, "$SLOT_WIFI,$SLOT_ETHERNET")
- assertThat(latest1).containsExactly(ConnectivitySlot.WIFI, ConnectivitySlot.ETHERNET)
+ assertThat(latest1).containsExactly(ConnectivitySlot.WIFI, ConnectivitySlot.ETHERNET)
- // WHEN we add a second subscriber after having already emitted a value
- var latest2: Set<ConnectivitySlot>? = null
- val job2 = underTest
- .forceHiddenSlots
- .onEach { latest2 = it }
- .launchIn(this)
+ // WHEN we add a second subscriber after having already emitted a value
+ var latest2: Set<ConnectivitySlot>? = null
+ val job2 = underTest.forceHiddenSlots.onEach { latest2 = it }.launchIn(this)
- // THEN the second subscribe receives the already-emitted value
- assertThat(latest2).containsExactly(ConnectivitySlot.WIFI, ConnectivitySlot.ETHERNET)
+ // THEN the second subscribe receives the already-emitted value
+ assertThat(latest2).containsExactly(ConnectivitySlot.WIFI, ConnectivitySlot.ETHERNET)
- job1.cancel()
- job2.cancel()
- }
+ job1.cancel()
+ job2.cancel()
+ }
private fun getTunable(): TunerService.Tunable {
val callbackCaptor = argumentCaptor<TunerService.Tunable>()
@@ -280,10 +261,8 @@
private fun setUpEthernetWifiMobileSlotNames() {
whenever(connectivitySlots.getSlotFromName(SLOT_ETHERNET))
.thenReturn(ConnectivitySlot.ETHERNET)
- whenever(connectivitySlots.getSlotFromName(SLOT_WIFI))
- .thenReturn(ConnectivitySlot.WIFI)
- whenever(connectivitySlots.getSlotFromName(SLOT_MOBILE))
- .thenReturn(ConnectivitySlot.MOBILE)
+ whenever(connectivitySlots.getSlotFromName(SLOT_WIFI)).thenReturn(ConnectivitySlot.WIFI)
+ whenever(connectivitySlots.getSlotFromName(SLOT_MOBILE)).thenReturn(ConnectivitySlot.MOBILE)
}
companion object {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositorySwitcherTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositorySwitcherTest.kt
index 1085c2b..25678b0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositorySwitcherTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositorySwitcherTest.kt
@@ -23,11 +23,11 @@
import com.android.systemui.demomode.DemoMode
import com.android.systemui.demomode.DemoModeController
import com.android.systemui.log.table.TableLogBuffer
-import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger
import com.android.systemui.statusbar.pipeline.wifi.data.repository.demo.DemoModeWifiDataSource
import com.android.systemui.statusbar.pipeline.wifi.data.repository.demo.DemoWifiRepository
import com.android.systemui.statusbar.pipeline.wifi.data.repository.demo.model.FakeWifiEventModel
import com.android.systemui.statusbar.pipeline.wifi.data.repository.prod.WifiRepositoryImpl
+import com.android.systemui.statusbar.pipeline.wifi.shared.WifiInputLogger
import com.android.systemui.util.concurrency.FakeExecutor
import com.android.systemui.util.mockito.kotlinArgumentCaptor
import com.android.systemui.util.mockito.whenever
@@ -47,6 +47,7 @@
import org.mockito.MockitoAnnotations
@OptIn(ExperimentalCoroutinesApi::class)
+@Suppress("EXPERIMENTAL_IS_NOT_ENABLED")
@SmallTest
class WifiRepositorySwitcherTest : SysuiTestCase() {
private lateinit var underTest: WifiRepositorySwitcher
@@ -54,7 +55,7 @@
private lateinit var demoImpl: DemoWifiRepository
@Mock private lateinit var demoModeController: DemoModeController
- @Mock private lateinit var logger: ConnectivityPipelineLogger
+ @Mock private lateinit var logger: WifiInputLogger
@Mock private lateinit var tableLogger: TableLogBuffer
@Mock private lateinit var connectivityManager: ConnectivityManager
@Mock private lateinit var wifiManager: WifiManager
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImplTest.kt
index db791bb..c7b31bc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImplTest.kt
@@ -34,9 +34,9 @@
import com.android.systemui.SysuiTestCase
import com.android.systemui.broadcast.BroadcastDispatcher
import com.android.systemui.log.table.TableLogBuffer
-import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger
import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel
import com.android.systemui.statusbar.pipeline.wifi.data.repository.prod.WifiRepositoryImpl.Companion.WIFI_NETWORK_DEFAULT
+import com.android.systemui.statusbar.pipeline.wifi.shared.WifiInputLogger
import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiNetworkModel
import com.android.systemui.util.concurrency.FakeExecutor
import com.android.systemui.util.mockito.any
@@ -72,7 +72,7 @@
private lateinit var underTest: WifiRepositoryImpl
@Mock private lateinit var broadcastDispatcher: BroadcastDispatcher
- @Mock private lateinit var logger: ConnectivityPipelineLogger
+ @Mock private lateinit var logger: WifiInputLogger
@Mock private lateinit var tableLogger: TableLogBuffer
@Mock private lateinit var connectivityManager: ConnectivityManager
@Mock private lateinit var wifiManager: WifiManager
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiViewTest.kt
index 60f564e..64810d2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiViewTest.kt
@@ -36,7 +36,6 @@
import com.android.systemui.statusbar.pipeline.airplane.ui.viewmodel.AirplaneModeViewModel
import com.android.systemui.statusbar.pipeline.airplane.ui.viewmodel.AirplaneModeViewModelImpl
import com.android.systemui.statusbar.pipeline.shared.ConnectivityConstants
-import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger
import com.android.systemui.statusbar.pipeline.shared.data.repository.FakeConnectivityRepository
import com.android.systemui.statusbar.pipeline.wifi.data.repository.FakeWifiRepository
import com.android.systemui.statusbar.pipeline.wifi.domain.interactor.WifiInteractor
@@ -63,7 +62,6 @@
private lateinit var testableLooper: TestableLooper
@Mock private lateinit var statusBarPipelineFlags: StatusBarPipelineFlags
- @Mock private lateinit var logger: ConnectivityPipelineLogger
@Mock private lateinit var tableLogBuffer: TableLogBuffer
@Mock private lateinit var connectivityConstants: ConnectivityConstants
@Mock private lateinit var wifiConstants: WifiConstants
@@ -92,7 +90,7 @@
airplaneModeRepository,
connectivityRepository,
),
- logger,
+ tableLogBuffer,
scope,
)
viewModel =
@@ -100,7 +98,6 @@
airplaneModeViewModel,
connectivityConstants,
context,
- logger,
tableLogBuffer,
interactor,
scope,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelIconParameterizedTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelIconParameterizedTest.kt
index 648d7a5..12b1664 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelIconParameterizedTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelIconParameterizedTest.kt
@@ -33,7 +33,6 @@
import com.android.systemui.statusbar.pipeline.airplane.ui.viewmodel.AirplaneModeViewModel
import com.android.systemui.statusbar.pipeline.airplane.ui.viewmodel.AirplaneModeViewModelImpl
import com.android.systemui.statusbar.pipeline.shared.ConnectivityConstants
-import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger
import com.android.systemui.statusbar.pipeline.shared.data.model.ConnectivitySlot
import com.android.systemui.statusbar.pipeline.shared.data.repository.FakeConnectivityRepository
import com.android.systemui.statusbar.pipeline.wifi.data.repository.FakeWifiRepository
@@ -68,7 +67,6 @@
private lateinit var underTest: WifiViewModel
@Mock private lateinit var statusBarPipelineFlags: StatusBarPipelineFlags
- @Mock private lateinit var logger: ConnectivityPipelineLogger
@Mock private lateinit var tableLogBuffer: TableLogBuffer
@Mock private lateinit var connectivityConstants: ConnectivityConstants
@Mock private lateinit var wifiConstants: WifiConstants
@@ -94,7 +92,7 @@
airplaneModeRepository,
connectivityRepository,
),
- logger,
+ tableLogBuffer,
scope,
)
}
@@ -125,7 +123,6 @@
airplaneModeViewModel,
connectivityConstants,
context,
- logger,
tableLogBuffer,
interactor,
scope,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelTest.kt
index 45ebb39..7a62cb8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelTest.kt
@@ -25,7 +25,6 @@
import com.android.systemui.statusbar.pipeline.airplane.ui.viewmodel.AirplaneModeViewModel
import com.android.systemui.statusbar.pipeline.airplane.ui.viewmodel.AirplaneModeViewModelImpl
import com.android.systemui.statusbar.pipeline.shared.ConnectivityConstants
-import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger
import com.android.systemui.statusbar.pipeline.shared.data.model.ConnectivitySlot
import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel
import com.android.systemui.statusbar.pipeline.shared.data.repository.FakeConnectivityRepository
@@ -59,7 +58,6 @@
private lateinit var underTest: WifiViewModel
@Mock private lateinit var statusBarPipelineFlags: StatusBarPipelineFlags
- @Mock private lateinit var logger: ConnectivityPipelineLogger
@Mock private lateinit var tableLogBuffer: TableLogBuffer
@Mock private lateinit var connectivityConstants: ConnectivityConstants
@Mock private lateinit var wifiConstants: WifiConstants
@@ -85,7 +83,7 @@
airplaneModeRepository,
connectivityRepository,
),
- logger,
+ tableLogBuffer,
scope,
)
@@ -478,7 +476,6 @@
airplaneModeViewModel,
connectivityConstants,
context,
- logger,
tableLogBuffer,
interactor,
scope,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/FoldAodAnimationControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/FoldAodAnimationControllerTest.kt
index 3d75967..a87e61a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/unfold/FoldAodAnimationControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/FoldAodAnimationControllerTest.kt
@@ -28,6 +28,7 @@
import com.android.systemui.flags.FakeFeatureFlags
import com.android.systemui.flags.Flags.FACE_AUTH_REFACTOR
import com.android.systemui.keyguard.WakefulnessLifecycle
+import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
import com.android.systemui.shade.NotificationPanelViewController
@@ -112,7 +113,8 @@
KeyguardInteractor(
repository = keyguardRepository,
commandQueue = commandQueue,
- featureFlags = featureFlags
+ featureFlags = featureFlags,
+ bouncerRepository = FakeKeyguardBouncerRepository(),
)
// Needs to be run on the main thread
diff --git a/packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/UserInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/UserInteractorTest.kt
index 0257ebd..d00acb8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/UserInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/UserInteractorTest.kt
@@ -38,6 +38,7 @@
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.flags.FakeFeatureFlags
import com.android.systemui.flags.Flags
+import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
import com.android.systemui.plugins.ActivityStarter
@@ -143,6 +144,7 @@
repository = keyguardRepository,
commandQueue = commandQueue,
featureFlags = featureFlags,
+ bouncerRepository = FakeKeyguardBouncerRepository(),
),
manager = manager,
headlessSystemUserMode = headlessSystemUserMode,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/StatusBarUserChipViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/StatusBarUserChipViewModelTest.kt
index 2fedb87..22fc32a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/StatusBarUserChipViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/StatusBarUserChipViewModelTest.kt
@@ -31,6 +31,7 @@
import com.android.systemui.common.shared.model.Text
import com.android.systemui.flags.FakeFeatureFlags
import com.android.systemui.flags.Flags
+import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
import com.android.systemui.plugins.ActivityStarter
@@ -251,6 +252,7 @@
repository = keyguardRepository,
commandQueue = commandQueue,
featureFlags = featureFlags,
+ bouncerRepository = FakeKeyguardBouncerRepository(),
),
featureFlags = featureFlags,
manager = manager,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/UserSwitcherViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/UserSwitcherViewModelTest.kt
index 166b909..a2bd8d3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/UserSwitcherViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/UserSwitcherViewModelTest.kt
@@ -29,6 +29,7 @@
import com.android.systemui.common.shared.model.Text
import com.android.systemui.flags.FakeFeatureFlags
import com.android.systemui.flags.Flags
+import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
import com.android.systemui.plugins.ActivityStarter
@@ -152,7 +153,8 @@
KeyguardInteractor(
repository = keyguardRepository,
commandQueue = commandQueue,
- featureFlags = featureFlags
+ featureFlags = featureFlags,
+ bouncerRepository = FakeKeyguardBouncerRepository(),
),
featureFlags = featureFlags,
manager = manager,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardBouncerRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardBouncerRepository.kt
index d0383e9..3374219 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardBouncerRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardBouncerRepository.kt
@@ -57,10 +57,10 @@
override val bouncerPromptReason = 0
override val bouncerErrorMessage: CharSequence? = null
private val _isAlternateBouncerVisible = MutableStateFlow(false)
- override val isAlternateBouncerVisible = _isAlternateBouncerVisible.asStateFlow()
+ override val alternateBouncerVisible = _isAlternateBouncerVisible.asStateFlow()
override var lastAlternateBouncerVisibleTime: Long = 0L
private val _isAlternateBouncerUIAvailable = MutableStateFlow<Boolean>(false)
- override val isAlternateBouncerUIAvailable = _isAlternateBouncerUIAvailable.asStateFlow()
+ override val alternateBouncerUIAvailable = _isAlternateBouncerUIAvailable.asStateFlow()
override fun setPrimaryScrimmed(isScrimmed: Boolean) {
_primaryBouncerScrimmed.value = isScrimmed
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt
index 065fe89..1a371c7 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt
@@ -84,9 +84,6 @@
private val _isUdfpsSupported = MutableStateFlow(false)
- private val _isBouncerShowing = MutableStateFlow(false)
- override val isBouncerShowing: Flow<Boolean> = _isBouncerShowing
-
private val _isKeyguardGoingAway = MutableStateFlow(false)
override val isKeyguardGoingAway: Flow<Boolean> = _isKeyguardGoingAway
@@ -153,10 +150,6 @@
_wakefulnessModel.value = model
}
- fun setBouncerShowing(isShowing: Boolean) {
- _isBouncerShowing.value = isShowing
- }
-
fun setBiometricUnlockState(state: BiometricUnlockModel) {
_biometricUnlockState.tryEmit(state)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeKeyguardStateController.java b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeKeyguardStateController.java
index 95b62a1..bdf1aff 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeKeyguardStateController.java
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeKeyguardStateController.java
@@ -49,7 +49,7 @@
}
@Override
- public boolean isBouncerShowing() {
+ public boolean isPrimaryBouncerShowing() {
return false;
}
diff --git a/services/core/java/com/android/server/dreams/DreamController.java b/services/core/java/com/android/server/dreams/DreamController.java
index f74356d..97ab587 100644
--- a/services/core/java/com/android/server/dreams/DreamController.java
+++ b/services/core/java/com/android/server/dreams/DreamController.java
@@ -42,6 +42,7 @@
import java.util.ArrayList;
import java.util.Iterator;
import java.util.NoSuchElementException;
+import java.util.Objects;
/**
* Internal controller for starting and stopping the current dream and managing related state.
@@ -119,10 +120,20 @@
+ ", isPreviewMode=" + isPreviewMode + ", canDoze=" + canDoze
+ ", userId=" + userId + ", reason='" + reason + "'");
- if (mCurrentDream != null) {
- mPreviousDreams.add(mCurrentDream);
- }
+ final DreamRecord oldDream = mCurrentDream;
mCurrentDream = new DreamRecord(token, name, isPreviewMode, canDoze, userId, wakeLock);
+ if (oldDream != null) {
+ if (!oldDream.mWakingGently) {
+ // We will stop these previous dreams once the new dream is started.
+ mPreviousDreams.add(oldDream);
+ } else if (Objects.equals(oldDream.mName, mCurrentDream.mName)) {
+ // We are attempting to start a dream that is currently waking up gently.
+ // Let's silently stop the old instance here to clear the dream state.
+ // This should happen after the new mCurrentDream is set to avoid announcing
+ // a "dream stopped" state.
+ stopDreamInstance(/* immediately */ true, "restarting same dream", oldDream);
+ }
+ }
mCurrentDream.mDreamStartTime = SystemClock.elapsedRealtime();
MetricsLogger.visible(mContext,
diff --git a/services/core/java/com/android/server/wm/LetterboxUiController.java b/services/core/java/com/android/server/wm/LetterboxUiController.java
index cbc36c3..5a481f4 100644
--- a/services/core/java/com/android/server/wm/LetterboxUiController.java
+++ b/services/core/java/com/android/server/wm/LetterboxUiController.java
@@ -1000,7 +1000,7 @@
@VisibleForTesting
boolean shouldShowLetterboxUi(WindowState mainWindow) {
- return isSurfaceReadyAndVisible(mainWindow) && mainWindow.areAppWindowBoundsLetterboxed()
+ return isSurfaceVisible(mainWindow) && mainWindow.areAppWindowBoundsLetterboxed()
// Check for FLAG_SHOW_WALLPAPER explicitly instead of using
// WindowContainer#showWallpaper because the later will return true when this
// activity is using blurred wallpaper for letterbox background.
@@ -1008,11 +1008,8 @@
}
@VisibleForTesting
- boolean isSurfaceReadyAndVisible(WindowState mainWindow) {
- boolean surfaceReady = mainWindow.isDrawn() // Regular case
- // Waiting for relayoutWindow to call preserveSurface
- || mainWindow.isDragResizeChanged();
- return surfaceReady && (mActivityRecord.isVisible()
+ boolean isSurfaceVisible(WindowState mainWindow) {
+ return mainWindow.isOnScreen() && (mActivityRecord.isVisible()
|| mActivityRecord.isVisibleRequested());
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java
index 0d20f17..656c07b 100644
--- a/services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java
@@ -494,6 +494,7 @@
doReturn(insets).when(mainWindow).getInsetsState();
doReturn(attrs).when(mainWindow).getAttrs();
doReturn(true).when(mainWindow).isDrawn();
+ doReturn(true).when(mainWindow).isOnScreen();
doReturn(false).when(mainWindow).isLetterboxedForDisplayCutout();
doReturn(true).when(mainWindow).areAppWindowBoundsLetterboxed();
doReturn(true).when(mLetterboxConfiguration).isLetterboxActivityCornersRounded();
diff --git a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
index 0f9ff7d..de84655 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
@@ -502,7 +502,7 @@
spyOn(mActivity.mLetterboxUiController);
doReturn(true).when(mActivity.mLetterboxUiController)
- .isSurfaceReadyAndVisible(any());
+ .isSurfaceVisible(any());
assertTrue(mActivity.mLetterboxUiController.shouldShowLetterboxUi(
mActivity.findMainWindow()));