summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/hardware/biometrics/IBiometricAuthenticator.aidl3
-rw-r--r--core/java/android/hardware/fingerprint/IFingerprintService.aidl3
-rw-r--r--core/java/android/window/flags/windowing_frontend.aconfig8
-rw-r--r--core/java/com/android/internal/policy/DecorView.java4
-rw-r--r--libs/WindowManager/Shell/res/values/strings.xml4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java29
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SnapshotWindowCreator.java12
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenWindowCreator.java2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java20
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/WindowlessSnapshotWindowCreator.java8
-rw-r--r--media/java/android/media/AudioFormat.java3
-rw-r--r--packages/SystemUI/compose/core/src/com/android/compose/animation/scene/transformation/PunchHole.kt5
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/QSTileDataInteractor.kt26
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/QSTileDataRequest.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/QSTileUserActionInteractor.kt13
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/StateUpdateTrigger.kt11
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfig.kt14
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileLifecycle.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileState.kt18
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileUserAction.kt13
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModel.kt41
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/AospPolicyModule.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java16
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerLogger.kt121
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/BatteryControllerLog.kt25
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/StatusBarPolicyModule.java12
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BatteryControllerTest.java3
-rw-r--r--services/core/java/com/android/server/biometrics/AuthSession.java17
-rw-r--r--services/core/java/com/android/server/biometrics/BiometricSensor.java5
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java6
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/face/FaceAuthenticator.java3
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintAuthenticator.java5
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java8
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/iris/IrisAuthenticator.java3
-rwxr-xr-xservices/core/java/com/android/server/notification/NotificationManagerService.java1
-rw-r--r--services/core/java/com/android/server/wallpaper/WallpaperManagerService.java118
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java8
-rw-r--r--services/core/java/com/android/server/wm/DisplayPolicy.java12
-rw-r--r--services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java19
-rw-r--r--services/tests/servicestests/src/com/android/server/biometrics/AuthSessionTest.java3
-rw-r--r--services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java3
-rw-r--r--services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClientTest.java43
-rw-r--r--services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClientTest.java40
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java14
44 files changed, 608 insertions, 128 deletions
diff --git a/core/java/android/hardware/biometrics/IBiometricAuthenticator.aidl b/core/java/android/hardware/biometrics/IBiometricAuthenticator.aidl
index addd622eef35..17cd18cc4182 100644
--- a/core/java/android/hardware/biometrics/IBiometricAuthenticator.aidl
+++ b/core/java/android/hardware/biometrics/IBiometricAuthenticator.aidl
@@ -48,7 +48,8 @@ interface IBiometricAuthenticator {
// startPreparedClient().
void prepareForAuthentication(boolean requireConfirmation, IBinder token, long operationId,
int userId, IBiometricSensorReceiver sensorReceiver, String opPackageName,
- long requestId, int cookie, boolean allowBackgroundAuthentication);
+ long requestId, int cookie, boolean allowBackgroundAuthentication,
+ boolean isForLegacyFingerprintManager);
// Starts authentication with the previously prepared client.
void startPreparedClient(int cookie);
diff --git a/core/java/android/hardware/fingerprint/IFingerprintService.aidl b/core/java/android/hardware/fingerprint/IFingerprintService.aidl
index e2840ec20ff9..0100660669e9 100644
--- a/core/java/android/hardware/fingerprint/IFingerprintService.aidl
+++ b/core/java/android/hardware/fingerprint/IFingerprintService.aidl
@@ -74,7 +74,8 @@ interface IFingerprintService {
@EnforcePermission("MANAGE_BIOMETRIC")
void prepareForAuthentication(IBinder token, long operationId,
IBiometricSensorReceiver sensorReceiver, in FingerprintAuthenticateOptions options, long requestId,
- int cookie, boolean allowBackgroundAuthentication);
+ int cookie, boolean allowBackgroundAuthentication,
+ boolean isForLegacyFingerprintManager);
// Starts authentication with the previously prepared client.
@EnforcePermission("MANAGE_BIOMETRIC")
diff --git a/core/java/android/window/flags/windowing_frontend.aconfig b/core/java/android/window/flags/windowing_frontend.aconfig
new file mode 100644
index 000000000000..7a4c5bc669fc
--- /dev/null
+++ b/core/java/android/window/flags/windowing_frontend.aconfig
@@ -0,0 +1,8 @@
+package: "com.android.window.flags"
+
+flag {
+ name: "nav_bar_transparent_by_default"
+ namespace: "windowing_frontend"
+ description: "Make nav bar color transparent by default when targeting SDK 35 or greater"
+ bug: "232195501"
+}
diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java
index 3e16df4d7f67..1be916f44f5b 100644
--- a/core/java/com/android/internal/policy/DecorView.java
+++ b/core/java/com/android/internal/policy/DecorView.java
@@ -1160,7 +1160,9 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
mForceWindowDrawsBarBackgrounds, requestedVisibleTypes);
boolean oldDrawLegacy = mDrawLegacyNavigationBarBackground;
mDrawLegacyNavigationBarBackground =
- (mWindow.getAttributes().flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) == 0;
+ ((requestedVisibleTypes | mLastForceConsumingTypes)
+ & WindowInsets.Type.navigationBars()) != 0
+ && (mWindow.getAttributes().flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) == 0;
if (oldDrawLegacy != mDrawLegacyNavigationBarBackground) {
mDrawLegacyNavigationBarBackgroundHandled =
mWindow.onDrawLegacyNavigationBarBackgroundChanged(
diff --git a/libs/WindowManager/Shell/res/values/strings.xml b/libs/WindowManager/Shell/res/values/strings.xml
index eabe3a4eca0b..b556150e2ab9 100644
--- a/libs/WindowManager/Shell/res/values/strings.xml
+++ b/libs/WindowManager/Shell/res/values/strings.xml
@@ -142,6 +142,10 @@
<string name="bubble_accessibility_action_move_bottom_left">Move bottom left</string>
<!-- Action in accessibility menu to move the stack of bubbles to the bottom right of the screen. [CHAR LIMIT=30]-->
<string name="bubble_accessibility_action_move_bottom_right">Move bottom right</string>
+ <!-- Accessibility announcement when the stack of bubbles expands. [CHAR LIMIT=NONE]-->
+ <string name="bubble_accessibility_announce_expand">expand <xliff:g id="bubble_title" example="Messages">%1$s</xliff:g></string>
+ <!-- Accessibility announcement when the stack of bubbles collapses. [CHAR LIMIT=NONE]-->
+ <string name="bubble_accessibility_announce_collapse">collapse <xliff:g id="bubble_title" example="Messages">%1$s</xliff:g></string>
<!-- Label for the button that takes the user to the notification settings for the given app. -->
<string name="bubbles_app_settings"><xliff:g id="notification_title" example="Android Messages">%1$s</xliff:g> settings</string>
<!-- Text used for the bubble dismiss area. Bubbles dragged to, or flung towards, this area will go away. [CHAR LIMIT=30] -->
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
index 3f9dcc19dda7..c124b532b89d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
@@ -2037,6 +2037,7 @@ public class BubbleStackView extends FrameLayout
});
}
notifyExpansionChanged(mExpandedBubble, mIsExpanded);
+ announceExpandForAccessibility(mExpandedBubble, mIsExpanded);
}
/**
@@ -2053,6 +2054,34 @@ public class BubbleStackView extends FrameLayout
}
}
+ private void announceExpandForAccessibility(BubbleViewProvider bubble, boolean expanded) {
+ if (bubble instanceof Bubble) {
+ String contentDescription = getBubbleContentDescription((Bubble) bubble);
+ String message = getResources().getString(
+ expanded
+ ? R.string.bubble_accessibility_announce_expand
+ : R.string.bubble_accessibility_announce_collapse, contentDescription);
+ announceForAccessibility(message);
+ }
+ }
+
+ @NonNull
+ private String getBubbleContentDescription(Bubble bubble) {
+ final String appName = bubble.getAppName();
+ final String title = bubble.getTitle() != null
+ ? bubble.getTitle()
+ : getResources().getString(R.string.notification_bubble_title);
+
+ if (appName == null || title.equals(appName)) {
+ // App bubble title equals the app name, so return only the title to avoid having
+ // content description like: `<app> from <app>`.
+ return title;
+ } else {
+ return getResources().getString(
+ R.string.bubble_content_description_single, title, appName);
+ }
+ }
+
private boolean isGestureNavEnabled() {
return mContext.getResources().getInteger(
com.android.internal.R.integer.config_navBarInteractionMode)
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SnapshotWindowCreator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SnapshotWindowCreator.java
index 20c4d5ae5f58..e7e1e0a98550 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SnapshotWindowCreator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SnapshotWindowCreator.java
@@ -35,13 +35,14 @@ class SnapshotWindowCreator {
void makeTaskSnapshotWindow(StartingWindowInfo startingWindowInfo, TaskSnapshot snapshot) {
final int taskId = startingWindowInfo.taskInfo.taskId;
// Remove any existing starting window for this task before adding.
- mStartingWindowRecordManager.removeWindow(taskId, true);
+ mStartingWindowRecordManager.removeWindow(taskId);
final TaskSnapshotWindow surface = TaskSnapshotWindow.create(startingWindowInfo,
startingWindowInfo.appToken, snapshot, mMainExecutor,
- () -> mStartingWindowRecordManager.removeWindow(taskId, true));
+ () -> mStartingWindowRecordManager.removeWindow(taskId));
if (surface != null) {
final SnapshotWindowRecord tView = new SnapshotWindowRecord(surface,
- startingWindowInfo.taskInfo.topActivityType, mMainExecutor);
+ startingWindowInfo.taskInfo.topActivityType, mMainExecutor,
+ taskId, mStartingWindowRecordManager);
mStartingWindowRecordManager.addRecord(taskId, tView);
}
}
@@ -50,8 +51,9 @@ class SnapshotWindowCreator {
private final TaskSnapshotWindow mTaskSnapshotWindow;
SnapshotWindowRecord(TaskSnapshotWindow taskSnapshotWindow,
- int activityType, ShellExecutor removeExecutor) {
- super(activityType, removeExecutor);
+ int activityType, ShellExecutor removeExecutor, int id,
+ StartingSurfaceDrawer.StartingWindowRecordManager recordManager) {
+ super(activityType, removeExecutor, id, recordManager);
mTaskSnapshotWindow = taskSnapshotWindow;
mBGColor = mTaskSnapshotWindow.getBackgroundColor();
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenWindowCreator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenWindowCreator.java
index 4cfbbd971fe3..31fc98b713ab 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenWindowCreator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenWindowCreator.java
@@ -358,7 +358,7 @@ class SplashscreenWindowCreator extends AbsSplashWindowCreator {
}
}
if (shouldSaveView) {
- mStartingWindowRecordManager.removeWindow(taskId, true);
+ mStartingWindowRecordManager.removeWindow(taskId);
saveSplashScreenRecord(appToken, taskId, view, suggestType);
}
return shouldSaveView;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java
index 7cbf263f7cb1..e2be1533118a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java
@@ -188,7 +188,7 @@ public class StartingSurfaceDrawer {
final SnapshotRecord record = sRecord instanceof SnapshotRecord
? (SnapshotRecord) sRecord : null;
if (record != null && record.hasImeSurface()) {
- records.removeWindow(taskId, true);
+ records.removeWindow(taskId);
}
}
@@ -256,10 +256,15 @@ public class StartingSurfaceDrawer {
@WindowConfiguration.ActivityType protected final int mActivityType;
protected final ShellExecutor mRemoveExecutor;
+ private final int mTaskId;
+ private final StartingWindowRecordManager mRecordManager;
- SnapshotRecord(int activityType, ShellExecutor removeExecutor) {
+ SnapshotRecord(int activityType, ShellExecutor removeExecutor, int taskId,
+ StartingWindowRecordManager recordManager) {
mActivityType = activityType;
mRemoveExecutor = removeExecutor;
+ mTaskId = taskId;
+ mRecordManager = recordManager;
}
@Override
@@ -301,6 +306,7 @@ public class StartingSurfaceDrawer {
@CallSuper
protected void removeImmediately() {
mRemoveExecutor.removeCallbacks(mScheduledRunnable);
+ mRecordManager.onRecordRemoved(mTaskId);
}
}
@@ -316,7 +322,7 @@ public class StartingSurfaceDrawer {
taskIds[i] = mStartingWindowRecords.keyAt(i);
}
for (int i = taskSize - 1; i >= 0; --i) {
- removeWindow(taskIds[i], true);
+ removeWindow(taskIds[i]);
}
}
@@ -335,9 +341,13 @@ public class StartingSurfaceDrawer {
}
}
- void removeWindow(int taskId, boolean immediately) {
+ void removeWindow(int taskId) {
mTmpRemovalInfo.taskId = taskId;
- removeWindow(mTmpRemovalInfo, immediately);
+ removeWindow(mTmpRemovalInfo, true/* immediately */);
+ }
+
+ void onRecordRemoved(int taskId) {
+ mStartingWindowRecords.remove(taskId);
}
StartingWindowRecord getRecord(int taskId) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/WindowlessSnapshotWindowCreator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/WindowlessSnapshotWindowCreator.java
index 144547885501..fed2f34b5e0c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/WindowlessSnapshotWindowCreator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/WindowlessSnapshotWindowCreator.java
@@ -92,7 +92,8 @@ class WindowlessSnapshotWindowCreator {
final SnapshotWindowRecord record = new SnapshotWindowRecord(mViewHost, wlw.mChildSurface,
taskDescription.getBackgroundColor(), snapshot.hasImeSurface(),
- runningTaskInfo.topActivityType, removeExecutor);
+ runningTaskInfo.topActivityType, removeExecutor,
+ taskId, mStartingWindowRecordManager);
mStartingWindowRecordManager.addRecord(taskId, record);
info.notifyAddComplete(wlw.mChildSurface);
}
@@ -104,8 +105,9 @@ class WindowlessSnapshotWindowCreator {
SnapshotWindowRecord(SurfaceControlViewHost viewHost, SurfaceControl childSurface,
int bgColor, boolean hasImeSurface, int activityType,
- ShellExecutor removeExecutor) {
- super(activityType, removeExecutor);
+ ShellExecutor removeExecutor, int id,
+ StartingSurfaceDrawer.StartingWindowRecordManager recordManager) {
+ super(activityType, removeExecutor, id, recordManager);
mViewHost = viewHost;
mChildSurface = childSurface;
mBGColor = bgColor;
diff --git a/media/java/android/media/AudioFormat.java b/media/java/android/media/AudioFormat.java
index ceb3858eb0b3..a311296dd90c 100644
--- a/media/java/android/media/AudioFormat.java
+++ b/media/java/android/media/AudioFormat.java
@@ -1284,7 +1284,8 @@ public final class AudioFormat implements Parcelable {
* {@link AudioFormat#CHANNEL_OUT_SIDE_RIGHT}.
* <p> For a valid {@link AudioTrack} channel position mask,
* the following conditions apply:
- * <br> (1) at most eight channel positions may be used;
+ * <br> (1) at most {@link AudioSystem#OUT_CHANNEL_COUNT_MAX} channel positions may be
+ * used;
* <br> (2) right/left pairs should be matched.
* <p> For input or {@link AudioRecord}, the mask should be
* {@link AudioFormat#CHANNEL_IN_MONO} or
diff --git a/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/transformation/PunchHole.kt b/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/transformation/PunchHole.kt
index 31e7d7c7c6ba..73b366ef57bc 100644
--- a/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/transformation/PunchHole.kt
+++ b/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/transformation/PunchHole.kt
@@ -72,15 +72,16 @@ internal class PunchHole(
}
private fun DrawScope.drawHole(bounds: Element) {
+ val boundsSize = bounds.lastSize.toSize()
if (shape == RectangleShape) {
- drawRect(Color.Black, blendMode = BlendMode.DstOut)
+ drawRect(Color.Black, size = boundsSize, blendMode = BlendMode.DstOut)
return
}
// TODO(b/290184746): Cache outline if the size of bounds does not change.
drawOutline(
shape.createOutline(
- bounds.lastSize.toSize(),
+ boundsSize,
layoutDirection,
this,
),
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/QSTileDataInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/QSTileDataInteractor.kt
new file mode 100644
index 000000000000..1a03481b9fca
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/QSTileDataInteractor.kt
@@ -0,0 +1,26 @@
+package com.android.systemui.qs.tiles.base.interactor
+
+import com.android.systemui.qs.tiles.viewmodel.QSTileState
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.flow.Flow
+
+/**
+ * Provides data and availability for the tile. In most cases it would delegate data retrieval to
+ * repository, manager, controller or a combination of those. Avoid doing long running operations in
+ * these methods because there is no background thread guarantee. Use [Flow.flowOn] (typically
+ * with @Background [CoroutineDispatcher]) instead to move the calculations to another thread.
+ */
+interface QSTileDataInteractor<DATA_TYPE> {
+
+ /**
+ * Returns the data to be mapped to [QSTileState]. Make sure to start the flow [Flow.onStart]
+ * with the current state to update the tile as soon as possible.
+ */
+ fun tileData(qsTileDataRequest: QSTileDataRequest): Flow<DATA_TYPE>
+
+ /**
+ * Returns tile availability - whether this device currently supports this tile. Make sure to
+ * start the flow [Flow.onStart] with the current state to update the tile as soon as possible.
+ */
+ fun availability(): Flow<Boolean>
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/QSTileDataRequest.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/QSTileDataRequest.kt
new file mode 100644
index 000000000000..82897044f06c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/QSTileDataRequest.kt
@@ -0,0 +1,6 @@
+package com.android.systemui.qs.tiles.base.interactor
+
+data class QSTileDataRequest(
+ val userId: Int,
+ val trigger: StateUpdateTrigger,
+)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/QSTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/QSTileUserActionInteractor.kt
new file mode 100644
index 000000000000..8569fc73adb4
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/QSTileUserActionInteractor.kt
@@ -0,0 +1,13 @@
+package com.android.systemui.qs.tiles.base.interactor
+
+import android.annotation.WorkerThread
+import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction
+
+interface QSTileUserActionInteractor<DATA_TYPE> {
+
+ /**
+ * Processes user input based on [userAction] and [currentData]. It's safe to run long running
+ * computations inside this function in this.
+ */
+ @WorkerThread suspend fun handleInput(userAction: QSTileUserAction, currentData: DATA_TYPE)
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/StateUpdateTrigger.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/StateUpdateTrigger.kt
new file mode 100644
index 000000000000..ed7ec8e32de4
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/StateUpdateTrigger.kt
@@ -0,0 +1,11 @@
+package com.android.systemui.qs.tiles.base.interactor
+
+import com.android.systemui.qs.tiles.viewmodel.QSTileState
+import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction
+
+sealed interface StateUpdateTrigger {
+ class UserAction<T>(val action: QSTileUserAction, val tileState: QSTileState, val tileData: T) :
+ StateUpdateTrigger
+ data object ForceUpdate : StateUpdateTrigger
+ data object InitialRequest : StateUpdateTrigger
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfig.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfig.kt
new file mode 100644
index 000000000000..a5eaac154230
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfig.kt
@@ -0,0 +1,14 @@
+package com.android.systemui.qs.tiles.viewmodel
+
+import android.graphics.drawable.Icon
+import com.android.systemui.qs.pipeline.shared.TileSpec
+
+data class QSTileConfig(
+ val tileSpec: TileSpec,
+ val tileIcon: Icon,
+ val tileLabel: CharSequence,
+// TODO(b/299908705): Fill necessary params
+/*
+val instanceId: InstanceId,
+ */
+)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileLifecycle.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileLifecycle.kt
new file mode 100644
index 000000000000..39db7038bfa2
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileLifecycle.kt
@@ -0,0 +1,6 @@
+package com.android.systemui.qs.tiles.viewmodel
+
+enum class QSTileLifecycle {
+ ON_CREATE,
+ ON_DESTROY,
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileState.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileState.kt
new file mode 100644
index 000000000000..53f9edfb954c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileState.kt
@@ -0,0 +1,18 @@
+package com.android.systemui.qs.tiles.viewmodel
+
+import android.graphics.drawable.Icon
+
+data class QSTileState(
+ val icon: Icon,
+ val label: CharSequence,
+// TODO(b/299908705): Fill necessary params
+/*
+ val subtitle: CharSequence = "",
+ val activeState: ActivationState = Active,
+ val enabledState: Enabled = Enabled,
+ val loopIconAnimation: Boolean = false,
+ val secondaryIcon: Icon? = null,
+ val slashState: SlashState? = null,
+ val supportedActions: Collection<UserAction> = listOf(Click), clicks should be a default action
+*/
+)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileUserAction.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileUserAction.kt
new file mode 100644
index 000000000000..f1f8f0152c67
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileUserAction.kt
@@ -0,0 +1,13 @@
+package com.android.systemui.qs.tiles.viewmodel
+
+import android.content.Context
+import android.view.View
+
+sealed interface QSTileUserAction {
+
+ val context: Context
+ val view: View?
+
+ class Click(override val context: Context, override val view: View?) : QSTileUserAction
+ class LongClick(override val context: Context, override val view: View?) : QSTileUserAction
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModel.kt
new file mode 100644
index 000000000000..49077f3f310d
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModel.kt
@@ -0,0 +1,41 @@
+package com.android.systemui.qs.tiles.viewmodel
+
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.StateFlow
+
+/**
+ * Represents tiles behaviour logic. This ViewModel is a connection between tile view and data
+ * layers.
+ */
+interface QSTileViewModel {
+
+ /**
+ * State of the tile to be shown by the view. Favor reactive consumption over the
+ * [StateFlow.value], because there is no guarantee that current value would be available at any
+ * time.
+ */
+ val state: StateFlow<QSTileState>
+
+ val config: QSTileConfig
+
+ val isAvailable: Flow<Boolean>
+
+ /**
+ * Handles ViewModel lifecycle. Implementations should be inactive outside of
+ * [QSTileLifecycle.ON_CREATE] and [QSTileLifecycle.ON_DESTROY] bounds.
+ */
+ fun onLifecycle(lifecycle: QSTileLifecycle)
+
+ /**
+ * Notifies about the user change. Implementations should avoid using 3rd party userId sources
+ * and use this value instead. This is to maintain consistent and concurrency-free behaviour
+ * across different parts of QS.
+ */
+ fun onUserIdChanged(userId: Int)
+
+ /** Triggers emit of the new [QSTileState] in [state]. */
+ fun forceUpdate()
+
+ /** Notifies underlying logic about user input. */
+ fun onActionPerformed(userAction: QSTileUserAction)
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/AospPolicyModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/AospPolicyModule.java
index ba5fa1df4b15..3d51ab0a2b27 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/AospPolicyModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/AospPolicyModule.java
@@ -45,6 +45,7 @@ public class AospPolicyModule {
BroadcastDispatcher broadcastDispatcher,
DemoModeController demoModeController,
DumpManager dumpManager,
+ BatteryControllerLogger logger,
@Main Handler mainHandler,
@Background Handler bgHandler) {
BatteryController bC = new BatteryControllerImpl(
@@ -54,6 +55,7 @@ public class AospPolicyModule {
broadcastDispatcher,
demoModeController,
dumpManager,
+ logger,
mainHandler,
bgHandler);
bC.init();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java
index 4b515115dd77..41ed76d7edb1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java
@@ -20,7 +20,6 @@ import static android.os.BatteryManager.CHARGING_POLICY_ADAPTIVE_LONGLIFE;
import static android.os.BatteryManager.CHARGING_POLICY_DEFAULT;
import static android.os.BatteryManager.EXTRA_CHARGING_STATUS;
import static android.os.BatteryManager.EXTRA_PRESENT;
-
import static com.android.settingslib.fuelgauge.BatterySaverLogging.SAVER_ENABLED_QS;
import static com.android.systemui.util.DumpUtilsKt.asIndenting;
@@ -85,6 +84,7 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC
private final PowerManager mPowerManager;
private final DemoModeController mDemoModeController;
private final DumpManager mDumpManager;
+ private final BatteryControllerLogger mLogger;
private final Handler mMainHandler;
private final Handler mBgHandler;
protected final Context mContext;
@@ -122,6 +122,7 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC
BroadcastDispatcher broadcastDispatcher,
DemoModeController demoModeController,
DumpManager dumpManager,
+ BatteryControllerLogger logger,
@Main Handler mainHandler,
@Background Handler bgHandler) {
mContext = context;
@@ -132,6 +133,8 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC
mBroadcastDispatcher = broadcastDispatcher;
mDemoModeController = demoModeController;
mDumpManager = dumpManager;
+ mLogger = logger;
+ mLogger.logBatteryControllerInstance(this);
}
private void registerReceiver() {
@@ -145,6 +148,7 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC
@Override
public void init() {
+ mLogger.logBatteryControllerInit(this, mHasReceivedBattery);
registerReceiver();
if (!mHasReceivedBattery) {
// Get initial state. Relying on Sticky behavior until API for getting info.
@@ -232,8 +236,13 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC
@Override
public void onReceive(final Context context, Intent intent) {
final String action = intent.getAction();
+ mLogger.logIntentReceived(action);
if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
- if (mTestMode && !intent.getBooleanExtra("testmode", false)) return;
+ mLogger.logBatteryChangedIntent(intent);
+ if (mTestMode && !intent.getBooleanExtra("testmode", false)) {
+ mLogger.logBatteryChangedSkipBecauseTest();
+ return;
+ }
mHasReceivedBattery = true;
mLevel = (int) (100f
* intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0)
@@ -275,6 +284,7 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC
fireIsIncompatibleChargingChanged();
}
} else if (action.equals(ACTION_LEVEL_TEST)) {
+ mLogger.logEnterTestMode();
mTestMode = true;
mMainHandler.post(new Runnable() {
int mCurrentLevel = 0;
@@ -286,6 +296,7 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC
@Override
public void run() {
if (mCurrentLevel < 0) {
+ mLogger.logExitTestMode();
mTestMode = false;
mTestIntent.putExtra("level", mSavedLevel);
mTestIntent.putExtra("plugged", mSavedPluggedIn);
@@ -438,6 +449,7 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC
}
protected void fireBatteryLevelChanged() {
+ mLogger.logBatteryLevelChangedCallback(mLevel, mPluggedIn, mCharging);
synchronized (mChangeCallbacks) {
final int N = mChangeCallbacks.size();
for (int i = 0; i < N; i++) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerLogger.kt
new file mode 100644
index 000000000000..4a2a2dbad638
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerLogger.kt
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.policy
+
+import android.content.Intent
+import android.os.BatteryManager.EXTRA_LEVEL
+import android.os.BatteryManager.EXTRA_SCALE
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.log.LogBuffer
+import com.android.systemui.log.core.LogLevel
+import com.android.systemui.statusbar.policy.dagger.BatteryControllerLog
+import javax.inject.Inject
+
+/** Detailed, [LogBuffer]-backed logs for [BatteryControllerImpl] */
+@SysUISingleton
+class BatteryControllerLogger
+@Inject
+constructor(@BatteryControllerLog private val logBuffer: LogBuffer) {
+ fun logBatteryControllerInstance(controller: BatteryController) {
+ logBuffer.log(
+ TAG,
+ LogLevel.DEBUG,
+ { int1 = System.identityHashCode(controller) },
+ { "BatteryController CREATE (${Integer.toHexString(int1)})" }
+ )
+ }
+
+ fun logBatteryControllerInit(controller: BatteryController, hasReceivedBattery: Boolean) {
+ logBuffer.log(
+ TAG,
+ LogLevel.DEBUG,
+ {
+ int1 = System.identityHashCode(controller)
+ bool1 = hasReceivedBattery
+ },
+ { "BatteryController INIT (${Integer.toHexString(int1)}) hasReceivedBattery=$bool1" }
+ )
+ }
+
+ fun logIntentReceived(action: String) {
+ logBuffer.log(TAG, LogLevel.DEBUG, { str1 = action }, { "Received intent $str1" })
+ }
+
+ fun logBatteryChangedIntent(intent: Intent) {
+ logBuffer.log(
+ TAG,
+ LogLevel.DEBUG,
+ {
+ int1 = intent.getIntExtra(EXTRA_LEVEL, DEFAULT)
+ int2 = intent.getIntExtra(EXTRA_SCALE, DEFAULT)
+ },
+ { "Processing BATTERY_CHANGED intent. level=${int1.report()} scale=${int2.report()}" }
+ )
+ }
+
+ fun logBatteryChangedSkipBecauseTest() {
+ logBuffer.log(
+ TAG,
+ LogLevel.DEBUG,
+ {},
+ { "Detected test intent. Will not execute battery level callbacks." }
+ )
+ }
+
+ fun logEnterTestMode() {
+ logBuffer.log(
+ TAG,
+ LogLevel.DEBUG,
+ {},
+ { "Entering test mode for BATTERY_LEVEL_TEST intent" }
+ )
+ }
+
+ fun logExitTestMode() {
+ logBuffer.log(TAG, LogLevel.DEBUG, {}, { "Exiting test mode" })
+ }
+
+ fun logBatteryLevelChangedCallback(level: Int, plugged: Boolean, charging: Boolean) {
+ logBuffer.log(
+ TAG,
+ LogLevel.DEBUG,
+ {
+ int1 = level
+ bool1 = plugged
+ bool2 = charging
+ },
+ {
+ "Sending onBatteryLevelChanged callbacks " +
+ "with level=$int1, plugged=$bool1, charging=$bool2"
+ }
+ )
+ }
+
+ private fun Int.report(): String =
+ if (this == DEFAULT) {
+ "(missing)"
+ } else {
+ toString()
+ }
+
+ companion object {
+ const val TAG: String = "BatteryControllerLog"
+ }
+}
+
+// Use a token value so we can determine if we got the default
+private const val DEFAULT = -11
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/BatteryControllerLog.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/BatteryControllerLog.kt
new file mode 100644
index 000000000000..5322b3811f95
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/BatteryControllerLog.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.policy.dagger
+
+import javax.inject.Qualifier
+
+/** Logs for Battery events. See [BatteryControllerImpl] */
+@Qualifier
+@MustBeDocumented
+@Retention(AnnotationRetention.RUNTIME)
+annotation class BatteryControllerLog
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/StatusBarPolicyModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/StatusBarPolicyModule.java
index c2a8e701653a..de07a48a2b56 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/StatusBarPolicyModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/StatusBarPolicyModule.java
@@ -24,6 +24,8 @@ import com.android.internal.R;
import com.android.settingslib.devicestate.DeviceStateRotationLockSettingsManager;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.log.LogBuffer;
+import com.android.systemui.log.LogBufferFactory;
import com.android.systemui.settings.UserTracker;
import com.android.systemui.statusbar.connectivity.AccessPointController;
import com.android.systemui.statusbar.connectivity.AccessPointControllerImpl;
@@ -31,6 +33,7 @@ import com.android.systemui.statusbar.connectivity.NetworkController;
import com.android.systemui.statusbar.connectivity.NetworkControllerImpl;
import com.android.systemui.statusbar.connectivity.WifiPickerTrackerFactory;
import com.android.systemui.statusbar.phone.ConfigurationControllerImpl;
+import com.android.systemui.statusbar.policy.BatteryControllerLogger;
import com.android.systemui.statusbar.policy.BluetoothController;
import com.android.systemui.statusbar.policy.BluetoothControllerImpl;
import com.android.systemui.statusbar.policy.CastController;
@@ -202,4 +205,13 @@ public interface StatusBarPolicyModule {
static DataSaverController provideDataSaverController(NetworkController networkController) {
return networkController.getDataSaverController();
}
+
+ /** Provides a log bufffer for BatteryControllerImpl */
+ @Provides
+ @SysUISingleton
+ @BatteryControllerLog
+ //TODO(b/300147438): reduce the size of this log buffer
+ static LogBuffer provideBatteryControllerLog(LogBufferFactory factory) {
+ return factory.create(BatteryControllerLogger.TAG, 300);
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BatteryControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BatteryControllerTest.java
index cdeb59278851..58d93c98f015 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BatteryControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BatteryControllerTest.java
@@ -17,12 +17,10 @@
package com.android.systemui.statusbar.policy;
import static android.os.BatteryManager.EXTRA_PRESENT;
-
import static com.android.dx.mockito.inline.extended.ExtendedMockito.inOrder;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.staticMockMarker;
import static com.android.settingslib.fuelgauge.BatterySaverLogging.SAVER_ENABLED_QS;
-
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
@@ -91,6 +89,7 @@ public class BatteryControllerTest extends SysuiTestCase {
mBroadcastDispatcher,
mDemoModeController,
mock(DumpManager.class),
+ mock(BatteryControllerLogger.class),
new Handler(),
new Handler());
// Can throw if updateEstimate is called on the main thread
diff --git a/services/core/java/com/android/server/biometrics/AuthSession.java b/services/core/java/com/android/server/biometrics/AuthSession.java
index 2ae3118d7bfa..b9ccbfbf55e7 100644
--- a/services/core/java/com/android/server/biometrics/AuthSession.java
+++ b/services/core/java/com/android/server/biometrics/AuthSession.java
@@ -275,7 +275,8 @@ public final class AuthSession implements IBinder.DeathRecipient {
}
sensor.goToStateWaitingForCookie(requireConfirmation, mToken, mOperationId,
mUserId, mSensorReceiver, mOpPackageName, mRequestId, cookie,
- mPromptInfo.isAllowBackgroundAuthentication());
+ mPromptInfo.isAllowBackgroundAuthentication(),
+ mPromptInfo.isForLegacyFingerprintManager());
}
}
@@ -747,7 +748,7 @@ public final class AuthSession implements IBinder.DeathRecipient {
Slog.v(TAG, "Confirmed! Modality: " + statsModality()
+ ", User: " + mUserId
+ ", IsCrypto: " + isCrypto()
- + ", Client: " + BiometricsProtoEnums.CLIENT_BIOMETRIC_PROMPT
+ + ", Client: " + getStatsClient()
+ ", RequireConfirmation: " + mPreAuthInfo.confirmationRequested
+ ", State: " + FrameworkStatsLog.BIOMETRIC_AUTHENTICATED__STATE__CONFIRMED
+ ", Latency: " + latency
@@ -758,7 +759,7 @@ public final class AuthSession implements IBinder.DeathRecipient {
mOperationContext,
statsModality(),
BiometricsProtoEnums.ACTION_UNKNOWN,
- BiometricsProtoEnums.CLIENT_BIOMETRIC_PROMPT,
+ getStatsClient(),
mDebugEnabled,
latency,
FrameworkStatsLog.BIOMETRIC_AUTHENTICATED__STATE__CONFIRMED,
@@ -784,7 +785,7 @@ public final class AuthSession implements IBinder.DeathRecipient {
+ ", User: " + mUserId
+ ", IsCrypto: " + isCrypto()
+ ", Action: " + BiometricsProtoEnums.ACTION_AUTHENTICATE
- + ", Client: " + BiometricsProtoEnums.CLIENT_BIOMETRIC_PROMPT
+ + ", Client: " + getStatsClient()
+ ", Reason: " + reason
+ ", Error: " + error
+ ", Latency: " + latency
@@ -796,7 +797,7 @@ public final class AuthSession implements IBinder.DeathRecipient {
mOperationContext,
statsModality(),
BiometricsProtoEnums.ACTION_AUTHENTICATE,
- BiometricsProtoEnums.CLIENT_BIOMETRIC_PROMPT,
+ getStatsClient(),
mDebugEnabled,
latency,
error,
@@ -998,6 +999,12 @@ public final class AuthSession implements IBinder.DeathRecipient {
}
}
+ private int getStatsClient() {
+ return mPromptInfo.isForLegacyFingerprintManager()
+ ? BiometricsProtoEnums.CLIENT_FINGERPRINT_MANAGER
+ : BiometricsProtoEnums.CLIENT_BIOMETRIC_PROMPT;
+ }
+
@Override
public String toString() {
return "State: " + mState
diff --git a/services/core/java/com/android/server/biometrics/BiometricSensor.java b/services/core/java/com/android/server/biometrics/BiometricSensor.java
index 937e3f8f8668..42dd36a5c35a 100644
--- a/services/core/java/com/android/server/biometrics/BiometricSensor.java
+++ b/services/core/java/com/android/server/biometrics/BiometricSensor.java
@@ -106,12 +106,13 @@ public abstract class BiometricSensor {
void goToStateWaitingForCookie(boolean requireConfirmation, IBinder token, long sessionId,
int userId, IBiometricSensorReceiver sensorReceiver, String opPackageName,
- long requestId, int cookie, boolean allowBackgroundAuthentication)
+ long requestId, int cookie, boolean allowBackgroundAuthentication,
+ boolean isForLegacyFingerprintManager)
throws RemoteException {
mCookie = cookie;
impl.prepareForAuthentication(requireConfirmation, token,
sessionId, userId, sensorReceiver, opPackageName, requestId, mCookie,
- allowBackgroundAuthentication);
+ allowBackgroundAuthentication, isForLegacyFingerprintManager);
mSensorState = STATE_WAITING_FOR_COOKIE;
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java
index 6ac163121d8c..78c95ad4576b 100644
--- a/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java
@@ -283,7 +283,11 @@ public abstract class AuthenticationClient<T, O extends AuthenticateOptions>
}
try {
- listener.onAuthenticationFailed(getSensorId());
+ if (listener != null) {
+ listener.onAuthenticationFailed(getSensorId());
+ } else {
+ Slog.e(TAG, "Received failed auth, but client was not listening");
+ }
} catch (RemoteException e) {
Slog.e(TAG, "Unable to notify listener", e);
mCallback.onClientFinished(this, false);
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/FaceAuthenticator.java b/services/core/java/com/android/server/biometrics/sensors/face/FaceAuthenticator.java
index fb64bcc3abc1..22110037890f 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/FaceAuthenticator.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/FaceAuthenticator.java
@@ -62,7 +62,8 @@ public final class FaceAuthenticator extends IBiometricAuthenticator.Stub {
@Override
public void prepareForAuthentication(boolean requireConfirmation, IBinder token,
long operationId, int userId, IBiometricSensorReceiver sensorReceiver,
- String opPackageName, long requestId, int cookie, boolean allowBackgroundAuthentication)
+ String opPackageName, long requestId, int cookie, boolean allowBackgroundAuthentication,
+ boolean isForLegacyFingerprintManager)
throws RemoteException {
mFaceService.prepareForAuthentication(requireConfirmation, token, operationId,
sensorReceiver, new FaceAuthenticateOptions.Builder()
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintAuthenticator.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintAuthenticator.java
index d47a57ad6742..b6fa0c126cd6 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintAuthenticator.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintAuthenticator.java
@@ -62,7 +62,8 @@ public final class FingerprintAuthenticator extends IBiometricAuthenticator.Stub
@Override
public void prepareForAuthentication(boolean requireConfirmation, IBinder token,
long operationId, int userId, IBiometricSensorReceiver sensorReceiver,
- String opPackageName, long requestId, int cookie, boolean allowBackgroundAuthentication)
+ String opPackageName, long requestId, int cookie, boolean allowBackgroundAuthentication,
+ boolean isForLegacyFingerprintManager)
throws RemoteException {
mFingerprintService.prepareForAuthentication(token, operationId, sensorReceiver,
new FingerprintAuthenticateOptions.Builder()
@@ -70,7 +71,7 @@ public final class FingerprintAuthenticator extends IBiometricAuthenticator.Stub
.setUserId(userId)
.setOpPackageName(opPackageName)
.build(),
- requestId, cookie, allowBackgroundAuthentication);
+ requestId, cookie, allowBackgroundAuthentication, isForLegacyFingerprintManager);
}
@Override
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
index 7cc6940f4b9d..5ce0c8b384ef 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
@@ -464,7 +464,8 @@ public class FingerprintService extends SystemService {
public void prepareForAuthentication(IBinder token, long operationId,
IBiometricSensorReceiver sensorReceiver,
@NonNull FingerprintAuthenticateOptions options,
- long requestId, int cookie, boolean allowBackgroundAuthentication) {
+ long requestId, int cookie, boolean allowBackgroundAuthentication,
+ boolean isForLegacyFingerprintManager) {
super.prepareForAuthentication_enforcePermission();
final ServiceProvider provider = mRegistry.getProviderForSensor(options.getSensorId());
@@ -473,10 +474,13 @@ public class FingerprintService extends SystemService {
return;
}
+ final int statsClient =
+ isForLegacyFingerprintManager ? BiometricsProtoEnums.CLIENT_FINGERPRINT_MANAGER
+ : BiometricsProtoEnums.CLIENT_BIOMETRIC_PROMPT;
final boolean restricted = true; // BiometricPrompt is always restricted
provider.scheduleAuthenticate(token, operationId, cookie,
new ClientMonitorCallbackConverter(sensorReceiver), options, requestId,
- restricted, BiometricsProtoEnums.CLIENT_BIOMETRIC_PROMPT,
+ restricted, statsClient,
allowBackgroundAuthentication);
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/iris/IrisAuthenticator.java b/services/core/java/com/android/server/biometrics/sensors/iris/IrisAuthenticator.java
index 5c0c3626037a..01d1e378a735 100644
--- a/services/core/java/com/android/server/biometrics/sensors/iris/IrisAuthenticator.java
+++ b/services/core/java/com/android/server/biometrics/sensors/iris/IrisAuthenticator.java
@@ -59,7 +59,8 @@ public final class IrisAuthenticator extends IBiometricAuthenticator.Stub {
@Override
public void prepareForAuthentication(boolean requireConfirmation, IBinder token,
long sessionId, int userId, IBiometricSensorReceiver sensorReceiver,
- String opPackageName, long requestId, int cookie, boolean allowBackgroundAuthentication)
+ String opPackageName, long requestId, int cookie, boolean allowBackgroundAuthentication,
+ boolean isForLegacyFingerprintManager)
throws RemoteException {
}
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index ec071a73d74f..c80661692217 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -2047,7 +2047,6 @@ public class NotificationManagerService extends SystemService {
protected class StrongAuthTracker extends LockPatternUtils.StrongAuthTracker {
SparseBooleanArray mUserInLockDownMode = new SparseBooleanArray();
- boolean mIsInLockDownMode = false;
StrongAuthTracker(Context context) {
super(context);
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index cfc7031d01d7..3c2d0fcb8cdf 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -1005,11 +1005,11 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
return;
}
- if (!mWallpaper.wallpaperUpdating
- && mWallpaper.userId == mCurrentUserId) {
+ if (!mWallpaper.wallpaperUpdating && mWallpaper.userId == mCurrentUserId) {
Slog.w(TAG, "Wallpaper reconnect timed out for " + mWallpaper.wallpaperComponent
+ ", reverting to built-in wallpaper!");
- clearWallpaperLocked(FLAG_SYSTEM, mWallpaper.userId, null);
+ int which = mIsLockscreenLiveWallpaperEnabled ? mWallpaper.mWhich : FLAG_SYSTEM;
+ clearWallpaperLocked(which, mWallpaper.userId, null);
}
}
};
@@ -1189,7 +1189,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
} else {
// Timeout
Slog.w(TAG, "Reverting to built-in wallpaper!");
- clearWallpaperLocked(FLAG_SYSTEM, mWallpaper.userId, null);
+ clearWallpaperLocked(mWallpaper.mWhich, mWallpaper.userId, null);
final String flattened = wpService.flattenToString();
EventLog.writeEvent(EventLogTags.WP_WALLPAPER_CRASHED,
flattened.substring(0, Math.min(flattened.length(),
@@ -1228,7 +1228,8 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
} else {
if (mLmkLimitRebindRetries <= 0) {
Slog.w(TAG, "Reverting to built-in wallpaper due to lmk!");
- clearWallpaperLocked(FLAG_SYSTEM, mWallpaper.userId, null);
+ clearWallpaperLocked(
+ mWallpaper.mWhich, mWallpaper.userId, null);
mLmkLimitRebindRetries = LMK_RECONNECT_REBIND_RETRIES;
return;
}
@@ -1470,8 +1471,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
if (mCurrentUserId != getChangingUserId()) {
return;
}
- WallpaperData wallpaper = mWallpaperMap.get(mCurrentUserId);
- if (wallpaper != null) {
+ for (WallpaperData wallpaper: getWallpapers()) {
final ComponentName wpService = wallpaper.wallpaperComponent;
if (wpService != null && wpService.getPackageName().equals(packageName)) {
if (DEBUG_LIVE) {
@@ -1483,7 +1483,9 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
wallpaper, null)) {
Slog.w(TAG, "Wallpaper " + wpService
+ " no longer available; reverting to default");
- clearWallpaperLocked(FLAG_SYSTEM, wallpaper.userId, null);
+ int which = mIsLockscreenLiveWallpaperEnabled
+ ? wallpaper.mWhich : FLAG_SYSTEM;
+ clearWallpaperLocked(which, wallpaper.userId, null);
}
}
}
@@ -1496,13 +1498,11 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
if (mCurrentUserId != getChangingUserId()) {
return;
}
- WallpaperData wallpaper = mWallpaperMap.get(mCurrentUserId);
- if (wallpaper != null) {
- if (wallpaper.wallpaperComponent == null
- || !wallpaper.wallpaperComponent.getPackageName().equals(packageName)) {
- return;
+ for (WallpaperData wallpaper: getWallpapers()) {
+ if (wallpaper.wallpaperComponent != null
+ && wallpaper.wallpaperComponent.getPackageName().equals(packageName)) {
+ doPackagesChangedLocked(true, wallpaper);
}
- doPackagesChangedLocked(true, wallpaper);
}
}
}
@@ -1513,8 +1513,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
if (mCurrentUserId != getChangingUserId()) {
return;
}
- WallpaperData wallpaper = mWallpaperMap.get(mCurrentUserId);
- if (wallpaper != null) {
+ for (WallpaperData wallpaper: getWallpapers()) {
if (wallpaper.wallpaperComponent != null
&& wallpaper.wallpaperComponent.getPackageName().equals(packageName)) {
if (DEBUG_LIVE) {
@@ -1538,8 +1537,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
if (mCurrentUserId != getChangingUserId()) {
return false;
}
- WallpaperData wallpaper = mWallpaperMap.get(mCurrentUserId);
- if (wallpaper != null) {
+ for (WallpaperData wallpaper: getWallpapers()) {
boolean res = doPackagesChangedLocked(doit, wallpaper);
changed |= res;
}
@@ -1553,8 +1551,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
if (mCurrentUserId != getChangingUserId()) {
return;
}
- WallpaperData wallpaper = mWallpaperMap.get(mCurrentUserId);
- if (wallpaper != null) {
+ for (WallpaperData wallpaper: getWallpapers()) {
doPackagesChangedLocked(true, wallpaper);
}
}
@@ -1562,6 +1559,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
boolean doPackagesChangedLocked(boolean doit, WallpaperData wallpaper) {
boolean changed = false;
+ int which = mIsLockscreenLiveWallpaperEnabled ? wallpaper.mWhich : FLAG_SYSTEM;
if (wallpaper.wallpaperComponent != null) {
int change = isPackageDisappearing(wallpaper.wallpaperComponent
.getPackageName());
@@ -1571,7 +1569,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
if (doit) {
Slog.w(TAG, "Wallpaper uninstalled, removing: "
+ wallpaper.wallpaperComponent);
- clearWallpaperLocked(FLAG_SYSTEM, wallpaper.userId, null);
+ clearWallpaperLocked(which, wallpaper.userId, null);
}
}
}
@@ -1592,7 +1590,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
} catch (NameNotFoundException e) {
Slog.w(TAG, "Wallpaper component gone, removing: "
+ wallpaper.wallpaperComponent);
- clearWallpaperLocked(FLAG_SYSTEM, wallpaper.userId, null);
+ clearWallpaperLocked(which, wallpaper.userId, null);
}
}
if (wallpaper.nextWallpaperComponent != null
@@ -1708,7 +1706,8 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
if (DEBUG) {
Slog.i(TAG, "Unable to regenerate crop; resetting");
}
- clearWallpaperLocked(FLAG_SYSTEM, UserHandle.USER_SYSTEM, null);
+ int which = isLockscreenLiveWallpaperEnabled() ? wallpaper.mWhich : FLAG_SYSTEM;
+ clearWallpaperLocked(which, UserHandle.USER_SYSTEM, null);
}
} else {
if (DEBUG) {
@@ -1988,12 +1987,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
WallpaperData wallpaper, IRemoteCallback reply, ServiceInfo serviceInfo) {
if (serviceInfo == null) {
- if (wallpaper.mWhich == (FLAG_LOCK | FLAG_SYSTEM)) {
- clearWallpaperLocked(FLAG_SYSTEM, wallpaper.userId, null);
- clearWallpaperLocked(FLAG_LOCK, wallpaper.userId, reply);
- } else {
- clearWallpaperLocked(wallpaper.mWhich, wallpaper.userId, reply);
- }
+ clearWallpaperLocked(wallpaper.mWhich, wallpaper.userId, reply);
return;
}
Slog.w(TAG, "Wallpaper isn't direct boot aware; using fallback until unlocked");
@@ -2014,7 +2008,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
@Override
public void clearWallpaper(String callingPackage, int which, int userId) {
- if (DEBUG) Slog.v(TAG, "clearWallpaper");
+ if (DEBUG) Slog.v(TAG, "clearWallpaper: " + which);
checkPermission(android.Manifest.permission.SET_WALLPAPER);
if (!isWallpaperSupported(callingPackage) || !isSetWallpaperAllowed(callingPackage)) {
return;
@@ -2025,7 +2019,8 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
WallpaperData data = null;
synchronized (mLock) {
if (mIsLockscreenLiveWallpaperEnabled) {
- clearWallpaperLocked(callingPackage, which, userId);
+ boolean fromForeground = isFromForegroundApp(callingPackage);
+ clearWallpaperLocked(which, userId, fromForeground, null);
} else {
clearWallpaperLocked(which, userId, null);
}
@@ -2045,7 +2040,8 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
}
}
- private void clearWallpaperLocked(String callingPackage, int which, int userId) {
+ private void clearWallpaperLocked(int which, int userId, boolean fromForeground,
+ IRemoteCallback reply) {
// Might need to bring it in the first time to establish our rewrite
if (!mWallpaperMap.contains(userId)) {
@@ -2084,8 +2080,10 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
finalWhich = which;
}
- boolean success = withCleanCallingIdentity(() -> setWallpaperComponent(
- component, callingPackage, finalWhich, userId));
+ // except for the lock case (for which we keep the system wallpaper as-is), force rebind
+ boolean force = which != FLAG_LOCK;
+ boolean success = withCleanCallingIdentity(() -> setWallpaperComponentInternal(
+ component, finalWhich, userId, force, fromForeground, reply));
if (success) return;
} catch (IllegalArgumentException e1) {
e = e1;
@@ -2097,10 +2095,23 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
// wallpaper.
Slog.e(TAG, "Default wallpaper component not found!", e);
withCleanCallingIdentity(() -> clearWallpaperComponentLocked(wallpaper));
+ if (reply != null) {
+ try {
+ reply.sendResult(null);
+ } catch (RemoteException e1) {
+ Slog.w(TAG, "Failed to notify callback after wallpaper clear", e1);
+ }
+ }
}
- // TODO(b/266818039) remove this version of the method
+ // TODO(b/266818039) remove
private void clearWallpaperLocked(int which, int userId, IRemoteCallback reply) {
+
+ if (mIsLockscreenLiveWallpaperEnabled) {
+ clearWallpaperLocked(which, userId, false, reply);
+ return;
+ }
+
if (which != FLAG_SYSTEM && which != FLAG_LOCK) {
throw new IllegalArgumentException("Must specify exactly one kind of wallpaper to clear");
}
@@ -2815,6 +2826,18 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
: new WallpaperData[0];
}
+ // TODO(b/266818039) remove
+ private WallpaperData[] getWallpapers() {
+ WallpaperData systemWallpaper = mWallpaperMap.get(mCurrentUserId);
+ WallpaperData lockWallpaper = mLockWallpaperMap.get(mCurrentUserId);
+ boolean systemValid = systemWallpaper != null;
+ boolean lockValid = lockWallpaper != null && !isLockscreenLiveWallpaperEnabled();
+ return systemValid && lockValid ? new WallpaperData[]{systemWallpaper, lockWallpaper}
+ : systemValid ? new WallpaperData[]{systemWallpaper}
+ : lockValid ? new WallpaperData[]{lockWallpaper}
+ : new WallpaperData[0];
+ }
+
private IWallpaperEngine getEngine(int which, int userId, int displayId) {
WallpaperData wallpaperData = findWallpaperAtDisplay(userId, displayId);
if (wallpaperData == null) return null;
@@ -3272,15 +3295,16 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
boolean setWallpaperComponent(ComponentName name, String callingPackage,
@SetWallpaperFlags int which, int userId) {
if (mIsLockscreenLiveWallpaperEnabled) {
- return setWallpaperComponentInternal(name, callingPackage, which, userId);
+ boolean fromForeground = isFromForegroundApp(callingPackage);
+ return setWallpaperComponentInternal(name, which, userId, false, fromForeground, null);
} else {
setWallpaperComponentInternalLegacy(name, callingPackage, which, userId);
return true;
}
}
- private boolean setWallpaperComponentInternal(ComponentName name, String callingPackage,
- @SetWallpaperFlags int which, int userIdIn) {
+ private boolean setWallpaperComponentInternal(ComponentName name, @SetWallpaperFlags int which,
+ int userIdIn, boolean force, boolean fromForeground, IRemoteCallback reply) {
if (DEBUG) {
Slog.v(TAG, "Setting new live wallpaper: which=" + which + ", component: " + name);
}
@@ -3294,7 +3318,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
final WallpaperData newWallpaper;
synchronized (mLock) {
- Slog.v(TAG, "setWallpaperComponent name=" + name);
+ Slog.v(TAG, "setWallpaperComponent name=" + name + ", which = " + which);
final WallpaperData originalSystemWallpaper = mWallpaperMap.get(userId);
if (originalSystemWallpaper == null) {
throw new IllegalStateException("Wallpaper not yet initialized for user " + userId);
@@ -3317,29 +3341,21 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
newWallpaper.imageWallpaperPending = false;
newWallpaper.mWhich = which;
newWallpaper.mSystemWasBoth = systemIsBoth;
- newWallpaper.fromForegroundApp = isFromForegroundApp(callingPackage);
+ newWallpaper.fromForegroundApp = fromForeground;
final WallpaperDestinationChangeHandler
liveSync = new WallpaperDestinationChangeHandler(
newWallpaper);
boolean same = changingToSame(name, newWallpaper);
- IRemoteCallback.Stub callback = new IRemoteCallback.Stub() {
- @Override
- public void sendResult(Bundle data) throws RemoteException {
- if (DEBUG) {
- Slog.d(TAG, "publish system wallpaper changed!");
- }
- }
- };
/*
* If we have a shared system+lock wallpaper, and we reapply the same wallpaper
* to system only, force rebind: the current wallpaper will be migrated to lock
* and a new engine with the same wallpaper will be applied to system.
*/
- boolean forceRebind = same && systemIsBoth && which == FLAG_SYSTEM;
+ boolean forceRebind = force || (same && systemIsBoth && which == FLAG_SYSTEM);
bindSuccess = bindWallpaperComponentLocked(name, /* force */
- forceRebind, /* fromUser */ true, newWallpaper, callback);
+ forceRebind, /* fromUser */ true, newWallpaper, reply);
if (bindSuccess) {
if (!same) {
newWallpaper.primaryColors = null;
@@ -3409,7 +3425,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
WallpaperData wallpaper;
synchronized (mLock) {
- Slog.v(TAG, "setWallpaperComponent name=" + name + ", which=" + which);
+ Slog.v(TAG, "setWallpaperComponentLegacy name=" + name + ", which=" + which);
wallpaper = mWallpaperMap.get(userId);
if (wallpaper == null) {
throw new IllegalStateException("Wallpaper not yet initialized for user " + userId);
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index daa73db4684d..996d66681d05 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -6505,14 +6505,6 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
}
/**
- * @return whether AOD is showing on this display
- */
- boolean isAodShowing() {
- return mRootWindowContainer.mTaskSupervisor
- .getKeyguardController().isAodShowing(mDisplayId);
- }
-
- /**
* @return whether this display maintains its own focus and touch mode.
*/
boolean hasOwnFocus() {
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index 395ab3a641b4..17bfeb453304 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -1677,18 +1677,6 @@ public class DisplayPolicy {
}
private boolean shouldBeHiddenByKeyguard(WindowState win, WindowState imeTarget) {
- // If AOD is showing, the IME should be hidden. However, sometimes the AOD is considered
- // hidden because it's in the process of hiding, but it's still being shown on screen.
- // In that case, we want to continue hiding the IME until the windows have completed
- // drawing. This way, we know that the IME can be safely shown since the other windows are
- // now shown.
- final boolean hideIme = win.mIsImWindow
- && (mDisplayContent.isAodShowing()
- || (mDisplayContent.isDefaultDisplay && !mWindowManagerDrawComplete));
- if (hideIme) {
- return true;
- }
-
if (!mDisplayContent.isDefaultDisplay || !isKeyguardShowing()) {
return false;
}
diff --git a/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java b/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java
index a27cc3ad9973..ea722b61be6f 100644
--- a/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java
+++ b/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java
@@ -184,14 +184,31 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
}
void dispose() {
+ boolean wasVisible = false;
for (int i = mOrganizedTaskFragments.size() - 1; i >= 0; i--) {
+ final TaskFragment taskFragment = mOrganizedTaskFragments.get(i);
+ if (taskFragment.isVisibleRequested()) {
+ wasVisible = true;
+ }
// Cleanup the TaskFragmentOrganizer from all TaskFragments it organized before
// removing the windows to prevent it from adding any additional TaskFragment
// pending event.
- final TaskFragment taskFragment = mOrganizedTaskFragments.get(i);
taskFragment.onTaskFragmentOrganizerRemoved();
}
+ final TransitionController transitionController = mAtmService.getTransitionController();
+ if (wasVisible && transitionController.isShellTransitionsEnabled()
+ && !transitionController.isCollecting()) {
+ final Task task = mOrganizedTaskFragments.get(0).getTask();
+ final boolean containsNonEmbeddedActivity =
+ task != null && task.getActivity(a -> !a.isEmbedded()) != null;
+ transitionController.requestStartTransition(
+ transitionController.createTransition(WindowManager.TRANSIT_CLOSE),
+ // The task will be removed if all its activities are embedded, then the
+ // task is the trigger.
+ containsNonEmbeddedActivity ? null : task,
+ null /* remoteTransition */, null /* displayChange */);
+ }
// Defer to avoid unnecessary layout when there are multiple TaskFragments removal.
mAtmService.deferWindowLayout();
try {
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/AuthSessionTest.java b/services/tests/servicestests/src/com/android/server/biometrics/AuthSessionTest.java
index 769be177ce03..0f3daec263e0 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/AuthSessionTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/AuthSessionTest.java
@@ -182,7 +182,8 @@ public class AuthSessionTest {
eq(TEST_PACKAGE),
eq(TEST_REQUEST_ID),
eq(sensor.getCookie()),
- anyBoolean() /* allowBackgroundAuthentication */);
+ anyBoolean() /* allowBackgroundAuthentication */,
+ anyBoolean() /* isForLegacyFingerprintManager */);
}
final int cookie1 = session.mPreAuthInfo.eligibleSensors.get(0).getCookie();
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java b/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java
index e79ac0986dc8..0230d77e8e14 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java
@@ -598,7 +598,8 @@ public class BiometricServiceTest {
anyString() /* opPackageName */,
eq(TEST_REQUEST_ID),
cookieCaptor.capture() /* cookie */,
- anyBoolean() /* allowBackgroundAuthentication */);
+ anyBoolean() /* allowBackgroundAuthentication */,
+ anyBoolean() /* isForLegacyFingerprintManager */);
// onReadyForAuthentication, mAuthSession state OK
mBiometricService.mImpl.onReadyForAuthentication(TEST_REQUEST_ID, cookieCaptor.getValue());
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClientTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClientTest.java
index 046b01c831b5..9e5a0479ea70 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClientTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClientTest.java
@@ -36,6 +36,7 @@ import static org.mockito.Mockito.when;
import android.app.ActivityManager;
import android.app.ActivityTaskManager;
import android.content.ComponentName;
+import android.hardware.biometrics.BiometricManager;
import android.hardware.biometrics.common.AuthenticateReason;
import android.hardware.biometrics.common.ICancellationSignal;
import android.hardware.biometrics.common.OperationContext;
@@ -109,6 +110,8 @@ public class FaceAuthenticationClientTest {
private ICancellationSignal mCancellationSignal;
@Mock
private AuthSessionCoordinator mAuthSessionCoordinator;
+ @Mock
+ private BiometricManager mBiometricManager;
@Captor
private ArgumentCaptor<OperationContextExt> mOperationContextCaptor;
@Captor
@@ -119,6 +122,7 @@ public class FaceAuthenticationClientTest {
@Before
public void setup() {
+ mContext.addMockSystemService(BiometricManager.class, mBiometricManager);
when(mBiometricContext.updateContext(any(), anyBoolean())).thenAnswer(
i -> i.getArgument(0));
when(mBiometricContext.getAuthSessionCoordinator()).thenReturn(mAuthSessionCoordinator);
@@ -212,11 +216,44 @@ public class FaceAuthenticationClientTest {
.onError(anyInt(), anyInt(), eq(BIOMETRIC_ERROR_CANCELED), anyInt());
}
+ @Test
+ public void testOnAuthenticatedFalseWhenListenerIsNull() throws RemoteException {
+ final FaceAuthenticationClient client = createClientWithNullListener();
+ client.start(mCallback);
+ client.onAuthenticated(new Face("friendly", 1 /* faceId */, 2 /* deviceId */),
+ false /* authenticated */, new ArrayList<>());
+
+ verify(mCallback).onClientFinished(client, true);
+ }
+
+ @Test
+ public void testOnAuthenticatedTrueWhenListenerIsNull() throws RemoteException {
+ final FaceAuthenticationClient client = createClientWithNullListener();
+ client.start(mCallback);
+ client.onAuthenticated(new Face("friendly", 1 /* faceId */, 2 /* deviceId */),
+ true /* authenticated */, new ArrayList<>());
+
+ verify(mCallback).onClientFinished(client, true);
+ }
+
private FaceAuthenticationClient createClient() throws RemoteException {
- return createClient(2 /* version */);
+ return createClient(2 /* version */, mClientMonitorCallbackConverter,
+ false /* allowBackgroundAuthentication */);
+ }
+
+ private FaceAuthenticationClient createClientWithNullListener() throws RemoteException {
+ return createClient(2 /* version */, null /* listener */,
+ true /* allowBackgroundAuthentication */);
}
private FaceAuthenticationClient createClient(int version) throws RemoteException {
+ return createClient(version, mClientMonitorCallbackConverter,
+ false /* allowBackgroundAuthentication */);
+ }
+
+ private FaceAuthenticationClient createClient(int version,
+ ClientMonitorCallbackConverter listener,
+ boolean allowBackgroundAuthentication) throws RemoteException {
when(mHal.getInterfaceVersion()).thenReturn(version);
final AidlSession aidl = new AidlSession(version, mHal, USER_ID, mHalSessionCallback);
@@ -229,11 +266,11 @@ public class FaceAuthenticationClientTest {
FaceAuthenticateOptions.AUTHENTICATE_REASON_ASSISTANT_VISIBLE)
.build();
return new FaceAuthenticationClient(mContext, () -> aidl, mToken,
- 2 /* requestId */, mClientMonitorCallbackConverter, OP_ID,
+ 2 /* requestId */, listener, OP_ID,
false /* restricted */, options, 4 /* cookie */,
false /* requireConfirmation */,
mBiometricLogger, mBiometricContext, true /* isStrongBiometric */,
- mUsageStats, null /* mLockoutCache */, false /* allowBackgroundAuthentication */,
+ mUsageStats, null /* mLockoutCache */, allowBackgroundAuthentication,
null /* sensorPrivacyManager */, 0 /* biometricStrength */) {
@Override
protected ActivityTaskManager getActivityTaskManager() {
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClientTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClientTest.java
index 46af90537c03..8a11e31014d5 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClientTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClientTest.java
@@ -392,7 +392,6 @@ public class FingerprintAuthenticationClientTest {
final ActivityManager.RunningTaskInfo topTask = new ActivityManager.RunningTaskInfo();
topTask.topActivity = new ComponentName("other", "thing");
when(mActivityTaskManager.getTasks(anyInt())).thenReturn(List.of(topTask));
- when(mHal.authenticateWithContext(anyLong(), any())).thenReturn(mCancellationSignal);
final FingerprintAuthenticationClient client = createClientWithoutBackgroundAuth();
client.start(mCallback);
@@ -406,21 +405,50 @@ public class FingerprintAuthenticationClientTest {
.onError(anyInt(), anyInt(), eq(BIOMETRIC_ERROR_CANCELED), anyInt());
}
+ @Test
+ public void testOnAuthenticatedFalseWhenListenerIsNull() throws RemoteException {
+ final FingerprintAuthenticationClient client = createClientWithNullListener();
+ client.start(mCallback);
+ client.onAuthenticated(new Fingerprint("friendly", 1 /* fingerId */,
+ 2 /* deviceId */), false /* authenticated */, new ArrayList<>());
+
+ verify(mCallback, never()).onClientFinished(eq(client), anyBoolean());
+ }
+
+ @Test
+ public void testOnAuthenticatedTrueWhenListenerIsNull() throws RemoteException {
+ final FingerprintAuthenticationClient client = createClientWithNullListener();
+ client.start(mCallback);
+ client.onAuthenticated(new Fingerprint("friendly", 1 /* fingerId */,
+ 2 /* deviceId */), true /* authenticated */, new ArrayList<>());
+
+ verify(mCallback).onClientFinished(client, true);
+ }
+
private FingerprintAuthenticationClient createClient() throws RemoteException {
- return createClient(100 /* version */, true /* allowBackgroundAuthentication */);
+ return createClient(100 /* version */, true /* allowBackgroundAuthentication */,
+ mClientMonitorCallbackConverter);
}
private FingerprintAuthenticationClient createClientWithoutBackgroundAuth()
throws RemoteException {
- return createClient(100 /* version */, false /* allowBackgroundAuthentication */);
+ return createClient(100 /* version */, false /* allowBackgroundAuthentication */,
+ mClientMonitorCallbackConverter);
}
private FingerprintAuthenticationClient createClient(int version) throws RemoteException {
- return createClient(version, true /* allowBackgroundAuthentication */);
+ return createClient(version, true /* allowBackgroundAuthentication */,
+ mClientMonitorCallbackConverter);
+ }
+
+ private FingerprintAuthenticationClient createClientWithNullListener() throws RemoteException {
+ return createClient(100 /* version */, true /* allowBackgroundAuthentication */,
+ null /* listener */);
}
private FingerprintAuthenticationClient createClient(int version,
- boolean allowBackgroundAuthentication) throws RemoteException {
+ boolean allowBackgroundAuthentication, ClientMonitorCallbackConverter listener)
+ throws RemoteException {
when(mHal.getInterfaceVersion()).thenReturn(version);
final AidlSession aidl = new AidlSession(version, mHal, USER_ID, mHalSessionCallback);
@@ -430,7 +458,7 @@ public class FingerprintAuthenticationClientTest {
.setSensorId(9)
.build();
return new FingerprintAuthenticationClient(mContext, () -> aidl, mToken,
- REQUEST_ID, mClientMonitorCallbackConverter, OP_ID,
+ REQUEST_ID, listener, OP_ID,
false /* restricted */, options, 4 /* cookie */,
false /* requireConfirmation */,
mBiometricLogger, mBiometricContext,
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java
index 5341588c3992..72c3ebece242 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java
@@ -237,26 +237,27 @@ public class ActivityTaskManagerServiceTests extends WindowTestsBase {
displayInfo.copyFrom(mDisplayInfo);
displayInfo.type = Display.TYPE_VIRTUAL;
DisplayContent virtualDisplay = createNewDisplay(displayInfo);
+ final KeyguardController keyguardController = mSupervisor.getKeyguardController();
// Make sure we're starting out with 2 unlocked displays
assertEquals(2, mRootWindowContainer.getChildCount());
mRootWindowContainer.forAllDisplays(displayContent -> {
assertFalse(displayContent.isKeyguardLocked());
- assertFalse(displayContent.isAodShowing());
+ assertFalse(keyguardController.isAodShowing(displayContent.mDisplayId));
});
// Check that setLockScreenShown locks both displays
mAtm.setLockScreenShown(true, true);
mRootWindowContainer.forAllDisplays(displayContent -> {
assertTrue(displayContent.isKeyguardLocked());
- assertTrue(displayContent.isAodShowing());
+ assertTrue(keyguardController.isAodShowing(displayContent.mDisplayId));
});
// Check setLockScreenShown unlocking both displays
mAtm.setLockScreenShown(false, false);
mRootWindowContainer.forAllDisplays(displayContent -> {
assertFalse(displayContent.isKeyguardLocked());
- assertFalse(displayContent.isAodShowing());
+ assertFalse(keyguardController.isAodShowing(displayContent.mDisplayId));
});
}
@@ -270,25 +271,26 @@ public class ActivityTaskManagerServiceTests extends WindowTestsBase {
displayInfo.displayGroupId = Display.DEFAULT_DISPLAY_GROUP + 1;
displayInfo.flags = Display.FLAG_OWN_DISPLAY_GROUP | Display.FLAG_ALWAYS_UNLOCKED;
DisplayContent newDisplay = createNewDisplay(displayInfo);
+ final KeyguardController keyguardController = mSupervisor.getKeyguardController();
// Make sure we're starting out with 2 unlocked displays
assertEquals(2, mRootWindowContainer.getChildCount());
mRootWindowContainer.forAllDisplays(displayContent -> {
assertFalse(displayContent.isKeyguardLocked());
- assertFalse(displayContent.isAodShowing());
+ assertFalse(keyguardController.isAodShowing(displayContent.mDisplayId));
});
// setLockScreenShown should only lock the default display, not the virtual one
mAtm.setLockScreenShown(true, true);
assertTrue(mDefaultDisplay.isKeyguardLocked());
- assertTrue(mDefaultDisplay.isAodShowing());
+ assertTrue(keyguardController.isAodShowing(mDefaultDisplay.mDisplayId));
DisplayContent virtualDisplay = mRootWindowContainer.getDisplayContent(
newDisplay.getDisplayId());
assertNotEquals(Display.DEFAULT_DISPLAY, virtualDisplay.getDisplayId());
assertFalse(virtualDisplay.isKeyguardLocked());
- assertFalse(virtualDisplay.isAodShowing());
+ assertFalse(keyguardController.isAodShowing(virtualDisplay.mDisplayId));
}
/*