summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/content/pm/PackageManager.java18
-rw-r--r--core/java/android/provider/CallLog.java6
-rw-r--r--core/java/android/widget/Editor.java42
-rw-r--r--data/etc/com.android.systemui.xml1
-rw-r--r--libs/WindowManager/Shell/Android.bp1
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/animation/FlingAnimationUtils.java37
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java10
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragPositioningCallback.java7
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/FluidResizeTaskPositioner.java6
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositioner.java6
-rw-r--r--packages/SystemUI/Android.bp2
-rw-r--r--packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/shaders/SolidColorShader.kt36
-rw-r--r--packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/shaders/SparkleShader.kt115
-rw-r--r--packages/SystemUI/compose/facade/disabled/src/com/android/systemui/scene/ui/composable/SceneModule.kt4
-rw-r--r--packages/SystemUI/compose/facade/enabled/src/com/android/systemui/scene/ui/composable/SceneModule.kt91
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerScene.kt20
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenScene.kt12
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt12
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/ComposableScene.kt2
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/GoneScene.kt10
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainer.kt6
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt12
-rw-r--r--packages/SystemUI/res-keyguard/layout/keyguard_pin_view.xml200
-rw-r--r--packages/SystemUI/res-keyguard/layout/keyguard_pin_view_portrait.xml218
-rw-r--r--packages/SystemUI/res/layout/media_projection_app_selector.xml6
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java3
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardSecurityViewFlipperController.java25
-rw-r--r--packages/SystemUI/src/com/android/systemui/ExpandHelper.java12
-rw-r--r--packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractor.kt21
-rw-r--r--packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModel.kt20
-rw-r--r--packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamModule.java13
-rw-r--r--packages/SystemUI/src/com/android/systemui/flags/Flags.kt9
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepository.kt29
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/data/repository/NoopDeviceEntryFaceAuthRepository.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/LockscreenSceneInteractor.kt23
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/SystemUIKeyguardFaceAuthInteractor.kt26
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModel.kt20
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaProjectionAppSelectorActivity.kt49
-rw-r--r--packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionBlockerEmptyStateProvider.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModel.kt21
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/scene/SceneContainerFrameworkModule.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/scene/data/repository/SceneContainerRepository.kt118
-rw-r--r--packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneInteractor.kt44
-rw-r--r--packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt (renamed from packages/SystemUI/src/com/android/systemui/scene/domain/startable/SystemUiDefaultSceneContainerStartable.kt)25
-rw-r--r--packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartableModule.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/scene/shared/model/Scene.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/scene/shared/model/SceneContainerConfig.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/scene/shared/model/SceneContainerConfigModule.kt43
-rw-r--r--packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModel.kt20
-rw-r--r--packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModelModule.kt40
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/ShadeViewProviderModule.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModel.kt27
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationMemoryModule.kt33
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerImpl.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryMonitor.kt5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java15
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/touch/TouchInsetManager.java7
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.kt30
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityViewFlipperControllerTest.java5
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/ExpandHelperTest.java7
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorTest.kt45
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModelTest.kt40
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModelTest.kt40
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModelTest.kt80
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt10
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardFaceAuthInteractorTest.kt38
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/LockscreenSceneInteractorTest.kt19
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt31
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModelTest.kt27
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/scene/data/repository/SceneContainerRepositoryTest.kt121
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt26
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/scene/domain/startable/SystemUiDefaultSceneContainerStartableTest.kt)126
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModelTest.kt5
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt28
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/events/SystemEventChipAnimationControllerTest.kt3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java44
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/shaders/SolidColorShaderTest.kt (renamed from packages/SystemUI/src/com/android/systemui/scene/shared/model/SceneContainerNames.kt)18
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/shaders/SparkleShaderTest.kt44
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java13
-rw-r--r--packages/SystemUI/tests/utils/src/androidx/core/animation/AndroidXAnimatorIsolationRule.kt55
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestCase.java8
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeDeviceEntryFaceAuthRepository.kt13
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/scene/SceneTestUtils.kt31
-rw-r--r--services/core/java/com/android/server/pm/InstallPackageHelper.java28
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java3
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerServiceInjector.java10
-rw-r--r--services/core/java/com/android/server/pm/RemovePackageHelper.java1
-rw-r--r--services/core/java/com/android/server/pm/UpdateOwnershipHelper.java185
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt2
-rw-r--r--services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionManagerServiceTest.java2
-rw-r--r--services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java2
96 files changed, 1442 insertions, 1271 deletions
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 9933c8be6015..54fb4e72a79c 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -234,6 +234,24 @@ public abstract class PackageManager {
"android.camera.PROPERTY_COMPAT_OVERRIDE_LANDSCAPE_TO_PORTRAIT";
/**
+ * Application level {@link android.content.pm.PackageManager.Property PackageManager
+ * .Property} for a privileged system installer to define a list of up to 500 packages that
+ * should not have their updates owned by any installer. The list must be provided via a default
+ * XML resource with the following format:
+ *
+ * <pre>
+ * &lt;deny-ownership&gt;PACKAGE_NAME&lt;/deny-ownership&gt;
+ * &lt;deny-ownership&gt;PACKAGE_NAME&lt;/deny-ownership&gt;
+ * </pre>
+ *
+ * <b>NOTE:</b> Installers that provide this property will not granted update ownership for any
+ * packages that they request update ownership of.
+ * @hide
+ */
+ public static final String PROPERTY_LEGACY_UPDATE_OWNERSHIP_DENYLIST =
+ "android.app.PROPERTY_LEGACY_UPDATE_OWNERSHIP_DENYLIST";
+
+ /**
* A property value set within the manifest.
* <p>
* The value of a property will only have a single type, as defined by
diff --git a/core/java/android/provider/CallLog.java b/core/java/android/provider/CallLog.java
index 3c5757dd5615..5d6dfc760b02 100644
--- a/core/java/android/provider/CallLog.java
+++ b/core/java/android/provider/CallLog.java
@@ -63,6 +63,7 @@ import java.io.InputStream;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.List;
+import java.util.Locale;
import java.util.Objects;
import java.util.concurrent.Executor;
@@ -1956,9 +1957,8 @@ public class CallLog {
userManager.isUserUnlocked(user) ? CONTENT_URI : SHADOW_CONTENT_URI,
user.getIdentifier());
- if (VERBOSE_LOG) {
- Log.v(LOG_TAG, String.format("Inserting to %s", uri));
- }
+ Log.i(LOG_TAG, String.format(Locale.getDefault(),
+ "addEntryAndRemoveExpiredEntries: provider uri=%s", uri));
try {
// When cleaning up the call log, try to delete older call long entries on a per
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 3da9e96618f3..f39122a0a5c1 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -8207,7 +8207,8 @@ public class Editor {
*/
void beforeSetText() {
// TextView#setText is called because our call to
- // TextView#setTransformationMethodInternal in enterInsertMode() or exitInsertMode().
+ // TextView#setTransformationMethodInternal in enterInsertMode(), exitInsertMode() or
+ // updateTransformationMethod().
// Do nothing in this case.
if (mUpdatingTransformationMethod) {
return;
@@ -8218,22 +8219,28 @@ public class Editor {
}
/**
- * Notify the {@link InsertModeController} before the TextView's
- * {@link TransformationMethod} is updated. If it's not in the insert mode,
- * the given method is directly returned. Otherwise, it will wrap the given transformation
- * method with an {@link InsertModeTransformationMethod} and then return.
+ * Notify the {@link InsertModeController} that TextView#setTransformationMethod is called.
+ * If it's not in the insert mode, the given transformation method is directly set to the
+ * TextView. Otherwise, it will wrap the given transformation method with an
+ * {@link InsertModeTransformationMethod} and then set it on the TextView.
*
- * @param oldTransformationMethod the new {@link TransformationMethod} to be set on the
+ * @param transformationMethod the new {@link TransformationMethod} to be set on the
* TextView.
- * @return the updated {@link TransformationMethod} to be set on the Textview.
*/
- TransformationMethod updateTransformationMethod(
- TransformationMethod oldTransformationMethod) {
- if (!mIsInsertModeActive) return oldTransformationMethod;
+ void updateTransformationMethod(TransformationMethod transformationMethod) {
+ if (!mIsInsertModeActive) {
+ setTransformationMethod(transformationMethod, /* updateText */ true);
+ return;
+ }
+ // Changing TransformationMethod will reset selection range to [0, 0), we need to
+ // manually restore the old selection range.
+ final int selectionStart = mTextView.getSelectionStart();
+ final int selectionEnd = mTextView.getSelectionEnd();
mInsertModeTransformationMethod = mInsertModeTransformationMethod.update(
- oldTransformationMethod, mTextView.isSingleLine());
- return mInsertModeTransformationMethod;
+ transformationMethod, mTextView.isSingleLine());
+ setTransformationMethod(mInsertModeTransformationMethod, /* updateText */ true);
+ Selection.setSelection((Spannable) mTextView.getText(), selectionStart, selectionEnd);
}
}
@@ -8259,18 +8266,11 @@ public class Editor {
* @param method the {@link TransformationMethod} to be set on the TextView.
*/
void setTransformationMethod(TransformationMethod method) {
- if (mInsertModeController == null || !mInsertModeController.mIsInsertModeActive) {
+ if (mInsertModeController == null) {
mTextView.setTransformationMethodInternal(method, /* updateText */ true);
return;
}
-
- // Changing TransformationMethod will reset selection range to [0, 0), we need to
- // manually restore the old selection range.
- final int selectionStart = mTextView.getSelectionStart();
- final int selectionEnd = mTextView.getSelectionEnd();
- method = mInsertModeController.updateTransformationMethod(method);
- mTextView.setTransformationMethodInternal(method, /* updateText */ true);
- Selection.setSelection((Spannable) mTextView.getText(), selectionStart, selectionEnd);
+ mInsertModeController.updateTransformationMethod(method);
}
/**
diff --git a/data/etc/com.android.systemui.xml b/data/etc/com.android.systemui.xml
index 43683ffad432..c6a9033210e3 100644
--- a/data/etc/com.android.systemui.xml
+++ b/data/etc/com.android.systemui.xml
@@ -87,5 +87,6 @@
<permission name="android.permission.SET_UNRESTRICTED_KEEP_CLEAR_AREAS" />
<permission name="android.permission.READ_SEARCH_INDEXABLES" />
<permission name="android.permission.ACCESS_AMBIENT_CONTEXT_EVENT"/>
+ <permission name="android.permission.QUERY_CLONED_APPS"/>
</privapp-permissions>
</permissions>
diff --git a/libs/WindowManager/Shell/Android.bp b/libs/WindowManager/Shell/Android.bp
index 71598938f42f..603272e3df1d 100644
--- a/libs/WindowManager/Shell/Android.bp
+++ b/libs/WindowManager/Shell/Android.bp
@@ -151,6 +151,7 @@ android_library {
],
static_libs: [
"androidx.appcompat_appcompat",
+ "androidx.core_core-animation",
"androidx.arch.core_core-runtime",
"androidx-constraintlayout_constraintlayout",
"androidx.dynamicanimation_dynamicanimation",
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/animation/FlingAnimationUtils.java b/libs/WindowManager/Shell/src/com/android/wm/shell/animation/FlingAnimationUtils.java
index 798250de89d0..26edd7d2268b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/animation/FlingAnimationUtils.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/animation/FlingAnimationUtils.java
@@ -117,6 +117,20 @@ public class FlingAnimationUtils {
* @param endValue the end value of the animator
* @param velocity the current velocity of the motion
*/
+ public void apply(androidx.core.animation.Animator animator,
+ float currValue, float endValue, float velocity) {
+ apply(animator, currValue, endValue, velocity, Math.abs(endValue - currValue));
+ }
+
+ /**
+ * Applies the interpolator and length to the animator, such that the fling animation is
+ * consistent with the finger motion.
+ *
+ * @param animator the animator to apply
+ * @param currValue the current value
+ * @param endValue the end value of the animator
+ * @param velocity the current velocity of the motion
+ */
public void apply(ViewPropertyAnimator animator, float currValue, float endValue,
float velocity) {
apply(animator, currValue, endValue, velocity, Math.abs(endValue - currValue));
@@ -152,6 +166,24 @@ public class FlingAnimationUtils {
* @param maxDistance the maximum distance for this interaction; the maximum animation length
* gets multiplied by the ratio between the actual distance and this value
*/
+ public void apply(androidx.core.animation.Animator animator,
+ float currValue, float endValue, float velocity, float maxDistance) {
+ AnimatorProperties properties = getProperties(currValue, endValue, velocity, maxDistance);
+ animator.setDuration(properties.mDuration);
+ animator.setInterpolator(properties.getInterpolator());
+ }
+
+ /**
+ * Applies the interpolator and length to the animator, such that the fling animation is
+ * consistent with the finger motion.
+ *
+ * @param animator the animator to apply
+ * @param currValue the current value
+ * @param endValue the end value of the animator
+ * @param velocity the current velocity of the motion
+ * @param maxDistance the maximum distance for this interaction; the maximum animation length
+ * gets multiplied by the ratio between the actual distance and this value
+ */
public void apply(ViewPropertyAnimator animator, float currValue, float endValue,
float velocity, float maxDistance) {
AnimatorProperties properties = getProperties(currValue, endValue, velocity,
@@ -367,6 +399,11 @@ public class FlingAnimationUtils {
private static class AnimatorProperties {
Interpolator mInterpolator;
long mDuration;
+
+ /** Get an AndroidX interpolator wrapper of the current mInterpolator */
+ public androidx.core.animation.Interpolator getInterpolator() {
+ return mInterpolator::getInterpolation;
+ }
}
/** Builder for {@link #FlingAnimationUtils}. */
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
index f8d7b6bc3aad..9bc28a4626c4 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
@@ -730,7 +730,7 @@ class DesktopTasksController(
*
* @param taskInfo the task being dragged.
* @param position position of surface when drag ends.
- * @param y the Y position of the motion event.
+ * @param y the Y position of the top edge of the task
* @param windowDecor the window decoration for the task being dragged
*/
fun onDragPositioningEnd(
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 2d7e6a602f2f..ea9976da3229 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
@@ -429,10 +429,10 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
mDragPointerId = e.getPointerId(0);
}
final int dragPointerIdx = e.findPointerIndex(mDragPointerId);
- mDesktopTasksController.ifPresent(c -> c.onDragPositioningMove(taskInfo,
- decoration.mTaskSurface, e.getRawY(dragPointerIdx)));
- mDragPositioningCallback.onDragPositioningMove(
+ final Rect newTaskBounds = mDragPositioningCallback.onDragPositioningMove(
e.getRawX(dragPointerIdx), e.getRawY(dragPointerIdx));
+ mDesktopTasksController.ifPresent(c -> c.onDragPositioningMove(taskInfo,
+ decoration.mTaskSurface, newTaskBounds.top));
mIsDragging = true;
mShouldClick = false;
return true;
@@ -458,10 +458,10 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
final Point position = new Point(
(int) (e.getRawX(dragPointerIdx) - e.getX(dragPointerIdx)),
(int) (e.getRawY(dragPointerIdx) - e.getY(dragPointerIdx)));
- mDragPositioningCallback.onDragPositioningEnd(
+ final Rect newTaskBounds = mDragPositioningCallback.onDragPositioningEnd(
e.getRawX(dragPointerIdx), e.getRawY(dragPointerIdx));
mDesktopTasksController.ifPresent(c -> c.onDragPositioningEnd(taskInfo,
- position, e.getRawY(), mWindowDecorByTaskId.get(mTaskId)));
+ position, newTaskBounds.top, mWindowDecorByTaskId.get(mTaskId)));
mIsDragging = false;
return true;
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragPositioningCallback.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragPositioningCallback.java
index 941617de3aec..1669cf4a222c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragPositioningCallback.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragPositioningCallback.java
@@ -17,6 +17,7 @@
package com.android.wm.shell.windowdecor;
import android.annotation.IntDef;
+import android.graphics.Rect;
/**
* Callback called when receiving drag-resize or drag-move related input events.
@@ -46,13 +47,15 @@ public interface DragPositioningCallback {
* Called when the pointer moves during a drag-resize or drag-move.
* @param x x coordinate in window decoration coordinate system of the new pointer location
* @param y y coordinate in window decoration coordinate system of the new pointer location
+ * @return the updated task bounds
*/
- void onDragPositioningMove(float x, float y);
+ Rect onDragPositioningMove(float x, float y);
/**
* Called when a drag-resize or drag-move stops.
* @param x x coordinate in window decoration coordinate system where the drag resize stops
* @param y y coordinate in window decoration coordinate system where the drag resize stops
+ * @return the final bounds for the dragged task
*/
- void onDragPositioningEnd(float x, float y);
+ Rect onDragPositioningEnd(float x, float y);
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/FluidResizeTaskPositioner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/FluidResizeTaskPositioner.java
index e1b6db595975..e0ee25242550 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/FluidResizeTaskPositioner.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/FluidResizeTaskPositioner.java
@@ -85,7 +85,7 @@ class FluidResizeTaskPositioner implements DragPositioningCallback {
}
@Override
- public void onDragPositioningMove(float x, float y) {
+ public Rect onDragPositioningMove(float x, float y) {
final WindowContainerTransaction wct = new WindowContainerTransaction();
PointF delta = DragPositioningCallbackUtility.calculateDelta(x, y, mRepositionStartPoint);
if (isResizing() && DragPositioningCallbackUtility.changeBounds(mCtrlType,
@@ -106,10 +106,11 @@ class FluidResizeTaskPositioner implements DragPositioningCallback {
mRepositionTaskBounds, mTaskBoundsAtDragStart, mRepositionStartPoint, t, x, y);
t.apply();
}
+ return new Rect(mRepositionTaskBounds);
}
@Override
- public void onDragPositioningEnd(float x, float y) {
+ public Rect onDragPositioningEnd(float x, float y) {
// If task has been resized or task was dragged into area outside of
// mDisallowedAreaForEndBounds, apply WCT to finish it.
if (isResizing() && mHasDragResized) {
@@ -136,6 +137,7 @@ class FluidResizeTaskPositioner implements DragPositioningCallback {
mRepositionStartPoint.set(0, 0);
mCtrlType = CTRL_TYPE_UNDEFINED;
mHasDragResized = false;
+ return new Rect(mRepositionTaskBounds);
}
private boolean isResizing() {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositioner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositioner.java
index ae3b5eb6a5b5..fb05c696af82 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositioner.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositioner.java
@@ -105,7 +105,7 @@ public class VeiledResizeTaskPositioner implements DragPositioningCallback,
}
@Override
- public void onDragPositioningMove(float x, float y) {
+ public Rect onDragPositioningMove(float x, float y) {
PointF delta = DragPositioningCallbackUtility.calculateDelta(x, y, mRepositionStartPoint);
if (isResizing() && DragPositioningCallbackUtility.changeBounds(mCtrlType,
mRepositionTaskBounds, mTaskBoundsAtDragStart, mStableBounds, delta,
@@ -117,10 +117,11 @@ public class VeiledResizeTaskPositioner implements DragPositioningCallback,
mRepositionTaskBounds, mTaskBoundsAtDragStart, mRepositionStartPoint, t, x, y);
t.apply();
}
+ return new Rect(mRepositionTaskBounds);
}
@Override
- public void onDragPositioningEnd(float x, float y) {
+ public Rect onDragPositioningEnd(float x, float y) {
PointF delta = DragPositioningCallbackUtility.calculateDelta(x, y,
mRepositionStartPoint);
if (isResizing()) {
@@ -151,6 +152,7 @@ public class VeiledResizeTaskPositioner implements DragPositioningCallback,
mCtrlType = CTRL_TYPE_UNDEFINED;
mTaskBoundsAtDragStart.setEmpty();
mRepositionStartPoint.set(0, 0);
+ return new Rect(mRepositionTaskBounds);
}
private boolean isResizing() {
diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp
index 2bac32785d41..dca9e2148237 100644
--- a/packages/SystemUI/Android.bp
+++ b/packages/SystemUI/Android.bp
@@ -200,6 +200,7 @@ android_library {
"lottie",
"LowLightDreamLib",
"motion_tool_lib",
+ "IntentResolver-core",
],
manifest: "AndroidManifest.xml",
@@ -383,6 +384,7 @@ android_library {
"motion_tool_lib",
"androidx.core_core-animation-testing-nodeps",
"androidx.compose.ui_ui",
+ "IntentResolver-core",
],
}
diff --git a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/shaders/SolidColorShader.kt b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/shaders/SolidColorShader.kt
new file mode 100644
index 000000000000..c94fad7246fa
--- /dev/null
+++ b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/shaders/SolidColorShader.kt
@@ -0,0 +1,36 @@
+/*
+ * 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.surfaceeffects.shaders
+
+import android.graphics.RuntimeShader
+
+/** Simply renders a solid color. */
+class SolidColorShader(color: Int) : RuntimeShader(SHADER) {
+ // language=AGSL
+ private companion object {
+ private const val SHADER =
+ """
+ layout(color) uniform vec4 in_color;
+ vec4 main(vec2 p) {
+ return in_color;
+ }
+ """
+ }
+
+ init {
+ setColorUniform("in_color", color)
+ }
+}
diff --git a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/shaders/SparkleShader.kt b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/shaders/SparkleShader.kt
new file mode 100644
index 000000000000..df07856e325e
--- /dev/null
+++ b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/shaders/SparkleShader.kt
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.surfaceeffects.shaders
+
+import android.graphics.Color
+import android.graphics.RuntimeShader
+import android.graphics.Shader
+import com.android.systemui.surfaceeffects.shaderutil.ShaderUtilLibrary
+
+/**
+ * Renders sparkles based on the luma matte.
+ *
+ * For example, you can pass in simplex noise as the luma matte and have a cloud looking sparkles.
+ *
+ * You may want to utilize this shader by: (Preferred) 1. Create a RuntimeShaderEffect and set the
+ * [RenderEffect] to the target [View].
+ * 2. Create a custom [View], set the shader to the [Paint] and use [Canvas.drawPaint] in [onDraw].
+ */
+class SparkleShader : RuntimeShader(SPARKLE_SHADER) {
+ // language=AGSL
+ companion object {
+ private const val UNIFORMS =
+ """
+ // Used it for RenderEffect. For example:
+ // myView.setRenderEffect(
+ // RenderEffect.createRuntimeShaderEffect(SparkleShader(), "in_src")
+ // )
+ uniform shader in_src;
+ uniform half in_time;
+ uniform half in_pixelate;
+ uniform shader in_lumaMatte;
+ layout(color) uniform vec4 in_color;
+ """
+ private const val MAIN_SHADER =
+ """vec4 main(vec2 p) {
+ half3 src = in_src.eval(p).rgb;
+ half luma = getLuminosity(in_lumaMatte.eval(p).rgb);
+ half sparkle = sparkles(p - mod(p, in_pixelate), in_time);
+ half3 mask = maskLuminosity(in_color.rgb * sparkle, luma);
+
+ return vec4(src * mask * in_color.a, in_color.a);
+ }
+ """
+ private const val SPARKLE_SHADER = UNIFORMS + ShaderUtilLibrary.SHADER_LIB + MAIN_SHADER
+
+ /** Highly recommended to use this value unless specified by design spec. */
+ const val DEFAULT_SPARKLE_PIXELATE_AMOUNT = 0.8f
+ }
+
+ init {
+ // Initializes the src and luma matte to be white.
+ setInputShader("in_src", SolidColorShader(Color.WHITE))
+ setLumaMatteColor(Color.WHITE)
+ }
+
+ /**
+ * Sets the time of the sparkle animation.
+ *
+ * This is used for animating sparkles. Note that this only makes the sparkles sparkle in place.
+ * In order to move the sparkles in x, y directions, move the luma matte input instead.
+ */
+ fun setTime(time: Float) {
+ setFloatUniform("in_time", time)
+ }
+
+ /**
+ * Sets pixelated amount of the sparkle.
+ *
+ * This value *must* be based on [resources.displayMetrics.density]. Otherwise, this will result
+ * in having different sparkle sizes on different screens.
+ *
+ * Expected to be used as follows:
+ * <pre>
+ * {@code
+ * val pixelDensity = context.resources.displayMetrics.density
+ * // Sparkles will be 0.8 of the pixel size.
+ * val sparkleShader = SparkleShader().apply { setPixelateAmount(pixelDensity * 0.8f) }
+ * }
+ * </pre>
+ */
+ fun setPixelateAmount(pixelateAmount: Float) {
+ setFloatUniform("in_pixelate", pixelateAmount)
+ }
+
+ /**
+ * Sets the luma matte for the sparkles. The luminosity determines the sparkle's visibility.
+ * Useful for setting a complex mask (e.g. simplex noise, texture, etc.)
+ */
+ fun setLumaMatte(lumaMatte: Shader) {
+ setInputShader("in_lumaMatte", lumaMatte)
+ }
+
+ /** Sets the luma matte for the sparkles. Useful for setting a solid color. */
+ fun setLumaMatteColor(color: Int) {
+ setInputShader("in_lumaMatte", SolidColorShader(color))
+ }
+
+ /** Sets the color of the sparkles. Expect to have the alpha value encoded. */
+ fun setColor(color: Int) {
+ setColorUniform("in_color", color)
+ }
+}
diff --git a/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/scene/ui/composable/SceneModule.kt b/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/scene/ui/composable/SceneModule.kt
index 5413f9097c5b..24064b1261b7 100644
--- a/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/scene/ui/composable/SceneModule.kt
+++ b/packages/SystemUI/compose/facade/disabled/src/com/android/systemui/scene/ui/composable/SceneModule.kt
@@ -17,12 +17,10 @@
package com.android.systemui.scene.ui.composable
import com.android.systemui.scene.shared.model.Scene
-import com.android.systemui.scene.shared.model.SceneContainerNames
import dagger.Module
import dagger.multibindings.Multibinds
-import javax.inject.Named
@Module
interface SceneModule {
- @Multibinds @Named(SceneContainerNames.SYSTEM_UI_DEFAULT) fun scenes(): Set<Scene>
+ @Multibinds fun scenes(): Set<Scene>
}
diff --git a/packages/SystemUI/compose/facade/enabled/src/com/android/systemui/scene/ui/composable/SceneModule.kt b/packages/SystemUI/compose/facade/enabled/src/com/android/systemui/scene/ui/composable/SceneModule.kt
index d3643747ad91..3e9b3975eef4 100644
--- a/packages/SystemUI/compose/facade/enabled/src/com/android/systemui/scene/ui/composable/SceneModule.kt
+++ b/packages/SystemUI/compose/facade/enabled/src/com/android/systemui/scene/ui/composable/SceneModule.kt
@@ -16,35 +16,29 @@
package com.android.systemui.scene.ui.composable
+import android.app.AlertDialog
import android.content.Context
import com.android.systemui.bouncer.ui.composable.BouncerScene
-import com.android.systemui.bouncer.ui.viewmodel.BouncerViewModel
+import com.android.systemui.bouncer.ui.composable.BouncerSceneDialogFactory
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.keyguard.ui.composable.LockscreenScene
-import com.android.systemui.keyguard.ui.viewmodel.LockscreenSceneViewModel
import com.android.systemui.qs.ui.composable.QuickSettingsScene
-import com.android.systemui.qs.ui.viewmodel.QuickSettingsSceneViewModel
import com.android.systemui.scene.shared.model.Scene
-import com.android.systemui.scene.shared.model.SceneContainerNames
import com.android.systemui.shade.ui.composable.ShadeScene
-import com.android.systemui.shade.ui.viewmodel.ShadeSceneViewModel
import com.android.systemui.statusbar.phone.SystemUIDialog
import dagger.Module
import dagger.Provides
-import javax.inject.Named
-import kotlinx.coroutines.CoroutineScope
@Module
object SceneModule {
@Provides
- @Named(SceneContainerNames.SYSTEM_UI_DEFAULT)
fun scenes(
- @Named(SceneContainerNames.SYSTEM_UI_DEFAULT) bouncer: BouncerScene,
- @Named(SceneContainerNames.SYSTEM_UI_DEFAULT) gone: GoneScene,
- @Named(SceneContainerNames.SYSTEM_UI_DEFAULT) lockScreen: LockscreenScene,
- @Named(SceneContainerNames.SYSTEM_UI_DEFAULT) qs: QuickSettingsScene,
- @Named(SceneContainerNames.SYSTEM_UI_DEFAULT) shade: ShadeScene,
+ bouncer: BouncerScene,
+ gone: GoneScene,
+ lockScreen: LockscreenScene,
+ qs: QuickSettingsScene,
+ shade: ShadeScene,
): Set<Scene> {
return setOf(
bouncer,
@@ -57,70 +51,11 @@ object SceneModule {
@Provides
@SysUISingleton
- @Named(SceneContainerNames.SYSTEM_UI_DEFAULT)
- fun bouncerScene(
- @Application context: Context,
- viewModelFactory: BouncerViewModel.Factory,
- ): BouncerScene {
- return BouncerScene(
- viewModel =
- viewModelFactory.create(
- containerName = SceneContainerNames.SYSTEM_UI_DEFAULT,
- ),
- dialogFactory = { SystemUIDialog(context) },
- )
- }
-
- @Provides
- @SysUISingleton
- @Named(SceneContainerNames.SYSTEM_UI_DEFAULT)
- fun goneScene(): GoneScene {
- return GoneScene()
- }
-
- @Provides
- @SysUISingleton
- @Named(SceneContainerNames.SYSTEM_UI_DEFAULT)
- fun lockscreenScene(
- @Application applicationScope: CoroutineScope,
- viewModelFactory: LockscreenSceneViewModel.Factory,
- ): LockscreenScene {
- return LockscreenScene(
- applicationScope = applicationScope,
- viewModel =
- viewModelFactory.create(
- containerName = SceneContainerNames.SYSTEM_UI_DEFAULT,
- ),
- )
- }
-
- @Provides
- @SysUISingleton
- @Named(SceneContainerNames.SYSTEM_UI_DEFAULT)
- fun quickSettingsScene(
- viewModelFactory: QuickSettingsSceneViewModel.Factory,
- ): QuickSettingsScene {
- return QuickSettingsScene(
- viewModel =
- viewModelFactory.create(
- containerName = SceneContainerNames.SYSTEM_UI_DEFAULT,
- ),
- )
- }
-
- @Provides
- @SysUISingleton
- @Named(SceneContainerNames.SYSTEM_UI_DEFAULT)
- fun shadeScene(
- @Application applicationScope: CoroutineScope,
- viewModelFactory: ShadeSceneViewModel.Factory,
- ): ShadeScene {
- return ShadeScene(
- applicationScope = applicationScope,
- viewModel =
- viewModelFactory.create(
- containerName = SceneContainerNames.SYSTEM_UI_DEFAULT,
- ),
- )
+ fun bouncerSceneDialogFactory(@Application context: Context): BouncerSceneDialogFactory {
+ return object : BouncerSceneDialogFactory {
+ override fun invoke(): AlertDialog {
+ return SystemUIDialog(context)
+ }
+ }
}
}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerScene.kt
index d83596eeb853..6d9497dac8ea 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerScene.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/BouncerScene.kt
@@ -52,24 +52,27 @@ import com.android.systemui.bouncer.ui.viewmodel.BouncerViewModel
import com.android.systemui.bouncer.ui.viewmodel.PasswordBouncerViewModel
import com.android.systemui.bouncer.ui.viewmodel.PatternBouncerViewModel
import com.android.systemui.bouncer.ui.viewmodel.PinBouncerViewModel
+import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.scene.shared.model.SceneKey
import com.android.systemui.scene.shared.model.SceneModel
import com.android.systemui.scene.shared.model.UserAction
import com.android.systemui.scene.ui.composable.ComposableScene
+import javax.inject.Inject
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
/** The bouncer scene displays authentication challenges like PIN, password, or pattern. */
-class BouncerScene(
+@SysUISingleton
+class BouncerScene
+@Inject
+constructor(
private val viewModel: BouncerViewModel,
- private val dialogFactory: () -> AlertDialog,
+ private val dialogFactory: BouncerSceneDialogFactory,
) : ComposableScene {
override val key = SceneKey.Bouncer
- override fun destinationScenes(
- containerName: String,
- ): StateFlow<Map<UserAction, SceneModel>> =
+ override fun destinationScenes(): StateFlow<Map<UserAction, SceneModel>> =
MutableStateFlow<Map<UserAction, SceneModel>>(
mapOf(
UserAction.Back to SceneModel(SceneKey.Lockscreen),
@@ -79,7 +82,6 @@ class BouncerScene(
@Composable
override fun Content(
- containerName: String,
modifier: Modifier,
) = BouncerScene(viewModel, dialogFactory, modifier)
}
@@ -87,7 +89,7 @@ class BouncerScene(
@Composable
private fun BouncerScene(
viewModel: BouncerViewModel,
- dialogFactory: () -> AlertDialog,
+ dialogFactory: BouncerSceneDialogFactory,
modifier: Modifier = Modifier,
) {
val message: BouncerViewModel.MessageViewModel by viewModel.message.collectAsState()
@@ -175,3 +177,7 @@ private fun BouncerScene(
}
}
}
+
+interface BouncerSceneDialogFactory {
+ operator fun invoke(): AlertDialog
+}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenScene.kt
index 10652678739c..ab7bc26d59e1 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenScene.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenScene.kt
@@ -31,6 +31,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import com.android.systemui.common.shared.model.Icon
import com.android.systemui.common.ui.compose.Icon
+import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.keyguard.ui.viewmodel.LockscreenSceneViewModel
import com.android.systemui.scene.shared.model.Direction
@@ -38,6 +39,7 @@ import com.android.systemui.scene.shared.model.SceneKey
import com.android.systemui.scene.shared.model.SceneModel
import com.android.systemui.scene.shared.model.UserAction
import com.android.systemui.scene.ui.composable.ComposableScene
+import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
@@ -45,15 +47,16 @@ import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
/** The lock screen scene shows when the device is locked. */
-class LockscreenScene(
+@SysUISingleton
+class LockscreenScene
+@Inject
+constructor(
@Application private val applicationScope: CoroutineScope,
private val viewModel: LockscreenSceneViewModel,
) : ComposableScene {
override val key = SceneKey.Lockscreen
- override fun destinationScenes(
- containerName: String,
- ): StateFlow<Map<UserAction, SceneModel>> =
+ override fun destinationScenes(): StateFlow<Map<UserAction, SceneModel>> =
viewModel.upDestinationSceneKey
.map { pageKey -> destinationScenes(up = pageKey) }
.stateIn(
@@ -64,7 +67,6 @@ class LockscreenScene(
@Composable
override fun Content(
- containerName: String,
modifier: Modifier,
) {
LockscreenScene(
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt
index 30b80ca7fc1e..130395a38512 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt
@@ -27,25 +27,28 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
+import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.qs.ui.viewmodel.QuickSettingsSceneViewModel
import com.android.systemui.scene.shared.model.Direction
import com.android.systemui.scene.shared.model.SceneKey
import com.android.systemui.scene.shared.model.SceneModel
import com.android.systemui.scene.shared.model.UserAction
import com.android.systemui.scene.ui.composable.ComposableScene
+import javax.inject.Inject
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
/** The Quick Settings (AKA "QS") scene shows the quick setting tiles. */
-class QuickSettingsScene(
+@SysUISingleton
+class QuickSettingsScene
+@Inject
+constructor(
private val viewModel: QuickSettingsSceneViewModel,
) : ComposableScene {
override val key = SceneKey.QuickSettings
- override fun destinationScenes(
- containerName: String,
- ): StateFlow<Map<UserAction, SceneModel>> =
+ override fun destinationScenes(): StateFlow<Map<UserAction, SceneModel>> =
MutableStateFlow<Map<UserAction, SceneModel>>(
mapOf(
UserAction.Swipe(Direction.UP) to SceneModel(SceneKey.Shade),
@@ -55,7 +58,6 @@ class QuickSettingsScene(
@Composable
override fun Content(
- containerName: String,
modifier: Modifier,
) {
QuickSettingsScene(
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/ComposableScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/ComposableScene.kt
index 6f3363e940e5..a21366695f66 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/ComposableScene.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/ComposableScene.kt
@@ -22,5 +22,5 @@ import com.android.systemui.scene.shared.model.Scene
/** Compose-capable extension of [Scene]. */
interface ComposableScene : Scene {
- @Composable fun Content(containerName: String, modifier: Modifier)
+ @Composable fun Content(modifier: Modifier)
}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/GoneScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/GoneScene.kt
index 0a4da1d6ba1e..007055221691 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/GoneScene.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/GoneScene.kt
@@ -23,10 +23,12 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
+import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.scene.shared.model.Direction
import com.android.systemui.scene.shared.model.SceneKey
import com.android.systemui.scene.shared.model.SceneModel
import com.android.systemui.scene.shared.model.UserAction
+import javax.inject.Inject
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
@@ -35,12 +37,11 @@ import kotlinx.coroutines.flow.asStateFlow
* "Gone" is not a real scene but rather the absence of scenes when we want to skip showing any
* content from the scene framework.
*/
-class GoneScene : ComposableScene {
+@SysUISingleton
+class GoneScene @Inject constructor() : ComposableScene {
override val key = SceneKey.Gone
- override fun destinationScenes(
- containerName: String,
- ): StateFlow<Map<UserAction, SceneModel>> =
+ override fun destinationScenes(): StateFlow<Map<UserAction, SceneModel>> =
MutableStateFlow<Map<UserAction, SceneModel>>(
mapOf(
UserAction.Swipe(Direction.DOWN) to SceneModel(SceneKey.Shade),
@@ -50,7 +51,6 @@ class GoneScene : ComposableScene {
@Composable
override fun Content(
- containerName: String,
modifier: Modifier,
) {
/*
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainer.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainer.kt
index 32986649388d..49e2bf97b3f0 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainer.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainer.kt
@@ -75,7 +75,6 @@ fun SceneContainer(
if (key == currentSceneKey) {
Scene(
scene = composableScene,
- containerName = viewModel.containerName,
onSceneChanged = viewModel::setCurrentScene,
modifier = Modifier.fillMaxSize(),
)
@@ -88,12 +87,10 @@ fun SceneContainer(
@Composable
private fun Scene(
scene: ComposableScene,
- containerName: String,
onSceneChanged: (SceneModel) -> Unit,
modifier: Modifier = Modifier,
) {
- val destinationScenes: Map<UserAction, SceneModel> by
- scene.destinationScenes(containerName).collectAsState()
+ val destinationScenes: Map<UserAction, SceneModel> by scene.destinationScenes().collectAsState()
val swipeLeftDestinationScene = destinationScenes[UserAction.Swipe(Direction.LEFT)]
val swipeUpDestinationScene = destinationScenes[UserAction.Swipe(Direction.UP)]
val swipeRightDestinationScene = destinationScenes[UserAction.Swipe(Direction.RIGHT)]
@@ -107,7 +104,6 @@ private fun Scene(
modifier = Modifier.align(Alignment.Center),
) {
scene.Content(
- containerName = containerName,
modifier = Modifier,
)
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt
index 27358f53aaf2..b73e0b26f208 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt
@@ -26,6 +26,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
+import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.notifications.ui.composable.Notifications
import com.android.systemui.qs.footer.ui.compose.QuickSettings
@@ -35,6 +36,7 @@ import com.android.systemui.scene.shared.model.SceneModel
import com.android.systemui.scene.shared.model.UserAction
import com.android.systemui.scene.ui.composable.ComposableScene
import com.android.systemui.shade.ui.viewmodel.ShadeSceneViewModel
+import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
@@ -42,15 +44,16 @@ import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
/** The shade scene shows scrolling list of notifications and some of the quick setting tiles. */
-class ShadeScene(
+@SysUISingleton
+class ShadeScene
+@Inject
+constructor(
@Application private val applicationScope: CoroutineScope,
private val viewModel: ShadeSceneViewModel,
) : ComposableScene {
override val key = SceneKey.Shade
- override fun destinationScenes(
- containerName: String,
- ): StateFlow<Map<UserAction, SceneModel>> =
+ override fun destinationScenes(): StateFlow<Map<UserAction, SceneModel>> =
viewModel.upDestinationSceneKey
.map { sceneKey -> destinationScenes(up = sceneKey) }
.stateIn(
@@ -61,7 +64,6 @@ class ShadeScene(
@Composable
override fun Content(
- containerName: String,
modifier: Modifier,
) = ShadeScene(viewModel, modifier)
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_pin_view.xml b/packages/SystemUI/res-keyguard/layout/keyguard_pin_view.xml
index c7d2d81ded36..29e14c57a047 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_pin_view.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_pin_view.xml
@@ -16,202 +16,10 @@
** limitations under the License.
*/
-->
-
-<com.android.keyguard.KeyguardPINView xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:androidprv="http://schemas.android.com/apk/res-auto"
- android:id="@+id/keyguard_pin_view"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_gravity="center_horizontal|bottom"
- android:clipChildren="false"
- android:clipToPadding="false"
- android:orientation="vertical"
- androidprv:layout_maxWidth="@dimen/keyguard_security_width">
-<include layout="@layout/keyguard_bouncer_message_area"/>
-
-<com.android.systemui.bouncer.ui.BouncerMessageView
- android:id="@+id/bouncer_message_view"
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical" />
-
-<androidx.constraintlayout.widget.ConstraintLayout
- android:id="@+id/pin_container"
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_marginBottom="8dp"
- android:clipChildren="false"
- android:clipToPadding="false"
- android:layout_weight="1"
- android:layoutDirection="ltr"
- android:orientation="vertical">
-
- <!-- Set this to be just above key1. It would be better to introduce a barrier above
- key1/key2/key3, then place this View above that. Sadly, that doesn't work (the Barrier
- drops to the bottom of the page, and key1/2/3 all shoot up to the top-left). In any
- case, the Flow should ensure that key1/2/3 all have the same top, so this should be
- fine. -->
- <com.android.keyguard.AlphaOptimizedRelativeLayout
- android:id="@+id/row0"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:paddingBottom="@dimen/num_pad_entry_row_margin_bottom"
- androidprv:layout_constraintTop_toTopOf="parent"
- androidprv:layout_constraintEnd_toEndOf="parent"
- androidprv:layout_constraintStart_toStartOf="parent"
- androidprv:layout_constraintBottom_toTopOf="@id/key1"
- androidprv:layout_constraintVertical_bias="0.5">
-
- <com.android.keyguard.PasswordTextView
- android:id="@+id/pinEntry"
- style="@style/Widget.TextView.Password"
- android:layout_width="@dimen/keyguard_security_width"
- android:layout_height="@dimen/keyguard_password_height"
- android:layout_centerHorizontal="true"
- android:layout_marginRight="72dp"
- android:contentDescription="@string/keyguard_accessibility_pin_area"
- androidprv:scaledTextSize="@integer/scaled_password_text_size" />
- </com.android.keyguard.AlphaOptimizedRelativeLayout>
-
- <!-- Guideline used to place the top row of keys relative to the screen height. This will be
- updated in KeyguardPINView to reduce the height of the PIN pad. -->
- <androidx.constraintlayout.widget.Guideline
- android:id="@+id/pin_pad_top_guideline"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- androidprv:layout_constraintGuide_percent="0"
- android:orientation="horizontal" />
-
- <com.android.keyguard.KeyguardPinFlowView
- android:id="@+id/flow1"
- android:layout_width="0dp"
- android:layout_height="0dp"
- android:orientation="horizontal"
- android:clipChildren="false"
- android:clipToPadding="false"
-
- androidprv:constraint_referenced_ids="key1,key2,key3,key4,key5,key6,key7,key8,key9,delete_button,key0,key_enter"
-
- androidprv:flow_horizontalGap="@dimen/num_pad_key_margin_end"
-
- androidprv:flow_horizontalStyle="packed"
- androidprv:flow_maxElementsWrap="3"
-
- androidprv:flow_verticalBias="1.0"
- androidprv:flow_verticalGap="@dimen/num_pad_entry_row_margin_bottom"
- androidprv:flow_verticalStyle="packed"
-
- androidprv:flow_wrapMode="aligned"
- androidprv:layout_constraintBottom_toBottomOf="parent"
- androidprv:layout_constraintEnd_toEndOf="parent"
- androidprv:layout_constraintStart_toStartOf="parent"
- androidprv:layout_constraintTop_toBottomOf="@id/pin_pad_top_guideline" />
-
- <com.android.keyguard.NumPadKey
- android:id="@+id/key1"
- android:layout_width="0dp"
- android:layout_height="0dp"
- android:accessibilityTraversalBefore="@id/key2"
- androidprv:digit="1"
- androidprv:textView="@+id/pinEntry" />
-
- <com.android.keyguard.NumPadKey
- android:id="@+id/key2"
- android:layout_width="0dp"
- android:layout_height="0dp"
- android:accessibilityTraversalBefore="@id/key3"
- androidprv:digit="2"
- androidprv:textView="@+id/pinEntry" />
-
- <com.android.keyguard.NumPadKey
- android:id="@+id/key3"
- android:layout_width="0dp"
- android:layout_height="0dp"
- android:accessibilityTraversalBefore="@id/key4"
- androidprv:digit="3"
- androidprv:textView="@+id/pinEntry" />
-
- <com.android.keyguard.NumPadKey
- android:id="@+id/key4"
- android:layout_width="0dp"
- android:layout_height="0dp"
- android:accessibilityTraversalBefore="@id/key5"
- androidprv:digit="4"
- androidprv:textView="@+id/pinEntry" />
-
- <com.android.keyguard.NumPadKey
- android:id="@+id/key5"
- android:layout_width="0dp"
- android:layout_height="0dp"
- android:accessibilityTraversalBefore="@id/key6"
- androidprv:digit="5"
- androidprv:textView="@+id/pinEntry" />
-
- <com.android.keyguard.NumPadKey
- android:id="@+id/key6"
- android:layout_width="0dp"
- android:layout_height="0dp"
- android:accessibilityTraversalBefore="@id/key7"
- androidprv:digit="6"
- androidprv:textView="@+id/pinEntry" />
-
- <com.android.keyguard.NumPadKey
- android:id="@+id/key7"
- android:layout_width="0dp"
- android:layout_height="0dp"
- android:accessibilityTraversalBefore="@id/key8"
- androidprv:digit="7"
- androidprv:textView="@+id/pinEntry" />
-
-
- <com.android.keyguard.NumPadKey
- android:id="@+id/key8"
- android:layout_width="0dp"
- android:layout_height="0dp"
- android:accessibilityTraversalBefore="@id/key9"
- androidprv:digit="8"
- androidprv:textView="@+id/pinEntry" />
-
- <com.android.keyguard.NumPadKey
- android:id="@+id/key9"
- android:layout_width="0dp"
- android:layout_height="0dp"
- android:accessibilityTraversalBefore="@id/delete_button"
- androidprv:digit="9"
- androidprv:textView="@+id/pinEntry" />
-
- <com.android.keyguard.NumPadButton
- android:id="@+id/delete_button"
- style="@style/NumPadKey.Delete"
- android:layout_width="0dp"
- android:layout_height="0dp"
- android:accessibilityTraversalBefore="@id/key0"
- android:contentDescription="@string/keyboardview_keycode_delete" />
-
- <com.android.keyguard.NumPadKey
- android:id="@+id/key0"
- android:layout_width="0dp"
- android:layout_height="0dp"
- android:accessibilityTraversalBefore="@id/key_enter"
- androidprv:digit="0"
- androidprv:textView="@+id/pinEntry" />
-
- <com.android.keyguard.NumPadButton
- android:id="@+id/key_enter"
- style="@style/NumPadKey.Enter"
- android:layout_width="0dp"
- android:layout_height="0dp"
- android:contentDescription="@string/keyboardview_keycode_enter" />
-</androidx.constraintlayout.widget.ConstraintLayout>
+ android:layout_height="match_parent">
- <include layout="@layout/keyguard_eca"
- android:id="@+id/keyguard_selector_fade_container"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical"
- android:layout_gravity="bottom|center_horizontal"
- android:layout_marginTop="@dimen/keyguard_eca_top_margin"
- android:layout_marginBottom="@dimen/keyguard_eca_bottom_margin"
- android:gravity="center_horizontal"/>
+ <include layout="@layout/keyguard_pin_view_portrait" />
-</com.android.keyguard.KeyguardPINView>
+</FrameLayout>
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_pin_view_portrait.xml b/packages/SystemUI/res-keyguard/layout/keyguard_pin_view_portrait.xml
new file mode 100644
index 000000000000..f3cd9e49b49c
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_pin_view_portrait.xml
@@ -0,0 +1,218 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2023, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License")
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<com.android.keyguard.KeyguardPINView xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/res-auto"
+ android:id="@+id/keyguard_pin_view"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_gravity="center_horizontal|bottom"
+ android:clipChildren="false"
+ android:clipToPadding="false"
+ android:orientation="vertical"
+ androidprv:layout_maxWidth="@dimen/keyguard_security_width">
+
+ <include layout="@layout/keyguard_bouncer_message_area"/>
+
+ <com.android.systemui.bouncer.ui.BouncerMessageView
+ android:id="@+id/bouncer_message_view"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical" />
+
+ <androidx.constraintlayout.widget.ConstraintLayout
+ android:id="@+id/pin_container"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_marginBottom="8dp"
+ android:clipChildren="false"
+ android:clipToPadding="false"
+ android:layout_weight="1"
+ android:layoutDirection="ltr"
+ android:orientation="vertical">
+
+ <!-- Set this to be just above key1. It would be better to introduce a barrier above
+ key1/key2/key3, then place this View above that. Sadly, that doesn't work (the Barrier
+ drops to the bottom of the page, and key1/2/3 all shoot up to the top-left). In any
+ case, the Flow should ensure that key1/2/3 all have the same top, so this should be
+ fine. -->
+ <com.android.keyguard.AlphaOptimizedRelativeLayout
+ android:id="@+id/row0"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingBottom="@dimen/num_pad_entry_row_margin_bottom"
+ androidprv:layout_constraintTop_toTopOf="parent"
+ androidprv:layout_constraintEnd_toEndOf="parent"
+ androidprv:layout_constraintStart_toStartOf="parent"
+ androidprv:layout_constraintBottom_toTopOf="@id/key1"
+ androidprv:layout_constraintVertical_bias="0.5">
+
+ <com.android.keyguard.PasswordTextView
+ android:id="@+id/pinEntry"
+ style="@style/Widget.TextView.Password"
+ android:layout_width="@dimen/keyguard_security_width"
+ android:layout_height="@dimen/keyguard_password_height"
+ android:layout_centerHorizontal="true"
+ android:layout_marginRight="72dp"
+ android:contentDescription="@string/keyguard_accessibility_pin_area"
+ androidprv:scaledTextSize="@integer/scaled_password_text_size" />
+ </com.android.keyguard.AlphaOptimizedRelativeLayout>
+
+ <!-- Guideline used to place the top row of keys relative to the screen height. This will be
+ updated in KeyguardPINView to reduce the height of the PIN pad. -->
+ <androidx.constraintlayout.widget.Guideline
+ android:id="@+id/pin_pad_top_guideline"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ androidprv:layout_constraintGuide_percent="0"
+ android:orientation="horizontal" />
+
+ <com.android.keyguard.KeyguardPinFlowView
+ android:id="@+id/flow1"
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ android:orientation="horizontal"
+ android:clipChildren="false"
+ android:clipToPadding="false"
+
+ androidprv:constraint_referenced_ids="key1,key2,key3,key4,key5,key6,key7,key8,key9,delete_button,key0,key_enter"
+
+ androidprv:flow_horizontalGap="@dimen/num_pad_key_margin_end"
+
+ androidprv:flow_horizontalStyle="packed"
+ androidprv:flow_maxElementsWrap="3"
+
+ androidprv:flow_verticalBias="1.0"
+ androidprv:flow_verticalGap="@dimen/num_pad_entry_row_margin_bottom"
+ androidprv:flow_verticalStyle="packed"
+
+ androidprv:flow_wrapMode="aligned"
+ androidprv:layout_constraintBottom_toBottomOf="parent"
+ androidprv:layout_constraintEnd_toEndOf="parent"
+ androidprv:layout_constraintStart_toStartOf="parent"
+ androidprv:layout_constraintTop_toBottomOf="@id/pin_pad_top_guideline" />
+
+ <com.android.keyguard.NumPadKey
+ android:id="@+id/key1"
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ android:accessibilityTraversalBefore="@id/key2"
+ androidprv:digit="1"
+ androidprv:textView="@+id/pinEntry" />
+
+ <com.android.keyguard.NumPadKey
+ android:id="@+id/key2"
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ android:accessibilityTraversalBefore="@id/key3"
+ androidprv:digit="2"
+ androidprv:textView="@+id/pinEntry" />
+
+ <com.android.keyguard.NumPadKey
+ android:id="@+id/key3"
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ android:accessibilityTraversalBefore="@id/key4"
+ androidprv:digit="3"
+ androidprv:textView="@+id/pinEntry" />
+
+ <com.android.keyguard.NumPadKey
+ android:id="@+id/key4"
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ android:accessibilityTraversalBefore="@id/key5"
+ androidprv:digit="4"
+ androidprv:textView="@+id/pinEntry" />
+
+ <com.android.keyguard.NumPadKey
+ android:id="@+id/key5"
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ android:accessibilityTraversalBefore="@id/key6"
+ androidprv:digit="5"
+ androidprv:textView="@+id/pinEntry" />
+
+ <com.android.keyguard.NumPadKey
+ android:id="@+id/key6"
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ android:accessibilityTraversalBefore="@id/key7"
+ androidprv:digit="6"
+ androidprv:textView="@+id/pinEntry" />
+
+ <com.android.keyguard.NumPadKey
+ android:id="@+id/key7"
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ android:accessibilityTraversalBefore="@id/key8"
+ androidprv:digit="7"
+ androidprv:textView="@+id/pinEntry" />
+
+
+ <com.android.keyguard.NumPadKey
+ android:id="@+id/key8"
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ android:accessibilityTraversalBefore="@id/key9"
+ androidprv:digit="8"
+ androidprv:textView="@+id/pinEntry" />
+
+ <com.android.keyguard.NumPadKey
+ android:id="@+id/key9"
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ android:accessibilityTraversalBefore="@id/delete_button"
+ androidprv:digit="9"
+ androidprv:textView="@+id/pinEntry" />
+
+ <com.android.keyguard.NumPadButton
+ android:id="@+id/delete_button"
+ style="@style/NumPadKey.Delete"
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ android:accessibilityTraversalBefore="@id/key0"
+ android:contentDescription="@string/keyboardview_keycode_delete" />
+
+ <com.android.keyguard.NumPadKey
+ android:id="@+id/key0"
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ android:accessibilityTraversalBefore="@id/key_enter"
+ androidprv:digit="0"
+ androidprv:textView="@+id/pinEntry" />
+
+ <com.android.keyguard.NumPadButton
+ android:id="@+id/key_enter"
+ style="@style/NumPadKey.Enter"
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ android:contentDescription="@string/keyboardview_keycode_enter" />
+ </androidx.constraintlayout.widget.ConstraintLayout>
+
+ <include layout="@layout/keyguard_eca"
+ android:id="@+id/keyguard_selector_fade_container"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:layout_gravity="bottom|center_horizontal"
+ android:layout_marginTop="@dimen/keyguard_eca_top_margin"
+ android:layout_marginBottom="@dimen/keyguard_eca_bottom_margin"
+ android:gravity="center_horizontal"/>
+
+</com.android.keyguard.KeyguardPINView>
diff --git a/packages/SystemUI/res/layout/media_projection_app_selector.xml b/packages/SystemUI/res/layout/media_projection_app_selector.xml
index e4749381243a..5404cfad25c5 100644
--- a/packages/SystemUI/res/layout/media_projection_app_selector.xml
+++ b/packages/SystemUI/res/layout/media_projection_app_selector.xml
@@ -14,7 +14,7 @@
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
-<com.android.internal.widget.ResolverDrawerLayout
+<com.android.intentresolver.widget.ResolverDrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
android:layout_width="match_parent"
@@ -84,7 +84,7 @@
android:id="@*android:id/tabcontent"
android:layout_width="match_parent"
android:layout_height="wrap_content">
- <com.android.internal.app.ResolverViewPager
+ <com.android.intentresolver.ResolverViewPager
android:id="@*android:id/profile_pager"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
@@ -92,4 +92,4 @@
</LinearLayout>
</TabHost>
-</com.android.internal.widget.ResolverDrawerLayout>
+</com.android.intentresolver.widget.ResolverDrawerLayout>
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
index bc24249b23c9..3b09910fbe88 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
@@ -81,7 +81,6 @@ import com.android.systemui.log.SessionTracker;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.scene.domain.interactor.SceneInteractor;
-import com.android.systemui.scene.shared.model.SceneContainerNames;
import com.android.systemui.scene.shared.model.SceneKey;
import com.android.systemui.shared.system.SysUiStatsLog;
import com.android.systemui.statusbar.policy.ConfigurationController;
@@ -476,7 +475,7 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
if (mFeatureFlags.isEnabled(Flags.SCENE_CONTAINER)) {
// When the scene framework transitions from bouncer to gone, we dismiss the keyguard.
mSceneTransitionCollectionJob = mJavaAdapter.get().alwaysCollectFlow(
- mSceneInteractor.get().sceneTransitions(SceneContainerNames.SYSTEM_UI_DEFAULT),
+ mSceneInteractor.get().getTransitions(),
sceneTransitionModel -> {
if (sceneTransitionModel != null
&& sceneTransitionModel.getFrom() == SceneKey.Bouncer.INSTANCE
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityViewFlipperController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityViewFlipperController.java
index fbacd6818648..bc5b1ba9a294 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityViewFlipperController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityViewFlipperController.java
@@ -117,15 +117,19 @@ public class KeyguardSecurityViewFlipperController
KeyguardSecurityCallback keyguardSecurityCallback,
@Nullable OnViewInflatedCallback onViewInflatedListener) {
int layoutId = getLayoutIdFor(securityMode);
- if (layoutId != 0) {
- if (DEBUG) Log.v(TAG, "inflating on bg thread id = " + layoutId);
+ int viewID = getKeyguardInputViewId(securityMode);
+ if (layoutId != 0 && viewID != 0) {
+ if (DEBUG) {
+ Log.v(TAG, "inflating on bg thread id = "
+ + layoutId + " . viewID = " + viewID);
+ }
mAsyncLayoutInflater.inflate(layoutId, mView,
(view, resId, parent) -> {
mView.addView(view);
KeyguardInputViewController<KeyguardInputView> childController =
mKeyguardSecurityViewControllerFactory.create(
- (KeyguardInputView) view, securityMode,
- keyguardSecurityCallback);
+ (KeyguardInputView) view.findViewById(viewID),
+ securityMode, keyguardSecurityCallback);
childController.init();
mChildren.add(childController);
if (onViewInflatedListener != null) {
@@ -147,6 +151,19 @@ public class KeyguardSecurityViewFlipperController
}
}
+ private int getKeyguardInputViewId(SecurityMode securityMode) {
+ //Keyguard Input View is not the root view of the layout, use these IDs for lookup.
+ switch (securityMode) {
+ case Pattern: return R.id.keyguard_pattern_view;
+ case PIN: return R.id.keyguard_pin_view;
+ case Password: return R.id.keyguard_password_view;
+ case SimPin: return R.id.keyguard_sim_pin_view;
+ case SimPuk: return R.id.keyguard_sim_puk_view;
+ default:
+ return 0;
+ }
+ }
+
/** Makes the supplied child visible if it is contained win this view, */
public void show(KeyguardInputViewController<KeyguardInputView> childController) {
int index = childController.getIndexIn(mView);
diff --git a/packages/SystemUI/src/com/android/systemui/ExpandHelper.java b/packages/SystemUI/src/com/android/systemui/ExpandHelper.java
index f00615bc0fe6..7c377d2841e3 100644
--- a/packages/SystemUI/src/com/android/systemui/ExpandHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/ExpandHelper.java
@@ -19,9 +19,6 @@ package com.android.systemui;
import static com.android.internal.jank.InteractionJankMonitor.CUJ_NOTIFICATION_SHADE_ROW_EXPAND;
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.ObjectAnimator;
import android.content.Context;
import android.util.FloatProperty;
import android.util.Log;
@@ -34,6 +31,11 @@ import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
+import androidx.annotation.NonNull;
+import androidx.core.animation.Animator;
+import androidx.core.animation.AnimatorListenerAdapter;
+import androidx.core.animation.ObjectAnimator;
+
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.jank.InteractionJankMonitor;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
@@ -616,7 +618,7 @@ public class ExpandHelper implements Gefingerpoken {
public boolean mCancelled;
@Override
- public void onAnimationEnd(Animator animation) {
+ public void onAnimationEnd(@NonNull Animator animation) {
if (!mCancelled) {
mCallback.setUserExpandedChild(scaledView, expand);
if (!mExpanding) {
@@ -633,7 +635,7 @@ public class ExpandHelper implements Gefingerpoken {
}
@Override
- public void onAnimationCancel(Animator animation) {
+ public void onAnimationCancel(@NonNull Animator animation) {
mCancelled = true;
}
});
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractor.kt b/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractor.kt
index 8e14237c0586..d8cf398b696b 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractor.kt
@@ -24,6 +24,7 @@ import com.android.systemui.authentication.domain.interactor.AuthenticationInter
import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
import com.android.systemui.authentication.shared.model.AuthenticationThrottlingModel
import com.android.systemui.bouncer.data.repository.BouncerRepository
+import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags
@@ -31,9 +32,7 @@ import com.android.systemui.scene.domain.interactor.SceneInteractor
import com.android.systemui.scene.shared.model.SceneKey
import com.android.systemui.scene.shared.model.SceneModel
import com.android.systemui.util.kotlin.pairwise
-import dagger.assisted.Assisted
-import dagger.assisted.AssistedFactory
-import dagger.assisted.AssistedInject
+import javax.inject.Inject
import kotlin.time.Duration.Companion.milliseconds
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -44,8 +43,9 @@ import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
/** Encapsulates business logic and application state accessing use-cases. */
+@SysUISingleton
class BouncerInteractor
-@AssistedInject
+@Inject
constructor(
@Application private val applicationScope: CoroutineScope,
@Application private val applicationContext: Context,
@@ -53,7 +53,6 @@ constructor(
private val authenticationInteractor: AuthenticationInteractor,
private val sceneInteractor: SceneInteractor,
featureFlags: FeatureFlags,
- @Assisted private val containerName: String,
) {
/** The user-facing message to show in the bouncer. */
@@ -118,23 +117,19 @@ constructor(
/**
* Either shows the bouncer or unlocks the device, if the bouncer doesn't need to be shown.
*
- * @param containerName The name of the scene container to show the bouncer in.
* @param message An optional message to show to the user in the bouncer.
*/
fun showOrUnlockDevice(
- containerName: String,
message: String? = null,
) {
applicationScope.launch {
if (authenticationInteractor.isAuthenticationRequired()) {
repository.setMessage(message ?: promptMessage(getAuthenticationMethod()))
sceneInteractor.setCurrentScene(
- containerName = containerName,
scene = SceneModel(SceneKey.Bouncer),
)
} else {
sceneInteractor.setCurrentScene(
- containerName = containerName,
scene = SceneModel(SceneKey.Gone),
)
}
@@ -180,7 +175,6 @@ constructor(
if (isAuthenticated) {
sceneInteractor.setCurrentScene(
- containerName = containerName,
scene = SceneModel(SceneKey.Gone),
)
} else {
@@ -228,11 +222,4 @@ constructor(
else -> ""
}
}
-
- @AssistedFactory
- interface Factory {
- fun create(
- containerName: String,
- ): BouncerInteractor
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModel.kt b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModel.kt
index a4ef5cec6525..68e1a29bc609 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModel.kt
@@ -22,13 +22,12 @@ import android.content.Context
import com.android.systemui.R
import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
import com.android.systemui.bouncer.domain.interactor.BouncerInteractor
+import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags
import com.android.systemui.util.kotlin.pairwise
-import dagger.assisted.Assisted
-import dagger.assisted.AssistedFactory
-import dagger.assisted.AssistedInject
+import javax.inject.Inject
import kotlin.math.ceil
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -45,17 +44,15 @@ import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
/** Holds UI state and handles user input on bouncer UIs. */
+@SysUISingleton
class BouncerViewModel
-@AssistedInject
+@Inject
constructor(
@Application private val applicationContext: Context,
@Application private val applicationScope: CoroutineScope,
- interactorFactory: BouncerInteractor.Factory,
+ private val interactor: BouncerInteractor,
featureFlags: FeatureFlags,
- @Assisted containerName: String,
) {
- private val interactor: BouncerInteractor = interactorFactory.create(containerName)
-
private val isInputEnabled: StateFlow<Boolean> =
interactor.isThrottled
.map { !it }
@@ -222,11 +219,4 @@ constructor(
*/
val isUpdateAnimated: Boolean,
)
-
- @AssistedFactory
- interface Factory {
- fun create(
- containerName: String,
- ): BouncerViewModel
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java
index 553405f2c944..5577cbcb0dd7 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java
@@ -17,6 +17,7 @@
package com.android.systemui.dreams;
import static com.android.systemui.dreams.dagger.DreamModule.DREAM_OVERLAY_WINDOW_TITLE;
+import static com.android.systemui.dreams.dagger.DreamModule.DREAM_TOUCH_INSET_MANAGER;
import android.content.ComponentName;
import android.content.Context;
@@ -161,7 +162,7 @@ public class DreamOverlayService extends android.service.dreams.DreamOverlayServ
DreamOverlayStateController stateController,
KeyguardUpdateMonitor keyguardUpdateMonitor,
UiEventLogger uiEventLogger,
- TouchInsetManager touchInsetManager,
+ @Named(DREAM_TOUCH_INSET_MANAGER) TouchInsetManager touchInsetManager,
@Nullable @Named(LowLightDreamModule.LOW_LIGHT_DREAM_COMPONENT)
ComponentName lowLightDreamComponent,
DreamOverlayCallbackController dreamOverlayCallbackController,
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamModule.java b/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamModule.java
index c61b47758ab7..4bafe325cda0 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamModule.java
@@ -31,11 +31,13 @@ import com.android.systemui.dreams.DreamOverlayNotificationCountProvider;
import com.android.systemui.dreams.DreamOverlayService;
import com.android.systemui.dreams.complication.dagger.ComplicationComponent;
import com.android.systemui.dreams.touch.scrim.dagger.ScrimModule;
+import com.android.systemui.touch.TouchInsetManager;
import dagger.Module;
import dagger.Provides;
import java.util.Optional;
+import java.util.concurrent.Executor;
import javax.inject.Named;
@@ -55,7 +57,7 @@ public interface DreamModule {
String DREAM_ONLY_ENABLED_FOR_DOCK_USER = "dream_only_enabled_for_dock_user";
String DREAM_OVERLAY_SERVICE_COMPONENT = "dream_overlay_service_component";
String DREAM_OVERLAY_ENABLED = "dream_overlay_enabled";
-
+ String DREAM_TOUCH_INSET_MANAGER = "dream_touch_inset_manager";
String DREAM_SUPPORTED = "dream_supported";
String DREAM_OVERLAY_WINDOW_TITLE = "dream_overlay_window_title";
@@ -69,6 +71,15 @@ public interface DreamModule {
}
/**
+ * Provides a touch inset manager for dreams.
+ */
+ @Provides
+ @Named(DREAM_TOUCH_INSET_MANAGER)
+ static TouchInsetManager providesTouchInsetManager(@Main Executor executor) {
+ return new TouchInsetManager(executor);
+ }
+
+ /**
* Provides whether dream overlay is enabled.
*/
@Provides
diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
index b04d9705f857..dc38ec040830 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
@@ -62,11 +62,12 @@ object Flags {
val INSTANT_VOICE_REPLY = unreleasedFlag(111, "instant_voice_reply")
/**
- * This flag is server-controlled and should stay as [unreleasedFlag] since we never want to
- * enable it on release builds.
+ * This flag controls whether we register a listener for StatsD notification memory reports.
+ * For statsd to actually call the listener however, a server-side toggle needs to be
+ * enabled as well.
*/
val NOTIFICATION_MEMORY_LOGGING_ENABLED =
- unreleasedFlag(119, "notification_memory_logging_enabled")
+ releasedFlag(119, "notification_memory_logging_enabled")
// TODO(b/260335638): Tracking Bug
@JvmField
@@ -239,7 +240,7 @@ object Flags {
/** Whether to delay showing bouncer UI when face auth or active unlock are enrolled. */
// TODO(b/279794160): Tracking bug.
- @JvmField val DELAY_BOUNCER = unreleasedFlag(235, "delay_bouncer", teamfood = true)
+ @JvmField val DELAY_BOUNCER = releasedFlag(235, "delay_bouncer")
/** Keyguard Migration */
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepository.kt
index 6fd3e21b25a4..30f8f3edfa8f 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepository.kt
@@ -110,6 +110,18 @@ interface DeviceEntryFaceAuthRepository {
fun lockoutFaceAuth()
/**
+ * Cancel current face authentication and prevent it from running until [resumeFaceAuth] is
+ * invoked.
+ */
+ fun pauseFaceAuth()
+
+ /**
+ * Allow face auth paused using [pauseFaceAuth] to run again. The next invocation to
+ * [authenticate] will run as long as other gating conditions don't stop it from running.
+ */
+ fun resumeFaceAuth()
+
+ /**
* Trigger face authentication.
*
* [uiEvent] provided should be logged whenever face authentication runs. Invocation should be
@@ -186,6 +198,15 @@ constructor(
override val isAuthRunning: StateFlow<Boolean>
get() = _isAuthRunning
+ private val faceAuthPaused = MutableStateFlow(false)
+ override fun pauseFaceAuth() {
+ faceAuthPaused.value = true
+ }
+
+ override fun resumeFaceAuth() {
+ faceAuthPaused.value = false
+ }
+
private val keyguardSessionId: InstanceId?
get() = sessionTracker.getSessionId(StatusBarManager.SESSION_KEYGUARD)
@@ -329,11 +350,7 @@ constructor(
"isFaceAuthenticationEnabled",
tableLogBuffer
),
- logAndObserve(
- userRepository.userSwitchingInProgress.isFalse(),
- "userSwitchingNotInProgress",
- tableLogBuffer
- ),
+ logAndObserve(faceAuthPaused.isFalse(), "faceAuthIsNotPaused", tableLogBuffer),
logAndObserve(
keyguardRepository.isKeyguardGoingAway.isFalse(),
"keyguardNotGoingAway",
@@ -454,7 +471,6 @@ constructor(
}
private fun handleFaceCancellationError() {
- cancelNotReceivedHandlerJob?.cancel()
applicationScope.launch {
faceAuthRequestedWhileCancellation?.let {
faceAuthLogger.launchingQueuedFaceAuthRequest(it)
@@ -483,6 +499,7 @@ constructor(
}
private fun onFaceAuthRequestCompleted() {
+ cancelNotReceivedHandlerJob?.cancel()
cancellationInProgress = false
_isAuthRunning.value = false
authCancellationSignal = null
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/NoopDeviceEntryFaceAuthRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/NoopDeviceEntryFaceAuthRepository.kt
index 5ef9a9e0482c..e4e6a6dae6b0 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/NoopDeviceEntryFaceAuthRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/NoopDeviceEntryFaceAuthRepository.kt
@@ -56,6 +56,9 @@ class NoopDeviceEntryFaceAuthRepository @Inject constructor() : DeviceEntryFaceA
get() = emptyFlow()
override fun lockoutFaceAuth() = Unit
+ override fun pauseFaceAuth() = Unit
+
+ override fun resumeFaceAuth() = Unit
/**
* Trigger face authentication.
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/LockscreenSceneInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/LockscreenSceneInteractor.kt
index 1c200b086990..278c68d3c55b 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/LockscreenSceneInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/LockscreenSceneInteractor.kt
@@ -19,10 +19,9 @@ package com.android.systemui.keyguard.domain.interactor
import com.android.systemui.authentication.domain.interactor.AuthenticationInteractor
import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
import com.android.systemui.bouncer.domain.interactor.BouncerInteractor
+import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
-import dagger.assisted.Assisted
-import dagger.assisted.AssistedFactory
-import dagger.assisted.AssistedInject
+import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
@@ -30,17 +29,14 @@ import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
/** Hosts business and application state accessing logic for the lockscreen scene. */
+@SysUISingleton
class LockscreenSceneInteractor
-@AssistedInject
+@Inject
constructor(
@Application applicationScope: CoroutineScope,
private val authenticationInteractor: AuthenticationInteractor,
- bouncerInteractorFactory: BouncerInteractor.Factory,
- @Assisted private val containerName: String,
+ private val bouncerInteractor: BouncerInteractor,
) {
- private val bouncerInteractor: BouncerInteractor =
- bouncerInteractorFactory.create(containerName)
-
/** Whether the device is currently locked. */
val isDeviceLocked: StateFlow<Boolean> =
authenticationInteractor.isUnlocked
@@ -67,13 +63,6 @@ constructor(
/** Attempts to dismiss the lockscreen. This will cause the bouncer to show, if needed. */
fun dismissLockscreen() {
- bouncerInteractor.showOrUnlockDevice(containerName = containerName)
- }
-
- @AssistedFactory
- interface Factory {
- fun create(
- containerName: String,
- ): LockscreenSceneInteractor
+ bouncerInteractor.showOrUnlockDevice()
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/SystemUIKeyguardFaceAuthInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/SystemUIKeyguardFaceAuthInteractor.kt
index 8f4776fa2ed3..2a3f8520a63c 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/SystemUIKeyguardFaceAuthInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/SystemUIKeyguardFaceAuthInteractor.kt
@@ -35,6 +35,7 @@ import com.android.systemui.keyguard.shared.model.ErrorFaceAuthenticationStatus
import com.android.systemui.keyguard.shared.model.FaceAuthenticationStatus
import com.android.systemui.keyguard.shared.model.TransitionState
import com.android.systemui.log.FaceAuthenticationLogger
+import com.android.systemui.user.data.repository.UserRepository
import com.android.systemui.util.kotlin.pairwise
import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher
@@ -49,6 +50,7 @@ import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.merge
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
/**
* Encapsulates business logic related face authentication being triggered for device entry from
@@ -69,6 +71,7 @@ constructor(
private val faceAuthenticationLogger: FaceAuthenticationLogger,
private val keyguardUpdateMonitor: KeyguardUpdateMonitor,
private val deviceEntryFingerprintAuthRepository: DeviceEntryFingerprintAuthRepository,
+ private val userRepository: UserRepository,
) : CoreStartable, KeyguardFaceAuthInteractor {
private val listeners: MutableList<FaceAuthenticationListener> = mutableListOf()
@@ -128,6 +131,23 @@ constructor(
}
}
.launchIn(applicationScope)
+
+ // User switching should stop face auth and then when it is complete we should trigger face
+ // auth so that the switched user can unlock the device with face auth.
+ userRepository.userSwitchingInProgress
+ .pairwise(false)
+ .onEach { (wasSwitching, isSwitching) ->
+ if (!wasSwitching && isSwitching) {
+ repository.pauseFaceAuth()
+ } else if (wasSwitching && !isSwitching) {
+ repository.resumeFaceAuth()
+ runFaceAuth(
+ FaceAuthUiEvent.FACE_AUTH_UPDATED_USER_SWITCHING,
+ fallbackToDetect = true
+ )
+ }
+ }
+ .launchIn(applicationScope)
}
override fun onSwipeUpOnBouncer() {
@@ -199,8 +219,10 @@ constructor(
} else {
faceAuthenticationStatusOverride.value = null
applicationScope.launch {
- faceAuthenticationLogger.authRequested(uiEvent)
- repository.authenticate(uiEvent, fallbackToDetection = fallbackToDetect)
+ withContext(mainDispatcher) {
+ faceAuthenticationLogger.authRequested(uiEvent)
+ repository.authenticate(uiEvent, fallbackToDetection = fallbackToDetect)
+ }
}
}
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModel.kt
index f212a553aeb3..abd178ca6c1d 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModel.kt
@@ -19,12 +19,11 @@ package com.android.systemui.keyguard.ui.viewmodel
import com.android.systemui.R
import com.android.systemui.common.shared.model.ContentDescription
import com.android.systemui.common.shared.model.Icon
+import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.keyguard.domain.interactor.LockscreenSceneInteractor
import com.android.systemui.scene.shared.model.SceneKey
-import dagger.assisted.Assisted
-import dagger.assisted.AssistedFactory
-import dagger.assisted.AssistedInject
+import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
@@ -32,15 +31,13 @@ import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
/** Models UI state and handles user input for the lockscreen scene. */
+@SysUISingleton
class LockscreenSceneViewModel
-@AssistedInject
+@Inject
constructor(
@Application applicationScope: CoroutineScope,
- interactorFactory: LockscreenSceneInteractor.Factory,
- @Assisted containerName: String,
+ private val interactor: LockscreenSceneInteractor,
) {
- private val interactor: LockscreenSceneInteractor = interactorFactory.create(containerName)
-
/** The icon for the "lock" button on the lockscreen. */
val lockButtonIcon: StateFlow<Icon> =
interactor.isDeviceLocked
@@ -98,11 +95,4 @@ constructor(
)
)
}
-
- @AssistedFactory
- interface Factory {
- fun create(
- containerName: String,
- ): LockscreenSceneViewModel
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaProjectionAppSelectorActivity.kt b/packages/SystemUI/src/com/android/systemui/media/MediaProjectionAppSelectorActivity.kt
index 42164c795b06..fdb3ddd7294f 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaProjectionAppSelectorActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaProjectionAppSelectorActivity.kt
@@ -30,16 +30,11 @@ import android.os.IBinder
import android.os.ResultReceiver
import android.os.UserHandle
import android.view.ViewGroup
-import androidx.lifecycle.Lifecycle
-import androidx.lifecycle.LifecycleOwner
-import androidx.lifecycle.LifecycleRegistry
+import com.android.intentresolver.AbstractMultiProfilePagerAdapter.EmptyStateProvider
+import com.android.intentresolver.AbstractMultiProfilePagerAdapter.MyUserIdProvider
+import com.android.intentresolver.ChooserActivity
+import com.android.intentresolver.chooser.TargetInfo
import com.android.internal.annotations.VisibleForTesting
-import com.android.internal.app.AbstractMultiProfilePagerAdapter.EmptyStateProvider
-import com.android.internal.app.AbstractMultiProfilePagerAdapter.MyUserIdProvider
-import com.android.internal.app.ChooserActivity
-import com.android.internal.app.ResolverListController
-import com.android.internal.app.chooser.NotSelectableTargetInfo
-import com.android.internal.app.chooser.TargetInfo
import com.android.systemui.R
import com.android.systemui.mediaprojection.appselector.MediaProjectionAppSelectorComponent
import com.android.systemui.mediaprojection.appselector.MediaProjectionAppSelectorController
@@ -56,12 +51,8 @@ class MediaProjectionAppSelectorActivity(
private val activityLauncher: AsyncActivityLauncher,
/** This is used to override the dependency in a screenshot test */
@VisibleForTesting
- private val listControllerFactory: ((userHandle: UserHandle) -> ResolverListController)?
-) :
- ChooserActivity(),
- MediaProjectionAppSelectorView,
- MediaProjectionAppSelectorResultHandler,
- LifecycleOwner {
+ private val listControllerFactory: ((userHandle: UserHandle) -> ChooserListController)?
+) : ChooserActivity(), MediaProjectionAppSelectorView, MediaProjectionAppSelectorResultHandler {
@Inject
constructor(
@@ -69,8 +60,6 @@ class MediaProjectionAppSelectorActivity(
activityLauncher: AsyncActivityLauncher
) : this(componentFactory, activityLauncher, listControllerFactory = null)
- private val lifecycleRegistry = LifecycleRegistry(this)
- override val lifecycle = lifecycleRegistry
private lateinit var configurationController: ConfigurationController
private lateinit var controller: MediaProjectionAppSelectorController
private lateinit var recentsViewController: MediaProjectionRecentsViewController
@@ -84,7 +73,6 @@ class MediaProjectionAppSelectorActivity(
override fun getLayoutResource() = R.layout.media_projection_app_selector
public override fun onCreate(bundle: Bundle?) {
- lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE)
component = componentFactory.create(view = this, resultHandler = this)
component.lifecycleObservers.forEach { lifecycle.addObserver(it) }
@@ -107,26 +95,6 @@ class MediaProjectionAppSelectorActivity(
controller.init()
}
- override fun onStart() {
- super.onStart()
- lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START)
- }
-
- override fun onResume() {
- super.onResume()
- lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME)
- }
-
- override fun onPause() {
- lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_PAUSE)
- super.onPause()
- }
-
- override fun onStop() {
- lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP)
- super.onStop()
- }
-
override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
configurationController.onConfigurationChanged(newConfig)
@@ -137,13 +105,13 @@ class MediaProjectionAppSelectorActivity(
override fun createBlockerEmptyStateProvider(): EmptyStateProvider =
component.emptyStateProvider
- override fun createListController(userHandle: UserHandle): ResolverListController =
+ override fun createListController(userHandle: UserHandle): ChooserListController =
listControllerFactory?.invoke(userHandle) ?: super.createListController(userHandle)
override fun startSelected(which: Int, always: Boolean, filtered: Boolean) {
val currentListAdapter = mChooserMultiProfilePagerAdapter.activeListAdapter
val targetInfo = currentListAdapter.targetInfoForPosition(which, filtered) ?: return
- if (targetInfo is NotSelectableTargetInfo) return
+ if (targetInfo.isNotSelectableTargetInfo) return
val intent = createIntent(targetInfo)
@@ -183,7 +151,6 @@ class MediaProjectionAppSelectorActivity(
}
override fun onDestroy() {
- lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY)
component.lifecycleObservers.forEach { lifecycle.removeObserver(it) }
// onDestroy is also called when an app is selected, in that case we only want to send
// RECORD_CONTENT_TASK but not RECORD_CANCEL
diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionBlockerEmptyStateProvider.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionBlockerEmptyStateProvider.kt
index 829b0ddbe3a8..fd14e2b9a96b 100644
--- a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionBlockerEmptyStateProvider.kt
+++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionBlockerEmptyStateProvider.kt
@@ -17,10 +17,10 @@ package com.android.systemui.mediaprojection.appselector
import android.content.Context
import android.os.UserHandle
+import com.android.intentresolver.AbstractMultiProfilePagerAdapter.EmptyState
+import com.android.intentresolver.AbstractMultiProfilePagerAdapter.EmptyStateProvider
+import com.android.intentresolver.ResolverListAdapter
import com.android.internal.R as AndroidR
-import com.android.internal.app.AbstractMultiProfilePagerAdapter.EmptyState
-import com.android.internal.app.AbstractMultiProfilePagerAdapter.EmptyStateProvider
-import com.android.internal.app.ResolverListAdapter
import com.android.systemui.R
import com.android.systemui.mediaprojection.devicepolicy.PersonalProfile
import com.android.systemui.mediaprojection.devicepolicy.ScreenCaptureDevicePolicyResolver
diff --git a/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModel.kt
index 36dec1d112b9..5e6a44bf8130 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModel.kt
@@ -16,30 +16,19 @@
package com.android.systemui.qs.ui.viewmodel
+import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.keyguard.domain.interactor.LockscreenSceneInteractor
-import dagger.assisted.Assisted
-import dagger.assisted.AssistedFactory
-import dagger.assisted.AssistedInject
+import javax.inject.Inject
/** Models UI state and handles user input for the quick settings scene. */
+@SysUISingleton
class QuickSettingsSceneViewModel
-@AssistedInject
+@Inject
constructor(
- lockscreenSceneInteractorFactory: LockscreenSceneInteractor.Factory,
- @Assisted containerName: String,
+ private val lockscreenSceneInteractor: LockscreenSceneInteractor,
) {
- private val lockscreenSceneInteractor: LockscreenSceneInteractor =
- lockscreenSceneInteractorFactory.create(containerName)
-
/** Notifies that some content in quick settings was clicked. */
fun onContentClicked() {
lockscreenSceneInteractor.dismissLockscreen()
}
-
- @AssistedFactory
- interface Factory {
- fun create(
- containerName: String,
- ): QuickSettingsSceneViewModel
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
index bf40a2d0ad51..03bd11bb433e 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
@@ -97,7 +97,6 @@ import com.android.systemui.navigationbar.NavigationModeController;
import com.android.systemui.navigationbar.buttons.KeyButtonView;
import com.android.systemui.recents.OverviewProxyService.OverviewProxyListener;
import com.android.systemui.scene.domain.interactor.SceneInteractor;
-import com.android.systemui.scene.shared.model.SceneContainerNames;
import com.android.systemui.settings.DisplayTracker;
import com.android.systemui.settings.UserTracker;
import com.android.systemui.shade.ShadeViewController;
@@ -221,8 +220,7 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis
// If scene framework is enabled, set the scene container window to
// visible and let the touch "slip" into that window.
if (mFeatureFlags.isEnabled(Flags.SCENE_CONTAINER)) {
- mSceneInteractor.get().setVisible(
- SceneContainerNames.SYSTEM_UI_DEFAULT, true);
+ mSceneInteractor.get().setVisible(true);
} else {
centralSurfaces.onInputFocusTransfer(
mInputFocusTransferStarted, false /* cancel */,
diff --git a/packages/SystemUI/src/com/android/systemui/scene/SceneContainerFrameworkModule.kt b/packages/SystemUI/src/com/android/systemui/scene/SceneContainerFrameworkModule.kt
index 26c52199f493..398e64b1981b 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/SceneContainerFrameworkModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/SceneContainerFrameworkModule.kt
@@ -19,7 +19,6 @@ package com.android.systemui.scene
import com.android.systemui.scene.domain.startable.SceneContainerStartableModule
import com.android.systemui.scene.shared.model.SceneContainerConfigModule
import com.android.systemui.scene.ui.composable.SceneModule
-import com.android.systemui.scene.ui.viewmodel.SceneContainerViewModelModule
import dagger.Module
@Module(
@@ -27,7 +26,6 @@ import dagger.Module
[
SceneContainerConfigModule::class,
SceneContainerStartableModule::class,
- SceneContainerViewModelModule::class,
SceneModule::class,
],
)
diff --git a/packages/SystemUI/src/com/android/systemui/scene/data/repository/SceneContainerRepository.kt b/packages/SystemUI/src/com/android/systemui/scene/data/repository/SceneContainerRepository.kt
index 0a86d35b7b62..1fca4886a31f 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/data/repository/SceneContainerRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/data/repository/SceneContainerRepository.kt
@@ -29,26 +29,20 @@ import kotlinx.coroutines.flow.asStateFlow
class SceneContainerRepository
@Inject
constructor(
- private val containerConfigByName: Map<String, SceneContainerConfig>,
+ private val config: SceneContainerConfig,
) {
- private val containerVisibilityByName: Map<String, MutableStateFlow<Boolean>> =
- containerConfigByName
- .map { (containerName, _) -> containerName to MutableStateFlow(true) }
- .toMap()
- private val currentSceneByContainerName: Map<String, MutableStateFlow<SceneModel>> =
- containerConfigByName
- .map { (containerName, config) ->
- containerName to MutableStateFlow(SceneModel(config.initialSceneKey))
- }
- .toMap()
- private val sceneTransitionProgressByContainerName: Map<String, MutableStateFlow<Float>> =
- containerConfigByName
- .map { (containerName, _) -> containerName to MutableStateFlow(1f) }
- .toMap()
- private val sceneTransitionByContainerName:
- Map<String, MutableStateFlow<SceneTransitionModel?>> =
- containerConfigByName.keys.associateWith { MutableStateFlow(null) }
+ private val _isVisible = MutableStateFlow(true)
+ val isVisible: StateFlow<Boolean> = _isVisible.asStateFlow()
+
+ private val _currentScene = MutableStateFlow(SceneModel(config.initialSceneKey))
+ val currentScene: StateFlow<SceneModel> = _currentScene.asStateFlow()
+
+ private val _transitionProgress = MutableStateFlow(1f)
+ val transitionProgress: StateFlow<Float> = _transitionProgress.asStateFlow()
+
+ private val _transitions = MutableStateFlow<SceneTransitionModel?>(null)
+ val transitions: StateFlow<SceneTransitionModel?> = _transitions.asStateFlow()
/**
* Returns the keys to all scenes in the container with the given name.
@@ -56,100 +50,50 @@ constructor(
* The scenes will be sorted in z-order such that the last one is the one that should be
* rendered on top of all previous ones.
*/
- fun allSceneKeys(containerName: String): List<SceneKey> {
- return containerConfigByName[containerName]?.sceneKeys
- ?: error(noSuchContainerErrorMessage(containerName))
+ fun allSceneKeys(): List<SceneKey> {
+ return config.sceneKeys
}
/** Sets the current scene in the container with the given name. */
- fun setCurrentScene(containerName: String, scene: SceneModel) {
- check(allSceneKeys(containerName).contains(scene.key)) {
+ fun setCurrentScene(scene: SceneModel) {
+ check(allSceneKeys().contains(scene.key)) {
"""
- Cannot set current scene key to "${scene.key}". The container "$containerName" does
- not contain a scene with that key.
+ Cannot set current scene key to "${scene.key}". The configuration does not contain a
+ scene with that key.
"""
.trimIndent()
}
- currentSceneByContainerName.setValue(containerName, scene)
+ _currentScene.value = scene
}
/** Sets the scene transition in the container with the given name. */
- fun setSceneTransition(containerName: String, from: SceneKey, to: SceneKey) {
- check(allSceneKeys(containerName).contains(from)) {
+ fun setSceneTransition(from: SceneKey, to: SceneKey) {
+ check(allSceneKeys().contains(from)) {
"""
- Cannot set current scene key to "$from". The container "$containerName" does
- not contain a scene with that key.
+ Cannot set current scene key to "$from". The configuration does not contain a scene
+ with that key.
"""
.trimIndent()
}
- check(allSceneKeys(containerName).contains(to)) {
+ check(allSceneKeys().contains(to)) {
"""
- Cannot set current scene key to "$to". The container "$containerName" does
- not contain a scene with that key.
+ Cannot set current scene key to "$to". The configuration does not contain a scene
+ with that key.
"""
.trimIndent()
}
- sceneTransitionByContainerName.setValue(
- containerName,
- SceneTransitionModel(from = from, to = to)
- )
- }
-
- /** The current scene in the container with the given name. */
- fun currentScene(containerName: String): StateFlow<SceneModel> {
- return currentSceneByContainerName.mutableOrError(containerName).asStateFlow()
- }
-
- /**
- * Scene transitions as pairs of keys. A new value is emitted exactly once, each time a scene
- * transition occurs. The flow begins with a `null` value at first, because the initial scene is
- * not something that we transition to from another scene.
- */
- fun sceneTransitions(containerName: String): StateFlow<SceneTransitionModel?> {
- return sceneTransitionByContainerName.mutableOrError(containerName).asStateFlow()
+ _transitions.value = SceneTransitionModel(from = from, to = to)
}
/** Sets whether the container with the given name is visible. */
- fun setVisible(containerName: String, isVisible: Boolean) {
- containerVisibilityByName.setValue(containerName, isVisible)
- }
-
- /** Whether the container with the given name should be visible. */
- fun isVisible(containerName: String): StateFlow<Boolean> {
- return containerVisibilityByName.mutableOrError(containerName).asStateFlow()
+ fun setVisible(isVisible: Boolean) {
+ _isVisible.value = isVisible
}
/** Sets scene transition progress to the current scene in the container with the given name. */
- fun setSceneTransitionProgress(containerName: String, progress: Float) {
- sceneTransitionProgressByContainerName.setValue(containerName, progress)
- }
-
- /** Progress of the transition into the current scene in the container with the given name. */
- fun sceneTransitionProgress(containerName: String): StateFlow<Float> {
- return sceneTransitionProgressByContainerName.mutableOrError(containerName).asStateFlow()
- }
-
- private fun <T> Map<String, MutableStateFlow<T>>.mutableOrError(
- containerName: String,
- ): MutableStateFlow<T> {
- return this[containerName] ?: error(noSuchContainerErrorMessage(containerName))
- }
-
- private fun <T> Map<String, MutableStateFlow<T>>.setValue(
- containerName: String,
- value: T,
- ) {
- val mutable = mutableOrError(containerName)
- mutable.value = value
- }
-
- private fun noSuchContainerErrorMessage(containerName: String): String {
- return """
- No container named "$containerName". Existing containers:
- ${containerConfigByName.values.joinToString(", ") { it.name }}
- """
- .trimIndent()
+ fun setSceneTransitionProgress(progress: Float) {
+ _transitionProgress.value = progress
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneInteractor.kt b/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneInteractor.kt
index f03f040c206d..39daad33f75e 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneInteractor.kt
@@ -30,12 +30,8 @@ import kotlinx.coroutines.flow.asStateFlow
/**
* Generic business logic and app state accessors for the scene framework.
*
- * Note that scene container specific business logic does not belong in this class. Instead, it
- * should be hoisted to a class that is specific to that scene container, for an example, please see
- * [SystemUiDefaultSceneContainerStartable].
- *
- * Also note that this class should not depend on state or logic of other modules or features.
- * Instead, other feature modules should depend on and call into this class when their parts of the
+ * Note that this class should not depend on state or logic of other modules or features. Instead,
+ * other feature modules should depend on and call into this class when their parts of the
* application state change.
*/
@SysUISingleton
@@ -51,50 +47,42 @@ constructor(
* The scenes will be sorted in z-order such that the last one is the one that should be
* rendered on top of all previous ones.
*/
- fun allSceneKeys(containerName: String): List<SceneKey> {
- return repository.allSceneKeys(containerName)
+ fun allSceneKeys(): List<SceneKey> {
+ return repository.allSceneKeys()
}
/** Sets the scene in the container with the given name. */
- fun setCurrentScene(containerName: String, scene: SceneModel) {
- val currentSceneKey = repository.currentScene(containerName).value.key
- repository.setCurrentScene(containerName, scene)
- repository.setSceneTransition(containerName, from = currentSceneKey, to = scene.key)
+ fun setCurrentScene(scene: SceneModel) {
+ val currentSceneKey = repository.currentScene.value.key
+ repository.setCurrentScene(scene)
+ repository.setSceneTransition(from = currentSceneKey, to = scene.key)
}
/** The current scene in the container with the given name. */
- fun currentScene(containerName: String): StateFlow<SceneModel> {
- return repository.currentScene(containerName)
- }
+ val currentScene: StateFlow<SceneModel> = repository.currentScene
/** Sets the visibility of the container with the given name. */
- fun setVisible(containerName: String, isVisible: Boolean) {
- return repository.setVisible(containerName, isVisible)
+ fun setVisible(isVisible: Boolean) {
+ return repository.setVisible(isVisible)
}
/** Whether the container with the given name is visible. */
- fun isVisible(containerName: String): StateFlow<Boolean> {
- return repository.isVisible(containerName)
- }
+ val isVisible: StateFlow<Boolean> = repository.isVisible
/** Sets scene transition progress to the current scene in the container with the given name. */
- fun setSceneTransitionProgress(containerName: String, progress: Float) {
- repository.setSceneTransitionProgress(containerName, progress)
+ fun setSceneTransitionProgress(progress: Float) {
+ repository.setSceneTransitionProgress(progress)
}
/** Progress of the transition into the current scene in the container with the given name. */
- fun sceneTransitionProgress(containerName: String): StateFlow<Float> {
- return repository.sceneTransitionProgress(containerName)
- }
+ val transitionProgress: StateFlow<Float> = repository.transitionProgress
/**
* Scene transitions as pairs of keys. A new value is emitted exactly once, each time a scene
* transition occurs. The flow begins with a `null` value at first, because the initial scene is
* not something that we transition to from another scene.
*/
- fun sceneTransitions(containerName: String): StateFlow<SceneTransitionModel?> {
- return repository.sceneTransitions(containerName)
- }
+ val transitions: StateFlow<SceneTransitionModel?> = repository.transitions
private val _remoteUserInput: MutableStateFlow<RemoteUserInput?> = MutableStateFlow(null)
diff --git a/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SystemUiDefaultSceneContainerStartable.kt b/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt
index 92384d68157b..1c87eb25004e 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SystemUiDefaultSceneContainerStartable.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt
@@ -28,7 +28,6 @@ import com.android.systemui.keyguard.shared.model.WakefulnessState
import com.android.systemui.model.SysUiState
import com.android.systemui.model.updateFlags
import com.android.systemui.scene.domain.interactor.SceneInteractor
-import com.android.systemui.scene.shared.model.SceneContainerNames
import com.android.systemui.scene.shared.model.SceneKey
import com.android.systemui.scene.shared.model.SceneModel
import com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BOUNCER_SHOWING
@@ -44,12 +43,11 @@ import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch
/**
- * Hooks up business logic that manipulates the state of the [SceneInteractor] for the default
- * system UI scene container (the one named [SceneContainerNames.SYSTEM_UI_DEFAULT]) based on state
- * from other systems.
+ * Hooks up business logic that manipulates the state of the [SceneInteractor] for the system UI
+ * scene container based on state from other systems.
*/
@SysUISingleton
-class SystemUiDefaultSceneContainerStartable
+class SceneContainerStartable
@Inject
constructor(
@Application private val applicationScope: CoroutineScope,
@@ -72,13 +70,10 @@ constructor(
/** Updates the visibility of the scene container based on the current scene. */
private fun hydrateVisibility() {
applicationScope.launch {
- sceneInteractor
- .currentScene(CONTAINER_NAME)
+ sceneInteractor.currentScene
.map { it.key }
.distinctUntilChanged()
- .collect { sceneKey ->
- sceneInteractor.setVisible(CONTAINER_NAME, sceneKey != SceneKey.Gone)
- }
+ .collect { sceneKey -> sceneInteractor.setVisible(sceneKey != SceneKey.Gone) }
}
}
@@ -87,7 +82,7 @@ constructor(
applicationScope.launch {
authenticationInteractor.isUnlocked
.map { isUnlocked ->
- val currentSceneKey = sceneInteractor.currentScene(CONTAINER_NAME).value.key
+ val currentSceneKey = sceneInteractor.currentScene.value.key
val isBypassEnabled = authenticationInteractor.isBypassEnabled()
when {
isUnlocked ->
@@ -135,8 +130,7 @@ constructor(
/** Keeps [SysUiState] up-to-date */
private fun hydrateSystemUiState() {
applicationScope.launch {
- sceneInteractor
- .currentScene(SceneContainerNames.SYSTEM_UI_DEFAULT)
+ sceneInteractor.currentScene
.map { it.key }
.distinctUntilChanged()
.collect { sceneKey ->
@@ -155,12 +149,7 @@ constructor(
private fun switchToScene(targetSceneKey: SceneKey) {
sceneInteractor.setCurrentScene(
- containerName = CONTAINER_NAME,
scene = SceneModel(targetSceneKey),
)
}
-
- companion object {
- private const val CONTAINER_NAME = SceneContainerNames.SYSTEM_UI_DEFAULT
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartableModule.kt b/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartableModule.kt
index b3de2d158a53..8da1803053f4 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartableModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartableModule.kt
@@ -27,6 +27,6 @@ interface SceneContainerStartableModule {
@Binds
@IntoMap
- @ClassKey(SystemUiDefaultSceneContainerStartable::class)
- fun bind(impl: SystemUiDefaultSceneContainerStartable): CoreStartable
+ @ClassKey(SceneContainerStartable::class)
+ fun bind(impl: SceneContainerStartable): CoreStartable
}
diff --git a/packages/SystemUI/src/com/android/systemui/scene/shared/model/Scene.kt b/packages/SystemUI/src/com/android/systemui/scene/shared/model/Scene.kt
index 354de8ac7aa5..31597c1752db 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/shared/model/Scene.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/shared/model/Scene.kt
@@ -27,8 +27,6 @@ import kotlinx.coroutines.flow.asStateFlow
* takes care of rendering the current scene and allowing scenes to be switched from one to another
* based on either user action (for example, swiping down while on the lock screen scene may switch
* to the shade scene).
- *
- * The framework also supports multiple containers, each one with its own configuration.
*/
interface Scene {
@@ -59,7 +57,7 @@ interface Scene {
* The API is designed such that it's possible to emit ever-changing values for each
* [UserAction] to enable, disable, or change the destination scene of a given user action.
*/
- fun destinationScenes(containerName: String): StateFlow<Map<UserAction, SceneModel>> =
+ fun destinationScenes(): StateFlow<Map<UserAction, SceneModel>> =
MutableStateFlow(emptyMap<UserAction, SceneModel>()).asStateFlow()
}
diff --git a/packages/SystemUI/src/com/android/systemui/scene/shared/model/SceneContainerConfig.kt b/packages/SystemUI/src/com/android/systemui/scene/shared/model/SceneContainerConfig.kt
index 0327edbb06b4..8204edc33fe4 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/shared/model/SceneContainerConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/shared/model/SceneContainerConfig.kt
@@ -16,10 +16,8 @@
package com.android.systemui.scene.shared.model
-/** Models the configuration of a single scene container. */
+/** Models the configuration of the scene container. */
data class SceneContainerConfig(
- /** Container name. Must be unique across all containers in System UI. */
- val name: String,
/**
* The keys to all scenes in the container, sorted by z-order such that the last one renders on
diff --git a/packages/SystemUI/src/com/android/systemui/scene/shared/model/SceneContainerConfigModule.kt b/packages/SystemUI/src/com/android/systemui/scene/shared/model/SceneContainerConfigModule.kt
index 7562a5a848d8..f74005b03816 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/shared/model/SceneContainerConfigModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/shared/model/SceneContainerConfigModule.kt
@@ -16,44 +16,27 @@
package com.android.systemui.scene.shared.model
-import com.android.systemui.dagger.SysUISingleton
import dagger.Module
import dagger.Provides
-import javax.inject.Named
@Module
object SceneContainerConfigModule {
@Provides
- fun containerConfigs(): Map<String, SceneContainerConfig> {
- return mapOf(
- SceneContainerNames.SYSTEM_UI_DEFAULT to
- SceneContainerConfig(
- name = SceneContainerNames.SYSTEM_UI_DEFAULT,
- // Note that this list is in z-order. The first one is the bottom-most and the
- // last
- // one is top-most.
- sceneKeys =
- listOf(
- SceneKey.Gone,
- SceneKey.Lockscreen,
- SceneKey.Bouncer,
- SceneKey.Shade,
- SceneKey.QuickSettings,
- ),
- initialSceneKey = SceneKey.Lockscreen,
+ fun containerConfig(): SceneContainerConfig {
+ return SceneContainerConfig(
+ // Note that this list is in z-order. The first one is the bottom-most and the
+ // last
+ // one is top-most.
+ sceneKeys =
+ listOf(
+ SceneKey.Gone,
+ SceneKey.Lockscreen,
+ SceneKey.Bouncer,
+ SceneKey.Shade,
+ SceneKey.QuickSettings,
),
+ initialSceneKey = SceneKey.Lockscreen,
)
}
-
- @Provides
- @SysUISingleton
- @Named(SceneContainerNames.SYSTEM_UI_DEFAULT)
- fun provideDefaultSceneContainerConfig(
- configs: Map<String, SceneContainerConfig>,
- ): SceneContainerConfig {
- return checkNotNull(configs[SceneContainerNames.SYSTEM_UI_DEFAULT]) {
- "No SceneContainerConfig named \"${SceneContainerNames.SYSTEM_UI_DEFAULT}\"."
- }
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModel.kt b/packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModel.kt
index 005f48d9f250..f44748a99080 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModel.kt
@@ -17,16 +17,20 @@
package com.android.systemui.scene.ui.viewmodel
import android.view.MotionEvent
+import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.scene.domain.interactor.SceneInteractor
import com.android.systemui.scene.shared.model.RemoteUserInput
import com.android.systemui.scene.shared.model.SceneKey
import com.android.systemui.scene.shared.model.SceneModel
+import javax.inject.Inject
import kotlinx.coroutines.flow.StateFlow
-/** Models UI state for a single scene container. */
-class SceneContainerViewModel(
+/** Models UI state for the scene container. */
+@SysUISingleton
+class SceneContainerViewModel
+@Inject
+constructor(
private val interactor: SceneInteractor,
- val containerName: String,
) {
/** A flow of motion events originating from outside of the scene framework. */
val remoteUserInput: StateFlow<RemoteUserInput?> = interactor.remoteUserInput
@@ -37,22 +41,22 @@ class SceneContainerViewModel(
* The scenes will be sorted in z-order such that the last one is the one that should be
* rendered on top of all previous ones.
*/
- val allSceneKeys: List<SceneKey> = interactor.allSceneKeys(containerName)
+ val allSceneKeys: List<SceneKey> = interactor.allSceneKeys()
/** The current scene. */
- val currentScene: StateFlow<SceneModel> = interactor.currentScene(containerName)
+ val currentScene: StateFlow<SceneModel> = interactor.currentScene
/** Whether the container is visible. */
- val isVisible: StateFlow<Boolean> = interactor.isVisible(containerName)
+ val isVisible: StateFlow<Boolean> = interactor.isVisible
/** Requests a transition to the scene with the given key. */
fun setCurrentScene(scene: SceneModel) {
- interactor.setCurrentScene(containerName, scene)
+ interactor.setCurrentScene(scene)
}
/** Notifies of the progress of a scene transition. */
fun setSceneTransitionProgress(progress: Float) {
- interactor.setSceneTransitionProgress(containerName, progress)
+ interactor.setSceneTransitionProgress(progress)
}
/** Handles a [MotionEvent] representing remote user input. */
diff --git a/packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModelModule.kt b/packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModelModule.kt
deleted file mode 100644
index 100f42764322..000000000000
--- a/packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModelModule.kt
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.scene.ui.viewmodel
-
-import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.scene.domain.interactor.SceneInteractor
-import com.android.systemui.scene.shared.model.SceneContainerNames
-import dagger.Module
-import dagger.Provides
-import javax.inject.Named
-
-@Module
-object SceneContainerViewModelModule {
-
- @Provides
- @SysUISingleton
- @Named(SceneContainerNames.SYSTEM_UI_DEFAULT)
- fun defaultSceneContainerViewModel(
- interactor: SceneInteractor,
- ): SceneContainerViewModel {
- return SceneContainerViewModel(
- interactor = interactor,
- containerName = SceneContainerNames.SYSTEM_UI_DEFAULT,
- )
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeViewProviderModule.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeViewProviderModule.kt
index e02c4275f095..29551188c5c7 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeViewProviderModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeViewProviderModule.kt
@@ -36,7 +36,6 @@ import com.android.systemui.keyguard.ui.view.KeyguardRootView
import com.android.systemui.privacy.OngoingPrivacyChip
import com.android.systemui.scene.shared.model.Scene
import com.android.systemui.scene.shared.model.SceneContainerConfig
-import com.android.systemui.scene.shared.model.SceneContainerNames
import com.android.systemui.scene.ui.view.SceneWindowRootView
import com.android.systemui.scene.ui.view.WindowRootView
import com.android.systemui.scene.ui.viewmodel.SceneContainerViewModel
@@ -73,11 +72,8 @@ abstract class ShadeViewProviderModule {
fun providesWindowRootView(
layoutInflater: LayoutInflater,
featureFlags: FeatureFlags,
- @Named(SceneContainerNames.SYSTEM_UI_DEFAULT)
viewModelProvider: Provider<SceneContainerViewModel>,
- @Named(SceneContainerNames.SYSTEM_UI_DEFAULT)
containerConfigProvider: Provider<SceneContainerConfig>,
- @Named(SceneContainerNames.SYSTEM_UI_DEFAULT)
scenesProvider: Provider<Set<@JvmSuppressWildcards Scene>>,
layoutInsetController: NotificationInsetsController,
): WindowRootView {
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModel.kt b/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModel.kt
index 8a96a4764e66..0b3ed5601c2e 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModel.kt
@@ -16,12 +16,11 @@
package com.android.systemui.shade.ui.viewmodel
+import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.keyguard.domain.interactor.LockscreenSceneInteractor
import com.android.systemui.scene.shared.model.SceneKey
-import dagger.assisted.Assisted
-import dagger.assisted.AssistedFactory
-import dagger.assisted.AssistedInject
+import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
@@ -29,32 +28,29 @@ import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
/** Models UI state and handles user input for the shade scene. */
+@SysUISingleton
class ShadeSceneViewModel
-@AssistedInject
+@Inject
constructor(
@Application private val applicationScope: CoroutineScope,
- lockscreenSceneInteractorFactory: LockscreenSceneInteractor.Factory,
- @Assisted private val containerName: String,
+ private val lockscreenSceneInteractor: LockscreenSceneInteractor,
) {
- private val lockScreenInteractor: LockscreenSceneInteractor =
- lockscreenSceneInteractorFactory.create(containerName)
-
/** The key of the scene we should switch to when swiping up. */
val upDestinationSceneKey: StateFlow<SceneKey> =
- lockScreenInteractor.isDeviceLocked
+ lockscreenSceneInteractor.isDeviceLocked
.map { isLocked -> upDestinationSceneKey(isLocked = isLocked) }
.stateIn(
scope = applicationScope,
started = SharingStarted.WhileSubscribed(),
initialValue =
upDestinationSceneKey(
- isLocked = lockScreenInteractor.isDeviceLocked.value,
+ isLocked = lockscreenSceneInteractor.isDeviceLocked.value,
),
)
/** Notifies that some content in the shade was clicked. */
fun onContentClicked() {
- lockScreenInteractor.dismissLockscreen()
+ lockscreenSceneInteractor.dismissLockscreen()
}
private fun upDestinationSceneKey(
@@ -62,11 +58,4 @@ constructor(
): SceneKey {
return if (isLocked) SceneKey.Lockscreen else SceneKey.Gone
}
-
- @AssistedFactory
- interface Factory {
- fun create(
- containerName: String,
- ): ShadeSceneViewModel
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationMemoryModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationMemoryModule.kt
new file mode 100644
index 000000000000..92e9765936d7
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationMemoryModule.kt
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.statusbar.notification.dagger
+
+import com.android.systemui.CoreStartable
+import com.android.systemui.statusbar.notification.logging.NotificationMemoryMonitor
+import dagger.Binds
+import dagger.Module
+import dagger.multibindings.ClassKey
+import dagger.multibindings.IntoMap
+
+@Module
+interface NotificationMemoryModule {
+
+ /** Binds memory monitor into startable map. */
+ @Binds
+ @IntoMap
+ @ClassKey(NotificationMemoryMonitor::class)
+ fun bindsNotificationMemoryMonitorStartable(monitor: NotificationMemoryMonitor): CoreStartable
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerImpl.kt
index f7bd177594a2..106d11f6bcc1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerImpl.kt
@@ -39,7 +39,6 @@ import com.android.systemui.statusbar.notification.collection.notifcollection.No
import com.android.systemui.statusbar.notification.collection.render.NotifStackController
import com.android.systemui.statusbar.notification.interruption.HeadsUpViewBinder
import com.android.systemui.statusbar.notification.logging.NotificationLogger
-import com.android.systemui.statusbar.notification.logging.NotificationMemoryMonitor
import com.android.systemui.statusbar.notification.row.NotifBindPipelineInitializer
import com.android.systemui.statusbar.notification.stack.NotificationListContainer
import com.android.wm.shell.bubbles.Bubbles
@@ -72,7 +71,6 @@ class NotificationsControllerImpl @Inject constructor(
private val peopleSpaceWidgetManager: PeopleSpaceWidgetManager,
private val bubblesOptional: Optional<Bubbles>,
private val fgsNotifListener: ForegroundServiceNotificationListener,
- private val memoryMonitor: Lazy<NotificationMemoryMonitor>,
private val featureFlags: FeatureFlags
) : NotificationsController {
@@ -108,7 +106,6 @@ class NotificationsControllerImpl @Inject constructor(
notificationLogger.setUpWithContainer(listContainer)
peopleSpaceWidgetManager.attach(notificationListener)
fgsNotifListener.init()
- memoryMonitor.get().init()
}
// TODO: Convert all functions below this line into listeners instead of public methods
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryMonitor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryMonitor.kt
index f38c1e557b25..0fdf681aac26 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryMonitor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationMemoryMonitor.kt
@@ -18,6 +18,7 @@
package com.android.systemui.statusbar.notification.logging
import android.util.Log
+import com.android.systemui.CoreStartable
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags
@@ -32,13 +33,13 @@ constructor(
private val featureFlags: FeatureFlags,
private val notificationMemoryDumper: NotificationMemoryDumper,
private val notificationMemoryLogger: Lazy<NotificationMemoryLogger>,
-) {
+) : CoreStartable {
companion object {
private const val TAG = "NotificationMemory"
}
- fun init() {
+ override fun start() {
Log.d(TAG, "NotificationMemoryMonitor initialized.")
notificationMemoryDumper.init()
if (featureFlags.isEnabled(Flags.NOTIFICATION_MEMORY_LOGGING_ENABLED)) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
index 36a8e9833d39..5e7e4be60104 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
@@ -426,16 +426,21 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
updateAppearAnimationAlpha();
updateAppearRect();
mAppearAnimator.addListener(new AnimatorListenerAdapter() {
- private boolean mWasCancelled;
+ private boolean mRunWithoutInterruptions;
@Override
public void onAnimationEnd(Animator animation) {
if (onFinishedRunnable != null) {
onFinishedRunnable.run();
}
- if (!mWasCancelled) {
+ if (mRunWithoutInterruptions) {
enableAppearDrawing(false);
- onAppearAnimationFinished(isAppearing);
+ }
+
+ // We need to reset the View state, even if the animation was cancelled
+ onAppearAnimationFinished(isAppearing);
+
+ if (mRunWithoutInterruptions) {
InteractionJankMonitor.getInstance().end(getCujType(isAppearing));
} else {
InteractionJankMonitor.getInstance().cancel(getCujType(isAppearing));
@@ -444,7 +449,7 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
@Override
public void onAnimationStart(Animator animation) {
- mWasCancelled = false;
+ mRunWithoutInterruptions = true;
Configuration.Builder builder = Configuration.Builder
.withView(getCujType(isAppearing), ActivatableNotificationView.this);
InteractionJankMonitor.getInstance().begin(builder);
@@ -452,7 +457,7 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
@Override
public void onAnimationCancel(Animator animation) {
- mWasCancelled = true;
+ mRunWithoutInterruptions = false;
}
});
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt
index 8c3050d48d53..122728716eee 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt
@@ -30,7 +30,6 @@ import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags
import com.android.systemui.scene.domain.interactor.SceneInteractor
import com.android.systemui.scene.shared.model.RemoteUserInput
-import com.android.systemui.scene.shared.model.SceneContainerNames
import com.android.systemui.shade.ShadeController
import com.android.systemui.shade.ShadeLogger
import com.android.systemui.shade.ShadeViewController
@@ -183,7 +182,7 @@ class PhoneStatusBarViewController private constructor(
sceneInteractor.get()
.onRemoteUserInput(RemoteUserInput.translateMotionEvent(event))
// TODO(b/291965119): remove once view is expanded to cover the status bar
- sceneInteractor.get().setVisible(SceneContainerNames.SYSTEM_UI_DEFAULT, true)
+ sceneInteractor.get().setVisible(true)
return false
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java
index 68a6b3d62bae..fa9b9d2c571a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java
@@ -37,7 +37,6 @@ import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.flags.Flags;
import com.android.systemui.scene.domain.interactor.SceneInteractor;
-import com.android.systemui.scene.shared.model.SceneContainerNames;
import com.android.systemui.shade.ShadeExpansionStateManager;
import com.android.systemui.statusbar.NotificationShadeWindowController;
import com.android.systemui.statusbar.policy.ConfigurationController;
@@ -126,7 +125,7 @@ public final class StatusBarTouchableRegionManager implements Dumpable {
if (featureFlags.isEnabled(Flags.SCENE_CONTAINER)) {
javaAdapter.get().alwaysCollectFlow(
- sceneInteractor.get().isVisible(SceneContainerNames.SYSTEM_UI_DEFAULT),
+ sceneInteractor.get().isVisible(),
this::onShadeExpansionFullyChanged);
}
diff --git a/packages/SystemUI/src/com/android/systemui/touch/TouchInsetManager.java b/packages/SystemUI/src/com/android/systemui/touch/TouchInsetManager.java
index 757b4e50c3f8..13c1019591a1 100644
--- a/packages/SystemUI/src/com/android/systemui/touch/TouchInsetManager.java
+++ b/packages/SystemUI/src/com/android/systemui/touch/TouchInsetManager.java
@@ -25,16 +25,12 @@ import android.view.ViewGroup;
import androidx.concurrent.futures.CallbackToFutureAdapter;
-import com.android.systemui.dagger.qualifiers.Main;
-
import com.google.common.util.concurrent.ListenableFuture;
import java.util.HashMap;
import java.util.HashSet;
import java.util.concurrent.Executor;
-import javax.inject.Inject;
-
/**
* {@link TouchInsetManager} handles setting the touchable inset regions for a given View. This
* is useful for passing through touch events for all but select areas.
@@ -153,8 +149,7 @@ public class TouchInsetManager {
* Default constructor.
* @param executor An {@link Executor} to marshal all operations on.
*/
- @Inject
- public TouchInsetManager(@Main Executor executor) {
+ public TouchInsetManager(Executor executor) {
mExecutor = executor;
}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.kt
index 3abae6bcd197..e447c29b351f 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.kt
@@ -733,29 +733,20 @@ class KeyguardSecurityContainerControllerTest : SysuiTestCase() {
// is
// not enough to trigger a dismissal of the keyguard.
underTest.onViewAttached()
- sceneInteractor.setCurrentScene(
- SceneTestUtils.CONTAINER_1,
- SceneModel(SceneKey.Bouncer, null)
- )
+ sceneInteractor.setCurrentScene(SceneModel(SceneKey.Bouncer, null))
runCurrent()
verify(viewMediatorCallback, never()).keyguardDone(anyBoolean(), anyInt())
// While listening, going from the bouncer scene to the gone scene, does dismiss the
// keyguard.
- sceneInteractor.setCurrentScene(
- SceneTestUtils.CONTAINER_1,
- SceneModel(SceneKey.Gone, null)
- )
+ sceneInteractor.setCurrentScene(SceneModel(SceneKey.Gone, null))
runCurrent()
verify(viewMediatorCallback).keyguardDone(anyBoolean(), anyInt())
// While listening, moving back to the bouncer scene does not dismiss the keyguard
// again.
clearInvocations(viewMediatorCallback)
- sceneInteractor.setCurrentScene(
- SceneTestUtils.CONTAINER_1,
- SceneModel(SceneKey.Bouncer, null)
- )
+ sceneInteractor.setCurrentScene(SceneModel(SceneKey.Bouncer, null))
runCurrent()
verify(viewMediatorCallback, never()).keyguardDone(anyBoolean(), anyInt())
@@ -763,18 +754,12 @@ class KeyguardSecurityContainerControllerTest : SysuiTestCase() {
// scene
// does not dismiss the keyguard while we're not listening.
underTest.onViewDetached()
- sceneInteractor.setCurrentScene(
- SceneTestUtils.CONTAINER_1,
- SceneModel(SceneKey.Gone, null)
- )
+ sceneInteractor.setCurrentScene(SceneModel(SceneKey.Gone, null))
runCurrent()
verify(viewMediatorCallback, never()).keyguardDone(anyBoolean(), anyInt())
// While not listening, moving back to the bouncer does not dismiss the keyguard.
- sceneInteractor.setCurrentScene(
- SceneTestUtils.CONTAINER_1,
- SceneModel(SceneKey.Bouncer, null)
- )
+ sceneInteractor.setCurrentScene(SceneModel(SceneKey.Bouncer, null))
runCurrent()
verify(viewMediatorCallback, never()).keyguardDone(anyBoolean(), anyInt())
@@ -782,10 +767,7 @@ class KeyguardSecurityContainerControllerTest : SysuiTestCase() {
// gone
// scene now does dismiss the keyguard again.
underTest.onViewAttached()
- sceneInteractor.setCurrentScene(
- SceneTestUtils.CONTAINER_1,
- SceneModel(SceneKey.Gone, null)
- )
+ sceneInteractor.setCurrentScene(SceneModel(SceneKey.Gone, null))
runCurrent()
verify(viewMediatorCallback).keyguardDone(anyBoolean(), anyInt())
}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityViewFlipperControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityViewFlipperControllerTest.java
index cd187540ba74..64e1458c42d4 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityViewFlipperControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityViewFlipperControllerTest.java
@@ -138,6 +138,11 @@ public class KeyguardSecurityViewFlipperControllerTest extends SysuiTestCase {
@Test
public void asynchronouslyInflateView_setNeedsInput() {
+ when(mKeyguardSecurityViewControllerFactory.create(
+ any(), any(SecurityMode.class),
+ any(KeyguardSecurityCallback.class)))
+ .thenReturn(mKeyguardInputViewController);
+
ArgumentCaptor<AsyncLayoutInflater.OnInflateFinishedListener> argumentCaptor =
ArgumentCaptor.forClass(AsyncLayoutInflater.OnInflateFinishedListener.class);
mKeyguardSecurityViewFlipperController.asynchronouslyInflateView(SecurityMode.PIN,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/ExpandHelperTest.java b/packages/SystemUI/tests/src/com/android/systemui/ExpandHelperTest.java
index 5867a40c78fa..44a2b682bf37 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/ExpandHelperTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/ExpandHelperTest.java
@@ -20,12 +20,13 @@ import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
-import android.animation.ObjectAnimator;
import android.content.Context;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.testing.TestableLooper.RunWithLooper;
+import androidx.core.animation.AnimatorTestRule;
+import androidx.core.animation.ObjectAnimator;
import androidx.test.annotation.UiThreadTest;
import androidx.test.filters.SmallTest;
@@ -37,6 +38,7 @@ import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
import com.android.systemui.statusbar.notification.row.NotificationTestHelper;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -45,6 +47,9 @@ import org.junit.runner.RunWith;
@RunWithLooper
public class ExpandHelperTest extends SysuiTestCase {
+ @Rule
+ public final AnimatorTestRule mAnimatorTestRule = new AnimatorTestRule();
+
private final FakeFeatureFlags mFeatureFlags = new FakeFeatureFlags();
private ExpandableNotificationRow mRow;
private ExpandHelper mExpandHelper;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorTest.kt
index 6babf0490ea9..14fc931522a4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorTest.kt
@@ -69,13 +69,12 @@ class BouncerInteractorTest : SysuiTestCase() {
@Test
fun pinAuthMethod() =
testScope.runTest {
- val currentScene by
- collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
+ val currentScene by collectLastValue(sceneInteractor.currentScene)
val message by collectLastValue(underTest.message)
utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
utils.authenticationRepository.setUnlocked(false)
- underTest.showOrUnlockDevice(SceneTestUtils.CONTAINER_1)
+ underTest.showOrUnlockDevice()
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
assertThat(message).isEqualTo(MESSAGE_ENTER_YOUR_PIN)
@@ -101,14 +100,13 @@ class BouncerInteractorTest : SysuiTestCase() {
@Test
fun pinAuthMethod_tryAutoConfirm_withAutoConfirmPin() =
testScope.runTest {
- val currentScene by
- collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
+ val currentScene by collectLastValue(sceneInteractor.currentScene)
val message by collectLastValue(underTest.message)
utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
utils.authenticationRepository.setAutoConfirmEnabled(true)
utils.authenticationRepository.setUnlocked(false)
- underTest.showOrUnlockDevice(SceneTestUtils.CONTAINER_1)
+ underTest.showOrUnlockDevice()
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
assertThat(message).isEqualTo(MESSAGE_ENTER_YOUR_PIN)
underTest.clearMessage()
@@ -138,13 +136,12 @@ class BouncerInteractorTest : SysuiTestCase() {
@Test
fun pinAuthMethod_tryAutoConfirm_withoutAutoConfirmPin() =
testScope.runTest {
- val currentScene by
- collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
+ val currentScene by collectLastValue(sceneInteractor.currentScene)
val message by collectLastValue(underTest.message)
utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
utils.authenticationRepository.setUnlocked(false)
- underTest.showOrUnlockDevice(SceneTestUtils.CONTAINER_1)
+ underTest.showOrUnlockDevice()
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
underTest.clearMessage()
@@ -168,14 +165,13 @@ class BouncerInteractorTest : SysuiTestCase() {
@Test
fun passwordAuthMethod() =
testScope.runTest {
- val currentScene by
- collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
+ val currentScene by collectLastValue(sceneInteractor.currentScene)
val message by collectLastValue(underTest.message)
utils.authenticationRepository.setAuthenticationMethod(
AuthenticationMethodModel.Password
)
utils.authenticationRepository.setUnlocked(false)
- underTest.showOrUnlockDevice(SceneTestUtils.CONTAINER_1)
+ underTest.showOrUnlockDevice()
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
assertThat(message).isEqualTo(MESSAGE_ENTER_YOUR_PASSWORD)
@@ -201,14 +197,13 @@ class BouncerInteractorTest : SysuiTestCase() {
@Test
fun patternAuthMethod() =
testScope.runTest {
- val currentScene by
- collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
+ val currentScene by collectLastValue(sceneInteractor.currentScene)
val message by collectLastValue(underTest.message)
utils.authenticationRepository.setAuthenticationMethod(
AuthenticationMethodModel.Pattern
)
utils.authenticationRepository.setUnlocked(false)
- underTest.showOrUnlockDevice(SceneTestUtils.CONTAINER_1)
+ underTest.showOrUnlockDevice()
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
assertThat(message).isEqualTo(MESSAGE_ENTER_YOUR_PATTERN)
@@ -239,13 +234,12 @@ class BouncerInteractorTest : SysuiTestCase() {
@Test
fun showOrUnlockDevice_notLocked_switchesToGoneScene() =
testScope.runTest {
- val currentScene by
- collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
+ val currentScene by collectLastValue(sceneInteractor.currentScene)
utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
utils.authenticationRepository.setUnlocked(true)
runCurrent()
- underTest.showOrUnlockDevice(SceneTestUtils.CONTAINER_1)
+ underTest.showOrUnlockDevice()
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Gone))
}
@@ -253,12 +247,11 @@ class BouncerInteractorTest : SysuiTestCase() {
@Test
fun showOrUnlockDevice_authMethodNotSecure_switchesToGoneScene() =
testScope.runTest {
- val currentScene by
- collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
+ val currentScene by collectLastValue(sceneInteractor.currentScene)
utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Swipe)
utils.authenticationRepository.setUnlocked(false)
- underTest.showOrUnlockDevice(SceneTestUtils.CONTAINER_1)
+ underTest.showOrUnlockDevice()
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Gone))
}
@@ -266,8 +259,7 @@ class BouncerInteractorTest : SysuiTestCase() {
@Test
fun showOrUnlockDevice_customMessageShown() =
testScope.runTest {
- val currentScene by
- collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
+ val currentScene by collectLastValue(sceneInteractor.currentScene)
val message by collectLastValue(underTest.message)
utils.authenticationRepository.setAuthenticationMethod(
AuthenticationMethodModel.Password
@@ -275,7 +267,7 @@ class BouncerInteractorTest : SysuiTestCase() {
utils.authenticationRepository.setUnlocked(false)
val customMessage = "Hello there!"
- underTest.showOrUnlockDevice(SceneTestUtils.CONTAINER_1, customMessage)
+ underTest.showOrUnlockDevice(customMessage)
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
assertThat(message).isEqualTo(customMessage)
@@ -287,11 +279,10 @@ class BouncerInteractorTest : SysuiTestCase() {
val isThrottled by collectLastValue(underTest.isThrottled)
val throttling by collectLastValue(underTest.throttling)
val message by collectLastValue(underTest.message)
- val currentScene by
- collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
+ val currentScene by collectLastValue(sceneInteractor.currentScene)
utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
runCurrent()
- underTest.showOrUnlockDevice(SceneTestUtils.CONTAINER_1)
+ underTest.showOrUnlockDevice()
runCurrent()
assertThat(currentScene?.key).isEqualTo(SceneKey.Bouncer)
assertThat(isThrottled).isFalse()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModelTest.kt
index b1533fecbc5e..1f089ca8b98e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModelTest.kt
@@ -72,18 +72,14 @@ class PasswordBouncerViewModelTest : SysuiTestCase() {
@Test
fun onShown() =
testScope.runTest {
- val currentScene by
- collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
+ val currentScene by collectLastValue(sceneInteractor.currentScene)
val message by collectLastValue(bouncerViewModel.message)
val password by collectLastValue(underTest.password)
utils.authenticationRepository.setAuthenticationMethod(
AuthenticationMethodModel.Password
)
utils.authenticationRepository.setUnlocked(false)
- sceneInteractor.setCurrentScene(
- SceneTestUtils.CONTAINER_1,
- SceneModel(SceneKey.Bouncer)
- )
+ sceneInteractor.setCurrentScene(SceneModel(SceneKey.Bouncer))
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
underTest.onShown()
@@ -96,18 +92,14 @@ class PasswordBouncerViewModelTest : SysuiTestCase() {
@Test
fun onPasswordInputChanged() =
testScope.runTest {
- val currentScene by
- collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
+ val currentScene by collectLastValue(sceneInteractor.currentScene)
val message by collectLastValue(bouncerViewModel.message)
val password by collectLastValue(underTest.password)
utils.authenticationRepository.setAuthenticationMethod(
AuthenticationMethodModel.Password
)
utils.authenticationRepository.setUnlocked(false)
- sceneInteractor.setCurrentScene(
- SceneTestUtils.CONTAINER_1,
- SceneModel(SceneKey.Bouncer)
- )
+ sceneInteractor.setCurrentScene(SceneModel(SceneKey.Bouncer))
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
underTest.onShown()
runCurrent()
@@ -122,16 +114,12 @@ class PasswordBouncerViewModelTest : SysuiTestCase() {
@Test
fun onAuthenticateKeyPressed_whenCorrect() =
testScope.runTest {
- val currentScene by
- collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
+ val currentScene by collectLastValue(sceneInteractor.currentScene)
utils.authenticationRepository.setAuthenticationMethod(
AuthenticationMethodModel.Password
)
utils.authenticationRepository.setUnlocked(false)
- sceneInteractor.setCurrentScene(
- SceneTestUtils.CONTAINER_1,
- SceneModel(SceneKey.Bouncer)
- )
+ sceneInteractor.setCurrentScene(SceneModel(SceneKey.Bouncer))
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
underTest.onShown()
underTest.onPasswordInputChanged("password")
@@ -144,18 +132,14 @@ class PasswordBouncerViewModelTest : SysuiTestCase() {
@Test
fun onAuthenticateKeyPressed_whenWrong() =
testScope.runTest {
- val currentScene by
- collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
+ val currentScene by collectLastValue(sceneInteractor.currentScene)
val message by collectLastValue(bouncerViewModel.message)
val password by collectLastValue(underTest.password)
utils.authenticationRepository.setAuthenticationMethod(
AuthenticationMethodModel.Password
)
utils.authenticationRepository.setUnlocked(false)
- sceneInteractor.setCurrentScene(
- SceneTestUtils.CONTAINER_1,
- SceneModel(SceneKey.Bouncer)
- )
+ sceneInteractor.setCurrentScene(SceneModel(SceneKey.Bouncer))
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
underTest.onShown()
underTest.onPasswordInputChanged("wrong")
@@ -170,18 +154,14 @@ class PasswordBouncerViewModelTest : SysuiTestCase() {
@Test
fun onAuthenticateKeyPressed_correctAfterWrong() =
testScope.runTest {
- val currentScene by
- collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
+ val currentScene by collectLastValue(sceneInteractor.currentScene)
val message by collectLastValue(bouncerViewModel.message)
val password by collectLastValue(underTest.password)
utils.authenticationRepository.setAuthenticationMethod(
AuthenticationMethodModel.Password
)
utils.authenticationRepository.setUnlocked(false)
- sceneInteractor.setCurrentScene(
- SceneTestUtils.CONTAINER_1,
- SceneModel(SceneKey.Bouncer)
- )
+ sceneInteractor.setCurrentScene(SceneModel(SceneKey.Bouncer))
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
underTest.onShown()
underTest.onPasswordInputChanged("wrong")
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModelTest.kt
index f69cbb8fd004..af54989002e9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModelTest.kt
@@ -75,8 +75,7 @@ class PatternBouncerViewModelTest : SysuiTestCase() {
@Test
fun onShown() =
testScope.runTest {
- val currentScene by
- collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
+ val currentScene by collectLastValue(sceneInteractor.currentScene)
val message by collectLastValue(bouncerViewModel.message)
val selectedDots by collectLastValue(underTest.selectedDots)
val currentDot by collectLastValue(underTest.currentDot)
@@ -84,10 +83,7 @@ class PatternBouncerViewModelTest : SysuiTestCase() {
AuthenticationMethodModel.Pattern
)
utils.authenticationRepository.setUnlocked(false)
- sceneInteractor.setCurrentScene(
- SceneTestUtils.CONTAINER_1,
- SceneModel(SceneKey.Bouncer)
- )
+ sceneInteractor.setCurrentScene(SceneModel(SceneKey.Bouncer))
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
underTest.onShown()
@@ -101,8 +97,7 @@ class PatternBouncerViewModelTest : SysuiTestCase() {
@Test
fun onDragStart() =
testScope.runTest {
- val currentScene by
- collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
+ val currentScene by collectLastValue(sceneInteractor.currentScene)
val message by collectLastValue(bouncerViewModel.message)
val selectedDots by collectLastValue(underTest.selectedDots)
val currentDot by collectLastValue(underTest.currentDot)
@@ -110,10 +105,7 @@ class PatternBouncerViewModelTest : SysuiTestCase() {
AuthenticationMethodModel.Pattern
)
utils.authenticationRepository.setUnlocked(false)
- sceneInteractor.setCurrentScene(
- SceneTestUtils.CONTAINER_1,
- SceneModel(SceneKey.Bouncer)
- )
+ sceneInteractor.setCurrentScene(SceneModel(SceneKey.Bouncer))
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
underTest.onShown()
runCurrent()
@@ -129,18 +121,14 @@ class PatternBouncerViewModelTest : SysuiTestCase() {
@Test
fun onDragEnd_whenCorrect() =
testScope.runTest {
- val currentScene by
- collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
+ val currentScene by collectLastValue(sceneInteractor.currentScene)
val selectedDots by collectLastValue(underTest.selectedDots)
val currentDot by collectLastValue(underTest.currentDot)
utils.authenticationRepository.setAuthenticationMethod(
AuthenticationMethodModel.Pattern
)
utils.authenticationRepository.setUnlocked(false)
- sceneInteractor.setCurrentScene(
- SceneTestUtils.CONTAINER_1,
- SceneModel(SceneKey.Bouncer)
- )
+ sceneInteractor.setCurrentScene(SceneModel(SceneKey.Bouncer))
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
underTest.onShown()
underTest.onDragStart()
@@ -180,8 +168,7 @@ class PatternBouncerViewModelTest : SysuiTestCase() {
@Test
fun onDragEnd_whenWrong() =
testScope.runTest {
- val currentScene by
- collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
+ val currentScene by collectLastValue(sceneInteractor.currentScene)
val message by collectLastValue(bouncerViewModel.message)
val selectedDots by collectLastValue(underTest.selectedDots)
val currentDot by collectLastValue(underTest.currentDot)
@@ -189,10 +176,7 @@ class PatternBouncerViewModelTest : SysuiTestCase() {
AuthenticationMethodModel.Pattern
)
utils.authenticationRepository.setUnlocked(false)
- sceneInteractor.setCurrentScene(
- SceneTestUtils.CONTAINER_1,
- SceneModel(SceneKey.Bouncer)
- )
+ sceneInteractor.setCurrentScene(SceneModel(SceneKey.Bouncer))
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
underTest.onShown()
underTest.onDragStart()
@@ -216,8 +200,7 @@ class PatternBouncerViewModelTest : SysuiTestCase() {
@Test
fun onDragEnd_correctAfterWrong() =
testScope.runTest {
- val currentScene by
- collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
+ val currentScene by collectLastValue(sceneInteractor.currentScene)
val message by collectLastValue(bouncerViewModel.message)
val selectedDots by collectLastValue(underTest.selectedDots)
val currentDot by collectLastValue(underTest.currentDot)
@@ -225,10 +208,7 @@ class PatternBouncerViewModelTest : SysuiTestCase() {
AuthenticationMethodModel.Pattern
)
utils.authenticationRepository.setUnlocked(false)
- sceneInteractor.setCurrentScene(
- SceneTestUtils.CONTAINER_1,
- SceneModel(SceneKey.Bouncer)
- )
+ sceneInteractor.setCurrentScene(SceneModel(SceneKey.Bouncer))
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
underTest.onShown()
underTest.onDragStart()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModelTest.kt
index 8edc6cf8dd54..c12ed033d752 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModelTest.kt
@@ -75,15 +75,11 @@ class PinBouncerViewModelTest : SysuiTestCase() {
@Test
fun onShown() =
testScope.runTest {
- val currentScene by
- collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
+ val currentScene by collectLastValue(sceneInteractor.currentScene)
val message by collectLastValue(bouncerViewModel.message)
val pin by collectLastValue(underTest.pinInput.map { it.getPin() })
utils.authenticationRepository.setUnlocked(false)
- sceneInteractor.setCurrentScene(
- SceneTestUtils.CONTAINER_1,
- SceneModel(SceneKey.Bouncer)
- )
+ sceneInteractor.setCurrentScene(SceneModel(SceneKey.Bouncer))
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
underTest.onShown()
@@ -96,16 +92,12 @@ class PinBouncerViewModelTest : SysuiTestCase() {
@Test
fun onPinButtonClicked() =
testScope.runTest {
- val currentScene by
- collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
+ val currentScene by collectLastValue(sceneInteractor.currentScene)
val message by collectLastValue(bouncerViewModel.message)
val pin by collectLastValue(underTest.pinInput.map { it.getPin() })
utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
utils.authenticationRepository.setUnlocked(false)
- sceneInteractor.setCurrentScene(
- SceneTestUtils.CONTAINER_1,
- SceneModel(SceneKey.Bouncer)
- )
+ sceneInteractor.setCurrentScene(SceneModel(SceneKey.Bouncer))
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
underTest.onShown()
runCurrent()
@@ -120,16 +112,12 @@ class PinBouncerViewModelTest : SysuiTestCase() {
@Test
fun onBackspaceButtonClicked() =
testScope.runTest {
- val currentScene by
- collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
+ val currentScene by collectLastValue(sceneInteractor.currentScene)
val message by collectLastValue(bouncerViewModel.message)
val pin by collectLastValue(underTest.pinInput.map { it.getPin() })
utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
utils.authenticationRepository.setUnlocked(false)
- sceneInteractor.setCurrentScene(
- SceneTestUtils.CONTAINER_1,
- SceneModel(SceneKey.Bouncer)
- )
+ sceneInteractor.setCurrentScene(SceneModel(SceneKey.Bouncer))
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
underTest.onShown()
runCurrent()
@@ -146,15 +134,11 @@ class PinBouncerViewModelTest : SysuiTestCase() {
@Test
fun onPinEdit() =
testScope.runTest {
- val currentScene by
- collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
+ val currentScene by collectLastValue(sceneInteractor.currentScene)
val pin by collectLastValue(underTest.pinInput.map { it.getPin() })
utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
utils.authenticationRepository.setUnlocked(false)
- sceneInteractor.setCurrentScene(
- SceneTestUtils.CONTAINER_1,
- SceneModel(SceneKey.Bouncer)
- )
+ sceneInteractor.setCurrentScene(SceneModel(SceneKey.Bouncer))
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
underTest.onShown()
@@ -172,16 +156,12 @@ class PinBouncerViewModelTest : SysuiTestCase() {
@Test
fun onBackspaceButtonLongPressed() =
testScope.runTest {
- val currentScene by
- collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
+ val currentScene by collectLastValue(sceneInteractor.currentScene)
val message by collectLastValue(bouncerViewModel.message)
val pin by collectLastValue(underTest.pinInput.map { it.getPin() })
utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
utils.authenticationRepository.setUnlocked(false)
- sceneInteractor.setCurrentScene(
- SceneTestUtils.CONTAINER_1,
- SceneModel(SceneKey.Bouncer)
- )
+ sceneInteractor.setCurrentScene(SceneModel(SceneKey.Bouncer))
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
underTest.onShown()
runCurrent()
@@ -200,14 +180,10 @@ class PinBouncerViewModelTest : SysuiTestCase() {
@Test
fun onAuthenticateButtonClicked_whenCorrect() =
testScope.runTest {
- val currentScene by
- collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
+ val currentScene by collectLastValue(sceneInteractor.currentScene)
utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
utils.authenticationRepository.setUnlocked(false)
- sceneInteractor.setCurrentScene(
- SceneTestUtils.CONTAINER_1,
- SceneModel(SceneKey.Bouncer)
- )
+ sceneInteractor.setCurrentScene(SceneModel(SceneKey.Bouncer))
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
underTest.onShown()
FakeAuthenticationRepository.DEFAULT_PIN.forEach { digit ->
@@ -222,16 +198,12 @@ class PinBouncerViewModelTest : SysuiTestCase() {
@Test
fun onAuthenticateButtonClicked_whenWrong() =
testScope.runTest {
- val currentScene by
- collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
+ val currentScene by collectLastValue(sceneInteractor.currentScene)
val message by collectLastValue(bouncerViewModel.message)
val pin by collectLastValue(underTest.pinInput.map { it.getPin() })
utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
utils.authenticationRepository.setUnlocked(false)
- sceneInteractor.setCurrentScene(
- SceneTestUtils.CONTAINER_1,
- SceneModel(SceneKey.Bouncer)
- )
+ sceneInteractor.setCurrentScene(SceneModel(SceneKey.Bouncer))
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
underTest.onShown()
underTest.onPinButtonClicked(1)
@@ -250,16 +222,12 @@ class PinBouncerViewModelTest : SysuiTestCase() {
@Test
fun onAuthenticateButtonClicked_correctAfterWrong() =
testScope.runTest {
- val currentScene by
- collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
+ val currentScene by collectLastValue(sceneInteractor.currentScene)
val message by collectLastValue(bouncerViewModel.message)
val pin by collectLastValue(underTest.pinInput.map { it.getPin() })
utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
utils.authenticationRepository.setUnlocked(false)
- sceneInteractor.setCurrentScene(
- SceneTestUtils.CONTAINER_1,
- SceneModel(SceneKey.Bouncer)
- )
+ sceneInteractor.setCurrentScene(SceneModel(SceneKey.Bouncer))
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
underTest.onShown()
underTest.onPinButtonClicked(1)
@@ -286,15 +254,11 @@ class PinBouncerViewModelTest : SysuiTestCase() {
@Test
fun onAutoConfirm_whenCorrect() =
testScope.runTest {
- val currentScene by
- collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
+ val currentScene by collectLastValue(sceneInteractor.currentScene)
utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
utils.authenticationRepository.setUnlocked(false)
utils.authenticationRepository.setAutoConfirmEnabled(true)
- sceneInteractor.setCurrentScene(
- SceneTestUtils.CONTAINER_1,
- SceneModel(SceneKey.Bouncer)
- )
+ sceneInteractor.setCurrentScene(SceneModel(SceneKey.Bouncer))
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
underTest.onShown()
FakeAuthenticationRepository.DEFAULT_PIN.forEach { digit ->
@@ -307,17 +271,13 @@ class PinBouncerViewModelTest : SysuiTestCase() {
@Test
fun onAutoConfirm_whenWrong() =
testScope.runTest {
- val currentScene by
- collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
+ val currentScene by collectLastValue(sceneInteractor.currentScene)
val message by collectLastValue(bouncerViewModel.message)
val pin by collectLastValue(underTest.pinInput.map { it.getPin() })
utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
utils.authenticationRepository.setUnlocked(false)
utils.authenticationRepository.setAutoConfirmEnabled(true)
- sceneInteractor.setCurrentScene(
- SceneTestUtils.CONTAINER_1,
- SceneModel(SceneKey.Bouncer)
- )
+ sceneInteractor.setCurrentScene(SceneModel(SceneKey.Bouncer))
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer))
underTest.onShown()
FakeAuthenticationRepository.DEFAULT_PIN.dropLast(1).forEach { digit ->
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt
index 01a6c64a6898..85ee0e4d6ec3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt
@@ -541,10 +541,8 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() {
}
@Test
- fun authenticateDoesNotRunIfUserIsCurrentlySwitching() =
- testScope.runTest {
- testGatingCheckForFaceAuth { fakeUserRepository.setUserSwitching(true) }
- }
+ fun authenticateDoesNotRunIfFaceAuthIsCurrentlyPaused() =
+ testScope.runTest { testGatingCheckForFaceAuth { underTest.pauseFaceAuth() } }
@Test
fun authenticateDoesNotRunIfKeyguardIsNotShowing() =
@@ -840,7 +838,7 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() {
@Test
fun detectDoesNotRunWhenUserSwitchingInProgress() =
- testScope.runTest { testGatingCheckForDetect { fakeUserRepository.setUserSwitching(true) } }
+ testScope.runTest { testGatingCheckForDetect { underTest.pauseFaceAuth() } }
@Test
fun detectDoesNotRunWhenKeyguardGoingAway() =
@@ -1130,7 +1128,7 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() {
.addLockoutResetCallback(faceLockoutResetCallback.capture())
biometricSettingsRepository.setFaceEnrolled(true)
biometricSettingsRepository.setIsFaceAuthEnabled(true)
- fakeUserRepository.setUserSwitching(false)
+ underTest.resumeFaceAuth()
trustRepository.setCurrentUserTrusted(false)
keyguardRepository.setKeyguardGoingAway(false)
keyguardRepository.setWakefulnessModel(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardFaceAuthInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardFaceAuthInteractorTest.kt
index 8636dd8df3b0..93f208ee14f5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardFaceAuthInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardFaceAuthInteractorTest.kt
@@ -48,6 +48,7 @@ import com.android.systemui.keyguard.shared.model.TransitionStep
import com.android.systemui.log.FaceAuthenticationLogger
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.statusbar.policy.KeyguardStateController
+import com.android.systemui.user.data.repository.FakeUserRepository
import com.android.systemui.util.time.FakeSystemClock
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -74,6 +75,7 @@ class KeyguardFaceAuthInteractorTest : SysuiTestCase() {
private lateinit var keyguardTransitionRepository: FakeKeyguardTransitionRepository
private lateinit var keyguardTransitionInteractor: KeyguardTransitionInteractor
private lateinit var faceAuthRepository: FakeDeviceEntryFaceAuthRepository
+ private lateinit var fakeUserRepository: FakeUserRepository
private lateinit var fakeDeviceEntryFingerprintAuthRepository:
FakeDeviceEntryFingerprintAuthRepository
@@ -98,6 +100,7 @@ class KeyguardFaceAuthInteractorTest : SysuiTestCase() {
.keyguardTransitionInteractor
fakeDeviceEntryFingerprintAuthRepository = FakeDeviceEntryFingerprintAuthRepository()
+ fakeUserRepository = FakeUserRepository()
underTest =
SystemUIKeyguardFaceAuthInteractor(
mContext,
@@ -131,7 +134,8 @@ class KeyguardFaceAuthInteractorTest : SysuiTestCase() {
featureFlags,
FaceAuthenticationLogger(logcatLogBuffer("faceAuthBuffer")),
keyguardUpdateMonitor,
- fakeDeviceEntryFingerprintAuthRepository
+ fakeDeviceEntryFingerprintAuthRepository,
+ fakeUserRepository,
)
}
@@ -212,6 +216,38 @@ class KeyguardFaceAuthInteractorTest : SysuiTestCase() {
}
@Test
+ fun faceAuthIsPausedWhenUserSwitchingIsInProgress() =
+ testScope.runTest {
+ underTest.start()
+
+ fakeUserRepository.setUserSwitching(false)
+ runCurrent()
+ fakeUserRepository.setUserSwitching(true)
+ runCurrent()
+
+ assertThat(faceAuthRepository.isFaceAuthPaused()).isTrue()
+ }
+
+ @Test
+ fun faceAuthIsUnpausedWhenUserSwitchingIsInComplete() =
+ testScope.runTest {
+ underTest.start()
+
+ // previously running
+ fakeUserRepository.setUserSwitching(true)
+ runCurrent()
+ fakeUserRepository.setUserSwitching(false)
+ runCurrent()
+
+ assertThat(faceAuthRepository.isFaceAuthPaused()).isFalse()
+
+ runCurrent()
+ assertThat(faceAuthRepository.runningAuthRequest.value!!.first)
+ .isEqualTo(FaceAuthUiEvent.FACE_AUTH_UPDATED_USER_SWITCHING)
+ assertThat(faceAuthRepository.runningAuthRequest.value!!.second).isEqualTo(true)
+ }
+
+ @Test
fun faceAuthIsRequestedWhenPrimaryBouncerIsVisible() =
testScope.runTest {
underTest.start()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/LockscreenSceneInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/LockscreenSceneInteractorTest.kt
index ca6a5b6234b9..d825c2a01464 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/LockscreenSceneInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/LockscreenSceneInteractorTest.kt
@@ -21,7 +21,6 @@ import com.android.systemui.SysuiTestCase
import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.scene.SceneTestUtils
-import com.android.systemui.scene.SceneTestUtils.Companion.CONTAINER_1
import com.android.systemui.scene.shared.model.SceneKey
import com.android.systemui.scene.shared.model.SceneModel
import com.google.common.truth.Truth.assertThat
@@ -91,7 +90,7 @@ class LockscreenSceneInteractorTest : SysuiTestCase() {
@Test
fun dismissLockScreen_deviceLockedWithSecureAuthMethod_switchesToBouncer() =
testScope.runTest {
- val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1))
+ val currentScene by collectLastValue(sceneInteractor.currentScene)
utils.authenticationRepository.setUnlocked(false)
utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Lockscreen))
@@ -104,7 +103,7 @@ class LockscreenSceneInteractorTest : SysuiTestCase() {
@Test
fun dismissLockScreen_deviceUnlocked_switchesToGone() =
testScope.runTest {
- val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1))
+ val currentScene by collectLastValue(sceneInteractor.currentScene)
utils.authenticationRepository.setUnlocked(true)
utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Lockscreen))
@@ -117,7 +116,7 @@ class LockscreenSceneInteractorTest : SysuiTestCase() {
@Test
fun dismissLockScreen_deviceLockedWithInsecureAuthMethod_switchesToGone() =
testScope.runTest {
- val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1))
+ val currentScene by collectLastValue(sceneInteractor.currentScene)
utils.authenticationRepository.setUnlocked(false)
utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Swipe)
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Lockscreen))
@@ -131,11 +130,11 @@ class LockscreenSceneInteractorTest : SysuiTestCase() {
fun switchFromLockScreenToGone_authMethodNotSwipe_doesNotUnlockDevice() =
testScope.runTest {
val isUnlocked by collectLastValue(authenticationInteractor.isUnlocked)
- sceneInteractor.setCurrentScene(CONTAINER_1, SceneModel(SceneKey.Lockscreen))
+ sceneInteractor.setCurrentScene(SceneModel(SceneKey.Lockscreen))
utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
assertThat(isUnlocked).isFalse()
- sceneInteractor.setCurrentScene(CONTAINER_1, SceneModel(SceneKey.Gone))
+ sceneInteractor.setCurrentScene(SceneModel(SceneKey.Gone))
assertThat(isUnlocked).isFalse()
}
@@ -145,13 +144,13 @@ class LockscreenSceneInteractorTest : SysuiTestCase() {
testScope.runTest {
val isUnlocked by collectLastValue(authenticationInteractor.isUnlocked)
runCurrent()
- sceneInteractor.setCurrentScene(CONTAINER_1, SceneModel(SceneKey.Shade))
+ sceneInteractor.setCurrentScene(SceneModel(SceneKey.Shade))
runCurrent()
utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Swipe)
runCurrent()
assertThat(isUnlocked).isFalse()
- sceneInteractor.setCurrentScene(CONTAINER_1, SceneModel(SceneKey.Gone))
+ sceneInteractor.setCurrentScene(SceneModel(SceneKey.Gone))
assertThat(isUnlocked).isFalse()
}
@@ -159,10 +158,10 @@ class LockscreenSceneInteractorTest : SysuiTestCase() {
@Test
fun authMethodChangedToNone_notOnLockScreenScene_doesNotDismissLockScreen() =
testScope.runTest {
- val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1))
+ val currentScene by collectLastValue(sceneInteractor.currentScene)
utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Swipe)
runCurrent()
- sceneInteractor.setCurrentScene(CONTAINER_1, SceneModel(SceneKey.QuickSettings))
+ sceneInteractor.setCurrentScene(SceneModel(SceneKey.QuickSettings))
runCurrent()
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.QuickSettings))
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt
index ba8e0f277b6b..63ee240fd2c6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt
@@ -22,9 +22,7 @@ import com.android.systemui.SysuiTestCase
import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
import com.android.systemui.common.shared.model.Icon
import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.keyguard.domain.interactor.LockscreenSceneInteractor
import com.android.systemui.scene.SceneTestUtils
-import com.android.systemui.scene.SceneTestUtils.Companion.CONTAINER_1
import com.android.systemui.scene.shared.model.SceneKey
import com.android.systemui.scene.shared.model.SceneModel
import com.google.common.truth.Truth.assertThat
@@ -51,20 +49,15 @@ class LockscreenSceneViewModelTest : SysuiTestCase() {
private val underTest =
LockscreenSceneViewModel(
applicationScope = testScope.backgroundScope,
- interactorFactory =
- object : LockscreenSceneInteractor.Factory {
- override fun create(containerName: String): LockscreenSceneInteractor {
- return utils.lockScreenSceneInteractor(
+ interactor =
+ utils.lockScreenSceneInteractor(
+ authenticationInteractor = authenticationInteractor,
+ bouncerInteractor =
+ utils.bouncerInteractor(
authenticationInteractor = authenticationInteractor,
- bouncerInteractor =
- utils.bouncerInteractor(
- authenticationInteractor = authenticationInteractor,
- sceneInteractor = sceneInteractor,
- ),
- )
- }
- },
- containerName = CONTAINER_1
+ sceneInteractor = sceneInteractor,
+ ),
+ ),
)
@Test
@@ -116,7 +109,7 @@ class LockscreenSceneViewModelTest : SysuiTestCase() {
@Test
fun onLockButtonClicked_deviceLockedSecurely_switchesToBouncer() =
testScope.runTest {
- val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1))
+ val currentScene by collectLastValue(sceneInteractor.currentScene)
utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
utils.authenticationRepository.setUnlocked(false)
runCurrent()
@@ -129,7 +122,7 @@ class LockscreenSceneViewModelTest : SysuiTestCase() {
@Test
fun onContentClicked_deviceUnlocked_switchesToGone() =
testScope.runTest {
- val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1))
+ val currentScene by collectLastValue(sceneInteractor.currentScene)
utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
utils.authenticationRepository.setUnlocked(true)
runCurrent()
@@ -142,7 +135,7 @@ class LockscreenSceneViewModelTest : SysuiTestCase() {
@Test
fun onContentClicked_deviceLockedSecurely_switchesToBouncer() =
testScope.runTest {
- val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1))
+ val currentScene by collectLastValue(sceneInteractor.currentScene)
utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
utils.authenticationRepository.setUnlocked(false)
runCurrent()
@@ -155,7 +148,7 @@ class LockscreenSceneViewModelTest : SysuiTestCase() {
@Test
fun onLockButtonClicked_deviceUnlocked_switchesToGone() =
testScope.runTest {
- val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1))
+ val currentScene by collectLastValue(sceneInteractor.currentScene)
utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
utils.authenticationRepository.setUnlocked(true)
runCurrent()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModelTest.kt
index ed7a59ea7032..ee42a7011264 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModelTest.kt
@@ -20,9 +20,7 @@ import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.keyguard.domain.interactor.LockscreenSceneInteractor
import com.android.systemui.scene.SceneTestUtils
-import com.android.systemui.scene.SceneTestUtils.Companion.CONTAINER_1
import com.android.systemui.scene.shared.model.SceneKey
import com.android.systemui.scene.shared.model.SceneModel
import com.google.common.truth.Truth.assertThat
@@ -48,26 +46,21 @@ class QuickSettingsSceneViewModelTest : SysuiTestCase() {
private val underTest =
QuickSettingsSceneViewModel(
- lockscreenSceneInteractorFactory =
- object : LockscreenSceneInteractor.Factory {
- override fun create(containerName: String): LockscreenSceneInteractor {
- return utils.lockScreenSceneInteractor(
+ lockscreenSceneInteractor =
+ utils.lockScreenSceneInteractor(
+ authenticationInteractor = authenticationInteractor,
+ bouncerInteractor =
+ utils.bouncerInteractor(
authenticationInteractor = authenticationInteractor,
- bouncerInteractor =
- utils.bouncerInteractor(
- authenticationInteractor = authenticationInteractor,
- sceneInteractor = sceneInteractor,
- ),
- )
- }
- },
- containerName = CONTAINER_1
+ sceneInteractor = sceneInteractor,
+ ),
+ ),
)
@Test
fun onContentClicked_deviceUnlocked_switchesToGone() =
testScope.runTest {
- val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1))
+ val currentScene by collectLastValue(sceneInteractor.currentScene)
utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
utils.authenticationRepository.setUnlocked(true)
runCurrent()
@@ -80,7 +73,7 @@ class QuickSettingsSceneViewModelTest : SysuiTestCase() {
@Test
fun onContentClicked_deviceLockedSecurely_switchesToBouncer() =
testScope.runTest {
- val currentScene by collectLastValue(sceneInteractor.currentScene(CONTAINER_1))
+ val currentScene by collectLastValue(sceneInteractor.currentScene)
utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
utils.authenticationRepository.setUnlocked(false)
runCurrent()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/scene/data/repository/SceneContainerRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/scene/data/repository/SceneContainerRepositoryTest.kt
index 9ce378dd079f..826a6ccfbaec 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/scene/data/repository/SceneContainerRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/scene/data/repository/SceneContainerRepositoryTest.kt
@@ -41,7 +41,7 @@ class SceneContainerRepositoryTest : SysuiTestCase() {
@Test
fun allSceneKeys() {
val underTest = utils.fakeSceneContainerRepository()
- assertThat(underTest.allSceneKeys(SceneTestUtils.CONTAINER_1))
+ assertThat(underTest.allSceneKeys())
.isEqualTo(
listOf(
SceneKey.QuickSettings,
@@ -53,115 +53,58 @@ class SceneContainerRepositoryTest : SysuiTestCase() {
)
}
- @Test(expected = IllegalStateException::class)
- fun allSceneKeys_noSuchContainer_throws() {
- val underTest = utils.fakeSceneContainerRepository()
- underTest.allSceneKeys("nonExistingContainer")
- }
-
@Test
fun currentScene() = runTest {
val underTest = utils.fakeSceneContainerRepository()
- val currentScene by collectLastValue(underTest.currentScene(SceneTestUtils.CONTAINER_1))
+ val currentScene by collectLastValue(underTest.currentScene)
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Lockscreen))
- underTest.setCurrentScene(SceneTestUtils.CONTAINER_1, SceneModel(SceneKey.Shade))
+ underTest.setCurrentScene(SceneModel(SceneKey.Shade))
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Shade))
}
@Test(expected = IllegalStateException::class)
- fun currentScene_noSuchContainer_throws() {
- val underTest = utils.fakeSceneContainerRepository()
- underTest.currentScene("nonExistingContainer")
- }
-
- @Test(expected = IllegalStateException::class)
- fun setCurrentScene_noSuchContainer_throws() {
- val underTest = utils.fakeSceneContainerRepository()
- underTest.setCurrentScene("nonExistingContainer", SceneModel(SceneKey.Shade))
- }
-
- @Test(expected = IllegalStateException::class)
fun setCurrentScene_noSuchSceneInContainer_throws() {
val underTest =
utils.fakeSceneContainerRepository(
- setOf(
- utils.fakeSceneContainerConfig(SceneTestUtils.CONTAINER_1),
- utils.fakeSceneContainerConfig(
- SceneTestUtils.CONTAINER_2,
- listOf(SceneKey.QuickSettings, SceneKey.Lockscreen)
- ),
- )
+ utils.fakeSceneContainerConfig(listOf(SceneKey.QuickSettings, SceneKey.Lockscreen)),
)
- underTest.setCurrentScene(SceneTestUtils.CONTAINER_2, SceneModel(SceneKey.Shade))
+ underTest.setCurrentScene(SceneModel(SceneKey.Shade))
}
@Test
fun isVisible() = runTest {
val underTest = utils.fakeSceneContainerRepository()
- val isVisible by collectLastValue(underTest.isVisible(SceneTestUtils.CONTAINER_1))
+ val isVisible by collectLastValue(underTest.isVisible)
assertThat(isVisible).isTrue()
- underTest.setVisible(SceneTestUtils.CONTAINER_1, false)
+ underTest.setVisible(false)
assertThat(isVisible).isFalse()
- underTest.setVisible(SceneTestUtils.CONTAINER_1, true)
+ underTest.setVisible(true)
assertThat(isVisible).isTrue()
}
- @Test(expected = IllegalStateException::class)
- fun isVisible_noSuchContainer_throws() {
- val underTest = utils.fakeSceneContainerRepository()
- underTest.isVisible("nonExistingContainer")
- }
-
- @Test(expected = IllegalStateException::class)
- fun setVisible_noSuchContainer_throws() {
- val underTest = utils.fakeSceneContainerRepository()
- underTest.setVisible("nonExistingContainer", false)
- }
-
@Test
- fun sceneTransitionProgress() = runTest {
+ fun transitionProgress() = runTest {
val underTest = utils.fakeSceneContainerRepository()
- val sceneTransitionProgress by
- collectLastValue(underTest.sceneTransitionProgress(SceneTestUtils.CONTAINER_1))
+ val sceneTransitionProgress by collectLastValue(underTest.transitionProgress)
assertThat(sceneTransitionProgress).isEqualTo(1f)
- underTest.setSceneTransitionProgress(SceneTestUtils.CONTAINER_1, 0.1f)
+ underTest.setSceneTransitionProgress(0.1f)
assertThat(sceneTransitionProgress).isEqualTo(0.1f)
- underTest.setSceneTransitionProgress(SceneTestUtils.CONTAINER_1, 0.9f)
+ underTest.setSceneTransitionProgress(0.9f)
assertThat(sceneTransitionProgress).isEqualTo(0.9f)
}
- @Test(expected = IllegalStateException::class)
- fun sceneTransitionProgress_noSuchContainer_throws() {
- val underTest = utils.fakeSceneContainerRepository()
- underTest.sceneTransitionProgress("nonExistingContainer")
- }
-
@Test
fun setSceneTransition() = runTest {
- val underTest =
- utils.fakeSceneContainerRepository(
- setOf(
- utils.fakeSceneContainerConfig(SceneTestUtils.CONTAINER_1),
- utils.fakeSceneContainerConfig(
- SceneTestUtils.CONTAINER_2,
- listOf(SceneKey.QuickSettings, SceneKey.Lockscreen)
- ),
- )
- )
- val sceneTransition by
- collectLastValue(underTest.sceneTransitions(SceneTestUtils.CONTAINER_2))
+ val underTest = utils.fakeSceneContainerRepository()
+ val sceneTransition by collectLastValue(underTest.transitions)
assertThat(sceneTransition).isNull()
- underTest.setSceneTransition(
- SceneTestUtils.CONTAINER_2,
- SceneKey.Lockscreen,
- SceneKey.QuickSettings
- )
+ underTest.setSceneTransition(SceneKey.Lockscreen, SceneKey.QuickSettings)
assertThat(sceneTransition)
.isEqualTo(
SceneTransitionModel(from = SceneKey.Lockscreen, to = SceneKey.QuickSettings)
@@ -169,46 +112,20 @@ class SceneContainerRepositoryTest : SysuiTestCase() {
}
@Test(expected = IllegalStateException::class)
- fun setSceneTransition_noSuchContainer_throws() {
- val underTest = utils.fakeSceneContainerRepository()
- underTest.setSceneTransition("nonExistingContainer", SceneKey.Lockscreen, SceneKey.Shade)
- }
-
- @Test(expected = IllegalStateException::class)
fun setSceneTransition_noFromSceneInContainer_throws() {
val underTest =
utils.fakeSceneContainerRepository(
- setOf(
- utils.fakeSceneContainerConfig(SceneTestUtils.CONTAINER_1),
- utils.fakeSceneContainerConfig(
- SceneTestUtils.CONTAINER_2,
- listOf(SceneKey.QuickSettings, SceneKey.Lockscreen)
- ),
- )
+ utils.fakeSceneContainerConfig(listOf(SceneKey.QuickSettings, SceneKey.Lockscreen)),
)
- underTest.setSceneTransition(
- SceneTestUtils.CONTAINER_2,
- SceneKey.Shade,
- SceneKey.Lockscreen
- )
+ underTest.setSceneTransition(SceneKey.Shade, SceneKey.Lockscreen)
}
@Test(expected = IllegalStateException::class)
fun setSceneTransition_noToSceneInContainer_throws() {
val underTest =
utils.fakeSceneContainerRepository(
- setOf(
- utils.fakeSceneContainerConfig(SceneTestUtils.CONTAINER_1),
- utils.fakeSceneContainerConfig(
- SceneTestUtils.CONTAINER_2,
- listOf(SceneKey.QuickSettings, SceneKey.Lockscreen)
- ),
- )
+ utils.fakeSceneContainerConfig(listOf(SceneKey.QuickSettings, SceneKey.Lockscreen)),
)
- underTest.setSceneTransition(
- SceneTestUtils.CONTAINER_2,
- SceneKey.Shade,
- SceneKey.Lockscreen
- )
+ underTest.setSceneTransition(SceneKey.Shade, SceneKey.Lockscreen)
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt
index d2bbfa85604b..13a602dcddb0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt
@@ -41,48 +41,46 @@ class SceneInteractorTest : SysuiTestCase() {
@Test
fun allSceneKeys() {
- assertThat(underTest.allSceneKeys(SceneTestUtils.CONTAINER_1))
- .isEqualTo(utils.fakeSceneKeys())
+ assertThat(underTest.allSceneKeys()).isEqualTo(utils.fakeSceneKeys())
}
@Test
fun currentScene() = runTest {
- val currentScene by collectLastValue(underTest.currentScene(SceneTestUtils.CONTAINER_1))
+ val currentScene by collectLastValue(underTest.currentScene)
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Lockscreen))
- underTest.setCurrentScene(SceneTestUtils.CONTAINER_1, SceneModel(SceneKey.Shade))
+ underTest.setCurrentScene(SceneModel(SceneKey.Shade))
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Shade))
}
@Test
fun sceneTransitionProgress() = runTest {
- val progress by
- collectLastValue(underTest.sceneTransitionProgress(SceneTestUtils.CONTAINER_1))
+ val progress by collectLastValue(underTest.transitionProgress)
assertThat(progress).isEqualTo(1f)
- underTest.setSceneTransitionProgress(SceneTestUtils.CONTAINER_1, 0.55f)
+ underTest.setSceneTransitionProgress(0.55f)
assertThat(progress).isEqualTo(0.55f)
}
@Test
fun isVisible() = runTest {
- val isVisible by collectLastValue(underTest.isVisible(SceneTestUtils.CONTAINER_1))
+ val isVisible by collectLastValue(underTest.isVisible)
assertThat(isVisible).isTrue()
- underTest.setVisible(SceneTestUtils.CONTAINER_1, false)
+ underTest.setVisible(false)
assertThat(isVisible).isFalse()
- underTest.setVisible(SceneTestUtils.CONTAINER_1, true)
+ underTest.setVisible(true)
assertThat(isVisible).isTrue()
}
@Test
fun sceneTransitions() = runTest {
- val transitions by collectLastValue(underTest.sceneTransitions(SceneTestUtils.CONTAINER_1))
+ val transitions by collectLastValue(underTest.transitions)
assertThat(transitions).isNull()
- val initialSceneKey = underTest.currentScene(SceneTestUtils.CONTAINER_1).value.key
- underTest.setCurrentScene(SceneTestUtils.CONTAINER_1, SceneModel(SceneKey.Shade))
+ val initialSceneKey = underTest.currentScene.value.key
+ underTest.setCurrentScene(SceneModel(SceneKey.Shade))
assertThat(transitions)
.isEqualTo(
SceneTransitionModel(
@@ -91,7 +89,7 @@ class SceneInteractorTest : SysuiTestCase() {
)
)
- underTest.setCurrentScene(SceneTestUtils.CONTAINER_1, SceneModel(SceneKey.QuickSettings))
+ underTest.setCurrentScene(SceneModel(SceneKey.QuickSettings))
assertThat(transitions)
.isEqualTo(
SceneTransitionModel(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/scene/domain/startable/SystemUiDefaultSceneContainerStartableTest.kt b/packages/SystemUI/tests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt
index 6f6c5a589f44..b6bd31f43d30 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/scene/domain/startable/SystemUiDefaultSceneContainerStartableTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt
@@ -28,7 +28,6 @@ import com.android.systemui.keyguard.shared.model.WakefulnessModel
import com.android.systemui.keyguard.shared.model.WakefulnessState
import com.android.systemui.model.SysUiState
import com.android.systemui.scene.SceneTestUtils
-import com.android.systemui.scene.shared.model.SceneContainerNames
import com.android.systemui.scene.shared.model.SceneKey
import com.android.systemui.scene.shared.model.SceneModel
import com.android.systemui.util.mockito.mock
@@ -47,7 +46,7 @@ import org.mockito.Mockito.verify
@SmallTest
@RunWith(JUnit4::class)
-class SystemUiDefaultSceneContainerStartableTest : SysuiTestCase() {
+class SceneContainerStartableTest : SysuiTestCase() {
private val utils = SceneTestUtils(this)
private val testScope = utils.testScope
@@ -66,7 +65,7 @@ class SystemUiDefaultSceneContainerStartableTest : SysuiTestCase() {
private val sysUiState: SysUiState = mock()
private val underTest =
- SystemUiDefaultSceneContainerStartable(
+ SceneContainerStartable(
applicationScope = testScope.backgroundScope,
sceneInteractor = sceneInteractor,
authenticationInteractor = authenticationInteractor,
@@ -84,14 +83,8 @@ class SystemUiDefaultSceneContainerStartableTest : SysuiTestCase() {
@Test
fun hydrateVisibility_featureEnabled() =
testScope.runTest {
- val currentSceneKey by
- collectLastValue(
- sceneInteractor.currentScene(SceneContainerNames.SYSTEM_UI_DEFAULT).map {
- it.key
- }
- )
- val isVisible by
- collectLastValue(sceneInteractor.isVisible(SceneContainerNames.SYSTEM_UI_DEFAULT))
+ val currentSceneKey by collectLastValue(sceneInteractor.currentScene.map { it.key })
+ val isVisible by collectLastValue(sceneInteractor.isVisible)
prepareState(
isFeatureEnabled = true,
isDeviceUnlocked = true,
@@ -104,24 +97,15 @@ class SystemUiDefaultSceneContainerStartableTest : SysuiTestCase() {
assertThat(isVisible).isFalse()
- sceneInteractor.setCurrentScene(
- SceneContainerNames.SYSTEM_UI_DEFAULT,
- SceneModel(SceneKey.Shade)
- )
+ sceneInteractor.setCurrentScene(SceneModel(SceneKey.Shade))
assertThat(isVisible).isTrue()
}
@Test
fun hydrateVisibility_featureDisabled() =
testScope.runTest {
- val currentSceneKey by
- collectLastValue(
- sceneInteractor.currentScene(SceneContainerNames.SYSTEM_UI_DEFAULT).map {
- it.key
- }
- )
- val isVisible by
- collectLastValue(sceneInteractor.isVisible(SceneContainerNames.SYSTEM_UI_DEFAULT))
+ val currentSceneKey by collectLastValue(sceneInteractor.currentScene.map { it.key })
+ val isVisible by collectLastValue(sceneInteractor.isVisible)
prepareState(
isFeatureEnabled = false,
isDeviceUnlocked = true,
@@ -133,28 +117,17 @@ class SystemUiDefaultSceneContainerStartableTest : SysuiTestCase() {
underTest.start()
assertThat(isVisible).isTrue()
- sceneInteractor.setCurrentScene(
- SceneContainerNames.SYSTEM_UI_DEFAULT,
- SceneModel(SceneKey.Gone)
- )
+ sceneInteractor.setCurrentScene(SceneModel(SceneKey.Gone))
assertThat(isVisible).isTrue()
- sceneInteractor.setCurrentScene(
- SceneContainerNames.SYSTEM_UI_DEFAULT,
- SceneModel(SceneKey.Shade)
- )
+ sceneInteractor.setCurrentScene(SceneModel(SceneKey.Shade))
assertThat(isVisible).isTrue()
}
@Test
fun switchToLockscreenWhenDeviceLocks_featureEnabled() =
testScope.runTest {
- val currentSceneKey by
- collectLastValue(
- sceneInteractor.currentScene(SceneContainerNames.SYSTEM_UI_DEFAULT).map {
- it.key
- }
- )
+ val currentSceneKey by collectLastValue(sceneInteractor.currentScene.map { it.key })
prepareState(
isFeatureEnabled = true,
isDeviceUnlocked = true,
@@ -171,12 +144,7 @@ class SystemUiDefaultSceneContainerStartableTest : SysuiTestCase() {
@Test
fun switchToLockscreenWhenDeviceLocks_featureDisabled() =
testScope.runTest {
- val currentSceneKey by
- collectLastValue(
- sceneInteractor.currentScene(SceneContainerNames.SYSTEM_UI_DEFAULT).map {
- it.key
- }
- )
+ val currentSceneKey by collectLastValue(sceneInteractor.currentScene.map { it.key })
prepareState(
isFeatureEnabled = false,
isDeviceUnlocked = false,
@@ -193,12 +161,7 @@ class SystemUiDefaultSceneContainerStartableTest : SysuiTestCase() {
@Test
fun switchFromBouncerToGoneWhenDeviceUnlocked_featureEnabled() =
testScope.runTest {
- val currentSceneKey by
- collectLastValue(
- sceneInteractor.currentScene(SceneContainerNames.SYSTEM_UI_DEFAULT).map {
- it.key
- }
- )
+ val currentSceneKey by collectLastValue(sceneInteractor.currentScene.map { it.key })
prepareState(
isFeatureEnabled = true,
isDeviceUnlocked = false,
@@ -215,12 +178,7 @@ class SystemUiDefaultSceneContainerStartableTest : SysuiTestCase() {
@Test
fun switchFromBouncerToGoneWhenDeviceUnlocked_featureDisabled() =
testScope.runTest {
- val currentSceneKey by
- collectLastValue(
- sceneInteractor.currentScene(SceneContainerNames.SYSTEM_UI_DEFAULT).map {
- it.key
- }
- )
+ val currentSceneKey by collectLastValue(sceneInteractor.currentScene.map { it.key })
prepareState(
isFeatureEnabled = false,
isDeviceUnlocked = false,
@@ -237,12 +195,7 @@ class SystemUiDefaultSceneContainerStartableTest : SysuiTestCase() {
@Test
fun switchFromLockscreenToGoneWhenDeviceUnlocksWithBypassOn_featureOn_bypassOn() =
testScope.runTest {
- val currentSceneKey by
- collectLastValue(
- sceneInteractor.currentScene(SceneContainerNames.SYSTEM_UI_DEFAULT).map {
- it.key
- }
- )
+ val currentSceneKey by collectLastValue(sceneInteractor.currentScene.map { it.key })
prepareState(
isFeatureEnabled = true,
isBypassEnabled = true,
@@ -259,12 +212,7 @@ class SystemUiDefaultSceneContainerStartableTest : SysuiTestCase() {
@Test
fun switchFromLockscreenToGoneWhenDeviceUnlocksWithBypassOn_featureOn_bypassOff() =
testScope.runTest {
- val currentSceneKey by
- collectLastValue(
- sceneInteractor.currentScene(SceneContainerNames.SYSTEM_UI_DEFAULT).map {
- it.key
- }
- )
+ val currentSceneKey by collectLastValue(sceneInteractor.currentScene.map { it.key })
prepareState(
isFeatureEnabled = true,
isBypassEnabled = false,
@@ -281,12 +229,7 @@ class SystemUiDefaultSceneContainerStartableTest : SysuiTestCase() {
@Test
fun switchFromLockscreenToGoneWhenDeviceUnlocksWithBypassOn_featureOff_bypassOn() =
testScope.runTest {
- val currentSceneKey by
- collectLastValue(
- sceneInteractor.currentScene(SceneContainerNames.SYSTEM_UI_DEFAULT).map {
- it.key
- }
- )
+ val currentSceneKey by collectLastValue(sceneInteractor.currentScene.map { it.key })
prepareState(
isFeatureEnabled = false,
isBypassEnabled = true,
@@ -303,12 +246,7 @@ class SystemUiDefaultSceneContainerStartableTest : SysuiTestCase() {
@Test
fun switchToGoneWhenDeviceSleepsUnlocked_featureEnabled() =
testScope.runTest {
- val currentSceneKey by
- collectLastValue(
- sceneInteractor.currentScene(SceneContainerNames.SYSTEM_UI_DEFAULT).map {
- it.key
- }
- )
+ val currentSceneKey by collectLastValue(sceneInteractor.currentScene.map { it.key })
prepareState(
isFeatureEnabled = true,
isDeviceUnlocked = true,
@@ -325,12 +263,7 @@ class SystemUiDefaultSceneContainerStartableTest : SysuiTestCase() {
@Test
fun switchToGoneWhenDeviceSleepsUnlocked_featureDisabled() =
testScope.runTest {
- val currentSceneKey by
- collectLastValue(
- sceneInteractor.currentScene(SceneContainerNames.SYSTEM_UI_DEFAULT).map {
- it.key
- }
- )
+ val currentSceneKey by collectLastValue(sceneInteractor.currentScene.map { it.key })
prepareState(
isFeatureEnabled = false,
isDeviceUnlocked = true,
@@ -347,12 +280,7 @@ class SystemUiDefaultSceneContainerStartableTest : SysuiTestCase() {
@Test
fun switchToLockscreenWhenDeviceSleepsLocked_featureEnabled() =
testScope.runTest {
- val currentSceneKey by
- collectLastValue(
- sceneInteractor.currentScene(SceneContainerNames.SYSTEM_UI_DEFAULT).map {
- it.key
- }
- )
+ val currentSceneKey by collectLastValue(sceneInteractor.currentScene.map { it.key })
prepareState(
isFeatureEnabled = true,
isDeviceUnlocked = false,
@@ -369,12 +297,7 @@ class SystemUiDefaultSceneContainerStartableTest : SysuiTestCase() {
@Test
fun switchToLockscreenWhenDeviceSleepsLocked_featureDisabled() =
testScope.runTest {
- val currentSceneKey by
- collectLastValue(
- sceneInteractor.currentScene(SceneContainerNames.SYSTEM_UI_DEFAULT).map {
- it.key
- }
- )
+ val currentSceneKey by collectLastValue(sceneInteractor.currentScene.map { it.key })
prepareState(
isFeatureEnabled = false,
isDeviceUnlocked = false,
@@ -403,10 +326,7 @@ class SystemUiDefaultSceneContainerStartableTest : SysuiTestCase() {
SceneKey.QuickSettings,
)
.forEachIndexed { index, sceneKey ->
- sceneInteractor.setCurrentScene(
- SceneContainerNames.SYSTEM_UI_DEFAULT,
- SceneModel(sceneKey),
- )
+ sceneInteractor.setCurrentScene(SceneModel(sceneKey))
runCurrent()
verify(sysUiState, times(index + 1)).commitUpdate(Display.DEFAULT_DISPLAY)
@@ -422,9 +342,7 @@ class SystemUiDefaultSceneContainerStartableTest : SysuiTestCase() {
featureFlags.set(Flags.SCENE_CONTAINER, isFeatureEnabled)
authenticationRepository.setUnlocked(isDeviceUnlocked)
keyguardRepository.setBypassEnabled(isBypassEnabled)
- initialSceneKey?.let {
- sceneInteractor.setCurrentScene(SceneContainerNames.SYSTEM_UI_DEFAULT, SceneModel(it))
- }
+ initialSceneKey?.let { sceneInteractor.setCurrentScene(SceneModel(it)) }
}
companion object {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModelTest.kt
index 63ea918c904a..0ab98ad512ea 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModelTest.kt
@@ -45,7 +45,6 @@ class SceneContainerViewModelTest : SysuiTestCase() {
private val underTest =
SceneContainerViewModel(
interactor = interactor,
- containerName = SceneTestUtils.CONTAINER_1,
)
@Test
@@ -53,10 +52,10 @@ class SceneContainerViewModelTest : SysuiTestCase() {
val isVisible by collectLastValue(underTest.isVisible)
assertThat(isVisible).isTrue()
- interactor.setVisible(SceneTestUtils.CONTAINER_1, false)
+ interactor.setVisible(false)
assertThat(isVisible).isFalse()
- interactor.setVisible(SceneTestUtils.CONTAINER_1, true)
+ interactor.setVisible(true)
assertThat(isVisible).isTrue()
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt
index 6e9fba64263b..8739b28c940e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt
@@ -20,7 +20,6 @@ import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.keyguard.domain.interactor.LockscreenSceneInteractor
import com.android.systemui.scene.SceneTestUtils
import com.android.systemui.scene.shared.model.SceneKey
import com.android.systemui.scene.shared.model.SceneModel
@@ -48,20 +47,15 @@ class ShadeSceneViewModelTest : SysuiTestCase() {
private val underTest =
ShadeSceneViewModel(
applicationScope = testScope.backgroundScope,
- lockscreenSceneInteractorFactory =
- object : LockscreenSceneInteractor.Factory {
- override fun create(containerName: String): LockscreenSceneInteractor {
- return utils.lockScreenSceneInteractor(
+ lockscreenSceneInteractor =
+ utils.lockScreenSceneInteractor(
+ authenticationInteractor = authenticationInteractor,
+ bouncerInteractor =
+ utils.bouncerInteractor(
authenticationInteractor = authenticationInteractor,
- bouncerInteractor =
- utils.bouncerInteractor(
- authenticationInteractor = authenticationInteractor,
- sceneInteractor = sceneInteractor,
- ),
- )
- }
- },
- containerName = SceneTestUtils.CONTAINER_1
+ sceneInteractor = sceneInteractor,
+ ),
+ ),
)
@Test
@@ -87,8 +81,7 @@ class ShadeSceneViewModelTest : SysuiTestCase() {
@Test
fun onContentClicked_deviceUnlocked_switchesToGone() =
testScope.runTest {
- val currentScene by
- collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
+ val currentScene by collectLastValue(sceneInteractor.currentScene)
utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
utils.authenticationRepository.setUnlocked(true)
runCurrent()
@@ -101,8 +94,7 @@ class ShadeSceneViewModelTest : SysuiTestCase() {
@Test
fun onContentClicked_deviceLockedSecurely_switchesToBouncer() =
testScope.runTest {
- val currentScene by
- collectLastValue(sceneInteractor.currentScene(SceneTestUtils.CONTAINER_1))
+ val currentScene by collectLastValue(sceneInteractor.currentScene)
utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
utils.authenticationRepository.setUnlocked(false)
runCurrent()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/events/SystemEventChipAnimationControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/events/SystemEventChipAnimationControllerTest.kt
index 0b2da8bfa649..0cfca614a256 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/events/SystemEventChipAnimationControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/events/SystemEventChipAnimationControllerTest.kt
@@ -24,6 +24,7 @@ import android.util.Pair
import android.view.Gravity
import android.view.View
import android.widget.FrameLayout
+import androidx.core.animation.AnimatorTestRule
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.flags.FakeFeatureFlags
@@ -38,6 +39,7 @@ import com.google.common.truth.Truth.assertThat
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.junit.Before
+import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
@@ -50,6 +52,7 @@ import org.mockito.MockitoAnnotations
class SystemEventChipAnimationControllerTest : SysuiTestCase() {
private lateinit var controller: SystemEventChipAnimationController
+ @get:Rule val animatorTestRule = AnimatorTestRule()
@Mock private lateinit var sbWindowController: StatusBarWindowController
@Mock private lateinit var insetsProvider: StatusBarContentInsetsProvider
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java
index 1dc8453a90ec..ac8b42afd4b2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java
@@ -789,6 +789,50 @@ public class ExpandableNotificationRowTest extends SysuiTestCase {
assertThat(row.isExpanded()).isTrue();
}
+ @Test
+ public void onDisappearAnimationFinished_shouldSetFalse_headsUpAnimatingAway()
+ throws Exception {
+ final ExpandableNotificationRow row = mNotificationTestHelper.createRow();
+
+ // Initial state: suppose heads up animation in progress
+ row.setHeadsUpAnimatingAway(true);
+ assertThat(row.isHeadsUpAnimatingAway()).isTrue();
+
+ // on disappear animation ends
+ row.onAppearAnimationFinished(/* wasAppearing = */ false);
+ assertThat(row.isHeadsUpAnimatingAway()).isFalse();
+ }
+
+ @Test
+ public void onHUNAppear_cancelAppearDrawing_shouldResetAnimationState() throws Exception {
+ final ExpandableNotificationRow row = mNotificationTestHelper.createRow();
+
+ row.performAddAnimation(/* delay */ 0, /* duration */ 1000, /* isHeadsUpAppear */ true);
+
+ waitForIdleSync();
+ assertThat(row.isDrawingAppearAnimation()).isTrue();
+
+ row.cancelAppearDrawing();
+
+ waitForIdleSync();
+ assertThat(row.isDrawingAppearAnimation()).isFalse();
+ }
+
+ @Test
+ public void onHUNDisappear_cancelAppearDrawing_shouldResetAnimationState() throws Exception {
+ final ExpandableNotificationRow row = mNotificationTestHelper.createRow();
+
+ row.performAddAnimation(/* delay */ 0, /* duration */ 1000, /* isHeadsUpAppear */ false);
+
+ waitForIdleSync();
+ assertThat(row.isDrawingAppearAnimation()).isTrue();
+
+ row.cancelAppearDrawing();
+
+ waitForIdleSync();
+ assertThat(row.isDrawingAppearAnimation()).isFalse();
+ }
+
private void setDrawableIconsInImageView(CachingIconView icon, Drawable iconDrawable,
Drawable rightIconDrawable) {
ImageView iconView = mock(ImageView.class);
diff --git a/packages/SystemUI/src/com/android/systemui/scene/shared/model/SceneContainerNames.kt b/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/shaders/SolidColorShaderTest.kt
index 64f5087d99bf..f1fadf6f1a4a 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/shared/model/SceneContainerNames.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/shaders/SolidColorShaderTest.kt
@@ -13,9 +13,21 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+package com.android.systemui.surfaceeffects.shaders
-package com.android.systemui.scene.shared.model
+import android.graphics.Color
+import android.testing.AndroidTestingRunner
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import org.junit.Test
+import org.junit.runner.RunWith
-object SceneContainerNames {
- const val SYSTEM_UI_DEFAULT = "system_ui"
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class SolidColorShaderTest : SysuiTestCase() {
+
+ @Test
+ fun compilesShader() {
+ SolidColorShader(Color.RED)
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/shaders/SparkleShaderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/shaders/SparkleShaderTest.kt
new file mode 100644
index 000000000000..64ea6a68a518
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/shaders/SparkleShaderTest.kt
@@ -0,0 +1,44 @@
+/*
+ * 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.surfaceeffects.shaders
+
+import android.graphics.Color
+import android.testing.AndroidTestingRunner
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class SparkleShaderTest : SysuiTestCase() {
+
+ private lateinit var sparkleShader: SparkleShader
+
+ @Test
+ fun compilesSparkleShader() {
+ sparkleShader =
+ SparkleShader().apply {
+ setPixelateAmount(
+ context.resources.displayMetrics.density *
+ SparkleShader.DEFAULT_SPARKLE_PIXELATE_AMOUNT
+ )
+ setColor(Color.RED)
+ setTime(0.01f)
+ setLumaMatteColor(Color.WHITE)
+ }
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
index 2f228a8da0c8..e10a80cce793 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
@@ -158,7 +158,6 @@ import com.android.wm.shell.transition.Transitions;
import org.junit.After;
import org.junit.Before;
-import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
@@ -174,7 +173,6 @@ import java.util.HashMap;
import java.util.List;
import java.util.Optional;
-@Ignore("b/292153259")
@SmallTest
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
@@ -280,8 +278,6 @@ public class BubblesTest extends SysuiTestCase {
@Mock
private TaskStackListenerImpl mTaskStackListener;
@Mock
- private ShellTaskOrganizer mShellTaskOrganizer;
- @Mock
private KeyguardStateController mKeyguardStateController;
@Mock
private ScreenOffAnimationController mScreenOffAnimationController;
@@ -298,6 +294,7 @@ public class BubblesTest extends SysuiTestCase {
@Mock
private Icon mAppBubbleIcon;
+ private ShellTaskOrganizer mShellTaskOrganizer;
private TaskViewTransitions mTaskViewTransitions;
private TestableBubblePositioner mPositioner;
@@ -379,7 +376,13 @@ public class BubblesTest extends SysuiTestCase {
mock(UiEventLogger.class),
mock(UserTracker.class)
);
- when(mShellTaskOrganizer.getExecutor()).thenReturn(syncExecutor);
+
+ mShellTaskOrganizer = new ShellTaskOrganizer(mock(ShellInit.class),
+ mock(ShellCommandHandler.class),
+ null,
+ Optional.empty(),
+ Optional.empty(),
+ syncExecutor);
mBubbleProperties = new FakeBubbleProperties();
mBubbleController = new TestableBubbleController(
mContext,
diff --git a/packages/SystemUI/tests/utils/src/androidx/core/animation/AndroidXAnimatorIsolationRule.kt b/packages/SystemUI/tests/utils/src/androidx/core/animation/AndroidXAnimatorIsolationRule.kt
new file mode 100644
index 000000000000..026372f64e2c
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/androidx/core/animation/AndroidXAnimatorIsolationRule.kt
@@ -0,0 +1,55 @@
+/*
+ * 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 androidx.core.animation
+
+import org.junit.rules.TestRule
+import org.junit.runner.Description
+import org.junit.runners.model.Statement
+
+class AndroidXAnimatorIsolationRule : TestRule {
+
+ private class TestAnimationHandler : AnimationHandler(null) {
+ override fun addAnimationFrameCallback(callback: AnimationFrameCallback?) = doFail()
+ override fun removeCallback(callback: AnimationFrameCallback?) = doFail()
+ override fun onAnimationFrame(frameTime: Long) = doFail()
+ override fun setFrameDelay(frameDelay: Long) = doFail()
+ override fun getFrameDelay(): Long = doFail()
+ }
+
+ override fun apply(base: Statement, description: Description): Statement {
+ return object : Statement() {
+ @Throws(Throwable::class)
+ override fun evaluate() {
+ AnimationHandler.setTestHandler(testHandler)
+ try {
+ base.evaluate()
+ } finally {
+ AnimationHandler.setTestHandler(null)
+ }
+ }
+ }
+ }
+
+ companion object {
+ private val testHandler = TestAnimationHandler()
+ private fun doFail(): Nothing =
+ error(
+ "Test's animations are not isolated! " +
+ "Did you forget to add an AnimatorTestRule to your test class?"
+ )
+ }
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestCase.java b/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestCase.java
index de177168e20f..28b7d4171df1 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestCase.java
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestCase.java
@@ -33,6 +33,7 @@ import android.testing.TestWithLooperRule;
import android.testing.TestableLooper;
import android.util.Log;
+import androidx.core.animation.AndroidXAnimatorIsolationRule;
import androidx.test.InstrumentationRegistry;
import androidx.test.uiautomator.UiDevice;
@@ -52,6 +53,7 @@ import com.android.systemui.statusbar.phone.SystemUIDialogManager;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
+import org.junit.ClassRule;
import org.junit.Rule;
import org.mockito.Mockito;
@@ -69,6 +71,12 @@ public abstract class SysuiTestCase {
private static final String TAG = "SysuiTestCase";
private Handler mHandler;
+
+ // set the lowest order so it's the outermost rule
+ @ClassRule(order = Integer.MIN_VALUE)
+ public static AndroidXAnimatorIsolationRule mAndroidXAnimatorIsolationRule =
+ new AndroidXAnimatorIsolationRule();
+
@Rule
public SysuiTestableContext mContext = new SysuiTestableContext(
InstrumentationRegistry.getContext(), getLeakCheck());
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeDeviceEntryFaceAuthRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeDeviceEntryFaceAuthRepository.kt
index f4c2db1b944e..1e1dc4fc59b1 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeDeviceEntryFaceAuthRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeDeviceEntryFaceAuthRepository.kt
@@ -61,6 +61,19 @@ class FakeDeviceEntryFaceAuthRepository : DeviceEntryFaceAuthRepository {
_wasDisabled = true
}
+ private val faceAuthPaused = MutableStateFlow(false)
+ override fun pauseFaceAuth() {
+ faceAuthPaused.value = true
+ }
+
+ override fun resumeFaceAuth() {
+ faceAuthPaused.value = false
+ }
+
+ fun isFaceAuthPaused(): Boolean {
+ return faceAuthPaused.value
+ }
+
override suspend fun authenticate(uiEvent: FaceAuthUiEvent, fallbackToDetection: Boolean) {
_runningAuthRequest.value = uiEvent to fallbackToDetection
_isAuthRunning.value = true
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/SceneTestUtils.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/SceneTestUtils.kt
index f39982f54441..26a75d0cc70a 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/SceneTestUtils.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/SceneTestUtils.kt
@@ -41,7 +41,6 @@ import com.android.systemui.scene.domain.interactor.SceneInteractor
import com.android.systemui.scene.shared.model.RemoteUserInput
import com.android.systemui.scene.shared.model.RemoteUserInputAction
import com.android.systemui.scene.shared.model.SceneContainerConfig
-import com.android.systemui.scene.shared.model.SceneContainerNames
import com.android.systemui.scene.shared.model.SceneKey
import com.android.systemui.user.data.repository.FakeUserRepository
import com.android.systemui.user.data.repository.UserRepository
@@ -96,13 +95,9 @@ class SceneTestUtils(
private val context = test.context
fun fakeSceneContainerRepository(
- containerConfigurations: Set<SceneContainerConfig> =
- setOf(
- fakeSceneContainerConfig(CONTAINER_1),
- fakeSceneContainerConfig(CONTAINER_2),
- )
+ containerConfig: SceneContainerConfig = fakeSceneContainerConfig(),
): SceneContainerRepository {
- return SceneContainerRepository(containerConfigurations.associateBy { it.name })
+ return SceneContainerRepository(containerConfig)
}
fun fakeSceneKeys(): List<SceneKey> {
@@ -116,11 +111,9 @@ class SceneTestUtils(
}
fun fakeSceneContainerConfig(
- name: String,
sceneKeys: List<SceneKey> = fakeSceneKeys(),
): SceneContainerConfig {
return SceneContainerConfig(
- name = name,
sceneKeys = sceneKeys,
initialSceneKey = SceneKey.Lockscreen,
)
@@ -174,7 +167,6 @@ class SceneTestUtils(
authenticationInteractor = authenticationInteractor,
sceneInteractor = sceneInteractor,
featureFlags = featureFlags,
- containerName = CONTAINER_1,
)
}
@@ -184,14 +176,8 @@ class SceneTestUtils(
return BouncerViewModel(
applicationContext = context,
applicationScope = applicationScope(),
- interactorFactory =
- object : BouncerInteractor.Factory {
- override fun create(containerName: String): BouncerInteractor {
- return bouncerInteractor
- }
- },
+ interactor = bouncerInteractor,
featureFlags = featureFlags,
- containerName = CONTAINER_1,
)
}
@@ -202,13 +188,7 @@ class SceneTestUtils(
return LockscreenSceneInteractor(
applicationScope = applicationScope(),
authenticationInteractor = authenticationInteractor,
- bouncerInteractorFactory =
- object : BouncerInteractor.Factory {
- override fun create(containerName: String): BouncerInteractor {
- return bouncerInteractor
- }
- },
- containerName = CONTAINER_1,
+ bouncerInteractor = bouncerInteractor,
)
}
@@ -217,9 +197,6 @@ class SceneTestUtils(
}
companion object {
- const val CONTAINER_1 = SceneContainerNames.SYSTEM_UI_DEFAULT
- const val CONTAINER_2 = "container2"
-
val REMOTE_INPUT_DOWN_GESTURE =
listOf(
RemoteUserInput(10f, 10f, RemoteUserInputAction.DOWN),
diff --git a/services/core/java/com/android/server/pm/InstallPackageHelper.java b/services/core/java/com/android/server/pm/InstallPackageHelper.java
index fbd54555dbbf..622cb6609630 100644
--- a/services/core/java/com/android/server/pm/InstallPackageHelper.java
+++ b/services/core/java/com/android/server/pm/InstallPackageHelper.java
@@ -166,6 +166,7 @@ import com.android.internal.util.CollectionUtils;
import com.android.internal.util.FrameworkStatsLog;
import com.android.server.EventLogTags;
import com.android.server.LocalManagerRegistry;
+import com.android.server.SystemConfig;
import com.android.server.art.model.DexoptParams;
import com.android.server.art.model.DexoptResult;
import com.android.server.pm.Installer.LegacyDexoptDisabledException;
@@ -230,6 +231,7 @@ final class InstallPackageHelper {
private final ViewCompiler mViewCompiler;
private final SharedLibrariesImpl mSharedLibraries;
private final PackageManagerServiceInjector mInjector;
+ private final UpdateOwnershipHelper mUpdateOwnershipHelper;
// TODO(b/198166813): remove PMS dependency
InstallPackageHelper(PackageManagerService pm, AppDataHelper appDataHelper) {
@@ -247,6 +249,7 @@ final class InstallPackageHelper {
mPackageAbiHelper = pm.mInjector.getAbiHelper();
mViewCompiler = pm.mInjector.getViewCompiler();
mSharedLibraries = pm.mInjector.getSharedLibrariesImpl();
+ mUpdateOwnershipHelper = pm.mInjector.getUpdateOwnershipHelper();
}
InstallPackageHelper(PackageManagerService pm) {
@@ -332,6 +335,8 @@ final class InstallPackageHelper {
final String updateOwnerFromSysconfig = isApex || !pkgSetting.isSystem() ? null
: mPm.mInjector.getSystemConfig().getSystemAppUpdateOwnerPackageName(
parsedPackage.getPackageName());
+ final boolean isUpdateOwnershipDenylisted =
+ mUpdateOwnershipHelper.isUpdateOwnershipDenylisted(parsedPackage.getPackageName());
final boolean isUpdateOwnershipEnabled = oldUpdateOwner != null;
// For standard install (install via session), the installSource isn't null.
@@ -367,6 +372,9 @@ final class InstallPackageHelper {
& PackageManager.INSTALL_REQUEST_UPDATE_OWNERSHIP) != 0;
final boolean isSameUpdateOwner =
TextUtils.equals(oldUpdateOwner, installSource.mInstallerPackageName);
+ final boolean isInstallerUpdateOwnerDenylistProvider =
+ mUpdateOwnershipHelper.isUpdateOwnershipDenyListProvider(
+ installSource.mUpdateOwnerPackageName);
// Here we handle the update owner for the package, and the rules are:
// -. Only enabling update ownership enforcement on initial installation if the
@@ -374,13 +382,16 @@ final class InstallPackageHelper {
// -. Once the installer changes and users agree to proceed, clear the update
// owner (package state in other users are taken into account as well).
if (!isUpdate) {
- if (!isRequestUpdateOwnership) {
+ if (!isRequestUpdateOwnership
+ || isUpdateOwnershipDenylisted
+ || isInstallerUpdateOwnerDenylistProvider) {
installSource = installSource.setUpdateOwnerPackageName(null);
} else if ((!isUpdateOwnershipEnabled && pkgAlreadyExists)
|| (isUpdateOwnershipEnabled && !isSameUpdateOwner)) {
installSource = installSource.setUpdateOwnerPackageName(null);
}
- } else if (!isSameUpdateOwner || !isUpdateOwnershipEnabled) {
+ } else if (!isSameUpdateOwner
+ || !isUpdateOwnershipEnabled) {
installSource = installSource.setUpdateOwnerPackageName(null);
}
}
@@ -473,6 +484,19 @@ final class InstallPackageHelper {
pkgSetting.setLoadingProgress(1f);
}
+ ArraySet<String> listItems = mUpdateOwnershipHelper.readUpdateOwnerDenyList(pkgSetting);
+ if (listItems != null && !listItems.isEmpty()) {
+ mUpdateOwnershipHelper.addToUpdateOwnerDenyList(pkgSetting.getPackageName(), listItems);
+ for (String unownedPackage : listItems) {
+ PackageSetting unownedSetting = mPm.mSettings.getPackageLPr(unownedPackage);
+ SystemConfig config = SystemConfig.getInstance();
+ if (unownedSetting != null
+ && config.getSystemAppUpdateOwnerPackageName(unownedPackage) == null) {
+ unownedSetting.setUpdateOwnerPackage(null);
+ }
+ }
+ }
+
return pkg;
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index dbc2fd89e58c..e5dc688529e8 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -1608,7 +1608,8 @@ public class PackageManagerService implements PackageSender, TestUtilityService
(i, pm) -> new SharedLibrariesImpl(pm, i),
(i, pm) -> new CrossProfileIntentFilterHelper(i.getSettings(),
i.getUserManagerService(), i.getLock(), i.getUserManagerInternal(),
- context));
+ context),
+ (i, pm) -> new UpdateOwnershipHelper());
if (Build.VERSION.SDK_INT <= 0) {
Slog.w(TAG, "**** ro.build.version.sdk not set!");
diff --git a/services/core/java/com/android/server/pm/PackageManagerServiceInjector.java b/services/core/java/com/android/server/pm/PackageManagerServiceInjector.java
index 13549f536c9f..51840e70ed26 100644
--- a/services/core/java/com/android/server/pm/PackageManagerServiceInjector.java
+++ b/services/core/java/com/android/server/pm/PackageManagerServiceInjector.java
@@ -144,6 +144,7 @@ public class PackageManagerServiceInjector {
private final Singleton<IBackupManager> mIBackupManager;
private final Singleton<SharedLibrariesImpl> mSharedLibrariesProducer;
private final Singleton<CrossProfileIntentFilterHelper> mCrossProfileIntentFilterHelperProducer;
+ private final Singleton<UpdateOwnershipHelper> mUpdateOwnershipHelperProducer;
PackageManagerServiceInjector(Context context, PackageManagerTracedLock lock,
Installer installer, Object installLock, PackageAbiHelper abiHelper,
@@ -183,7 +184,8 @@ public class PackageManagerServiceInjector {
Producer<BackgroundDexOptService> backgroundDexOptService,
Producer<IBackupManager> iBackupManager,
Producer<SharedLibrariesImpl> sharedLibrariesProducer,
- Producer<CrossProfileIntentFilterHelper> crossProfileIntentFilterHelperProducer) {
+ Producer<CrossProfileIntentFilterHelper> crossProfileIntentFilterHelperProducer,
+ Producer<UpdateOwnershipHelper> updateOwnershipHelperProducer) {
mContext = context;
mLock = lock;
mInstaller = installer;
@@ -238,6 +240,7 @@ public class PackageManagerServiceInjector {
mSharedLibrariesProducer = new Singleton<>(sharedLibrariesProducer);
mCrossProfileIntentFilterHelperProducer = new Singleton<>(
crossProfileIntentFilterHelperProducer);
+ mUpdateOwnershipHelperProducer = new Singleton<>(updateOwnershipHelperProducer);
}
/**
@@ -423,6 +426,11 @@ public class PackageManagerServiceInjector {
return mSharedLibrariesProducer.get(this, mPackageManager);
}
+ public UpdateOwnershipHelper getUpdateOwnershipHelper() {
+ return mUpdateOwnershipHelperProducer.get(this, mPackageManager);
+ }
+
+
/** Provides an abstraction to static access to system state. */
public interface SystemWrapper {
void disablePackageCaches();
diff --git a/services/core/java/com/android/server/pm/RemovePackageHelper.java b/services/core/java/com/android/server/pm/RemovePackageHelper.java
index 10673c6f2dd2..59314a26ab97 100644
--- a/services/core/java/com/android/server/pm/RemovePackageHelper.java
+++ b/services/core/java/com/android/server/pm/RemovePackageHelper.java
@@ -312,6 +312,7 @@ final class RemovePackageHelper {
synchronized (mPm.mLock) {
mPm.mDomainVerificationManager.clearPackage(deletedPs.getPackageName());
mPm.mSettings.getKeySetManagerService().removeAppKeySetDataLPw(packageName);
+ mPm.mInjector.getUpdateOwnershipHelper().removeUpdateOwnerDenyList(packageName);
final Computer snapshot = mPm.snapshotComputer();
mPm.mAppsFilter.removePackage(snapshot,
snapshot.getPackageStateInternal(packageName));
diff --git a/services/core/java/com/android/server/pm/UpdateOwnershipHelper.java b/services/core/java/com/android/server/pm/UpdateOwnershipHelper.java
new file mode 100644
index 000000000000..43752f31a1a2
--- /dev/null
+++ b/services/core/java/com/android/server/pm/UpdateOwnershipHelper.java
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.pm;
+
+import static android.content.pm.PackageManager.PROPERTY_LEGACY_UPDATE_OWNERSHIP_DENYLIST;
+
+import static com.android.server.pm.PackageManagerService.TAG;
+
+import android.Manifest;
+import android.app.ResourcesManager;
+import android.content.pm.ApplicationInfo;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.content.res.XmlResourceParser;
+import android.util.ArrayMap;
+import android.util.ArraySet;
+import android.util.Slog;
+
+import com.android.server.pm.parsing.pkg.AndroidPackageUtils;
+import com.android.server.pm.pkg.AndroidPackage;
+import com.android.server.pm.pkg.component.ParsedUsesPermission;
+
+import org.xmlpull.v1.XmlPullParser;
+
+import java.util.List;
+
+/** Helper class for managing update ownership and optouts for the feature. */
+public class UpdateOwnershipHelper {
+
+ // Called out in PackageManager.PROPERTY_LEGACY_UPDATE_OWNERSHIP_DENYLIST docs
+ private static final int MAX_DENYLIST_SIZE = 500;
+ private static final String TAG_OWNERSHIP_OPT_OUT = "deny-ownership";
+ private final ArrayMap<String, ArraySet<String>> mUpdateOwnerOptOutsToOwners =
+ new ArrayMap<>(200);
+
+ private final Object mLock = new Object();
+
+ private static boolean hasValidOwnershipDenyList(PackageSetting pkgSetting) {
+ AndroidPackage pkg = pkgSetting.getPkg();
+ // we're checking for uses-permission for these priv permissions instead of grant as we're
+ // only considering system apps to begin with, so presumed to be granted.
+ return pkg != null
+ && (pkgSetting.isSystem() || pkgSetting.isUpdatedSystemApp())
+ && pkg.getProperties().containsKey(PROPERTY_LEGACY_UPDATE_OWNERSHIP_DENYLIST)
+ && usesAnyPermission(pkg,
+ Manifest.permission.INSTALL_PACKAGES,
+ Manifest.permission.INSTALL_PACKAGE_UPDATES);
+ }
+
+
+ /** Returns true if a package setting declares that it uses a permission */
+ private static boolean usesAnyPermission(AndroidPackage pkgSetting, String... permissions) {
+ List<ParsedUsesPermission> usesPermissions = pkgSetting.getUsesPermissions();
+ for (int i = 0; i < usesPermissions.size(); i++) {
+ for (int j = 0; j < permissions.length; j++) {
+ if (permissions[j].equals(usesPermissions.get(i).getName())) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Reads the update owner deny list from a {@link PackageSetting} and returns the set of
+ * packages it contains or {@code null} if it cannot be read.
+ */
+ public ArraySet<String> readUpdateOwnerDenyList(PackageSetting pkgSetting) {
+ if (!hasValidOwnershipDenyList(pkgSetting)) {
+ return null;
+ }
+ AndroidPackage pkg = pkgSetting.getPkg();
+ if (pkg == null) {
+ return null;
+ }
+ ArraySet<String> ownershipDenyList = new ArraySet<>(MAX_DENYLIST_SIZE);
+ try {
+ int resId = pkg.getProperties().get(PROPERTY_LEGACY_UPDATE_OWNERSHIP_DENYLIST)
+ .getResourceId();
+ ApplicationInfo appInfo = AndroidPackageUtils.generateAppInfoWithoutState(pkg);
+ Resources resources = ResourcesManager.getInstance().getResources(
+ null, appInfo.sourceDir, appInfo.splitSourceDirs, appInfo.resourceDirs,
+ appInfo.overlayPaths, appInfo.sharedLibraryFiles, null, Configuration.EMPTY,
+ null, null, null);
+ try (XmlResourceParser parser = resources.getXml(resId)) {
+ while (parser.getEventType() != XmlPullParser.END_DOCUMENT) {
+ if (parser.next() == XmlResourceParser.START_TAG) {
+ if (TAG_OWNERSHIP_OPT_OUT.equals(parser.getName())) {
+ parser.next();
+ String packageName = parser.getText();
+ if (packageName != null && !packageName.isBlank()) {
+ ownershipDenyList.add(packageName);
+ if (ownershipDenyList.size() > MAX_DENYLIST_SIZE) {
+ Slog.w(TAG, "Deny list defined by " + pkg.getPackageName()
+ + " was trucated to maximum size of "
+ + MAX_DENYLIST_SIZE);
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ } catch (Exception e) {
+ Slog.e(TAG, "Failed to parse update owner list for " + pkgSetting.getPackageName(), e);
+ return null;
+ }
+ return ownershipDenyList;
+ }
+
+ /**
+ * Begins tracking the contents of a deny list and the owner of that deny list for use in calls
+ * to {@link #isUpdateOwnershipDenylisted(String)} and
+ * {@link #isUpdateOwnershipDenyListProvider(String)}.
+ *
+ * @param listOwner the packageName of the package that owns the deny list.
+ * @param listContents the list of packageNames that are on the deny list.
+ */
+ public void addToUpdateOwnerDenyList(String listOwner, ArraySet<String> listContents) {
+ synchronized (mLock) {
+ for (int i = 0; i < listContents.size(); i++) {
+ String packageName = listContents.valueAt(i);
+ ArraySet<String> priorDenyListOwners = mUpdateOwnerOptOutsToOwners.putIfAbsent(
+ packageName, new ArraySet<>(new String[]{listOwner}));
+ if (priorDenyListOwners != null) {
+ priorDenyListOwners.add(listOwner);
+ }
+ }
+ }
+ }
+
+ /**
+ * Stop tracking the contents of a deny list owned by the provided owner of the deny list.
+ * @param listOwner the packageName of the package that owns the deny list.
+ */
+ public void removeUpdateOwnerDenyList(String listOwner) {
+ synchronized (mLock) {
+ for (int i = mUpdateOwnerOptOutsToOwners.size() - 1; i >= 0; i--) {
+ ArraySet<String> packageDenyListContributors =
+ mUpdateOwnerOptOutsToOwners.get(mUpdateOwnerOptOutsToOwners.keyAt(i));
+ if (packageDenyListContributors.remove(listOwner)
+ && packageDenyListContributors.isEmpty()) {
+ mUpdateOwnerOptOutsToOwners.removeAt(i);
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns {@code true} if the provided package name is on a valid update ownership deny list.
+ */
+ public boolean isUpdateOwnershipDenylisted(String packageName) {
+ return mUpdateOwnerOptOutsToOwners.containsKey(packageName);
+ }
+
+ /**
+ * Returns {@code true} if the provided package name defines a valid update ownership deny list.
+ */
+ public boolean isUpdateOwnershipDenyListProvider(String packageName) {
+ if (packageName == null) {
+ return false;
+ }
+ synchronized (mLock) {
+ for (int i = mUpdateOwnerOptOutsToOwners.size() - 1; i >= 0; i--) {
+ if (mUpdateOwnerOptOutsToOwners.valueAt(i).contains(packageName)) {
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+}
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt b/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt
index 931a2bf53b84..3c753326fb7d 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt
@@ -216,6 +216,7 @@ class MockSystem(withSession: (StaticMockitoSessionBuilder) -> Unit = {}) {
val handler = TestHandler(null)
val defaultAppProvider: DefaultAppProvider = mock()
val backgroundHandler = TestHandler(null)
+ val updateOwnershipHelper: UpdateOwnershipHelper = mock()
}
companion object {
@@ -303,6 +304,7 @@ class MockSystem(withSession: (StaticMockitoSessionBuilder) -> Unit = {}) {
whenever(mocks.injector.handler) { mocks.handler }
whenever(mocks.injector.defaultAppProvider) { mocks.defaultAppProvider }
whenever(mocks.injector.backgroundHandler) { mocks.backgroundHandler }
+ whenever(mocks.injector.updateOwnershipHelper) { mocks.updateOwnershipHelper }
wheneverStatic { SystemConfig.getInstance() }.thenReturn(mocks.systemConfig)
whenever(mocks.systemConfig.availableFeatures).thenReturn(DEFAULT_AVAILABLE_FEATURES_MAP)
whenever(mocks.systemConfig.sharedLibraries).thenReturn(DEFAULT_SHARED_LIBRARIES_LIST)
diff --git a/services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionManagerServiceTest.java
index bb8b986c6f61..ddd1221e4c91 100644
--- a/services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionManagerServiceTest.java
@@ -62,6 +62,7 @@ import android.platform.test.annotations.Presubmit;
import android.view.ContentRecordingSession;
import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.FlakyTest;
import androidx.test.filters.SmallTest;
import androidx.test.platform.app.InstrumentationRegistry;
@@ -688,6 +689,7 @@ public class MediaProjectionManagerServiceTest {
assertThat(mService.isCurrentProjection(projection)).isTrue();
}
+ @FlakyTest(bugId = 288342281)
@Test
public void setContentRecordingSession_successful_notifiesListeners()
throws Exception {
diff --git a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java
index 997015ff1c08..b3db2dea4a27 100644
--- a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java
+++ b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java
@@ -365,7 +365,7 @@ public class SoundTriggerService extends SystemService {
// Validate package name
try {
int uid = mPackageManager.getPackageUid(mOriginatorIdentity.packageName,
- PackageManager.PackageInfoFlags.of(0));
+ PackageManager.PackageInfoFlags.of(PackageManager.MATCH_ANY_USER));
if (!UserHandle.isSameApp(uid, mOriginatorIdentity.uid)) {
throw new SecurityException("Uid " + mOriginatorIdentity.uid +
" attempted to spoof package name " +