summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/app/ActivityThread.java10
-rw-r--r--core/java/android/provider/Settings.java18
-rw-r--r--core/proto/android/providers/settings/secure.proto7
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ToggleResizeDesktopTaskTransitionHandler.kt10
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDividerWindowManager.kt52
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecoration.kt6
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopActivityOrientationChangeHandlerTest.kt10
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt11
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDividerWindowManagerTest.kt20
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecorationTest.kt65
-rw-r--r--packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java2
-rw-r--r--packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java3
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java9
-rw-r--r--packages/SystemUI/BUILD_OWNERS22
-rw-r--r--packages/SystemUI/OWNERS3
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsControllerTest.java3
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsKeyguardAccessibilityDelegateTest.kt86
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeHomeStatusBarViewModel.kt6
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelImplTest.kt281
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt1
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardAccessibilityDelegate.kt54
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java43
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/AlternateBouncerUdfpsViewBinder.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerUdfpsIconViewModel.kt18
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/HomeStatusBarViewBinder.kt190
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/composable/StatusBarRoot.kt12
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/model/ChipsVisibilityModel.kt27
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModel.kt49
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/animation/back/FlingOnBackAnimationCallbackTest.kt8
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt5
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/binder/AlternateBouncerViewBinderKosmos.kt4
-rw-r--r--services/companion/java/com/android/server/companion/securechannel/SecureChannel.java37
-rw-r--r--services/core/java/com/android/server/display/DisplayAdapter.java16
-rw-r--r--services/core/java/com/android/server/display/DisplayManagerService.java7
-rw-r--r--services/core/java/com/android/server/display/LocalDisplayAdapter.java15
-rw-r--r--services/core/java/com/android/server/display/VirtualDisplayAdapter.java64
-rw-r--r--services/core/java/com/android/server/display/brightness/BrightnessReason.java9
-rw-r--r--services/core/java/com/android/server/display/brightness/clamper/BrightnessLowLuxModifier.java53
-rw-r--r--services/core/java/com/android/server/notification/NotificationManagerService.java9
-rw-r--r--services/core/java/com/android/server/notification/NotificationRecord.java18
-rw-r--r--services/core/java/com/android/server/notification/PermissionHelper.java21
-rw-r--r--services/core/java/com/android/server/notification/PreferencesHelper.java9
-rw-r--r--services/core/java/com/android/server/pm/BackgroundInstallControlService.java2
-rw-r--r--services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java11
-rw-r--r--services/tests/InputMethodSystemServerTests/src/com/android/inputmethodservice/AndroidTest.xml5
-rw-r--r--services/tests/InputMethodSystemServerTests/src/com/android/inputmethodservice/InputMethodServiceTest.java10
-rw-r--r--services/tests/InputMethodSystemServerTests/test-apps/SimpleTestIme/AndroidManifest.xml3
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java4
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/VirtualDisplayAdapterTest.java76
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/BrightnessLowLuxModifierTest.kt146
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java35
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java84
-rw-r--r--tests/FlickerTests/Rotation/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt14
-rw-r--r--tests/FlickerTests/test-apps/flickerapp/AndroidManifest.xml27
-rw-r--r--tests/FlickerTests/test-apps/flickerapp/res/layout/activity_ime.xml1
-rw-r--r--tests/FlickerTests/test-apps/flickerapp/res/layout/activity_mail.xml1
-rw-r--r--tests/FlickerTests/test-apps/flickerapp/res/layout/activity_simple.xml1
-rw-r--r--tests/FlickerTests/test-apps/flickerapp/res/layout/activity_surfaceview.xml1
-rw-r--r--tests/FlickerTests/test-apps/flickerapp/res/values/styles.xml6
60 files changed, 877 insertions, 853 deletions
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 4c9116b02c1d..2c1df73cc6cc 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -7362,16 +7362,6 @@ public final class ActivityThread extends ClientTransactionHandler
}
WindowManagerGlobal.getInstance().trimMemory(level);
-
- if (SystemProperties.getInt("debug.am.run_gc_trim_level", Integer.MAX_VALUE) <= level) {
- unscheduleGcIdler();
- doGcIfNeeded("tm");
- }
- if (SystemProperties.getInt("debug.am.run_mallopt_trim_level", Integer.MAX_VALUE)
- <= level) {
- unschedulePurgeIdler();
- purgePendingResources();
- }
}
private void setupGraphicsSupport(Context context) {
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 1210790668de..60e57b588be0 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -9465,24 +9465,6 @@ public final class Settings {
"reduce_bright_colors_persist_across_reboots";
/**
- * Setting that specifies whether Even Dimmer - a feature that allows the brightness
- * slider to go below what the display can conventionally do, should be enabled.
- *
- * @hide
- */
- public static final String EVEN_DIMMER_ACTIVATED =
- "even_dimmer_activated";
-
- /**
- * Setting that specifies which nits level Even Dimmer should allow the screen brightness
- * to go down to.
- *
- * @hide
- */
- public static final String EVEN_DIMMER_MIN_NITS =
- "even_dimmer_min_nits";
-
- /**
* Setting that holds EM_VALUE (proprietary)
*
* @hide
diff --git a/core/proto/android/providers/settings/secure.proto b/core/proto/android/providers/settings/secure.proto
index 8de77469d170..ac4bac6d206e 100644
--- a/core/proto/android/providers/settings/secure.proto
+++ b/core/proto/android/providers/settings/secure.proto
@@ -295,13 +295,6 @@ message SecureSettingsProto {
optional SettingProto enhanced_voice_privacy_enabled = 23 [ (android.privacy).dest = DEST_AUTOMATIC ];
- message EvenDimmer {
- optional SettingProto even_dimmer_activated = 1 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto even_dimmer_min_nits = 2 [ (android.privacy).dest = DEST_AUTOMATIC ];
- }
-
- optional EvenDimmer even_dimmer = 98;
-
optional SettingProto font_weight_adjustment = 85 [ (android.privacy).dest = DEST_AUTOMATIC ];
message Gesture {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ToggleResizeDesktopTaskTransitionHandler.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ToggleResizeDesktopTaskTransitionHandler.kt
index 5e84019b14f5..1a66ca808dad 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ToggleResizeDesktopTaskTransitionHandler.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ToggleResizeDesktopTaskTransitionHandler.kt
@@ -47,6 +47,7 @@ class ToggleResizeDesktopTaskTransitionHandler(
private var boundsAnimator: Animator? = null
private var initialBounds: Rect? = null
+ private var callback: (() -> Unit)? = null
constructor(
transitions: Transitions,
@@ -61,9 +62,14 @@ class ToggleResizeDesktopTaskTransitionHandler(
* bounds of the actual task). This is provided so that the animation resizing can begin where
* the task leash currently is for smoother UX.
*/
- fun startTransition(wct: WindowContainerTransaction, taskLeashBounds: Rect? = null) {
+ fun startTransition(
+ wct: WindowContainerTransaction,
+ taskLeashBounds: Rect? = null,
+ callback: (() -> Unit)? = null,
+ ) {
transitions.startTransition(TRANSIT_DESKTOP_MODE_TOGGLE_RESIZE, wct, this)
initialBounds = taskLeashBounds
+ this.callback = callback
}
fun setOnTaskResizeAnimationListener(listener: OnTaskResizeAnimationListener) {
@@ -121,6 +127,8 @@ class ToggleResizeDesktopTaskTransitionHandler(
interactionJankMonitor.end(Cuj.CUJ_DESKTOP_MODE_MAXIMIZE_WINDOW)
interactionJankMonitor.end(Cuj.CUJ_DESKTOP_MODE_UNMAXIMIZE_WINDOW)
interactionJankMonitor.end(Cuj.CUJ_DESKTOP_MODE_SNAP_RESIZE)
+ callback?.invoke()
+ callback = null
},
)
addUpdateListener { anim ->
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDividerWindowManager.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDividerWindowManager.kt
index cb45c1732476..57f8046065b4 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDividerWindowManager.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDividerWindowManager.kt
@@ -16,6 +16,9 @@
package com.android.wm.shell.windowdecor.tiling
+import android.animation.Animator
+import android.animation.AnimatorListenerAdapter
+import android.animation.ValueAnimator
import android.content.Context
import android.content.res.Configuration
import android.graphics.Path
@@ -144,7 +147,6 @@ class DesktopTilingDividerWindowManager(
* @param relativeLeash the task leash that the TilingDividerView should be shown on top of.
*/
fun generateViewHost(relativeLeash: SurfaceControl) {
- val t = transactionSupplier.get()
val surfaceControlViewHost =
SurfaceControlViewHost(context, context.display, this, "DesktopTilingManager")
val dividerView =
@@ -155,22 +157,40 @@ class DesktopTilingDividerWindowManager(
val tmpDividerBounds = Rect()
getDividerBounds(tmpDividerBounds)
dividerView.setup(this, tmpDividerBounds, handleRegionSize, isDarkMode)
- t.setRelativeLayer(leash, relativeLeash, 1)
- .setPosition(
- leash,
- dividerBounds.left.toFloat() - maxRoundedCornerRadius,
- dividerBounds.top.toFloat(),
- )
- .show(leash)
- syncQueue.runInSync { transaction ->
- transaction.merge(t)
- t.close()
- }
- dividerShown = true
+ val dividerAnimatorT = transactionSupplier.get()
+ val dividerAnimator =
+ ValueAnimator.ofFloat(0f, 1f).apply {
+ duration = DIVIDER_FADE_IN_ALPHA_DURATION
+ addUpdateListener {
+ dividerAnimatorT.setAlpha(leash, animatedValue as Float).apply()
+ }
+ addListener(
+ object : AnimatorListenerAdapter() {
+ override fun onAnimationStart(animation: Animator) {
+ dividerAnimatorT
+ .setRelativeLayer(leash, relativeLeash, 1)
+ .setPosition(
+ leash,
+ dividerBounds.left.toFloat() - maxRoundedCornerRadius,
+ dividerBounds.top.toFloat(),
+ )
+ .setAlpha(leash, 0f)
+ .show(leash)
+ .apply()
+ }
+
+ override fun onAnimationEnd(animation: Animator) {
+ dividerAnimatorT.setAlpha(leash, 1f).apply()
+ dividerShown = true
+ }
+ }
+ )
+ }
+ dividerAnimator.start()
viewHost = surfaceControlViewHost
- dividerView.addOnLayoutChangeListener(this)
tilingDividerView = dividerView
updateTouchRegion()
+ dividerView.addOnLayoutChangeListener(this)
}
/** Changes divider colour if dark/light mode is toggled. */
@@ -311,4 +331,8 @@ class DesktopTilingDividerWindowManager(
)
.maxOf { position -> display.getRoundedCorner(position)?.getRadius() ?: 0 }
}
+
+ companion object {
+ private const val DIVIDER_FADE_IN_ALPHA_DURATION = 300L
+ }
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecoration.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecoration.kt
index a45df045041f..c3d15df6eae5 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecoration.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecoration.kt
@@ -133,10 +133,10 @@ class DesktopTilingWindowDecoration(
isDarkMode = isTaskInDarkMode(taskInfo)
// Observe drag resizing to break tiling if a task is drag resized.
desktopModeWindowDecoration.addDragResizeListener(this)
-
+ val callback = { initTilingForDisplayIfNeeded(taskInfo.configuration, isFirstTiledApp) }
if (isTiled) {
val wct = WindowContainerTransaction().setBounds(taskInfo.token, destinationBounds)
- toggleResizeDesktopTaskTransitionHandler.startTransition(wct, currentBounds)
+ toggleResizeDesktopTaskTransitionHandler.startTransition(wct, currentBounds, callback)
} else {
// Handle the case where we attempt to snap resize when already snap resized: the task
// position won't need to change but we want to animate the surface going back to the
@@ -147,10 +147,10 @@ class DesktopTilingWindowDecoration(
resizeMetadata.getLeash(),
startBounds = currentBounds,
endBounds = destinationBounds,
+ callback,
)
}
}
- initTilingForDisplayIfNeeded(taskInfo.configuration, isFirstTiledApp)
return isTiled
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopActivityOrientationChangeHandlerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopActivityOrientationChangeHandlerTest.kt
index 70a30a3ca7a9..d58f8a34c98e 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopActivityOrientationChangeHandlerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopActivityOrientationChangeHandlerTest.kt
@@ -188,7 +188,7 @@ class DesktopActivityOrientationChangeHandlerTest : ShellTestCase() {
SCREEN_ORIENTATION_LANDSCAPE,
)
- verify(resizeTransitionHandler, never()).startTransition(any(), any())
+ verify(resizeTransitionHandler, never()).startTransition(any(), any(), any())
}
@Test
@@ -209,7 +209,7 @@ class DesktopActivityOrientationChangeHandlerTest : ShellTestCase() {
SCREEN_ORIENTATION_LANDSCAPE,
)
- verify(resizeTransitionHandler, never()).startTransition(any(), any())
+ verify(resizeTransitionHandler, never()).startTransition(any(), any(), any())
}
@Test
@@ -225,7 +225,7 @@ class DesktopActivityOrientationChangeHandlerTest : ShellTestCase() {
handler.handleActivityOrientationChange(task, newTask)
- verify(resizeTransitionHandler, never()).startTransition(any(), any())
+ verify(resizeTransitionHandler, never()).startTransition(any(), any(), any())
}
@Test
@@ -240,7 +240,7 @@ class DesktopActivityOrientationChangeHandlerTest : ShellTestCase() {
SCREEN_ORIENTATION_LANDSCAPE,
)
- verify(resizeTransitionHandler, never()).startTransition(any(), any())
+ verify(resizeTransitionHandler, never()).startTransition(any(), any(), any())
}
@Test
@@ -318,7 +318,7 @@ class DesktopActivityOrientationChangeHandlerTest : ShellTestCase() {
val arg: ArgumentCaptor<WindowContainerTransaction> =
ArgumentCaptor.forClass(WindowContainerTransaction::class.java)
verify(resizeTransitionHandler, atLeastOnce())
- .startTransition(capture(arg), eq(currentBounds))
+ .startTransition(capture(arg), eq(currentBounds), isNull())
return arg.value
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
index 0bccde13cabd..857f9bfb7294 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
@@ -5253,7 +5253,8 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase()
)
// Assert that task is NOT updated via WCT
- verify(toggleResizeDesktopTaskTransitionHandler, never()).startTransition(any(), any())
+ verify(toggleResizeDesktopTaskTransitionHandler, never())
+ .startTransition(any(), any(), any())
// Assert that task leash is updated via Surface Animations
verify(mReturnToDragStartAnimator)
.start(
@@ -5738,7 +5739,8 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase()
InputMethod.TOUCH,
)
// Assert that task is NOT updated via WCT
- verify(toggleResizeDesktopTaskTransitionHandler, never()).startTransition(any(), any())
+ verify(toggleResizeDesktopTaskTransitionHandler, never())
+ .startTransition(any(), any(), any())
// Assert that task leash is updated via Surface Animations
verify(mReturnToDragStartAnimator)
@@ -5835,7 +5837,8 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase()
)
// Assert that task is NOT updated via WCT
- verify(toggleResizeDesktopTaskTransitionHandler, never()).startTransition(any(), any())
+ verify(toggleResizeDesktopTaskTransitionHandler, never())
+ .startTransition(any(), any(), any())
verify(mockToast).show()
}
@@ -6903,7 +6906,7 @@ class DesktopTasksControllerTest(flags: FlagsParameterization) : ShellTestCase()
): WindowContainerTransaction {
val arg = argumentCaptor<WindowContainerTransaction>()
verify(toggleResizeDesktopTaskTransitionHandler, atLeastOnce())
- .startTransition(arg.capture(), eq(currentBounds))
+ .startTransition(arg.capture(), eq(currentBounds), isNull())
return arg.lastValue
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDividerWindowManagerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDividerWindowManagerTest.kt
index 844205682d31..42eab14042f9 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDividerWindowManagerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDividerWindowManagerTest.kt
@@ -70,6 +70,13 @@ class DesktopTilingDividerWindowManagerTest : ShellTestCase() {
whenever(context.display).thenReturn(display)
whenever(display.getRoundedCorner(any())).thenReturn(roundedCorner)
whenever(roundedCorner.radius).thenReturn(CORNER_RADIUS)
+ whenever(transactionSupplierMock.get()).thenReturn(transaction)
+ whenever(transaction.show(any())).thenReturn(transaction)
+ whenever(transaction.setAlpha(any(), any())).thenReturn(transaction)
+ whenever(transaction.hide(any())).thenReturn(transaction)
+ whenever(transaction.setRelativeLayer(any(), any(), any())).thenReturn(transaction)
+ whenever(transaction.setPosition(any(), any(), any())).thenReturn(transaction)
+ whenever(transaction.remove(any())).thenReturn(transaction)
desktopTilingWindowManager =
DesktopTilingDividerWindowManager(
config,
@@ -88,12 +95,6 @@ class DesktopTilingDividerWindowManagerTest : ShellTestCase() {
@Test
@UiThreadTest
fun testWindowManager_isInitialisedAndReleased() {
- whenever(transactionSupplierMock.get()).thenReturn(transaction)
- whenever(transaction.hide(any())).thenReturn(transaction)
- whenever(transaction.setRelativeLayer(any(), any(), any())).thenReturn(transaction)
- whenever(transaction.setPosition(any(), any(), any())).thenReturn(transaction)
- whenever(transaction.remove(any())).thenReturn(transaction)
-
desktopTilingWindowManager.generateViewHost(surfaceControl)
// Ensure a surfaceControl transaction runs to show the divider.
@@ -102,18 +103,11 @@ class DesktopTilingDividerWindowManagerTest : ShellTestCase() {
desktopTilingWindowManager.release()
verify(transaction, times(1)).hide(any())
verify(transaction, times(1)).remove(any())
- verify(transaction, times(1)).apply()
}
@Test
@UiThreadTest
fun testWindowManager_accountsForRoundedCornerDimensions() {
- whenever(transactionSupplierMock.get()).thenReturn(transaction)
- whenever(transaction.setRelativeLayer(any(), any(), any())).thenReturn(transaction)
- whenever(transaction.setRelativeLayer(any(), any(), any())).thenReturn(transaction)
- whenever(transaction.setPosition(any(), any(), any())).thenReturn(transaction)
- whenever(transaction.show(any())).thenReturn(transaction)
-
desktopTilingWindowManager.generateViewHost(surfaceControl)
// Ensure a surfaceControl transaction runs to show the divider.
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecorationTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecorationTest.kt
index 399a51e1ed08..bc8faedd77a9 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecorationTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecorationTest.kt
@@ -114,6 +114,7 @@ class DesktopTilingWindowDecorationTest : ShellTestCase() {
private val split_divider_width = 10
@Captor private lateinit var wctCaptor: ArgumentCaptor<WindowContainerTransaction>
+ @Captor private lateinit var callbackCaptor: ArgumentCaptor<(() -> Unit)>
@Before
fun setUp() {
@@ -134,7 +135,7 @@ class DesktopTilingWindowDecorationTest : ShellTestCase() {
userRepositories,
desktopModeEventLogger,
focusTransitionObserver,
- mainExecutor
+ mainExecutor,
)
whenever(context.createContextAsUser(any(), any())).thenReturn(context)
whenever(userRepositories.current).thenReturn(desktopRepository)
@@ -158,7 +159,8 @@ class DesktopTilingWindowDecorationTest : ShellTestCase() {
BOUNDS,
)
- verify(toggleResizeDesktopTaskTransitionHandler).startTransition(capture(wctCaptor), any())
+ verify(toggleResizeDesktopTaskTransitionHandler)
+ .startTransition(capture(wctCaptor), any(), any())
for (change in wctCaptor.value.changes) {
val bounds = change.value.configuration.windowConfiguration.bounds
val leftBounds = getLeftTaskBounds()
@@ -185,7 +187,8 @@ class DesktopTilingWindowDecorationTest : ShellTestCase() {
BOUNDS,
)
- verify(toggleResizeDesktopTaskTransitionHandler).startTransition(capture(wctCaptor), any())
+ verify(toggleResizeDesktopTaskTransitionHandler)
+ .startTransition(capture(wctCaptor), any(), any())
for (change in wctCaptor.value.changes) {
val bounds = change.value.configuration.windowConfiguration.bounds
val leftBounds = getRightTaskBounds()
@@ -220,7 +223,7 @@ class DesktopTilingWindowDecorationTest : ShellTestCase() {
)
verify(toggleResizeDesktopTaskTransitionHandler, times(1))
- .startTransition(capture(wctCaptor), any())
+ .startTransition(capture(wctCaptor), any(), any())
verify(returnToDragStartAnimator, times(1)).start(any(), any(), any(), any(), anyOrNull())
for (change in wctCaptor.value.changes) {
val bounds = change.value.configuration.windowConfiguration.bounds
@@ -308,9 +311,13 @@ class DesktopTilingWindowDecorationTest : ShellTestCase() {
DesktopTasksController.SnapPosition.LEFT,
BOUNDS,
)
+ verify(toggleResizeDesktopTaskTransitionHandler, times(2))
+ .startTransition(capture(wctCaptor), any(), capture(callbackCaptor))
+ (callbackCaptor.value).invoke()
task1.isFocused = true
- assertThat(tilingDecoration.moveTiledPairToFront(task1.taskId, isFocusedOnDisplay = true)).isTrue()
+ assertThat(tilingDecoration.moveTiledPairToFront(task1.taskId, isFocusedOnDisplay = true))
+ .isTrue()
verify(transitions, times(1)).startTransition(eq(TRANSIT_TO_FRONT), any(), eq(null))
}
@@ -341,6 +348,9 @@ class DesktopTilingWindowDecorationTest : ShellTestCase() {
)
task1.isFocused = true
task3.isFocused = true
+ verify(toggleResizeDesktopTaskTransitionHandler, times(2))
+ .startTransition(capture(wctCaptor), any(), capture(callbackCaptor))
+ (callbackCaptor.value).invoke()
assertThat(tilingDecoration.moveTiledPairToFront(task3.taskId, true)).isFalse()
assertThat(tilingDecoration.moveTiledPairToFront(task1.taskId, true)).isTrue()
@@ -372,9 +382,14 @@ class DesktopTilingWindowDecorationTest : ShellTestCase() {
DesktopTasksController.SnapPosition.LEFT,
BOUNDS,
)
-
- assertThat(tilingDecoration.moveTiledPairToFront(task3.taskId, isFocusedOnDisplay = true)).isFalse()
- assertThat(tilingDecoration.moveTiledPairToFront(task1.taskId, isFocusedOnDisplay = true)).isTrue()
+ verify(toggleResizeDesktopTaskTransitionHandler, times(2))
+ .startTransition(capture(wctCaptor), any(), capture(callbackCaptor))
+ (callbackCaptor.value).invoke()
+
+ assertThat(tilingDecoration.moveTiledPairToFront(task3.taskId, isFocusedOnDisplay = true))
+ .isFalse()
+ assertThat(tilingDecoration.moveTiledPairToFront(task1.taskId, isFocusedOnDisplay = true))
+ .isTrue()
verify(transitions, times(1)).startTransition(eq(TRANSIT_TO_FRONT), any(), eq(null))
}
@@ -482,27 +497,29 @@ class DesktopTilingWindowDecorationTest : ShellTestCase() {
tilingDecoration.onDividerHandleDragStart(motionEvent)
// Log start event for task1 and task2, but the tasks are the same in
// this test, so we verify the same log twice.
- verify(desktopModeEventLogger, times(2)).logTaskResizingStarted(
- ResizeTrigger.TILING_DIVIDER,
- DesktopModeEventLogger.Companion.InputMethod.UNKNOWN_INPUT_METHOD,
- task1,
- BOUNDS.width() / 2,
- BOUNDS.height(),
- displayController,
- )
+ verify(desktopModeEventLogger, times(2))
+ .logTaskResizingStarted(
+ ResizeTrigger.TILING_DIVIDER,
+ DesktopModeEventLogger.Companion.InputMethod.UNKNOWN_INPUT_METHOD,
+ task1,
+ BOUNDS.width() / 2,
+ BOUNDS.height(),
+ displayController,
+ )
tilingDecoration.onDividerHandleMoved(BOUNDS, transaction)
tilingDecoration.onDividerHandleDragEnd(BOUNDS, transaction, motionEvent)
// Log end event for task1 and task2, but the tasks are the same in
// this test, so we verify the same log twice.
- verify(desktopModeEventLogger, times(2)).logTaskResizingEnded(
- ResizeTrigger.TILING_DIVIDER,
- DesktopModeEventLogger.Companion.InputMethod.UNKNOWN_INPUT_METHOD,
- task1,
- BOUNDS.width(),
- BOUNDS.height(),
- displayController,
- )
+ verify(desktopModeEventLogger, times(2))
+ .logTaskResizingEnded(
+ ResizeTrigger.TILING_DIVIDER,
+ DesktopModeEventLogger.Companion.InputMethod.UNKNOWN_INPUT_METHOD,
+ task1,
+ BOUNDS.width(),
+ BOUNDS.height(),
+ displayController,
+ )
}
@Test
diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
index 3c70fc15485a..c0105298899b 100644
--- a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
+++ b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
@@ -271,8 +271,6 @@ public class SecureSettings {
Settings.Secure.DEFAULT_NOTE_TASK_PROFILE,
Settings.Secure.CREDENTIAL_SERVICE,
Settings.Secure.CREDENTIAL_SERVICE_PRIMARY,
- Settings.Secure.EVEN_DIMMER_ACTIVATED,
- Settings.Secure.EVEN_DIMMER_MIN_NITS,
Settings.Secure.STYLUS_POINTER_ICON_ENABLED,
Settings.Secure.CAMERA_EXTENSIONS_FALLBACK,
Settings.Secure.VISUAL_QUERY_ACCESSIBILITY_DETECTION_ENABLED,
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
index c09e45ed81a6..0ffdf53f2036 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
@@ -114,9 +114,6 @@ public class SecureSettingsValidators {
VALIDATORS.put(Secure.FONT_WEIGHT_ADJUSTMENT, ANY_INTEGER_VALIDATOR);
VALIDATORS.put(Secure.REDUCE_BRIGHT_COLORS_LEVEL, PERCENTAGE_INTEGER_VALIDATOR);
VALIDATORS.put(Secure.REDUCE_BRIGHT_COLORS_PERSIST_ACROSS_REBOOTS, BOOLEAN_VALIDATOR);
- VALIDATORS.put(Secure.EVEN_DIMMER_ACTIVATED, BOOLEAN_VALIDATOR);
- VALIDATORS.put(Secure.EVEN_DIMMER_MIN_NITS,
- new InclusiveFloatRangeValidator(0.0f, Float.MAX_VALUE));
VALIDATORS.put(Secure.TTS_DEFAULT_RATE, NON_NEGATIVE_INTEGER_VALIDATOR);
VALIDATORS.put(Secure.TTS_DEFAULT_PITCH, NON_NEGATIVE_INTEGER_VALIDATOR);
VALIDATORS.put(Secure.TTS_DEFAULT_SYNTH, PACKAGE_NAME_VALIDATOR);
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index 167674a451b3..e07832eea65e 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -2189,15 +2189,6 @@ class SettingsProtoDumpUtil {
Settings.Secure.ENHANCED_VOICE_PRIVACY_ENABLED,
SecureSettingsProto.ENHANCED_VOICE_PRIVACY_ENABLED);
- final long evenDimmerToken = p.start(SecureSettingsProto.EVEN_DIMMER);
- dumpSetting(s, p,
- Settings.Secure.EVEN_DIMMER_ACTIVATED,
- SecureSettingsProto.EvenDimmer.EVEN_DIMMER_ACTIVATED);
- dumpSetting(s, p,
- Settings.Secure.EVEN_DIMMER_MIN_NITS,
- SecureSettingsProto.EvenDimmer.EVEN_DIMMER_MIN_NITS);
- p.end(evenDimmerToken);
-
dumpSetting(s, p,
Settings.Secure.EM_VALUE,
SecureSettingsProto.Accessibility.EM_VALUE);
diff --git a/packages/SystemUI/BUILD_OWNERS b/packages/SystemUI/BUILD_OWNERS
new file mode 100644
index 000000000000..4aadee173388
--- /dev/null
+++ b/packages/SystemUI/BUILD_OWNERS
@@ -0,0 +1,22 @@
+# Build file owners for System UI. Owners should consider the following:
+#
+# - Does the change negatively affect developer builds? Will it make
+# the build slower?
+#
+# - Does the change add unnecessary dependencies or compilation steps
+# that will be difficult to refactor?
+#
+# For more information, see http://go/sysui-build-owners
+
+dsandler@android.com
+
+caitlinshk@google.com
+ccross@android.com
+cinek@google.com
+jernej@google.com
+mankoff@google.com
+nicomazz@google.com
+peskal@google.com
+pixel@google.com
+saff@google.com
+vadimt@google.com
diff --git a/packages/SystemUI/OWNERS b/packages/SystemUI/OWNERS
index f5c0233d56b1..ab3fa1b06255 100644
--- a/packages/SystemUI/OWNERS
+++ b/packages/SystemUI/OWNERS
@@ -125,3 +125,6 @@ silvajordan@google.com
uwaisashraf@google.com
vinayjoglekar@google.com
willosborn@google.com
+
+per-file *.mk,{**/,}Android.bp = set noparent
+per-file *.mk,{**/,}Android.bp = file:BUILD_OWNERS
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
index aeea99be40dd..a2f5a30a20ff 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
@@ -193,8 +193,6 @@ public class UdfpsControllerTest extends SysuiTestCase {
@Mock
private UdfpsOverlayInteractor mUdfpsOverlayInteractor;
@Mock
- private UdfpsKeyguardAccessibilityDelegate mUdfpsKeyguardAccessibilityDelegate;
- @Mock
private SelectedUserInteractor mSelectedUserInteractor;
// Capture listeners so that they can be used to send events
@@ -321,7 +319,6 @@ public class UdfpsControllerTest extends SysuiTestCase {
mAlternateBouncerInteractor,
mInputManager,
mock(DeviceEntryFaceAuthInteractor.class),
- mUdfpsKeyguardAccessibilityDelegate,
mSelectedUserInteractor,
mKeyguardTransitionInteractor,
mDeviceEntryUdfpsTouchOverlayViewModel,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsKeyguardAccessibilityDelegateTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsKeyguardAccessibilityDelegateTest.kt
deleted file mode 100644
index 921ff098753e..000000000000
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsKeyguardAccessibilityDelegateTest.kt
+++ /dev/null
@@ -1,86 +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.biometrics
-
-import android.testing.TestableLooper
-import android.view.View
-import android.view.accessibility.AccessibilityNodeInfo
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import androidx.test.filters.SmallTest
-import com.android.systemui.SysuiTestCase
-import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager
-import com.android.systemui.util.mockito.argumentCaptor
-import org.junit.Assert.assertEquals
-import org.junit.Before
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.mockito.ArgumentMatchers.anyBoolean
-import org.mockito.Mock
-import org.mockito.Mockito.mock
-import org.mockito.Mockito.verify
-import org.mockito.MockitoAnnotations
-
-@RunWith(AndroidJUnit4::class)
-@SmallTest
-@TestableLooper.RunWithLooper
-class UdfpsKeyguardAccessibilityDelegateTest : SysuiTestCase() {
-
- @Mock private lateinit var keyguardViewManager: StatusBarKeyguardViewManager
- @Mock private lateinit var hostView: View
- private lateinit var underTest: UdfpsKeyguardAccessibilityDelegate
-
- @Before
- fun setUp() {
- MockitoAnnotations.initMocks(this)
- underTest =
- UdfpsKeyguardAccessibilityDelegate(
- context.resources,
- keyguardViewManager,
- )
- }
-
- @Test
- fun onInitializeAccessibilityNodeInfo_clickActionAdded() {
- // WHEN node is initialized
- val mockedNodeInfo = mock(AccessibilityNodeInfo::class.java)
- underTest.onInitializeAccessibilityNodeInfo(hostView, mockedNodeInfo)
-
- // THEN a11y action is added
- val argumentCaptor = argumentCaptor<AccessibilityNodeInfo.AccessibilityAction>()
- verify(mockedNodeInfo).addAction(argumentCaptor.capture())
-
- // AND the a11y action is a click action
- assertEquals(
- AccessibilityNodeInfo.AccessibilityAction.ACTION_CLICK.id,
- argumentCaptor.value.id
- )
- }
-
- @Test
- fun performAccessibilityAction_actionClick_showsPrimaryBouncer() {
- // WHEN click action is performed
- val mockedNodeInfo = mock(AccessibilityNodeInfo::class.java)
- underTest.performAccessibilityAction(
- hostView,
- AccessibilityNodeInfo.AccessibilityAction.ACTION_CLICK.id,
- null
- )
-
- // THEN primary bouncer shows
- verify(keyguardViewManager).showPrimaryBouncer(anyBoolean())
- }
-}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeHomeStatusBarViewModel.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeHomeStatusBarViewModel.kt
index f91e3a612862..a083e59fe263 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeHomeStatusBarViewModel.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeHomeStatusBarViewModel.kt
@@ -31,6 +31,7 @@ import com.android.systemui.statusbar.events.shared.model.SystemEventAnimationSt
import com.android.systemui.statusbar.featurepods.popups.shared.model.PopupChipModel
import com.android.systemui.statusbar.phone.domain.interactor.IsAreaDark
import com.android.systemui.statusbar.pipeline.battery.ui.viewmodel.BatteryViewModel
+import com.android.systemui.statusbar.pipeline.shared.ui.model.ChipsVisibilityModel
import com.android.systemui.statusbar.pipeline.shared.ui.model.SystemInfoCombinedVisibilityModel
import com.android.systemui.statusbar.pipeline.shared.ui.model.VisibilityModel
import kotlinx.coroutines.flow.Flow
@@ -52,7 +53,10 @@ class FakeHomeStatusBarViewModel(
override val primaryOngoingActivityChip: MutableStateFlow<OngoingActivityChipModel> =
MutableStateFlow(OngoingActivityChipModel.Inactive())
- override val ongoingActivityChips = MutableStateFlow(MultipleOngoingActivityChipsModel())
+ override val ongoingActivityChips =
+ MutableStateFlow(
+ ChipsVisibilityModel(MultipleOngoingActivityChipsModel(), areChipsAllowed = false)
+ )
override val ongoingActivityChipsLegacy =
MutableStateFlow(MultipleOngoingActivityChipsModelLegacy())
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelImplTest.kt
index 7e8ee1b156df..27aa4bab3deb 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelImplTest.kt
@@ -64,6 +64,7 @@ import com.android.systemui.statusbar.chips.mediaprojection.domain.model.MediaPr
import com.android.systemui.statusbar.chips.notification.shared.StatusBarNotifChips
import com.android.systemui.statusbar.chips.sharetoapp.ui.viewmodel.shareToAppChipViewModel
import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel
+import com.android.systemui.statusbar.chips.ui.viewmodel.OngoingActivityChipsViewModelTest.Companion.assertIsCallChip
import com.android.systemui.statusbar.chips.ui.viewmodel.OngoingActivityChipsViewModelTest.Companion.assertIsScreenRecordChip
import com.android.systemui.statusbar.chips.ui.viewmodel.OngoingActivityChipsViewModelTest.Companion.assertIsShareToAppChip
import com.android.systemui.statusbar.core.StatusBarRootModernization
@@ -88,6 +89,7 @@ import com.android.systemui.statusbar.phone.SysuiDarkIconDispatcher
import com.android.systemui.statusbar.phone.data.repository.fakeDarkIconRepository
import com.android.systemui.statusbar.phone.ongoingcall.EnableChipsModernization
import com.android.systemui.statusbar.phone.ongoingcall.StatusBarChipsModernization
+import com.android.systemui.statusbar.phone.ongoingcall.shared.model.OngoingCallTestHelper.addOngoingCallState
import com.android.systemui.statusbar.pipeline.shared.domain.interactor.setHomeStatusBarIconBlockList
import com.android.systemui.statusbar.pipeline.shared.domain.interactor.setHomeStatusBarInteractorShowOperatorName
import com.android.systemui.statusbar.pipeline.shared.ui.model.VisibilityModel
@@ -716,7 +718,8 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
}
@Test
- fun canShowOngoingActivityChips_statusBarNotHidden_noSecureCamera_hun_false() =
+ @DisableFlags(StatusBarNoHunBehavior.FLAG_NAME)
+ fun canShowOngoingActivityChips_statusBarNotHidden_noSecureCamera_hunBySystem_noHunFlagOff_false() =
kosmos.runTest {
val latest by collectLastValue(underTest.canShowOngoingActivityChips)
@@ -725,7 +728,7 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
headsUpNotificationRepository.setNotifications(
UnconfinedFakeHeadsUpRowRepository(
key = "key",
- pinnedStatus = MutableStateFlow(PinnedStatus.PinnedByUser),
+ pinnedStatus = MutableStateFlow(PinnedStatus.PinnedBySystem),
)
)
@@ -733,6 +736,194 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
}
@Test
+ @DisableFlags(StatusBarNoHunBehavior.FLAG_NAME)
+ fun canShowOngoingActivityChips_statusBarNotHidden_noSecureCamera_hunByUser_noHunFlagOff_true() =
+ kosmos.runTest {
+ val latest by collectLastValue(underTest.canShowOngoingActivityChips)
+
+ transitionKeyguardToGone()
+
+ headsUpNotificationRepository.setNotifications(
+ UnconfinedFakeHeadsUpRowRepository(
+ key = "key",
+ pinnedStatus = MutableStateFlow(PinnedStatus.PinnedByUser),
+ )
+ )
+
+ assertThat(latest).isTrue()
+ }
+
+ @Test
+ @EnableFlags(StatusBarNoHunBehavior.FLAG_NAME)
+ fun canShowOngoingActivityChips_statusBarNotHidden_noSecureCamera_hunBySystem_noHunFlagOn_true() =
+ kosmos.runTest {
+ val latest by collectLastValue(underTest.canShowOngoingActivityChips)
+
+ transitionKeyguardToGone()
+
+ headsUpNotificationRepository.setNotifications(
+ UnconfinedFakeHeadsUpRowRepository(
+ key = "key",
+ pinnedStatus = MutableStateFlow(PinnedStatus.PinnedBySystem),
+ )
+ )
+
+ assertThat(latest).isTrue()
+ }
+
+ @Test
+ @EnableFlags(StatusBarNoHunBehavior.FLAG_NAME)
+ fun canShowOngoingActivityChips_statusBarNotHidden_noSecureCamera_hunByUser_noHunFlagOn_true() =
+ kosmos.runTest {
+ val latest by collectLastValue(underTest.canShowOngoingActivityChips)
+
+ transitionKeyguardToGone()
+
+ headsUpNotificationRepository.setNotifications(
+ UnconfinedFakeHeadsUpRowRepository(
+ key = "key",
+ pinnedStatus = MutableStateFlow(PinnedStatus.PinnedByUser),
+ )
+ )
+
+ assertThat(latest).isTrue()
+ }
+
+ @Test
+ @EnableChipsModernization
+ fun ongoingActivityChips_statusBarHidden_noSecureCamera_noHun_notAllowed() =
+ kosmos.runTest {
+ val latest by collectLastValue(underTest.ongoingActivityChips)
+
+ // home status bar not allowed
+ kosmos.sceneContainerRepository.snapToScene(Scenes.Lockscreen)
+ kosmos.keyguardOcclusionRepository.setShowWhenLockedActivityInfo(false, taskInfo = null)
+
+ assertThat(latest!!.areChipsAllowed).isFalse()
+ }
+
+ @Test
+ @EnableChipsModernization
+ fun ongoingActivityChips_statusBarNotHidden_noSecureCamera_noHun_isAllowed() =
+ kosmos.runTest {
+ val latest by collectLastValue(underTest.ongoingActivityChips)
+
+ transitionKeyguardToGone()
+
+ assertThat(latest!!.areChipsAllowed).isTrue()
+ }
+
+ @Test
+ @EnableChipsModernization
+ fun ongoingActivityChips_statusBarNotHidden_secureCamera_noHun_notAllowed() =
+ kosmos.runTest {
+ val latest by collectLastValue(underTest.ongoingActivityChips)
+
+ fakeKeyguardTransitionRepository.sendTransitionSteps(
+ from = KeyguardState.LOCKSCREEN,
+ to = KeyguardState.OCCLUDED,
+ testScope = testScope,
+ )
+ kosmos.keyguardInteractor.onCameraLaunchDetected(CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP)
+
+ assertThat(latest!!.areChipsAllowed).isFalse()
+ }
+
+ @Test
+ @DisableFlags(StatusBarNoHunBehavior.FLAG_NAME)
+ @EnableChipsModernization
+ fun ongoingActivityChips_statusBarNotHidden_noSecureCamera_hunBySystem_noHunFlagOff_notAllowed() =
+ kosmos.runTest {
+ val latest by collectLastValue(underTest.ongoingActivityChips)
+
+ transitionKeyguardToGone()
+
+ headsUpNotificationRepository.setNotifications(
+ UnconfinedFakeHeadsUpRowRepository(
+ key = "key",
+ pinnedStatus = MutableStateFlow(PinnedStatus.PinnedBySystem),
+ )
+ )
+
+ assertThat(latest!!.areChipsAllowed).isFalse()
+ }
+
+ @Test
+ @DisableFlags(StatusBarNoHunBehavior.FLAG_NAME)
+ @EnableChipsModernization
+ fun ongoingActivityChips_statusBarNotHidden_noSecureCamera_hunByUser_noHunFlagOff_isAllowed() =
+ kosmos.runTest {
+ val latest by collectLastValue(underTest.ongoingActivityChips)
+
+ transitionKeyguardToGone()
+
+ headsUpNotificationRepository.setNotifications(
+ UnconfinedFakeHeadsUpRowRepository(
+ key = "key",
+ pinnedStatus = MutableStateFlow(PinnedStatus.PinnedByUser),
+ )
+ )
+
+ assertThat(latest!!.areChipsAllowed).isTrue()
+ }
+
+ @Test
+ @EnableFlags(StatusBarNoHunBehavior.FLAG_NAME)
+ @EnableChipsModernization
+ fun ongoingActivityChips_tatusBarNotHidden_noSecureCamera_hunBySystem_noHunFlagOn_isAllowed() =
+ kosmos.runTest {
+ val latest by collectLastValue(underTest.ongoingActivityChips)
+
+ transitionKeyguardToGone()
+
+ headsUpNotificationRepository.setNotifications(
+ UnconfinedFakeHeadsUpRowRepository(
+ key = "key",
+ pinnedStatus = MutableStateFlow(PinnedStatus.PinnedBySystem),
+ )
+ )
+
+ assertThat(latest!!.areChipsAllowed).isTrue()
+ }
+
+ @Test
+ @EnableFlags(StatusBarNoHunBehavior.FLAG_NAME)
+ @EnableChipsModernization
+ fun ongoingActivityChips_statusBarNotHidden_noSecureCamera_hunByUser_noHunFlagOn_isAllowed() =
+ kosmos.runTest {
+ val latest by collectLastValue(underTest.ongoingActivityChips)
+
+ transitionKeyguardToGone()
+
+ headsUpNotificationRepository.setNotifications(
+ UnconfinedFakeHeadsUpRowRepository(
+ key = "key",
+ pinnedStatus = MutableStateFlow(PinnedStatus.PinnedByUser),
+ )
+ )
+
+ assertThat(latest!!.areChipsAllowed).isTrue()
+ }
+
+ @Test
+ @EnableFlags(StatusBarNotifChips.FLAG_NAME)
+ @EnableChipsModernization
+ fun ongoingActivityChips_followsChipsViewModel() =
+ kosmos.runTest {
+ val latest by collectLastValue(underTest.ongoingActivityChips)
+ transitionKeyguardToGone()
+
+ screenRecordRepository.screenRecordState.value = ScreenRecordModel.Recording
+
+ assertIsScreenRecordChip(latest!!.chips.active[0])
+
+ addOngoingCallState(key = "call")
+
+ assertIsScreenRecordChip(latest!!.chips.active[0])
+ assertIsCallChip(latest!!.chips.active[1], "call")
+ }
+
+ @Test
fun isClockVisible_allowedByDisableFlags_visible() =
kosmos.runTest {
val latest by collectLastValue(underTest.isClockVisible)
@@ -892,7 +1083,7 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
@Test
@EnableChipsModernization
- fun isNotificationIconContainerVisible_anyChipShowing_ChipsModernizationOn() =
+ fun isNotificationIconContainerVisible_anyChipShowing_chipsModernizationOn() =
kosmos.runTest {
val latest by collectLastValue(underTest.isNotificationIconContainerVisible)
transitionKeyguardToGone()
@@ -909,7 +1100,7 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
@Test
@DisableFlags(StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME)
@EnableFlags(StatusBarNotifChips.FLAG_NAME)
- fun isNotificationIconContainerVisible_anyChipShowing_PromotedNotifsOn() =
+ fun isNotificationIconContainerVisible_anyChipShowing_promotedNotifsOn() =
kosmos.runTest {
val latest by collectLastValue(underTest.isNotificationIconContainerVisible)
transitionKeyguardToGone()
@@ -929,7 +1120,7 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
StatusBarRootModernization.FLAG_NAME,
StatusBarChipsModernization.FLAG_NAME,
)
- fun isNotificationIconContainerVisible_anyChipShowing_ChipsModernizationAndPromotedNotifsOff() =
+ fun isNotificationIconContainerVisible_anyChipShowing_chipsModernizationAndPromotedNotifsOff() =
kosmos.runTest {
val latest by collectLastValue(underTest.isNotificationIconContainerVisible)
transitionKeyguardToGone()
@@ -943,6 +1134,86 @@ class HomeStatusBarViewModelImplTest : SysuiTestCase() {
assertThat(latest!!.visibility).isEqualTo(View.VISIBLE)
}
+ @DisableFlags(StatusBarNoHunBehavior.FLAG_NAME)
+ fun isNotificationIconContainerVisible_hasChipButAlsoHun_hunBySystem_noHunFlagOff_visible() =
+ kosmos.runTest {
+ val latest by collectLastValue(underTest.isNotificationIconContainerVisible)
+ transitionKeyguardToGone()
+
+ // Chip
+ kosmos.screenRecordRepository.screenRecordState.value = ScreenRecordModel.Recording
+
+ // HUN, PinnedBySystem
+ headsUpNotificationRepository.setNotifications(
+ UnconfinedFakeHeadsUpRowRepository(
+ key = "key",
+ pinnedStatus = MutableStateFlow(PinnedStatus.PinnedBySystem),
+ )
+ )
+
+ assertThat(latest!!.visibility).isEqualTo(View.VISIBLE)
+ }
+
+ @DisableFlags(StatusBarNoHunBehavior.FLAG_NAME)
+ fun isNotificationIconContainerVisible_hasChipButAlsoHun_hunByUser_noHunFlagOff_gone() =
+ kosmos.runTest {
+ val latest by collectLastValue(underTest.isNotificationIconContainerVisible)
+ transitionKeyguardToGone()
+
+ // Chip
+ kosmos.screenRecordRepository.screenRecordState.value = ScreenRecordModel.Recording
+
+ // HUN, PinnedByUser
+ headsUpNotificationRepository.setNotifications(
+ UnconfinedFakeHeadsUpRowRepository(
+ key = "key",
+ pinnedStatus = MutableStateFlow(PinnedStatus.PinnedByUser),
+ )
+ )
+
+ assertThat(latest!!.visibility).isEqualTo(View.GONE)
+ }
+
+ @EnableFlags(StatusBarNoHunBehavior.FLAG_NAME)
+ fun isNotificationIconContainerVisible_hasChipButAlsoHun_hunBySystem_noHunFlagOn_gone() =
+ kosmos.runTest {
+ val latest by collectLastValue(underTest.isNotificationIconContainerVisible)
+ transitionKeyguardToGone()
+
+ // Chip
+ kosmos.screenRecordRepository.screenRecordState.value = ScreenRecordModel.Recording
+
+ // HUN, PinnedBySystem
+ headsUpNotificationRepository.setNotifications(
+ UnconfinedFakeHeadsUpRowRepository(
+ key = "key",
+ pinnedStatus = MutableStateFlow(PinnedStatus.PinnedBySystem),
+ )
+ )
+
+ assertThat(latest!!.visibility).isEqualTo(View.GONE)
+ }
+
+ @EnableFlags(StatusBarNoHunBehavior.FLAG_NAME)
+ fun isNotificationIconContainerVisible_hasChipButAlsoHun_hunByUser_noHunFlagOn_gone() =
+ kosmos.runTest {
+ val latest by collectLastValue(underTest.isNotificationIconContainerVisible)
+ transitionKeyguardToGone()
+
+ // Chip
+ kosmos.screenRecordRepository.screenRecordState.value = ScreenRecordModel.Recording
+
+ // HUN, PinnedByUser
+ headsUpNotificationRepository.setNotifications(
+ UnconfinedFakeHeadsUpRowRepository(
+ key = "key",
+ pinnedStatus = MutableStateFlow(PinnedStatus.PinnedByUser),
+ )
+ )
+
+ assertThat(latest!!.visibility).isEqualTo(View.GONE)
+ }
+
@Test
fun isSystemInfoVisible_allowedByDisableFlags_visible() =
kosmos.runTest {
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
index 88694ae6db51..dfe8eb28b2a6 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
@@ -179,7 +179,6 @@ public class UdfpsController implements DozeReceiver, Dumpable {
@NonNull private final PowerInteractor mPowerInteractor;
@NonNull private final CoroutineScope mScope;
@NonNull private final InputManager mInputManager;
- @NonNull private final UdfpsKeyguardAccessibilityDelegate mUdfpsKeyguardAccessibilityDelegate;
@NonNull private final SelectedUserInteractor mSelectedUserInteractor;
private final boolean mIgnoreRefreshRate;
private final KeyguardTransitionInteractor mKeyguardTransitionInteractor;
@@ -292,7 +291,6 @@ public class UdfpsController implements DozeReceiver, Dumpable {
mActivityTransitionAnimator,
mPrimaryBouncerInteractor,
mAlternateBouncerInteractor,
- mUdfpsKeyguardAccessibilityDelegate,
mKeyguardTransitionInteractor,
mSelectedUserInteractor,
mDeviceEntryUdfpsTouchOverlayViewModel,
@@ -691,7 +689,6 @@ public class UdfpsController implements DozeReceiver, Dumpable {
@NonNull AlternateBouncerInteractor alternateBouncerInteractor,
@NonNull InputManager inputManager,
@NonNull DeviceEntryFaceAuthInteractor deviceEntryFaceAuthInteractor,
- @NonNull UdfpsKeyguardAccessibilityDelegate udfpsKeyguardAccessibilityDelegate,
@NonNull SelectedUserInteractor selectedUserInteractor,
@NonNull KeyguardTransitionInteractor keyguardTransitionInteractor,
Lazy<DeviceEntryUdfpsTouchOverlayViewModel> deviceEntryUdfpsTouchOverlayViewModel,
@@ -742,7 +739,6 @@ public class UdfpsController implements DozeReceiver, Dumpable {
mPowerInteractor = powerInteractor;
mScope = scope;
mInputManager = inputManager;
- mUdfpsKeyguardAccessibilityDelegate = udfpsKeyguardAccessibilityDelegate;
mSelectedUserInteractor = selectedUserInteractor;
mKeyguardTransitionInteractor = keyguardTransitionInteractor;
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt
index 702f23718ee8..bdf58275effa 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt
@@ -107,7 +107,6 @@ constructor(
private val primaryBouncerInteractor: PrimaryBouncerInteractor,
private val alternateBouncerInteractor: AlternateBouncerInteractor,
private val isDebuggable: Boolean = Build.IS_DEBUGGABLE,
- private val udfpsKeyguardAccessibilityDelegate: UdfpsKeyguardAccessibilityDelegate,
private val transitionInteractor: KeyguardTransitionInteractor,
private val selectedUserInteractor: SelectedUserInteractor,
private val deviceEntryUdfpsTouchOverlayViewModel: Lazy<DeviceEntryUdfpsTouchOverlayViewModel>,
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardAccessibilityDelegate.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardAccessibilityDelegate.kt
deleted file mode 100644
index 99da660d1fda..000000000000
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardAccessibilityDelegate.kt
+++ /dev/null
@@ -1,54 +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.biometrics
-
-import android.content.res.Resources
-import android.os.Bundle
-import android.view.View
-import android.view.accessibility.AccessibilityNodeInfo
-import com.android.systemui.res.R
-import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.dagger.qualifiers.Main
-import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager
-import javax.inject.Inject
-
-@SysUISingleton
-class UdfpsKeyguardAccessibilityDelegate
-@Inject
-constructor(
- @Main private val resources: Resources,
- private val keyguardViewManager: StatusBarKeyguardViewManager,
-) : View.AccessibilityDelegate() {
- override fun onInitializeAccessibilityNodeInfo(host: View, info: AccessibilityNodeInfo) {
- super.onInitializeAccessibilityNodeInfo(host, info)
- val clickAction =
- AccessibilityNodeInfo.AccessibilityAction(
- AccessibilityNodeInfo.AccessibilityAction.ACTION_CLICK.id,
- resources.getString(R.string.accessibility_bouncer)
- )
- info.addAction(clickAction)
- }
-
- override fun performAccessibilityAction(host: View, action: Int, args: Bundle?): Boolean {
- // when an a11y service is enabled, double tapping on the fingerprint sensor should
- // show the primary bouncer
- return if (action == AccessibilityNodeInfo.AccessibilityAction.ACTION_CLICK.id) {
- keyguardViewManager.showPrimaryBouncer(/* scrimmed */ true)
- true
- } else super.performAccessibilityAction(host, action, args)
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index b4b3053cba42..d8fc21af9724 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -1847,6 +1847,7 @@ public class KeyguardViewMediator implements CoreStartable,
// explicitly DO NOT want to call
// mKeyguardViewControllerLazy.get().setKeyguardGoingAwayState(false)
// here, since that will mess with the device lock state.
+ mKeyguardStateController.notifyKeyguardGoingAway(false);
mUpdateMonitor.dispatchKeyguardGoingAway(false);
notifyStartedGoingToSleep();
@@ -2994,7 +2995,6 @@ public class KeyguardViewMediator implements CoreStartable,
startKeyguardTransition(showing, aodShowing);
} else {
try {
-
mActivityTaskManagerService.setLockScreenShown(showing, aodShowing);
} catch (RemoteException ignored) {
}
@@ -3650,30 +3650,33 @@ public class KeyguardViewMediator implements CoreStartable,
return;
}
- try {
- int flags = KEYGUARD_GOING_AWAY_FLAG_NO_WINDOW_ANIMATIONS
- | KEYGUARD_GOING_AWAY_FLAG_WITH_WALLPAPER;
+ int flags = KEYGUARD_GOING_AWAY_FLAG_NO_WINDOW_ANIMATIONS
+ | KEYGUARD_GOING_AWAY_FLAG_WITH_WALLPAPER;
- // If we are unlocking to the launcher, clear the snapshot so that any changes as part
- // of the in-window animations are reflected. This is needed even if we're not actually
- // playing in-window animations for this particular unlock since a previous unlock might
- // have changed the Launcher state.
- if (mKeyguardUnlockAnimationControllerLazy.get().isSupportedLauncherUnderneath()) {
- flags |= KEYGUARD_GOING_AWAY_FLAG_TO_LAUNCHER_CLEAR_SNAPSHOT;
- }
+ // If we are unlocking to the launcher, clear the snapshot so that any changes as part
+ // of the in-window animations are reflected. This is needed even if we're not actually
+ // playing in-window animations for this particular unlock since a previous unlock might
+ // have changed the Launcher state.
+ if (mKeyguardUnlockAnimationControllerLazy.get().isSupportedLauncherUnderneath()) {
+ flags |= KEYGUARD_GOING_AWAY_FLAG_TO_LAUNCHER_CLEAR_SNAPSHOT;
+ }
- mKeyguardStateController.notifyKeyguardGoingAway(true);
+ mKeyguardStateController.notifyKeyguardGoingAway(true);
- if (!KeyguardWmStateRefactor.isEnabled()) {
- // Handled in WmLockscreenVisibilityManager.
- mGoingAwayRequestedForUserId = mSelectedUserInteractor.getSelectedUserId();
+ if (!KeyguardWmStateRefactor.isEnabled()) {
+ // Handled in WmLockscreenVisibilityManager.
+ mGoingAwayRequestedForUserId = mSelectedUserInteractor.getSelectedUserId();
+ final int goingAwayFlags = flags;
+ mUiBgExecutor.execute(() -> {
Log.d(TAG, "keyguardGoingAway requested for userId: "
+ mGoingAwayRequestedForUserId);
- mActivityTaskManagerService.keyguardGoingAway(flags);
- }
- } catch (RemoteException e) {
- mSurfaceBehindRemoteAnimationRequested = false;
- Log.e(TAG, "Failed to report keyguardGoingAway", e);
+ try {
+ mActivityTaskManagerService.keyguardGoingAway(goingAwayFlags);
+ } catch (RemoteException e) {
+ mSurfaceBehindRemoteAnimationRequested = false;
+ Log.e(TAG, "Failed to report keyguardGoingAway", e);
+ }
+ });
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/AlternateBouncerUdfpsViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/AlternateBouncerUdfpsViewBinder.kt
index 0b587ae1f58e..c031b53ab87d 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/AlternateBouncerUdfpsViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/AlternateBouncerUdfpsViewBinder.kt
@@ -38,9 +38,15 @@ object AlternateBouncerUdfpsViewBinder {
view.repeatWhenAttached {
repeatOnLifecycle(Lifecycle.State.STARTED) {
view.alpha = 0f
+
launch("$TAG#viewModel.accessibilityDelegateHint") {
viewModel.accessibilityDelegateHint.collect { hint ->
view.accessibilityHintType = hint
+ if (hint != DeviceEntryIconView.AccessibilityHintType.NONE) {
+ view.setOnClickListener { viewModel.onTapped() }
+ } else {
+ view.setOnClickListener(null)
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerUdfpsIconViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerUdfpsIconViewModel.kt
index acd381ec3280..9038922466df 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerUdfpsIconViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerUdfpsIconViewModel.kt
@@ -18,6 +18,7 @@ package com.android.systemui.keyguard.ui.viewmodel
import android.content.Context
import com.android.settingslib.Utils
+import com.android.systemui.accessibility.domain.interactor.AccessibilityInteractor
import com.android.systemui.biometrics.domain.interactor.FingerprintPropertyInteractor
import com.android.systemui.biometrics.domain.interactor.UdfpsOverlayInteractor
import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor
@@ -26,6 +27,7 @@ import com.android.systemui.keyguard.ui.view.DeviceEntryIconView
import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.shade.ShadeDisplayAware
import com.android.systemui.shared.recents.utilities.Utilities.clamp
+import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager
import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.combine
@@ -46,6 +48,8 @@ constructor(
fingerprintPropertyInteractor: FingerprintPropertyInteractor,
udfpsOverlayInteractor: UdfpsOverlayInteractor,
alternateBouncerViewModel: AlternateBouncerViewModel,
+ private val statusBarKeyguardViewManager: StatusBarKeyguardViewManager,
+ private val accessibilityInteractor: AccessibilityInteractor,
) {
private val isSupported: Flow<Boolean> = deviceEntryUdfpsInteractor.isUdfpsSupported
val alpha: Flow<Float> =
@@ -74,7 +78,15 @@ constructor(
}
}
val accessibilityDelegateHint: Flow<DeviceEntryIconView.AccessibilityHintType> =
- flowOf(DeviceEntryIconView.AccessibilityHintType.ENTER)
+ accessibilityInteractor.isEnabled.flatMapLatest { touchExplorationEnabled ->
+ flowOf(
+ if (touchExplorationEnabled) {
+ DeviceEntryIconView.AccessibilityHintType.BOUNCER
+ } else {
+ DeviceEntryIconView.AccessibilityHintType.NONE
+ }
+ )
+ }
private val fgIconColor: Flow<Int> =
configurationInteractor.onAnyConfigurationChange
@@ -93,6 +105,10 @@ constructor(
)
}
+ fun onTapped() {
+ statusBarKeyguardViewManager.showPrimaryBouncer(/* scrimmed */ true)
+ }
+
val bgColor: Flow<Int> = deviceEntryBackgroundViewModel.color
val bgAlpha: Flow<Float> = flowOf(1f)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/HomeStatusBarViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/HomeStatusBarViewBinder.kt
index d7348892356d..cdd02865bbee 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/HomeStatusBarViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/HomeStatusBarViewBinder.kt
@@ -47,7 +47,8 @@ import com.android.systemui.statusbar.phone.ongoingcall.StatusBarChipsModernizat
import com.android.systemui.statusbar.pipeline.shared.ui.model.VisibilityModel
import com.android.systemui.statusbar.pipeline.shared.ui.viewmodel.HomeStatusBarViewModel
import javax.inject.Inject
-import kotlinx.coroutines.flow.collectLatest
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.launch
/**
@@ -153,39 +154,43 @@ constructor(
OngoingActivityChipBinder.createBinding(primaryChipView)
launch {
- viewModel.primaryOngoingActivityChip.collect { primaryChipModel ->
- OngoingActivityChipBinder.bind(
- primaryChipModel,
- primaryChipViewBinding,
- iconViewStore,
+ combine(
+ viewModel.primaryOngoingActivityChip,
+ viewModel.canShowOngoingActivityChips,
+ ::Pair,
)
+ .distinctUntilChanged()
+ .collect { (primaryChipModel, areChipsAllowed) ->
+ OngoingActivityChipBinder.bind(
+ primaryChipModel,
+ primaryChipViewBinding,
+ iconViewStore,
+ )
- if (StatusBarRootModernization.isEnabled) {
- launch {
+ if (StatusBarRootModernization.isEnabled) {
bindLegacyPrimaryOngoingActivityChipWithVisibility(
- viewModel,
+ areChipsAllowed,
primaryChipModel,
primaryChipViewBinding,
)
- }
- } else {
- when (primaryChipModel) {
- is OngoingActivityChipModel.Active ->
- listener?.onOngoingActivityStatusChanged(
- hasPrimaryOngoingActivity = true,
- hasSecondaryOngoingActivity = false,
- shouldAnimate = true,
- )
-
- is OngoingActivityChipModel.Inactive ->
- listener?.onOngoingActivityStatusChanged(
- hasPrimaryOngoingActivity = false,
- hasSecondaryOngoingActivity = false,
- shouldAnimate = primaryChipModel.shouldAnimate,
- )
+ } else {
+ when (primaryChipModel) {
+ is OngoingActivityChipModel.Active ->
+ listener?.onOngoingActivityStatusChanged(
+ hasPrimaryOngoingActivity = true,
+ hasSecondaryOngoingActivity = false,
+ shouldAnimate = true,
+ )
+
+ is OngoingActivityChipModel.Inactive ->
+ listener?.onOngoingActivityStatusChanged(
+ hasPrimaryOngoingActivity = false,
+ hasSecondaryOngoingActivity = false,
+ shouldAnimate = primaryChipModel.shouldAnimate,
+ )
+ }
}
}
- }
}
}
@@ -199,49 +204,53 @@ constructor(
view.requireViewById(R.id.ongoing_activity_chip_secondary)
)
launch {
- viewModel.ongoingActivityChipsLegacy.collectLatest { chips ->
- OngoingActivityChipBinder.bind(
- chips.primary,
- primaryChipViewBinding,
- iconViewStore,
+ combine(
+ viewModel.ongoingActivityChipsLegacy,
+ viewModel.canShowOngoingActivityChips,
+ ::Pair,
)
- OngoingActivityChipBinder.bind(
- chips.secondary,
- secondaryChipViewBinding,
- iconViewStore,
- )
-
- if (StatusBarRootModernization.isEnabled) {
- launch {
+ .distinctUntilChanged()
+ .collect { (chips, areChipsAllowed) ->
+ OngoingActivityChipBinder.bind(
+ chips.primary,
+ primaryChipViewBinding,
+ iconViewStore,
+ )
+ OngoingActivityChipBinder.bind(
+ chips.secondary,
+ secondaryChipViewBinding,
+ iconViewStore,
+ )
+ if (StatusBarRootModernization.isEnabled) {
bindOngoingActivityChipsWithVisibility(
- viewModel,
+ areChipsAllowed,
chips,
primaryChipViewBinding,
secondaryChipViewBinding,
)
+ } else {
+ listener?.onOngoingActivityStatusChanged(
+ hasPrimaryOngoingActivity =
+ chips.primary is OngoingActivityChipModel.Active,
+ hasSecondaryOngoingActivity =
+ chips.secondary is OngoingActivityChipModel.Active,
+ // TODO(b/364653005): Figure out the animation story here.
+ shouldAnimate = true,
+ )
}
- } else {
- listener?.onOngoingActivityStatusChanged(
- hasPrimaryOngoingActivity =
- chips.primary is OngoingActivityChipModel.Active,
- hasSecondaryOngoingActivity =
- chips.secondary is OngoingActivityChipModel.Active,
- // TODO(b/364653005): Figure out the animation story here.
- shouldAnimate = true,
- )
- }
-
- viewModel.contentArea.collect { _ ->
- OngoingActivityChipBinder.resetPrimaryChipWidthRestrictions(
- primaryChipViewBinding,
- viewModel.ongoingActivityChipsLegacy.value.primary,
- )
- OngoingActivityChipBinder.resetSecondaryChipWidthRestrictions(
- secondaryChipViewBinding,
- viewModel.ongoingActivityChipsLegacy.value.secondary,
- )
- view.requestLayout()
}
+ }
+ launch {
+ viewModel.contentArea.collect { _ ->
+ OngoingActivityChipBinder.resetPrimaryChipWidthRestrictions(
+ primaryChipViewBinding,
+ viewModel.ongoingActivityChipsLegacy.value.primary,
+ )
+ OngoingActivityChipBinder.resetSecondaryChipWidthRestrictions(
+ secondaryChipViewBinding,
+ viewModel.ongoingActivityChipsLegacy.value.secondary,
+ )
+ view.requestLayout()
}
}
}
@@ -314,48 +323,42 @@ constructor(
}
/** Bind the (legacy) single primary ongoing activity chip with the status bar visibility */
- private suspend fun bindLegacyPrimaryOngoingActivityChipWithVisibility(
- viewModel: HomeStatusBarViewModel,
+ private fun bindLegacyPrimaryOngoingActivityChipWithVisibility(
+ areChipsAllowed: Boolean,
primaryChipModel: OngoingActivityChipModel,
primaryChipViewBinding: OngoingActivityChipViewBinding,
) {
- viewModel.canShowOngoingActivityChips.collectLatest { visible ->
- if (!visible) {
- primaryChipViewBinding.rootView.hide(shouldAnimateChange = false)
- } else {
- when (primaryChipModel) {
- is OngoingActivityChipModel.Active -> {
- primaryChipViewBinding.rootView.show(shouldAnimateChange = true)
- }
+ if (!areChipsAllowed) {
+ primaryChipViewBinding.rootView.hide(shouldAnimateChange = false)
+ } else {
+ when (primaryChipModel) {
+ is OngoingActivityChipModel.Active -> {
+ primaryChipViewBinding.rootView.show(shouldAnimateChange = true)
+ }
- is OngoingActivityChipModel.Inactive -> {
- primaryChipViewBinding.rootView.hide(
- state = View.GONE,
- shouldAnimateChange = primaryChipModel.shouldAnimate,
- )
- }
+ is OngoingActivityChipModel.Inactive -> {
+ primaryChipViewBinding.rootView.hide(
+ state = View.GONE,
+ shouldAnimateChange = primaryChipModel.shouldAnimate,
+ )
}
}
}
}
/** Bind the primary/secondary chips along with the home status bar's visibility */
- private suspend fun bindOngoingActivityChipsWithVisibility(
- viewModel: HomeStatusBarViewModel,
+ private fun bindOngoingActivityChipsWithVisibility(
+ areChipsAllowed: Boolean,
chips: MultipleOngoingActivityChipsModelLegacy,
primaryChipViewBinding: OngoingActivityChipViewBinding,
secondaryChipViewBinding: OngoingActivityChipViewBinding,
) {
- viewModel.canShowOngoingActivityChips.collectLatest { canShow ->
- if (!canShow) {
- primaryChipViewBinding.rootView.hide(shouldAnimateChange = false)
- secondaryChipViewBinding.rootView.hide(shouldAnimateChange = false)
- } else {
- primaryChipViewBinding.rootView.adjustVisibility(chips.primary.toVisibilityModel())
- secondaryChipViewBinding.rootView.adjustVisibility(
- chips.secondary.toVisibilityModel()
- )
- }
+ if (!areChipsAllowed) {
+ primaryChipViewBinding.rootView.hide(shouldAnimateChange = false)
+ secondaryChipViewBinding.rootView.hide(shouldAnimateChange = false)
+ } else {
+ primaryChipViewBinding.rootView.adjustVisibility(chips.primary.toVisibilityModel())
+ secondaryChipViewBinding.rootView.adjustVisibility(chips.secondary.toVisibilityModel())
}
}
@@ -428,10 +431,15 @@ constructor(
// See CollapsedStatusBarFragment#hide.
private fun View.hide(state: Int = View.INVISIBLE, shouldAnimateChange: Boolean) {
animate().cancel()
- if (visibility == View.INVISIBLE || visibility == View.GONE) {
+
+ if (
+ (visibility == View.INVISIBLE && state == View.INVISIBLE) ||
+ (visibility == View.GONE && state == View.GONE)
+ ) {
return
}
- if (!shouldAnimateChange) {
+ val isAlreadyHidden = visibility == View.INVISIBLE || visibility == View.GONE
+ if (!shouldAnimateChange || isAlreadyHidden) {
alpha = 0f
visibility = state
return
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/composable/StatusBarRoot.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/composable/StatusBarRoot.kt
index 4189221d8a83..c91ea9a50028 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/composable/StatusBarRoot.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/composable/StatusBarRoot.kt
@@ -196,13 +196,15 @@ fun StatusBarRoot(
setContent {
PlatformTheme {
- val chips by
+ val chipsVisibilityModel by
statusBarViewModel.ongoingActivityChips
.collectAsStateWithLifecycle()
- OngoingActivityChips(
- chips = chips,
- iconViewStore = iconViewStore,
- )
+ if (chipsVisibilityModel.areChipsAllowed) {
+ OngoingActivityChips(
+ chips = chipsVisibilityModel.chips,
+ iconViewStore = iconViewStore,
+ )
+ }
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/model/ChipsVisibilityModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/model/ChipsVisibilityModel.kt
new file mode 100644
index 000000000000..5cc432fc6771
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/model/ChipsVisibilityModel.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.pipeline.shared.ui.model
+
+import com.android.systemui.statusbar.chips.ui.model.MultipleOngoingActivityChipsModel
+
+data class ChipsVisibilityModel(
+ val chips: MultipleOngoingActivityChipsModel,
+ /**
+ * True if the chips are allowed to be shown and false otherwise (e.g. if we're on lockscreen).
+ */
+ val areChipsAllowed: Boolean,
+)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModel.kt
index 807e90567eb7..9975aff938d6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModel.kt
@@ -67,6 +67,7 @@ import com.android.systemui.statusbar.phone.ongoingcall.StatusBarChipsModernizat
import com.android.systemui.statusbar.pipeline.battery.ui.viewmodel.BatteryViewModel
import com.android.systemui.statusbar.pipeline.shared.domain.interactor.HomeStatusBarIconBlockListInteractor
import com.android.systemui.statusbar.pipeline.shared.domain.interactor.HomeStatusBarInteractor
+import com.android.systemui.statusbar.pipeline.shared.ui.model.ChipsVisibilityModel
import com.android.systemui.statusbar.pipeline.shared.ui.model.SystemInfoCombinedVisibilityModel
import com.android.systemui.statusbar.pipeline.shared.ui.model.VisibilityModel
import dagger.assisted.Assisted
@@ -125,7 +126,7 @@ interface HomeStatusBarViewModel : Activatable {
val primaryOngoingActivityChip: StateFlow<OngoingActivityChipModel>
/** All supported activity chips, whether they are currently active or not. */
- val ongoingActivityChips: StateFlow<MultipleOngoingActivityChipsModel>
+ val ongoingActivityChips: StateFlow<ChipsVisibilityModel>
/**
* The multiple ongoing activity chips that should be shown on the left-hand side of the status
@@ -252,8 +253,6 @@ constructor(
override val primaryOngoingActivityChip = ongoingActivityChipsViewModel.primaryChip
- override val ongoingActivityChips = ongoingActivityChipsViewModel.chips
-
override val ongoingActivityChipsLegacy = ongoingActivityChipsViewModel.chipsLegacy
override val popupChips
@@ -369,15 +368,6 @@ constructor(
)
.flowOn(bgDispatcher)
- private val isAnyChipVisible =
- if (StatusBarChipsModernization.isEnabled) {
- ongoingActivityChips.map { it.active.any { chip -> !chip.isHidden } }
- } else if (StatusBarNotifChips.isEnabled) {
- ongoingActivityChipsLegacy.map { it.primary is OngoingActivityChipModel.Active }
- } else {
- primaryOngoingActivityChip.map { it is OngoingActivityChipModel.Active }
- }
-
/**
* True if we need to hide the usual start side content in order to show the heads up
* notification info.
@@ -419,9 +409,38 @@ constructor(
combine(
isHomeStatusBarAllowed,
keyguardInteractor.isSecureCameraActive,
- headsUpNotificationInteractor.statusBarHeadsUpStatus,
- ) { isHomeStatusBarAllowed, isSecureCameraActive, headsUpState ->
- isHomeStatusBarAllowed && !isSecureCameraActive && !headsUpState.isPinned
+ hideStartSideContentForHeadsUp,
+ ) { isHomeStatusBarAllowed, isSecureCameraActive, hideStartSideContentForHeadsUp ->
+ isHomeStatusBarAllowed && !isSecureCameraActive && !hideStartSideContentForHeadsUp
+ }
+
+ override val ongoingActivityChips =
+ combine(ongoingActivityChipsViewModel.chips, canShowOngoingActivityChips) { chips, canShow
+ ->
+ ChipsVisibilityModel(chips, areChipsAllowed = canShow)
+ }
+ .stateIn(
+ bgScope,
+ SharingStarted.WhileSubscribed(),
+ initialValue =
+ ChipsVisibilityModel(
+ chips = MultipleOngoingActivityChipsModel(),
+ areChipsAllowed = false,
+ ),
+ )
+
+ private val hasOngoingActivityChips =
+ if (StatusBarChipsModernization.isEnabled) {
+ ongoingActivityChips.map { it.chips.active.any { chip -> !chip.isHidden } }
+ } else if (StatusBarNotifChips.isEnabled) {
+ ongoingActivityChipsLegacy.map { it.primary is OngoingActivityChipModel.Active }
+ } else {
+ primaryOngoingActivityChip.map { it is OngoingActivityChipModel.Active }
+ }
+
+ private val isAnyChipVisible =
+ combine(hasOngoingActivityChips, canShowOngoingActivityChips) { hasChips, canShowChips ->
+ hasChips && canShowChips
}
override val isClockVisible: Flow<VisibilityModel> =
diff --git a/packages/SystemUI/tests/src/com/android/systemui/animation/back/FlingOnBackAnimationCallbackTest.kt b/packages/SystemUI/tests/src/com/android/systemui/animation/back/FlingOnBackAnimationCallbackTest.kt
index 75a5768193cf..c81900da2581 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/animation/back/FlingOnBackAnimationCallbackTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/animation/back/FlingOnBackAnimationCallbackTest.kt
@@ -69,9 +69,11 @@ class FlingOnBackAnimationCallbackTest : SysuiTestCase() {
callback.onBackProgressed(backEventOf(0.6f, 32))
assertTrue("Assert onBackProgressedCompat called", callback.backProgressedCalled)
assertEquals("Assert interpolated progress", 0.6f, callback.progressEvent?.progress)
- getInstrumentation().runOnMainSync { callback.onBackInvoked() }
- // Assert that onBackInvoked is not called immediately...
- assertFalse(callback.backInvokedCalled)
+ getInstrumentation().runOnMainSync {
+ callback.onBackInvoked()
+ // Assert that onBackInvoked is not called immediately.
+ assertFalse(callback.backInvokedCalled)
+ }
// Instead the fling animation is played and eventually onBackInvoked is called.
callback.backInvokedLatch.await(1000, TimeUnit.MILLISECONDS)
assertTrue(callback.backInvokedCalled)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt
index 5249620dbdd0..a1d038ad8554 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt
@@ -120,9 +120,7 @@ class UdfpsControllerOverlayTest : SysuiTestCase() {
private lateinit var deviceEntryUdfpsTouchOverlayViewModel:
DeviceEntryUdfpsTouchOverlayViewModel
@Mock private lateinit var defaultUdfpsTouchOverlayViewModel: DefaultUdfpsTouchOverlayViewModel
- @Mock
- private lateinit var udfpsKeyguardAccessibilityDelegate: UdfpsKeyguardAccessibilityDelegate
- private lateinit var keyguardTransitionRepository: FakeKeyguardTransitionRepository
+ @Mock private lateinit var keyguardTransitionRepository: FakeKeyguardTransitionRepository
private lateinit var keyguardTransitionInteractor: KeyguardTransitionInteractor
@Mock private lateinit var shadeInteractor: ShadeInteractor
@Captor private lateinit var layoutParamsCaptor: ArgumentCaptor<WindowManager.LayoutParams>
@@ -185,7 +183,6 @@ class UdfpsControllerOverlayTest : SysuiTestCase() {
primaryBouncerInteractor,
alternateBouncerInteractor,
isDebuggable,
- udfpsKeyguardAccessibilityDelegate,
keyguardTransitionInteractor,
mSelectedUserInteractor,
{ deviceEntryUdfpsTouchOverlayViewModel },
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/binder/AlternateBouncerViewBinderKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/binder/AlternateBouncerViewBinderKosmos.kt
index 697e7b9476ca..3f3c3c0d478a 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/binder/AlternateBouncerViewBinderKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/binder/AlternateBouncerViewBinderKosmos.kt
@@ -19,6 +19,7 @@ package com.android.systemui.keyguard.ui.binder
import android.content.applicationContext
import android.view.mockedLayoutInflater
import android.view.windowManager
+import com.android.systemui.accessibility.domain.interactor.accessibilityInteractor
import com.android.systemui.biometrics.domain.interactor.fingerprintPropertyInteractor
import com.android.systemui.biometrics.domain.interactor.udfpsOverlayInteractor
import com.android.systemui.common.ui.domain.interactor.configurationInteractor
@@ -37,6 +38,7 @@ import com.android.systemui.kosmos.applicationCoroutineScope
import com.android.systemui.log.logcatLogBuffer
import com.android.systemui.power.domain.interactor.powerInteractor
import com.android.systemui.statusbar.gesture.TapGestureDetector
+import com.android.systemui.statusbar.phone.statusBarKeyguardViewManager
import com.android.systemui.util.mockito.mock
val Kosmos.alternateBouncerViewBinder by
@@ -76,5 +78,7 @@ private val Kosmos.alternateBouncerUdfpsIconViewModel by
fingerprintPropertyInteractor = fingerprintPropertyInteractor,
udfpsOverlayInteractor = udfpsOverlayInteractor,
alternateBouncerViewModel = alternateBouncerViewModel,
+ statusBarKeyguardViewManager = statusBarKeyguardViewManager,
+ accessibilityInteractor = accessibilityInteractor,
)
}
diff --git a/services/companion/java/com/android/server/companion/securechannel/SecureChannel.java b/services/companion/java/com/android/server/companion/securechannel/SecureChannel.java
index 6c7c9b3e073d..4c62c0deb2df 100644
--- a/services/companion/java/com/android/server/companion/securechannel/SecureChannel.java
+++ b/services/companion/java/com/android/server/companion/securechannel/SecureChannel.java
@@ -73,6 +73,8 @@ public class SecureChannel {
private int mVerificationResult = FLAG_FAILURE_UNKNOWN;
private boolean mPskVerified;
+ private final Object mHandshakeLock = new Object();
+
/**
* Create a new secure channel object. This secure channel allows secure messages to be
@@ -342,20 +344,22 @@ public class SecureChannel {
}
private void initiateHandshake() throws IOException, BadHandleException , HandshakeException {
- if (mConnectionContext != null) {
- Slog.d(TAG, "Ukey2 handshake is already completed.");
- return;
- }
+ synchronized (mHandshakeLock) {
+ if (mConnectionContext != null) {
+ Slog.d(TAG, "Ukey2 handshake is already completed.");
+ return;
+ }
- mRole = Role.INITIATOR;
- mHandshakeContext = D2DHandshakeContext.forInitiator();
- mClientInit = mHandshakeContext.getNextHandshakeMessage();
+ mRole = Role.INITIATOR;
+ mHandshakeContext = D2DHandshakeContext.forInitiator();
+ mClientInit = mHandshakeContext.getNextHandshakeMessage();
- // Send Client Init
- if (DEBUG) {
- Slog.d(TAG, "Sending Ukey2 Client Init message");
+ // Send Client Init
+ if (DEBUG) {
+ Slog.d(TAG, "Sending Ukey2 Client Init message");
+ }
+ sendMessage(MessageType.HANDSHAKE_INIT, constructHandshakeInitMessage(mClientInit));
}
- sendMessage(MessageType.HANDSHAKE_INIT, constructHandshakeInitMessage(mClientInit));
}
// In an occasion where both participants try to initiate a handshake, resolve the conflict
@@ -414,8 +418,17 @@ public class SecureChannel {
// Mark "in-progress" upon receiving the first message
mInProgress = true;
+ // Complete a series of handshake exchange and processing
+ synchronized (mHandshakeLock) {
+ completeHandshake(handshakeInitMessage);
+ }
+ }
+
+ private void completeHandshake(byte[] initMessage) throws IOException, HandshakeException,
+ BadHandleException, CryptoException, AlertException {
+
// Handle a potential collision where both devices tried to initiate a connection
- byte[] handshakeMessage = handleHandshakeCollision(handshakeInitMessage);
+ byte[] handshakeMessage = handleHandshakeCollision(initMessage);
// Proceed with the rest of Ukey2 handshake
if (mHandshakeContext == null) { // Server-side logic
diff --git a/services/core/java/com/android/server/display/DisplayAdapter.java b/services/core/java/com/android/server/display/DisplayAdapter.java
index 69bc66fea56c..155f82a421ae 100644
--- a/services/core/java/com/android/server/display/DisplayAdapter.java
+++ b/services/core/java/com/android/server/display/DisplayAdapter.java
@@ -19,6 +19,7 @@ package com.android.server.display;
import android.content.Context;
import android.os.Handler;
import android.view.Display;
+import android.view.SurfaceControl;
import com.android.server.display.feature.DisplayManagerFlags;
@@ -138,6 +139,21 @@ abstract class DisplayAdapter {
vsyncRate, /* isSynthetic= */ false, alternativeRefreshRates, supportedHdrTypes);
}
+ static int getPowerModeForState(int state) {
+ switch (state) {
+ case Display.STATE_OFF:
+ return SurfaceControl.POWER_MODE_OFF;
+ case Display.STATE_DOZE:
+ return SurfaceControl.POWER_MODE_DOZE;
+ case Display.STATE_DOZE_SUSPEND:
+ return SurfaceControl.POWER_MODE_DOZE_SUSPEND;
+ case Display.STATE_ON_SUSPEND:
+ return SurfaceControl.POWER_MODE_ON_SUSPEND;
+ default:
+ return SurfaceControl.POWER_MODE_NORMAL;
+ }
+ }
+
public interface Listener {
void onDisplayDeviceEvent(DisplayDevice device, int event);
void onTraversalRequested();
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 258c95582e3a..d402f010281f 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -2618,8 +2618,7 @@ public final class DisplayManagerService extends SystemService {
// Blank or unblank the display immediately to match the state requested
// by the display power controller (if known).
DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
- if ((info.flags & DisplayDeviceInfo.FLAG_NEVER_BLANK) == 0
- || android.companion.virtualdevice.flags.Flags.correctVirtualDisplayPowerState()) {
+ if ((info.flags & DisplayDeviceInfo.FLAG_NEVER_BLANK) == 0) {
final LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(device);
if (display == null) {
return null;
@@ -5580,9 +5579,7 @@ public final class DisplayManagerService extends SystemService {
final DisplayDevice displayDevice = mLogicalDisplayMapper.getDisplayLocked(
id).getPrimaryDisplayDeviceLocked();
final int flags = displayDevice.getDisplayDeviceInfoLocked().flags;
- if ((flags & DisplayDeviceInfo.FLAG_NEVER_BLANK) == 0
- || android.companion.virtualdevice.flags.Flags
- .correctVirtualDisplayPowerState()) {
+ if ((flags & DisplayDeviceInfo.FLAG_NEVER_BLANK) == 0) {
final DisplayPowerController displayPowerController =
mDisplayPowerControllers.get(id);
if (displayPowerController != null) {
diff --git a/services/core/java/com/android/server/display/LocalDisplayAdapter.java b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
index 551202c20cbb..7b714ad2bd9e 100644
--- a/services/core/java/com/android/server/display/LocalDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
@@ -208,21 +208,6 @@ final class LocalDisplayAdapter extends DisplayAdapter {
}
}
- static int getPowerModeForState(int state) {
- switch (state) {
- case Display.STATE_OFF:
- return SurfaceControl.POWER_MODE_OFF;
- case Display.STATE_DOZE:
- return SurfaceControl.POWER_MODE_DOZE;
- case Display.STATE_DOZE_SUSPEND:
- return SurfaceControl.POWER_MODE_DOZE_SUSPEND;
- case Display.STATE_ON_SUSPEND:
- return SurfaceControl.POWER_MODE_ON_SUSPEND;
- default:
- return SurfaceControl.POWER_MODE_NORMAL;
- }
- }
-
private final class LocalDisplayDevice extends DisplayDevice {
private final long mPhysicalDisplayId;
private final SparseArray<DisplayModeRecord> mSupportedModes = new SparseArray<>();
diff --git a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
index e7939bb50ece..ac03a93ca9e1 100644
--- a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
@@ -113,6 +113,11 @@ public class VirtualDisplayAdapter extends DisplayAdapter {
public void destroyDisplay(IBinder displayToken) {
DisplayControl.destroyVirtualDisplay(displayToken);
}
+
+ @Override
+ public void setDisplayPowerMode(IBinder displayToken, int mode) {
+ SurfaceControl.setDisplayPowerMode(displayToken, mode);
+ }
}, featureFlags);
}
@@ -340,6 +345,7 @@ public class VirtualDisplayAdapter extends DisplayAdapter {
private Display.Mode mMode;
private int mDisplayIdToMirror;
private boolean mIsWindowManagerMirroring;
+ private final boolean mNeverBlank;
private final DisplayCutout mDisplayCutout;
private final float mDefaultBrightness;
private final float mDimBrightness;
@@ -371,7 +377,11 @@ public class VirtualDisplayAdapter extends DisplayAdapter {
mCallback = callback;
mProjection = projection;
mMediaProjectionCallback = mediaProjectionCallback;
- if (android.companion.virtualdevice.flags.Flags.correctVirtualDisplayPowerState()) {
+ // Private non-mirror displays are never blank and always on.
+ mNeverBlank = (flags & VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR) == 0
+ && (flags & VIRTUAL_DISPLAY_FLAG_PUBLIC) == 0;
+ if (android.companion.virtualdevice.flags.Flags.correctVirtualDisplayPowerState()
+ && !mNeverBlank) {
// The display's power state depends on the power state of the state of its
// display / power group, which we don't know here. Initializing to UNKNOWN allows
// the first call to requestDisplayStateLocked() to set the correct state.
@@ -471,7 +481,15 @@ public class VirtualDisplayAdapter extends DisplayAdapter {
@Override
public Runnable requestDisplayStateLocked(int state, float brightnessState,
float sdrBrightnessState, DisplayOffloadSessionImpl displayOffloadSession) {
+ Runnable runnable = null;
if (state != mDisplayState) {
+ Slog.d(TAG, "Changing state of virtual display " + mName + " from "
+ + Display.stateToString(mDisplayState) + " to "
+ + Display.stateToString(state));
+ if (state != Display.STATE_ON && state != Display.STATE_OFF) {
+ Slog.wtf(TAG, "Unexpected display state for Virtual Display: "
+ + Display.stateToString(state));
+ }
mDisplayState = state;
mInfo = null;
sendDisplayDeviceEventLocked(this, DISPLAY_DEVICE_EVENT_CHANGED);
@@ -480,6 +498,15 @@ public class VirtualDisplayAdapter extends DisplayAdapter {
} else {
mCallback.dispatchDisplayResumed();
}
+
+ if (android.companion.virtualdevice.flags.Flags.correctVirtualDisplayPowerState()) {
+ final IBinder token = getDisplayTokenLocked();
+ runnable = () -> {
+ final int mode = getPowerModeForState(state);
+ Slog.d(TAG, "Requesting power mode for display " + mName + " to " + mode);
+ mSurfaceControlDisplayFactory.setDisplayPowerMode(token, mode);
+ };
+ }
}
if (android.companion.virtualdevice.flags.Flags.deviceAwareDisplayPower()
&& mBrightnessListener != null
@@ -488,7 +515,7 @@ public class VirtualDisplayAdapter extends DisplayAdapter {
mCurrentBrightness = brightnessState;
mCallback.dispatchRequestedBrightnessChanged(mCurrentBrightness);
}
- return null;
+ return runnable;
}
@Override
@@ -572,23 +599,14 @@ public class VirtualDisplayAdapter extends DisplayAdapter {
mInfo.yDpi = mDensityDpi;
mInfo.presentationDeadlineNanos = 1000000000L / (int) getRefreshRate(); // 1 frame
mInfo.flags = 0;
- if (android.companion.virtualdevice.flags.Flags.correctVirtualDisplayPowerState()) {
- if ((mFlags & VIRTUAL_DISPLAY_FLAG_PUBLIC) == 0) {
- mInfo.flags |= DisplayDeviceInfo.FLAG_PRIVATE;
- }
- if ((mFlags & VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR) == 0) {
- mInfo.flags |= DisplayDeviceInfo.FLAG_OWN_CONTENT_ONLY;
- }
- } else {
- if ((mFlags & VIRTUAL_DISPLAY_FLAG_PUBLIC) == 0) {
- mInfo.flags |= DisplayDeviceInfo.FLAG_PRIVATE
- | DisplayDeviceInfo.FLAG_NEVER_BLANK;
- }
- if ((mFlags & VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR) != 0) {
- mInfo.flags &= ~DisplayDeviceInfo.FLAG_NEVER_BLANK;
- } else {
- mInfo.flags |= DisplayDeviceInfo.FLAG_OWN_CONTENT_ONLY;
- }
+ if ((mFlags & VIRTUAL_DISPLAY_FLAG_PUBLIC) == 0) {
+ mInfo.flags |= DisplayDeviceInfo.FLAG_PRIVATE;
+ }
+ if ((mFlags & VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR) == 0) {
+ mInfo.flags |= DisplayDeviceInfo.FLAG_OWN_CONTENT_ONLY;
+ }
+ if (mNeverBlank) {
+ mInfo.flags |= DisplayDeviceInfo.FLAG_NEVER_BLANK;
}
if ((mFlags & VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP) != 0) {
mInfo.flags |= DisplayDeviceInfo.FLAG_OWN_DISPLAY_GROUP;
@@ -782,5 +800,13 @@ public class VirtualDisplayAdapter extends DisplayAdapter {
* @param displayToken The display token for the display to be destroyed.
*/
void destroyDisplay(IBinder displayToken);
+
+ /**
+ * Set the display power mode in SurfaceFlinger.
+ *
+ * @param displayToken The display token for the display.
+ * @param mode the SurfaceControl power mode, e.g. {@link SurfaceControl#POWER_MODE_OFF}.
+ */
+ void setDisplayPowerMode(IBinder displayToken, int mode);
}
}
diff --git a/services/core/java/com/android/server/display/brightness/BrightnessReason.java b/services/core/java/com/android/server/display/brightness/BrightnessReason.java
index a4804e1887fe..d4b9a6ce058b 100644
--- a/services/core/java/com/android/server/display/brightness/BrightnessReason.java
+++ b/services/core/java/com/android/server/display/brightness/BrightnessReason.java
@@ -49,11 +49,9 @@ public final class BrightnessReason {
public static final int MODIFIER_HDR = 0x4;
public static final int MODIFIER_THROTTLED = 0x8;
public static final int MODIFIER_MIN_LUX = 0x10;
- public static final int MODIFIER_MIN_USER_SET_LOWER_BOUND = 0x20;
- public static final int MODIFIER_STYLUS_UNDER_USE = 0x40;
+ public static final int MODIFIER_STYLUS_UNDER_USE = 0x20;
public static final int MODIFIER_MASK = MODIFIER_DIMMED | MODIFIER_LOW_POWER | MODIFIER_HDR
- | MODIFIER_THROTTLED | MODIFIER_MIN_LUX | MODIFIER_MIN_USER_SET_LOWER_BOUND
- | MODIFIER_STYLUS_UNDER_USE;
+ | MODIFIER_THROTTLED | MODIFIER_MIN_LUX | MODIFIER_STYLUS_UNDER_USE;
// ADJUSTMENT_*
// These things can happen at any point, even if the main brightness reason doesn't
@@ -157,9 +155,6 @@ public final class BrightnessReason {
if ((mModifier & MODIFIER_MIN_LUX) != 0) {
sb.append(" lux_lower_bound");
}
- if ((mModifier & MODIFIER_MIN_USER_SET_LOWER_BOUND) != 0) {
- sb.append(" user_min_pref");
- }
if ((mModifier & MODIFIER_STYLUS_UNDER_USE) != 0) {
sb.append(" stylus_under_use");
}
diff --git a/services/core/java/com/android/server/display/brightness/clamper/BrightnessLowLuxModifier.java b/services/core/java/com/android/server/display/brightness/clamper/BrightnessLowLuxModifier.java
index c3596c3e77fe..72cb31d8d1bb 100644
--- a/services/core/java/com/android/server/display/brightness/clamper/BrightnessLowLuxModifier.java
+++ b/services/core/java/com/android/server/display/brightness/clamper/BrightnessLowLuxModifier.java
@@ -19,12 +19,8 @@ package com.android.server.display.brightness.clamper;
import android.content.ContentResolver;
import android.content.Context;
-import android.database.ContentObserver;
import android.hardware.display.DisplayManagerInternal;
-import android.net.Uri;
import android.os.Handler;
-import android.os.UserHandle;
-import android.provider.Settings;
import android.util.Slog;
import com.android.internal.annotations.VisibleForTesting;
@@ -49,7 +45,6 @@ public class BrightnessLowLuxModifier extends BrightnessModifier implements
private static final String TAG = "BrightnessLowLuxModifier";
private static final boolean DEBUG = DebugUtils.isDebuggable(TAG);
private static final float MIN_NITS_DEFAULT = 0.2f;
- private final SettingsObserver mSettingsObserver;
private final ContentResolver mContentResolver;
private final Handler mHandler;
private final BrightnessClamperController.ClamperChangeListener mChangeListener;
@@ -69,7 +64,6 @@ public class BrightnessLowLuxModifier extends BrightnessModifier implements
mChangeListener = listener;
mHandler = handler;
mContentResolver = context.getContentResolver();
- mSettingsObserver = new SettingsObserver(mHandler);
mDisplayDeviceConfig = displayDeviceConfig;
mHandler.post(() -> {
start();
@@ -82,12 +76,7 @@ public class BrightnessLowLuxModifier extends BrightnessModifier implements
*/
@VisibleForTesting
public void recalculateLowerBound() {
- float settingNitsLowerBound = Settings.Secure.getFloatForUser(
- mContentResolver, Settings.Secure.EVEN_DIMMER_MIN_NITS,
- /* def= */ MIN_NITS_DEFAULT, UserHandle.USER_CURRENT);
-
- boolean isActive = isSettingEnabled()
- && mAmbientLux != BrightnessMappingStrategy.INVALID_LUX;
+ boolean isActive = mAmbientLux != BrightnessMappingStrategy.INVALID_LUX;
final int reason;
float minNitsAllowed = -1f; // undefined, if setting is off.
@@ -95,12 +84,9 @@ public class BrightnessLowLuxModifier extends BrightnessModifier implements
if (isActive) {
float luxBasedNitsLowerBound = mDisplayDeviceConfig.getMinNitsFromLux(mAmbientLux);
- minNitsAllowed = Math.max(settingNitsLowerBound,
- luxBasedNitsLowerBound);
+ minNitsAllowed = Math.max(MIN_NITS_DEFAULT, luxBasedNitsLowerBound);
minBrightnessAllowed = getBrightnessFromNits(minNitsAllowed);
- reason = settingNitsLowerBound > luxBasedNitsLowerBound
- ? BrightnessReason.MODIFIER_MIN_USER_SET_LOWER_BOUND
- : BrightnessReason.MODIFIER_MIN_LUX;
+ reason = BrightnessReason.MODIFIER_MIN_LUX;
} else {
minBrightnessAllowed = mDisplayDeviceConfig.getEvenDimmerTransitionPoint();
reason = 0;
@@ -169,7 +155,6 @@ public class BrightnessLowLuxModifier extends BrightnessModifier implements
@Override
public void apply(DisplayManagerInternal.DisplayPowerRequest request,
DisplayBrightnessState.Builder stateBuilder) {
-
stateBuilder.setMinBrightness(mBrightnessLowerBound);
float boundedBrightness = Math.max(mBrightnessLowerBound, stateBuilder.getBrightness());
stateBuilder.setBrightness(boundedBrightness);
@@ -181,12 +166,11 @@ public class BrightnessLowLuxModifier extends BrightnessModifier implements
@Override
public void stop() {
- mContentResolver.unregisterContentObserver(mSettingsObserver);
}
@Override
public boolean shouldListenToLightSensor() {
- return isSettingEnabled();
+ return true;
}
@Override
@@ -204,37 +188,8 @@ public class BrightnessLowLuxModifier extends BrightnessModifier implements
pw.println(" mMinNitsAllowed=" + mMinNitsAllowed);
}
- /**
- * Defaults to true, on devices where setting is unset.
- *
- * @return if setting indicates feature is enabled
- */
- private boolean isSettingEnabled() {
- return Settings.Secure.getFloatForUser(mContentResolver,
- Settings.Secure.EVEN_DIMMER_ACTIVATED,
- /* def= */ 1.0f, UserHandle.USER_CURRENT) == 1.0f;
- }
-
private float getBrightnessFromNits(float nits) {
return mDisplayDeviceConfig.getBrightnessFromBacklight(
mDisplayDeviceConfig.getBacklightFromNits(nits));
}
-
- private final class SettingsObserver extends ContentObserver {
-
- SettingsObserver(Handler handler) {
- super(handler);
- mContentResolver.registerContentObserver(
- Settings.Secure.getUriFor(Settings.Secure.EVEN_DIMMER_MIN_NITS),
- false, this, UserHandle.USER_ALL);
- mContentResolver.registerContentObserver(
- Settings.Secure.getUriFor(Settings.Secure.EVEN_DIMMER_ACTIVATED),
- false, this, UserHandle.USER_ALL);
- }
-
- @Override
- public void onChange(boolean selfChange, Uri uri) {
- recalculateLowerBound();
- }
- }
}
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 60371d751c4a..0f1d28db8d82 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -2809,7 +2809,6 @@ public class NotificationManagerService extends SystemService {
mNotificationChannelLogger,
mAppOps,
mUserProfiles,
- mUgmInternal,
mShowReviewPermissionsNotification,
Clock.systemUTC());
mRankingHelper = new RankingHelper(getContext(), mRankingHandler, mPreferencesHelper,
@@ -7210,7 +7209,13 @@ public class NotificationManagerService extends SystemService {
final Uri originalSoundUri =
(originalChannel != null) ? originalChannel.getSound() : null;
if (soundUri != null && !Objects.equals(originalSoundUri, soundUri)) {
- PermissionHelper.grantUriPermission(mUgmInternal, soundUri, sourceUid);
+ Binder.withCleanCallingIdentity(() -> {
+ mUgmInternal.checkGrantUriPermission(sourceUid, null,
+ ContentProvider.getUriWithoutUserId(soundUri),
+ Intent.FLAG_GRANT_READ_URI_PERMISSION,
+ ContentProvider.getUserIdFromUri(soundUri,
+ UserHandle.getUserId(sourceUid)));
+ });
}
}
diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java
index 5a58f457ba08..398894bf5273 100644
--- a/services/core/java/com/android/server/notification/NotificationRecord.java
+++ b/services/core/java/com/android/server/notification/NotificationRecord.java
@@ -37,7 +37,10 @@ import android.app.KeyguardManager;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.Person;
+import android.content.ContentProvider;
+import android.content.ContentResolver;
import android.content.Context;
+import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
import android.content.pm.ShortcutInfo;
@@ -46,6 +49,7 @@ import android.media.AudioAttributes;
import android.media.AudioSystem;
import android.metrics.LogMaker;
import android.net.Uri;
+import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
@@ -1532,15 +1536,21 @@ public final class NotificationRecord {
* {@link #mGrantableUris}. Otherwise, this will either log or throw
* {@link SecurityException} depending on target SDK of enqueuing app.
*/
- private void visitGrantableUri(Uri uri, boolean userOverriddenUri,
- boolean isSound) {
+ private void visitGrantableUri(Uri uri, boolean userOverriddenUri, boolean isSound) {
+ if (uri == null || !ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) return;
+
if (mGrantableUris != null && mGrantableUris.contains(uri)) {
return; // already verified this URI
}
final int sourceUid = getSbn().getUid();
+ final long ident = Binder.clearCallingIdentity();
try {
- PermissionHelper.grantUriPermission(mUgmInternal, uri, sourceUid);
+ // This will throw a SecurityException if the caller can't grant.
+ mUgmInternal.checkGrantUriPermission(sourceUid, null,
+ ContentProvider.getUriWithoutUserId(uri),
+ Intent.FLAG_GRANT_READ_URI_PERMISSION,
+ ContentProvider.getUserIdFromUri(uri, UserHandle.getUserId(sourceUid)));
if (mGrantableUris == null) {
mGrantableUris = new ArraySet<>();
@@ -1560,6 +1570,8 @@ public final class NotificationRecord {
}
}
}
+ } finally {
+ Binder.restoreCallingIdentity(ident);
}
}
diff --git a/services/core/java/com/android/server/notification/PermissionHelper.java b/services/core/java/com/android/server/notification/PermissionHelper.java
index 1464d481311a..b6f48890c528 100644
--- a/services/core/java/com/android/server/notification/PermissionHelper.java
+++ b/services/core/java/com/android/server/notification/PermissionHelper.java
@@ -25,25 +25,19 @@ import android.Manifest;
import android.annotation.NonNull;
import android.annotation.UserIdInt;
import android.companion.virtual.VirtualDeviceManager;
-import android.content.ContentProvider;
-import android.content.ContentResolver;
import android.content.Context;
-import android.content.Intent;
import android.content.pm.IPackageManager;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.ParceledListSlice;
-import android.net.Uri;
import android.os.Binder;
import android.os.RemoteException;
-import android.os.UserHandle;
import android.permission.IPermissionManager;
import android.util.ArrayMap;
import android.util.Pair;
import android.util.Slog;
import com.android.internal.util.ArrayUtils;
-import com.android.server.uri.UriGrantsManagerInternal;
import java.util.Collections;
import java.util.HashSet;
@@ -64,7 +58,7 @@ public final class PermissionHelper {
private final IPermissionManager mPermManager;
public PermissionHelper(Context context, IPackageManager packageManager,
- IPermissionManager permManager) {
+ IPermissionManager permManager) {
mContext = context;
mPackageManager = packageManager;
mPermManager = permManager;
@@ -304,19 +298,6 @@ public final class PermissionHelper {
return false;
}
- static void grantUriPermission(final UriGrantsManagerInternal ugmInternal, Uri uri,
- int sourceUid) {
- if (uri == null || !ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) return;
-
- Binder.withCleanCallingIdentity(() -> {
- // This will throw a SecurityException if the caller can't grant.
- ugmInternal.checkGrantUriPermission(sourceUid, null,
- ContentProvider.getUriWithoutUserId(uri),
- Intent.FLAG_GRANT_READ_URI_PERMISSION,
- ContentProvider.getUserIdFromUri(uri, UserHandle.getUserId(sourceUid)));
- });
- }
-
public static class PackagePermission {
public final String packageName;
public final @UserIdInt int userId;
diff --git a/services/core/java/com/android/server/notification/PreferencesHelper.java b/services/core/java/com/android/server/notification/PreferencesHelper.java
index 46ff7983bb2d..b26b4571b07a 100644
--- a/services/core/java/com/android/server/notification/PreferencesHelper.java
+++ b/services/core/java/com/android/server/notification/PreferencesHelper.java
@@ -100,7 +100,6 @@ import com.android.internal.util.XmlUtils;
import com.android.modules.utils.TypedXmlPullParser;
import com.android.modules.utils.TypedXmlSerializer;
import com.android.server.notification.PermissionHelper.PackagePermission;
-import com.android.server.uri.UriGrantsManagerInternal;
import org.json.JSONArray;
import org.json.JSONException;
@@ -228,7 +227,6 @@ public class PreferencesHelper implements RankingConfig {
private final NotificationChannelLogger mNotificationChannelLogger;
private final AppOpsManager mAppOps;
private final ManagedServices.UserProfiles mUserProfiles;
- private final UriGrantsManagerInternal mUgmInternal;
private SparseBooleanArray mBadgingEnabled;
private SparseBooleanArray mBubblesEnabled;
@@ -247,7 +245,6 @@ public class PreferencesHelper implements RankingConfig {
ZenModeHelper zenHelper, PermissionHelper permHelper, PermissionManager permManager,
NotificationChannelLogger notificationChannelLogger,
AppOpsManager appOpsManager, ManagedServices.UserProfiles userProfiles,
- UriGrantsManagerInternal ugmInternal,
boolean showReviewPermissionsNotification, Clock clock) {
mContext = context;
mZenModeHelper = zenHelper;
@@ -258,7 +255,6 @@ public class PreferencesHelper implements RankingConfig {
mNotificationChannelLogger = notificationChannelLogger;
mAppOps = appOpsManager;
mUserProfiles = userProfiles;
- mUgmInternal = ugmInternal;
mShowReviewPermissionsNotification = showReviewPermissionsNotification;
mIsMediaNotificationFilteringEnabled = context.getResources()
.getBoolean(R.bool.config_quickSettingsShowMediaPlayer);
@@ -1195,11 +1191,6 @@ public class PreferencesHelper implements RankingConfig {
}
clearLockedFieldsLocked(channel);
- // Verify that the app has permission to read the sound Uri
- // Only check for new channels, as regular apps can only set sound
- // before creating. See: {@link NotificationChannel#setSound}
- PermissionHelper.grantUriPermission(mUgmInternal, channel.getSound(), uid);
-
channel.setImportanceLockedByCriticalDeviceFunction(
r.defaultAppLockedImportance || r.fixedImportance);
diff --git a/services/core/java/com/android/server/pm/BackgroundInstallControlService.java b/services/core/java/com/android/server/pm/BackgroundInstallControlService.java
index 60d028b46970..f3797614dee0 100644
--- a/services/core/java/com/android/server/pm/BackgroundInstallControlService.java
+++ b/services/core/java/com/android/server/pm/BackgroundInstallControlService.java
@@ -392,7 +392,7 @@ public class BackgroundInstallControlService extends SystemService {
private boolean installedByAdb(String initiatingPackageName) {
// GTS tests needs to adopt shell identity to install apps.
- if(!SystemProperties.get("gts.transparency.bg-install-apps").isEmpty()) {
+ if(!SystemProperties.get("debug.gts.transparency.bg-install-apps").isEmpty()) {
Slog.d(TAG, "handlePackageAdd: is GTS tests, skipping ADB check");
} else if(PackageManagerServiceUtils.isInstalledByAdb(initiatingPackageName)) {
Slog.d(TAG, "handlePackageAdd: is installed by ADB, skipping");
diff --git a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
index 2a2ae12ab09b..2cac63c1e5e9 100644
--- a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
@@ -104,7 +104,8 @@ final class ImeInsetsSourceProvider extends InsetsSourceProvider {
if (!mGivenInsetsReady && isServerVisible() && !givenInsetsPending
&& mControlTarget != null) {
ProtoLog.d(WM_DEBUG_IME,
- "onPostLayout: IME control ready to be dispatched, ws=%s", ws);
+ "onPostLayout: IME control ready to be dispatched, controlTarget=%s",
+ mControlTarget);
mGivenInsetsReady = true;
ImeTracker.forLogging().onProgress(mStatsToken,
ImeTracker.PHASE_WM_POST_LAYOUT_NOTIFY_CONTROLS_CHANGED);
@@ -115,13 +116,15 @@ final class ImeInsetsSourceProvider extends InsetsSourceProvider {
// If the server visibility didn't change (still visible), and mGivenInsetsReady
// is set, we won't call into notifyControlChanged. Therefore, we can reset the
// statsToken, if available.
- ProtoLog.w(WM_DEBUG_IME, "onPostLayout cancel statsToken, ws=%s", ws);
+ ProtoLog.w(WM_DEBUG_IME, "onPostLayout cancel statsToken, controlTarget=%s",
+ mControlTarget);
ImeTracker.forLogging().onCancelled(mStatsToken,
ImeTracker.PHASE_WM_POST_LAYOUT_NOTIFY_CONTROLS_CHANGED);
mStatsToken = null;
} else if (wasServerVisible && !isServerVisible()) {
- ProtoLog.d(WM_DEBUG_IME, "onPostLayout: setImeShowing(false) was: %s, ws=%s",
- isImeShowing(), ws);
+ ProtoLog.d(WM_DEBUG_IME,
+ "onPostLayout: setImeShowing(false) was: %s, controlTarget=%s",
+ isImeShowing(), mControlTarget);
setImeShowing(false);
}
}
diff --git a/services/tests/InputMethodSystemServerTests/src/com/android/inputmethodservice/AndroidTest.xml b/services/tests/InputMethodSystemServerTests/src/com/android/inputmethodservice/AndroidTest.xml
index d6a685378d9e..ea01fc4e6140 100644
--- a/services/tests/InputMethodSystemServerTests/src/com/android/inputmethodservice/AndroidTest.xml
+++ b/services/tests/InputMethodSystemServerTests/src/com/android/inputmethodservice/AndroidTest.xml
@@ -18,9 +18,6 @@
<option name="test-suite-tag" value="apct" />
<option name="test-suite-tag" value="apct-instrumentation" />
- <!-- Needed for reading the app files for the test artifacts -->
- <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
-
<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
<option name="cleanup-apks" value="true" />
<option name="install-arg" value="-t" />
@@ -44,7 +41,7 @@
<!-- Collect output of DumpOnFailure -->
<metrics_collector class="com.android.tradefed.device.metric.FilePullerLogCollector">
- <option name="directory-keys" value="/data/user/0/com.android.apps.inputmethod.simpleime/files" />
+ <option name="directory-keys" value="/sdcard/DumpOnFailure" />
<option name="collect-on-run-ended-only" value="true" />
<option name="clean-up" value="true" />
</metrics_collector>
diff --git a/services/tests/InputMethodSystemServerTests/src/com/android/inputmethodservice/InputMethodServiceTest.java b/services/tests/InputMethodSystemServerTests/src/com/android/inputmethodservice/InputMethodServiceTest.java
index 2cd860ae6c12..e263e85f020f 100644
--- a/services/tests/InputMethodSystemServerTests/src/com/android/inputmethodservice/InputMethodServiceTest.java
+++ b/services/tests/InputMethodSystemServerTests/src/com/android/inputmethodservice/InputMethodServiceTest.java
@@ -77,6 +77,8 @@ import org.junit.Test;
import org.junit.rules.TestName;
import org.junit.runner.RunWith;
+import java.io.ByteArrayOutputStream;
+import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.CountDownLatch;
@@ -1294,6 +1296,14 @@ public class InputMethodServiceTest {
mInstrumentation.waitForIdleSync();
final var postScreenshot = mInstrumentation.getUiAutomation().takeScreenshot();
mDumpOnFailure.dumpOnFailure("post-getUiObject", postScreenshot);
+ try {
+ final var outputStream = new ByteArrayOutputStream();
+ mUiDevice.dumpWindowHierarchy(outputStream);
+ final String windowHierarchy = outputStream.toString(StandardCharsets.UTF_8);
+ mDumpOnFailure.dumpOnFailure("post-getUiObject", windowHierarchy);
+ } catch (Exception e) {
+ Log.i(TAG, "Failed to dump windowHierarchy", e);
+ }
assertWithMessage("UiObject with " + bySelector + " was found").that(uiObject).isNotNull();
return uiObject;
}
diff --git a/services/tests/InputMethodSystemServerTests/test-apps/SimpleTestIme/AndroidManifest.xml b/services/tests/InputMethodSystemServerTests/test-apps/SimpleTestIme/AndroidManifest.xml
index 00873de4aaed..b6965a4341d7 100644
--- a/services/tests/InputMethodSystemServerTests/test-apps/SimpleTestIme/AndroidManifest.xml
+++ b/services/tests/InputMethodSystemServerTests/test-apps/SimpleTestIme/AndroidManifest.xml
@@ -20,6 +20,9 @@
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
+ <!-- Enable writing output of DumpOnFailure to external storage -->
+ <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
+
<application android:debuggable="true"
android:label="@string/app_name">
<service
diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java
index c151732cec66..65585d06ff06 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java
@@ -332,6 +332,10 @@ public class DisplayManagerServiceTest {
@Override
public void destroyDisplay(IBinder displayToken) {
}
+
+ @Override
+ public void setDisplayPowerMode(IBinder displayToken, int mode) {
+ }
}, flags);
}
diff --git a/services/tests/displayservicetests/src/com/android/server/display/VirtualDisplayAdapterTest.java b/services/tests/displayservicetests/src/com/android/server/display/VirtualDisplayAdapterTest.java
index 9287b3004279..0bef3b89547f 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/VirtualDisplayAdapterTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/VirtualDisplayAdapterTest.java
@@ -21,19 +21,29 @@ import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyFloat;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.hardware.display.DisplayManager;
import android.hardware.display.IVirtualDisplayCallback;
import android.hardware.display.VirtualDisplayConfig;
import android.media.projection.IMediaProjection;
+import android.os.Binder;
import android.os.IBinder;
import android.os.PowerManager;
import android.os.Process;
+import android.platform.test.annotations.EnableFlags;
import android.platform.test.flag.junit.CheckFlagsRule;
import android.platform.test.flag.junit.DeviceFlagsValueProvider;
+import android.platform.test.flag.junit.SetFlagsRule;
import android.testing.TestableContext;
import android.view.Display;
import android.view.Surface;
+import android.view.SurfaceControl;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
@@ -67,6 +77,9 @@ public class VirtualDisplayAdapterTest {
public final TestableContext mContext = new TestableContext(
InstrumentationRegistry.getInstrumentation().getContext());
+ @Rule
+ public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+
@Mock
private VirtualDisplayAdapter.SurfaceControlDisplayFactory mMockSufaceControlDisplayFactory;
@@ -380,6 +393,69 @@ public class VirtualDisplayAdapterTest {
}
}
+ @EnableFlags(
+ android.companion.virtualdevice.flags.Flags.FLAG_CORRECT_VIRTUAL_DISPLAY_POWER_STATE)
+ @Test
+ public void neverBlankDisplay_alwaysOn() {
+ // A non-public non-mirror display is considered never blank.
+ DisplayDevice device = mAdapter.createVirtualDisplayLocked(mMockCallback,
+ /* projection= */ null, /* ownerUid= */ 10, /* packageName= */ "testpackage",
+ "uniqueId", /* surface= */ mSurfaceMock, /* flags= */ 0,
+ mVirtualDisplayConfigMock);
+
+ DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
+ assertThat(info.state).isEqualTo(Display.STATE_ON);
+ assertThat(info.flags & DisplayDeviceInfo.FLAG_NEVER_BLANK)
+ .isEqualTo(DisplayDeviceInfo.FLAG_NEVER_BLANK);
+ }
+
+ @EnableFlags(
+ android.companion.virtualdevice.flags.Flags.FLAG_CORRECT_VIRTUAL_DISPLAY_POWER_STATE)
+ @Test
+ public void virtualDisplayStateChange_propagatesToSurfaceControl() throws Exception {
+ final String uniqueId = "uniqueId";
+ final IBinder displayToken = new Binder();
+ when(mMockSufaceControlDisplayFactory.createDisplay(
+ any(), anyBoolean(), eq(uniqueId), anyFloat()))
+ .thenReturn(displayToken);
+
+ // The display needs to be public, otherwise it will be considered never blank.
+ DisplayDevice device = mAdapter.createVirtualDisplayLocked(mMockCallback,
+ /* projection= */ null, /* ownerUid= */ 10, /* packageName= */ "testpackage",
+ uniqueId, /* surface= */ mSurfaceMock, DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC,
+ mVirtualDisplayConfigMock);
+
+ DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
+ assertThat(info.state).isEqualTo(Display.STATE_UNKNOWN);
+ assertThat(info.flags & DisplayDeviceInfo.FLAG_NEVER_BLANK).isEqualTo(0);
+
+ // Any initial state change is processed because the display state is initially UNKNOWN
+ Runnable stateOnRunnable = device.requestDisplayStateLocked(
+ Display.STATE_ON, /* brightnessState= */ 1.0f, /* sdrBrightnessState= */ 1.0f,
+ /* displayOffloadSession= */ null);
+ assertThat(stateOnRunnable).isNotNull();
+ stateOnRunnable.run();
+ verify(mMockSufaceControlDisplayFactory)
+ .setDisplayPowerMode(displayToken, SurfaceControl.POWER_MODE_NORMAL);
+ verify(mMockCallback).onResumed();
+
+ // Requesting the same display state is a no-op
+ Runnable stateOnSecondRunnable = device.requestDisplayStateLocked(
+ Display.STATE_ON, /* brightnessState= */ 1.0f, /* sdrBrightnessState= */ 1.0f,
+ /* displayOffloadSession= */ null);
+ assertThat(stateOnSecondRunnable).isNull();
+
+ // A change to the display state is processed
+ Runnable stateOffRunnable = device.requestDisplayStateLocked(
+ Display.STATE_OFF, /* brightnessState= */ 1.0f, /* sdrBrightnessState= */ 1.0f,
+ /* displayOffloadSession= */ null);
+ assertThat(stateOffRunnable).isNotNull();
+ stateOffRunnable.run();
+ verify(mMockSufaceControlDisplayFactory)
+ .setDisplayPowerMode(displayToken, SurfaceControl.POWER_MODE_OFF);
+ verify(mMockCallback).onPaused();
+ }
+
private IVirtualDisplayCallback createCallback() {
return new IVirtualDisplayCallback.Stub() {
diff --git a/services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/BrightnessLowLuxModifierTest.kt b/services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/BrightnessLowLuxModifierTest.kt
index 6929690baaf8..d7c047768c1e 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/BrightnessLowLuxModifierTest.kt
+++ b/services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/BrightnessLowLuxModifierTest.kt
@@ -17,7 +17,6 @@ package com.android.server.display.brightness.clamper
import android.os.UserHandle
import android.platform.test.annotations.RequiresFlagsEnabled
-import android.provider.Settings
import android.testing.TestableContext
import androidx.test.platform.app.InstrumentationRegistry
import com.android.server.display.DisplayDeviceConfig
@@ -46,8 +45,6 @@ class BrightnessLowLuxModifierTest {
private var mockDisplayDeviceConfig = mock<DisplayDeviceConfig>()
private val LOW_LUX_BRIGHTNESS = 0.1f
- private val TRANSITION_POINT = 0.25f
- private val NORMAL_RANGE_BRIGHTNESS = 0.3f
@Before
fun setUp() {
@@ -73,127 +70,21 @@ class BrightnessLowLuxModifierTest {
whenever(mockDisplayDeviceConfig.getBrightnessFromBacklight(/* backlight = */ 0.15f))
.thenReturn(0.24f)
- // values above transition point (normal range)
- // nits: 10 -> backlight 0.2 -> brightness -> 0.3
- whenever(mockDisplayDeviceConfig.getBacklightFromNits(/* nits= */ 10f))
- .thenReturn(0.2f)
- whenever(mockDisplayDeviceConfig.getBrightnessFromBacklight(/* backlight = */ 0.2f))
- .thenReturn(NORMAL_RANGE_BRIGHTNESS)
-
// min nits when lux of 400
whenever(mockDisplayDeviceConfig.getMinNitsFromLux(/* lux= */ 400f))
.thenReturn(1.0f)
-
- whenever(mockDisplayDeviceConfig.evenDimmerTransitionPoint).thenReturn(TRANSITION_POINT)
-
- testHandler.flush()
- }
-
- @Test
- fun testSettingOffDisablesModifier() {
- // test transition point ensures brightness doesn't drop when setting is off.
- Settings.Secure.putIntForUser(context.contentResolver,
- Settings.Secure.EVEN_DIMMER_ACTIVATED, 0, USER_ID)
- modifier.recalculateLowerBound()
- testHandler.flush()
- assertThat(modifier.brightnessLowerBound).isEqualTo(TRANSITION_POINT)
- assertThat(modifier.brightnessReason).isEqualTo(0) // no reason - ie off
- modifier.setAmbientLux(3000f)
-
testHandler.flush()
- assertThat(modifier.isActive).isFalse()
- assertThat(modifier.brightnessLowerBound).isEqualTo(TRANSITION_POINT)
- assertThat(modifier.brightnessReason).isEqualTo(0) // no reason - ie off
}
@Test
@RequiresFlagsEnabled(Flags.FLAG_EVEN_DIMMER)
fun testLuxRestrictsBrightnessRange() {
// test that high lux prevents low brightness range.
- Settings.Secure.putIntForUser(context.contentResolver,
- Settings.Secure.EVEN_DIMMER_ACTIVATED, 1, USER_ID)
- Settings.Secure.putFloatForUser(context.contentResolver,
- Settings.Secure.EVEN_DIMMER_MIN_NITS, 0.1f, USER_ID)
- modifier.setAmbientLux(400f)
-
- testHandler.flush()
-
- assertThat(modifier.isActive).isTrue()
- // Test restriction from lux setting
- assertThat(modifier.brightnessReason).isEqualTo(BrightnessReason.MODIFIER_MIN_LUX)
- assertThat(modifier.brightnessLowerBound).isEqualTo(LOW_LUX_BRIGHTNESS)
- }
-
- @Test
- @RequiresFlagsEnabled(Flags.FLAG_EVEN_DIMMER)
- fun testUserRestrictsBrightnessRange() {
- // test that user minimum nits setting prevents low brightness range.
- Settings.Secure.putIntForUser(context.contentResolver,
- Settings.Secure.EVEN_DIMMER_ACTIVATED, 1, USER_ID)
- Settings.Secure.putFloatForUser(context.contentResolver,
- Settings.Secure.EVEN_DIMMER_MIN_NITS, 10.0f, USER_ID)
- modifier.recalculateLowerBound()
- testHandler.flush()
-
- // Test restriction from user setting
- assertThat(modifier.isActive).isTrue()
- assertThat(modifier.brightnessReason)
- .isEqualTo(BrightnessReason.MODIFIER_MIN_USER_SET_LOWER_BOUND)
- assertThat(modifier.brightnessLowerBound).isEqualTo(NORMAL_RANGE_BRIGHTNESS)
- }
-
- @Test
- @RequiresFlagsEnabled(Flags.FLAG_EVEN_DIMMER)
- fun testOnToOff() {
- // test that high lux prevents low brightness range.
- Settings.Secure.putIntForUser(context.contentResolver,
- Settings.Secure.EVEN_DIMMER_ACTIVATED, 1, USER_ID) // on
- Settings.Secure.putFloatForUser(context.contentResolver,
- Settings.Secure.EVEN_DIMMER_MIN_NITS, 1.0f, USER_ID)
- modifier.setAmbientLux(400f)
-
- testHandler.flush()
-
- assertThat(modifier.isActive).isTrue()
- // Test restriction from lux setting
- assertThat(modifier.brightnessReason).isEqualTo(BrightnessReason.MODIFIER_MIN_LUX)
- assertThat(modifier.brightnessLowerBound).isEqualTo(LOW_LUX_BRIGHTNESS)
-
- Settings.Secure.putIntForUser(context.contentResolver,
- Settings.Secure.EVEN_DIMMER_ACTIVATED, 0, USER_ID) // off
-
- modifier.recalculateLowerBound()
- testHandler.flush()
-
- assertThat(modifier.isActive).isFalse()
- assertThat(modifier.brightnessLowerBound).isEqualTo(TRANSITION_POINT)
- assertThat(modifier.brightnessReason).isEqualTo(0) // no reason - ie off
- }
-
- @Test
- @RequiresFlagsEnabled(Flags.FLAG_EVEN_DIMMER)
- fun testOffToOn() {
- // test that high lux prevents low brightness range.
- Settings.Secure.putIntForUser(context.contentResolver,
- Settings.Secure.EVEN_DIMMER_ACTIVATED, 0, USER_ID) // off
- Settings.Secure.putFloatForUser(context.contentResolver,
- Settings.Secure.EVEN_DIMMER_MIN_NITS, 1.0f, USER_ID)
modifier.setAmbientLux(400f)
testHandler.flush()
- assertThat(modifier.isActive).isFalse()
- assertThat(modifier.brightnessLowerBound).isEqualTo(TRANSITION_POINT)
- assertThat(modifier.brightnessReason).isEqualTo(0) // no reason - ie off
-
-
-
- Settings.Secure.putIntForUser(context.contentResolver,
- Settings.Secure.EVEN_DIMMER_ACTIVATED, 1, USER_ID) // on
- modifier.recalculateLowerBound()
- testHandler.flush()
-
assertThat(modifier.isActive).isTrue()
// Test restriction from lux setting
assertThat(modifier.brightnessReason).isEqualTo(BrightnessReason.MODIFIER_MIN_LUX)
@@ -204,11 +95,6 @@ class BrightnessLowLuxModifierTest {
@RequiresFlagsEnabled(Flags.FLAG_EVEN_DIMMER)
fun testEnabledEvenWhenAutobrightnessIsOff() {
// test that high lux prevents low brightness range.
- Settings.Secure.putIntForUser(context.contentResolver,
- Settings.Secure.EVEN_DIMMER_ACTIVATED, 1, USER_ID) // on
- Settings.Secure.putFloatForUser(context.contentResolver,
- Settings.Secure.EVEN_DIMMER_MIN_NITS, 1.0f, USER_ID)
-
modifier.setAmbientLux(400f)
testHandler.flush()
@@ -225,37 +111,5 @@ class BrightnessLowLuxModifierTest {
assertThat(modifier.brightnessReason).isEqualTo(BrightnessReason.MODIFIER_MIN_LUX)
assertThat(modifier.brightnessLowerBound).isEqualTo(LOW_LUX_BRIGHTNESS)
}
-
- @Test
- @RequiresFlagsEnabled(Flags.FLAG_EVEN_DIMMER)
- fun testUserSwitch() {
- // nits: 0.5 -> backlight 0.01 -> brightness -> 0.05
- whenever(mockDisplayDeviceConfig.getBacklightFromNits(/* nits= */ 0.5f))
- .thenReturn(0.01f)
- whenever(mockDisplayDeviceConfig.getBrightnessFromBacklight(/* backlight = */ 0.01f))
- .thenReturn(0.05f)
-
- Settings.Secure.putIntForUser(context.contentResolver,
- Settings.Secure.EVEN_DIMMER_ACTIVATED, 0, USER_ID) // off
- Settings.Secure.putFloatForUser(context.contentResolver,
- Settings.Secure.EVEN_DIMMER_MIN_NITS, 1.0f, USER_ID)
-
- modifier.recalculateLowerBound()
-
- assertThat(modifier.isActive).isFalse()
- assertThat(modifier.brightnessLowerBound).isEqualTo(TRANSITION_POINT)
- assertThat(modifier.brightnessReason).isEqualTo(0) // no reason - i.e. off
-
- Settings.Secure.putIntForUser(context.contentResolver,
- Settings.Secure.EVEN_DIMMER_ACTIVATED, 1, USER_ID) // on
- Settings.Secure.putFloatForUser(context.contentResolver,
- Settings.Secure.EVEN_DIMMER_MIN_NITS, 0.5f, USER_ID)
- modifier.onSwitchUser()
-
- assertThat(modifier.isActive).isTrue()
- assertThat(modifier.brightnessReason).isEqualTo(
- BrightnessReason.MODIFIER_MIN_USER_SET_LOWER_BOUND)
- assertThat(modifier.brightnessLowerBound).isEqualTo(0.05f)
- }
}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index 3727bbefb1d3..dd5c601619a0 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -5211,41 +5211,6 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
}
@Test
- public void
- updateNotificationChannelFromPrivilegedListener_oldSoundNoUriPerm_newSoundHasUriPerm()
- throws Exception {
- mService.setPreferencesHelper(mPreferencesHelper);
- when(mCompanionMgr.getAssociations(mPkg, mUserId))
- .thenReturn(singletonList(mock(AssociationInfo.class)));
- when(mPreferencesHelper.getNotificationChannel(eq(mPkg), anyInt(),
- eq(mTestNotificationChannel.getId()), anyBoolean()))
- .thenReturn(mTestNotificationChannel);
-
- // Missing Uri permissions for the old channel sound
- final Uri oldSoundUri = Settings.System.DEFAULT_NOTIFICATION_URI;
- doThrow(new SecurityException("no access")).when(mUgmInternal)
- .checkGrantUriPermission(eq(Process.myUid()), any(), eq(oldSoundUri),
- anyInt(), eq(Process.myUserHandle().getIdentifier()));
-
- // Has Uri permissions for the old channel sound
- final Uri newSoundUri = Uri.parse("content://media/test/sound/uri");
- final NotificationChannel updatedNotificationChannel = new NotificationChannel(
- TEST_CHANNEL_ID, TEST_CHANNEL_ID, IMPORTANCE_DEFAULT);
- updatedNotificationChannel.setSound(newSoundUri,
- updatedNotificationChannel.getAudioAttributes());
-
- mBinderService.updateNotificationChannelFromPrivilegedListener(
- null, mPkg, Process.myUserHandle(), updatedNotificationChannel);
-
- verify(mPreferencesHelper, times(1)).updateNotificationChannel(
- anyString(), anyInt(), any(), anyBoolean(), anyInt(), anyBoolean());
-
- verify(mListeners, never()).notifyNotificationChannelChanged(eq(mPkg),
- eq(Process.myUserHandle()), eq(mTestNotificationChannel),
- eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_UPDATED));
- }
-
- @Test
public void testGetNotificationChannelFromPrivilegedListener_cdm_success() throws Exception {
mService.setPreferencesHelper(mPreferencesHelper);
when(mCompanionMgr.getAssociations(mPkg, mUserId))
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
index 752910d6d3c1..a02f628ce9b7 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
@@ -46,13 +46,11 @@ import static android.app.NotificationManager.IMPORTANCE_MAX;
import static android.app.NotificationManager.IMPORTANCE_NONE;
import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
import static android.app.NotificationManager.VISIBILITY_NO_OVERRIDE;
-import static android.content.ContentResolver.SCHEME_ANDROID_RESOURCE;
-import static android.content.ContentResolver.SCHEME_CONTENT;
-import static android.content.ContentResolver.SCHEME_FILE;
import static android.media.AudioAttributes.CONTENT_TYPE_SONIFICATION;
import static android.media.AudioAttributes.USAGE_NOTIFICATION;
import static android.os.UserHandle.USER_ALL;
import static android.os.UserHandle.USER_SYSTEM;
+
import static android.platform.test.flag.junit.SetFlagsRule.DefaultInitValueType.DEVICE_DEFAULT;
import static android.service.notification.Adjustment.TYPE_CONTENT_RECOMMENDATION;
import static android.service.notification.Adjustment.TYPE_NEWS;
@@ -66,6 +64,7 @@ import static com.android.internal.config.sysui.SystemUiSystemPropertiesFlags.No
import static com.android.internal.util.FrameworkStatsLog.PACKAGE_NOTIFICATION_PREFERENCES__FSI_STATE__DENIED;
import static com.android.internal.util.FrameworkStatsLog.PACKAGE_NOTIFICATION_PREFERENCES__FSI_STATE__GRANTED;
import static com.android.internal.util.FrameworkStatsLog.PACKAGE_NOTIFICATION_PREFERENCES__FSI_STATE__NOT_REQUESTED;
+import static com.android.server.notification.Flags.FLAG_ALL_NOTIFS_NEED_TTL;
import static com.android.server.notification.Flags.FLAG_PERSIST_INCOMPLETE_RESTORE_DATA;
import static com.android.server.notification.NotificationChannelLogger.NotificationChannelEvent.NOTIFICATION_CHANNEL_UPDATED_BY_USER;
import static com.android.server.notification.PreferencesHelper.DEFAULT_BUBBLE_PREFERENCE;
@@ -92,7 +91,6 @@ import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
@@ -385,10 +383,10 @@ public class PreferencesHelperTest extends UiServiceTestCase {
mHelper = new TestPreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper,
mPermissionHelper, mPermissionManager, mLogger, mAppOpsManager, mUserProfiles,
- mUgmInternal, false, mClock);
+ false, mClock);
mXmlHelper = new TestPreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper,
mPermissionHelper, mPermissionManager, mLogger, mAppOpsManager, mUserProfiles,
- mUgmInternal, false, mClock);
+ false, mClock);
resetZenModeHelper();
mAudioAttributes = new AudioAttributes.Builder()
@@ -803,7 +801,7 @@ public class PreferencesHelperTest extends UiServiceTestCase {
public void testReadXml_oldXml_migrates() throws Exception {
mXmlHelper = new TestPreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper,
mPermissionHelper, mPermissionManager, mLogger, mAppOpsManager, mUserProfiles,
- mUgmInternal, /* showReviewPermissionsNotification= */ true, mClock);
+ /* showReviewPermissionsNotification= */ true, mClock);
String xml = "<ranking version=\"2\">\n"
+ "<package name=\"" + PKG_N_MR1 + "\" uid=\"" + UID_N_MR1
@@ -939,7 +937,7 @@ public class PreferencesHelperTest extends UiServiceTestCase {
public void testReadXml_newXml_noMigration_showPermissionNotification() throws Exception {
mXmlHelper = new TestPreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper,
mPermissionHelper, mPermissionManager, mLogger, mAppOpsManager, mUserProfiles,
- mUgmInternal, /* showReviewPermissionsNotification= */ true, mClock);
+ /* showReviewPermissionsNotification= */ true, mClock);
String xml = "<ranking version=\"3\">\n"
+ "<package name=\"" + PKG_N_MR1 + "\" show_badge=\"true\">\n"
@@ -998,7 +996,7 @@ public class PreferencesHelperTest extends UiServiceTestCase {
public void testReadXml_newXml_permissionNotificationOff() throws Exception {
mHelper = new TestPreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper,
mPermissionHelper, mPermissionManager, mLogger, mAppOpsManager, mUserProfiles,
- mUgmInternal, /* showReviewPermissionsNotification= */ false, mClock);
+ /* showReviewPermissionsNotification= */ false, mClock);
String xml = "<ranking version=\"3\">\n"
+ "<package name=\"" + PKG_N_MR1 + "\" show_badge=\"true\">\n"
@@ -1057,7 +1055,7 @@ public class PreferencesHelperTest extends UiServiceTestCase {
public void testReadXml_newXml_noMigration_noPermissionNotification() throws Exception {
mHelper = new TestPreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper,
mPermissionHelper, mPermissionManager, mLogger, mAppOpsManager, mUserProfiles,
- mUgmInternal, /* showReviewPermissionsNotification= */ true, mClock);
+ /* showReviewPermissionsNotification= */ true, mClock);
String xml = "<ranking version=\"4\">\n"
+ "<package name=\"" + PKG_N_MR1 + "\" show_badge=\"true\">\n"
@@ -1655,7 +1653,7 @@ public class PreferencesHelperTest extends UiServiceTestCase {
// simulate load after reboot
mXmlHelper = new TestPreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper,
mPermissionHelper, mPermissionManager, mLogger, mAppOpsManager, mUserProfiles,
- mUgmInternal, false, mClock);
+ false, mClock);
loadByteArrayXml(baos.toByteArray(), false, USER_ALL);
// Trigger 2nd restore pass
@@ -1710,7 +1708,7 @@ public class PreferencesHelperTest extends UiServiceTestCase {
// simulate load after reboot
mXmlHelper = new TestPreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper,
mPermissionHelper, mPermissionManager, mLogger, mAppOpsManager, mUserProfiles,
- mUgmInternal, false, mClock);
+ false, mClock);
loadByteArrayXml(xml.getBytes(), false, USER_ALL);
// Trigger 2nd restore pass
@@ -1788,10 +1786,10 @@ public class PreferencesHelperTest extends UiServiceTestCase {
mHelper = new TestPreferencesHelper(mContext, mPm, mHandler, mMockZenModeHelper,
mPermissionHelper, mPermissionManager, mLogger, mAppOpsManager, mUserProfiles,
- mUgmInternal, false, mClock);
+ false, mClock);
mXmlHelper = new TestPreferencesHelper(mContext, mPm, mHandler, mMockZenModeHelper,
mPermissionHelper, mPermissionManager, mLogger, mAppOpsManager, mUserProfiles,
- mUgmInternal, false, mClock);
+ false, mClock);
NotificationChannel channel =
new NotificationChannel("id", "name", IMPORTANCE_LOW);
@@ -3263,61 +3261,6 @@ public class PreferencesHelperTest extends UiServiceTestCase {
}
@Test
- public void testCreateChannel_noSoundUriPermission_contentSchemeVerified() {
- final Uri sound = Uri.parse(SCHEME_CONTENT + "://media/test/sound/uri");
-
- doThrow(new SecurityException("no access")).when(mUgmInternal)
- .checkGrantUriPermission(eq(UID_N_MR1), any(), eq(sound),
- anyInt(), eq(UserHandle.getUserId(UID_N_MR1)));
-
- final NotificationChannel channel = new NotificationChannel("id2", "name2",
- NotificationManager.IMPORTANCE_DEFAULT);
- channel.setSound(sound, mAudioAttributes);
-
- assertThrows(SecurityException.class,
- () -> mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel,
- true, false, UID_N_MR1, false));
- assertThat(mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId(), true))
- .isNull();
- }
-
- @Test
- public void testCreateChannel_noSoundUriPermission_fileSchemaIgnored() {
- final Uri sound = Uri.parse(SCHEME_FILE + "://path/sound");
-
- doThrow(new SecurityException("no access")).when(mUgmInternal)
- .checkGrantUriPermission(eq(UID_N_MR1), any(), any(),
- anyInt(), eq(UserHandle.getUserId(UID_N_MR1)));
-
- final NotificationChannel channel = new NotificationChannel("id2", "name2",
- NotificationManager.IMPORTANCE_DEFAULT);
- channel.setSound(sound, mAudioAttributes);
-
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false, UID_N_MR1,
- false);
- assertThat(mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId(), true)
- .getSound()).isEqualTo(sound);
- }
-
- @Test
- public void testCreateChannel_noSoundUriPermission_resourceSchemaIgnored() {
- final Uri sound = Uri.parse(SCHEME_ANDROID_RESOURCE + "://resId/sound");
-
- doThrow(new SecurityException("no access")).when(mUgmInternal)
- .checkGrantUriPermission(eq(UID_N_MR1), any(), any(),
- anyInt(), eq(UserHandle.getUserId(UID_N_MR1)));
-
- final NotificationChannel channel = new NotificationChannel("id2", "name2",
- NotificationManager.IMPORTANCE_DEFAULT);
- channel.setSound(sound, mAudioAttributes);
-
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false, UID_N_MR1,
- false);
- assertThat(mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId(), true)
- .getSound()).isEqualTo(sound);
- }
-
- @Test
public void testPermanentlyDeleteChannels() throws Exception {
NotificationChannel channel1 =
new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
@@ -7086,10 +7029,9 @@ public class PreferencesHelperTest extends UiServiceTestCase {
ZenModeHelper zenHelper, PermissionHelper permHelper, PermissionManager permManager,
NotificationChannelLogger notificationChannelLogger,
AppOpsManager appOpsManager, ManagedServices.UserProfiles userProfiles,
- UriGrantsManagerInternal ugmInternal,
boolean showReviewPermissionsNotification, Clock clock) {
super(context, pm, rankingHandler, zenHelper, permHelper, permManager,
- notificationChannelLogger, appOpsManager, userProfiles, ugmInternal,
+ notificationChannelLogger, appOpsManager, userProfiles,
showReviewPermissionsNotification, clock);
}
diff --git a/tests/FlickerTests/Rotation/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt b/tests/FlickerTests/Rotation/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt
index d7f91e009c92..2093ccc86653 100644
--- a/tests/FlickerTests/Rotation/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt
+++ b/tests/FlickerTests/Rotation/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt
@@ -156,19 +156,6 @@ class SeamlessAppRotationTest(flicker: LegacyFlickerTest) : RotationTransition(f
flicker.assertLayers { isVisible(testApp) }
}
- /** Checks that [testApp] layer covers the entire screen during the whole transition */
- @Presubmit
- @Test
- fun appLayerRotates() {
- flicker.assertLayers {
- this.invoke("entireScreenCovered") { entry ->
- entry.entry.displays.map { display ->
- entry.visibleRegion(testApp).coversExactly(display.layerStackSpace)
- }
- }
- }
- }
-
/** {@inheritDoc} */
@Test
@Ignore("Not applicable to this CUJ. App is full screen")
@@ -225,7 +212,6 @@ class SeamlessAppRotationTest(flicker: LegacyFlickerTest) : RotationTransition(f
visibleLayersShownMoreThanOneConsecutiveEntry()
visibleWindowsShownMoreThanOneConsecutiveEntry()
- runAndIgnoreAssumptionViolation { appLayerRotates() }
runAndIgnoreAssumptionViolation { appLayerAlwaysVisible() }
runAndIgnoreAssumptionViolation { navBarLayerIsVisibleAtStartAndEnd() }
runAndIgnoreAssumptionViolation { navBarWindowIsAlwaysVisible() }
diff --git a/tests/FlickerTests/test-apps/flickerapp/AndroidManifest.xml b/tests/FlickerTests/test-apps/flickerapp/AndroidManifest.xml
index 7c24a4adca3d..98af8b2f53b5 100644
--- a/tests/FlickerTests/test-apps/flickerapp/AndroidManifest.xml
+++ b/tests/FlickerTests/test-apps/flickerapp/AndroidManifest.xml
@@ -39,7 +39,6 @@
android:value="true" />
<activity android:name=".SimpleActivity"
android:taskAffinity="com.android.server.wm.flicker.testapp.SimpleActivity"
- android:theme="@style/CutoutShortEdges"
android:label="SimpleActivity"
android:exported="true">
<intent-filter>
@@ -49,7 +48,6 @@
</activity>
<activity android:name=".ImeActivity"
android:taskAffinity="com.android.server.wm.flicker.testapp.ImeActivity"
- android:theme="@style/CutoutShortEdges"
android:label="ImeActivity"
android:exported="true">
<intent-filter>
@@ -58,7 +56,6 @@
</intent-filter>
</activity>
<activity android:name=".ImeActivityAutoFocus"
- android:theme="@style/CutoutShortEdges"
android:taskAffinity="com.android.server.wm.flicker.testapp.ImeActivityAutoFocus"
android:windowSoftInputMode="stateVisible"
android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout"
@@ -81,7 +78,6 @@
</activity>
<activity android:name=".SeamlessRotationActivity"
android:taskAffinity="com.android.server.wm.flicker.testapp.SeamlessRotationActivity"
- android:theme="@style/CutoutShortEdges"
android:configChanges="orientation|screenSize|screenLayout|smallestScreenSize"
android:showWhenLocked="true"
android:label="SeamlessActivity"
@@ -92,7 +88,6 @@
</intent-filter>
</activity>
<activity android:name=".NonResizeableActivity"
- android:theme="@style/CutoutShortEdges"
android:resizeableActivity="false"
android:taskAffinity="com.android.server.wm.flicker.testapp.NonResizeableActivity"
android:label="NonResizeableActivity"
@@ -174,7 +169,6 @@
</activity>
<activity android:name=".LaunchNewActivity"
android:taskAffinity="com.android.server.wm.flicker.testapp.LaunchNewActivity"
- android:theme="@style/CutoutShortEdges"
android:configChanges="orientation|screenSize"
android:label="LaunchNewActivity"
android:exported="true">
@@ -185,7 +179,6 @@
</activity>
<activity android:name=".LaunchNewTaskActivity"
android:taskAffinity="com.android.server.wm.flicker.testapp.LaunchNewTaskActivity"
- android:theme="@style/CutoutShortEdges"
android:configChanges="orientation|screenSize"
android:label="LaunchNewTaskActivity"
android:exported="true">
@@ -207,7 +200,6 @@
</activity>
<activity android:name=".PortraitOnlyActivity"
android:taskAffinity="com.android.server.wm.flicker.testapp.PortraitOnlyActivity"
- android:theme="@style/CutoutShortEdges"
android:screenOrientation="portrait"
android:configChanges="orientation|screenSize"
android:exported="true">
@@ -219,7 +211,6 @@
<activity android:name=".ImeEditorPopupDialogActivity"
android:taskAffinity="com.android.server.wm.flicker.testapp.ImeEditorPopupDialogActivity"
android:configChanges="orientation|screenSize"
- android:theme="@style/CutoutShortEdges"
android:label="ImeEditorPopupDialogActivity"
android:exported="true">
<intent-filter>
@@ -229,7 +220,6 @@
</activity>
<activity android:name=".ShowWhenLockedActivity"
android:taskAffinity="com.android.server.wm.flicker.testapp.ShowWhenLockedActivity"
- android:theme="@style/CutoutShortEdges"
android:configChanges="orientation|screenSize"
android:label="ShowWhenLockedActivity"
android:showWhenLocked="true"
@@ -241,7 +231,6 @@
</activity>
<activity android:name=".NotificationActivity"
android:taskAffinity="com.android.server.wm.flicker.testapp.NotificationActivity"
- android:theme="@style/CutoutShortEdges"
android:configChanges="orientation|screenSize"
android:label="NotificationActivity"
android:exported="true">
@@ -254,7 +243,6 @@
android:name=".ActivityEmbeddingMainActivity"
android:label="ActivityEmbedding Main"
android:taskAffinity="com.android.server.wm.flicker.testapp.ActivityEmbedding"
- android:theme="@style/CutoutShortEdges"
android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout"
android:exported="true">
<intent-filter>
@@ -266,7 +254,6 @@
android:name=".ActivityEmbeddingTrampolineActivity"
android:label="ActivityEmbedding Trampoline"
android:taskAffinity="com.android.server.wm.flicker.testapp.ActivityEmbedding"
- android:theme="@style/CutoutShortEdges"
android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout"
android:exported="false">
</activity>
@@ -274,7 +261,6 @@
android:name=".ActivityEmbeddingSecondaryActivity"
android:label="ActivityEmbedding Secondary"
android:taskAffinity="com.android.server.wm.flicker.testapp.ActivityEmbedding"
- android:theme="@style/CutoutShortEdges"
android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout"
android:supportsPictureInPicture="true"
android:exported="false"/>
@@ -282,21 +268,18 @@
android:name=".ActivityEmbeddingThirdActivity"
android:label="ActivityEmbedding Third"
android:taskAffinity="com.android.server.wm.flicker.testapp.ActivityEmbedding"
- android:theme="@style/CutoutShortEdges"
android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout"
android:exported="false"/>
<activity
android:name=".ActivityEmbeddingAlwaysExpandActivity"
android:label="ActivityEmbedding AlwaysExpand"
android:taskAffinity="com.android.server.wm.flicker.testapp.ActivityEmbedding"
- android:theme="@style/CutoutShortEdges"
android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout"
android:exported="false"/>
<activity
android:name=".ActivityEmbeddingPlaceholderPrimaryActivity"
android:label="ActivityEmbedding Placeholder Primary"
android:taskAffinity="com.android.server.wm.flicker.testapp.ActivityEmbedding"
- android:theme="@style/CutoutShortEdges"
android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout"
android:exported="false">
</activity>
@@ -304,7 +287,6 @@
android:name=".ActivityEmbeddingPlaceholderSecondaryActivity"
android:label="ActivityEmbedding Placeholder Secondary"
android:taskAffinity="com.android.server.wm.flicker.testapp.ActivityEmbedding"
- android:theme="@style/CutoutShortEdges"
android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout"
android:exported="false"/>
<activity android:name=".MailActivity"
@@ -334,7 +316,6 @@
android:supportsPictureInPicture="true"
android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation"
android:taskAffinity="com.android.server.wm.flicker.testapp.PipActivity"
- android:theme="@style/CutoutShortEdges"
android:launchMode="singleTop"
android:label="PipActivity"
android:exported="true">
@@ -350,7 +331,6 @@
<activity android:name=".BottomHalfPipLaunchingActivity"
android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation"
android:taskAffinity="com.android.server.wm.flicker.testapp.BottomHalfPipLaunchingActivity"
- android:theme="@style/CutoutShortEdges"
android:label="BottomHalfPipLaunchingActivity"
android:exported="true">
<intent-filter>
@@ -371,7 +351,6 @@
<activity android:name=".SplitScreenActivity"
android:resizeableActivity="true"
android:taskAffinity="com.android.server.wm.flicker.testapp.SplitScreenActivity"
- android:theme="@style/CutoutShortEdges"
android:label="SplitScreenPrimaryActivity"
android:exported="true"
android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation">
@@ -383,7 +362,6 @@
<activity android:name=".SplitScreenSecondaryActivity"
android:resizeableActivity="true"
android:taskAffinity="com.android.server.wm.flicker.testapp.SplitScreenSecondaryActivity"
- android:theme="@style/CutoutShortEdges"
android:label="SplitScreenSecondaryActivity"
android:exported="true"
android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation">
@@ -396,7 +374,6 @@
</activity>
<activity android:name=".SendNotificationActivity"
android:taskAffinity="com.android.server.wm.flicker.testapp.SendNotificationActivity"
- android:theme="@style/CutoutShortEdges"
android:label="SendNotificationActivity"
android:exported="true">
<intent-filter>
@@ -408,7 +385,6 @@
android:name=".LaunchBubbleActivity"
android:label="LaunchBubbleActivity"
android:exported="true"
- android:theme="@style/CutoutShortEdges"
android:launchMode="singleTop">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
@@ -420,7 +396,6 @@
android:name=".BubbleActivity"
android:label="BubbleActivity"
android:exported="false"
- android:theme="@style/CutoutShortEdges"
android:resizeableActivity="true"/>
<activity
android:name=".TransferSplashscreenActivity"
@@ -468,4 +443,4 @@
</service>
</application>
<uses-permission android:name="android.permission.ACTIVITY_RECOGNITION"/>
-</manifest>
+</manifest> \ No newline at end of file
diff --git a/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_ime.xml b/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_ime.xml
index 507c1b622613..5e5203cb0545 100644
--- a/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_ime.xml
+++ b/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_ime.xml
@@ -17,6 +17,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/holo_green_light"
+ android:fitsSystemWindows="true"
android:focusableInTouchMode="true"
android:orientation="vertical">
diff --git a/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_mail.xml b/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_mail.xml
index 8a97433ede04..fcef791afe2e 100644
--- a/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_mail.xml
+++ b/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_mail.xml
@@ -19,6 +19,7 @@
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
+ android:fitsSystemWindows="true"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
diff --git a/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_simple.xml b/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_simple.xml
index 5d94e5177dcc..42213d6812da 100644
--- a/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_simple.xml
+++ b/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_simple.xml
@@ -18,6 +18,7 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
+ android:fitsSystemWindows="true"
android:background="@android:color/holo_orange_light">
</LinearLayout>
diff --git a/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_surfaceview.xml b/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_surfaceview.xml
index 0b4693dec6e1..4d12168ca8db 100644
--- a/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_surfaceview.xml
+++ b/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_surfaceview.xml
@@ -19,6 +19,7 @@
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
+ android:fitsSystemWindows="true"
android:background="@android:color/holo_orange_light">
<SurfaceView
diff --git a/tests/FlickerTests/test-apps/flickerapp/res/values/styles.xml b/tests/FlickerTests/test-apps/flickerapp/res/values/styles.xml
index 837d050b73ff..ca3244820893 100644
--- a/tests/FlickerTests/test-apps/flickerapp/res/values/styles.xml
+++ b/tests/FlickerTests/test-apps/flickerapp/res/values/styles.xml
@@ -36,10 +36,6 @@
<item name="android:windowLayoutInDisplayCutoutMode">default</item>
</style>
- <style name="CutoutShortEdges" parent="@style/DefaultTheme">
- <item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
- </style>
-
<style name="CutoutNever" parent="@style/DefaultTheme">
<item name="android:windowLayoutInDisplayCutoutMode">never</item>
</style>
@@ -78,4 +74,4 @@
<!-- Here we want to match the duration of our AVD -->
<item name="android:windowSplashScreenAnimationDuration">900</item>
</style>
-</resources>
+</resources> \ No newline at end of file