Merge "Make flexiglass window visible when swiping on launcher and status bar" into udc-qpr-dev am: ee6f8978ee

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/24122774

Change-Id: I19ddc56da73a43e324b12b9e52211ee7613ce002
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Shawn Lee
2023-07-24 16:58:56 +00:00
committed by Automerger Merge Worker
13 changed files with 215 additions and 20 deletions

View File

@@ -92,6 +92,14 @@ private fun Scene(
onSceneChanged: (SceneModel) -> Unit, onSceneChanged: (SceneModel) -> Unit,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
) { ) {
val destinationScenes: Map<UserAction, SceneModel> by
scene.destinationScenes(containerName).collectAsState()
val swipeLeftDestinationScene = destinationScenes[UserAction.Swipe(Direction.LEFT)]
val swipeUpDestinationScene = destinationScenes[UserAction.Swipe(Direction.UP)]
val swipeRightDestinationScene = destinationScenes[UserAction.Swipe(Direction.RIGHT)]
val swipeDownDestinationScene = destinationScenes[UserAction.Swipe(Direction.DOWN)]
val backDestinationScene = destinationScenes[UserAction.Back]
// TODO(b/280880714): replace with the real UI and make sure to call onTransitionProgress. // TODO(b/280880714): replace with the real UI and make sure to call onTransitionProgress.
Box(modifier) { Box(modifier) {
Column( Column(
@@ -103,14 +111,6 @@ private fun Scene(
modifier = Modifier, modifier = Modifier,
) )
val destinationScenes: Map<UserAction, SceneModel> by
scene.destinationScenes(containerName).collectAsState()
val swipeLeftDestinationScene = destinationScenes[UserAction.Swipe(Direction.LEFT)]
val swipeUpDestinationScene = destinationScenes[UserAction.Swipe(Direction.UP)]
val swipeRightDestinationScene = destinationScenes[UserAction.Swipe(Direction.RIGHT)]
val swipeDownDestinationScene = destinationScenes[UserAction.Swipe(Direction.DOWN)]
val backDestinationScene = destinationScenes[UserAction.Back]
Row( Row(
horizontalArrangement = Arrangement.spacedBy(8.dp), horizontalArrangement = Arrangement.spacedBy(8.dp),
) { ) {

View File

@@ -84,6 +84,8 @@ import com.android.systemui.Dumpable;
import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dump.DumpManager; import com.android.systemui.dump.DumpManager;
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.flags.Flags;
import com.android.systemui.keyguard.KeyguardUnlockAnimationController; import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
import com.android.systemui.keyguard.ScreenLifecycle; import com.android.systemui.keyguard.ScreenLifecycle;
import com.android.systemui.keyguard.WakefulnessLifecycle; import com.android.systemui.keyguard.WakefulnessLifecycle;
@@ -94,6 +96,8 @@ import com.android.systemui.navigationbar.NavigationBarView;
import com.android.systemui.navigationbar.NavigationModeController; import com.android.systemui.navigationbar.NavigationModeController;
import com.android.systemui.navigationbar.buttons.KeyButtonView; import com.android.systemui.navigationbar.buttons.KeyButtonView;
import com.android.systemui.recents.OverviewProxyService.OverviewProxyListener; import com.android.systemui.recents.OverviewProxyService.OverviewProxyListener;
import com.android.systemui.scene.domain.interactor.SceneInteractor;
import com.android.systemui.scene.shared.model.SceneContainerNames;
import com.android.systemui.settings.DisplayTracker; import com.android.systemui.settings.DisplayTracker;
import com.android.systemui.settings.UserTracker; import com.android.systemui.settings.UserTracker;
import com.android.systemui.shade.ShadeViewController; import com.android.systemui.shade.ShadeViewController;
@@ -120,6 +124,7 @@ import java.util.concurrent.Executor;
import java.util.function.Supplier; import java.util.function.Supplier;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Provider;
/** /**
* Class to send information from overview to launcher with a binder. * Class to send information from overview to launcher with a binder.
@@ -139,6 +144,7 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis
private static final long MAX_BACKOFF_MILLIS = 10 * 60 * 1000; private static final long MAX_BACKOFF_MILLIS = 10 * 60 * 1000;
private final Context mContext; private final Context mContext;
private final FeatureFlags mFeatureFlags;
private final Executor mMainExecutor; private final Executor mMainExecutor;
private final ShellInterface mShellInterface; private final ShellInterface mShellInterface;
private final Lazy<Optional<CentralSurfaces>> mCentralSurfacesOptionalLazy; private final Lazy<Optional<CentralSurfaces>> mCentralSurfacesOptionalLazy;
@@ -147,6 +153,8 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis
private final Handler mHandler; private final Handler mHandler;
private final Lazy<NavigationBarController> mNavBarControllerLazy; private final Lazy<NavigationBarController> mNavBarControllerLazy;
private final NotificationShadeWindowController mStatusBarWinController; private final NotificationShadeWindowController mStatusBarWinController;
private final Provider<SceneInteractor> mSceneInteractor;
private final Runnable mConnectionRunnable = () -> private final Runnable mConnectionRunnable = () ->
internalConnectToCurrentUser("runnable: startConnectionToCurrentUser"); internalConnectToCurrentUser("runnable: startConnectionToCurrentUser");
private final ComponentName mRecentsComponentName; private final ComponentName mRecentsComponentName;
@@ -209,18 +217,29 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis
mInputFocusTransferStarted = true; mInputFocusTransferStarted = true;
mInputFocusTransferStartY = event.getY(); mInputFocusTransferStartY = event.getY();
mInputFocusTransferStartMillis = event.getEventTime(); mInputFocusTransferStartMillis = event.getEventTime();
// If scene framework is enabled, set the scene container window to
// visible and let the touch "slip" into that window.
if (mFeatureFlags.isEnabled(Flags.SCENE_CONTAINER)) {
mSceneInteractor.get().setVisible(
SceneContainerNames.SYSTEM_UI_DEFAULT, true);
} else {
centralSurfaces.onInputFocusTransfer( centralSurfaces.onInputFocusTransfer(
mInputFocusTransferStarted, false /* cancel */, mInputFocusTransferStarted, false /* cancel */,
0 /* velocity */); 0 /* velocity */);
} }
}
if (action == ACTION_UP || action == ACTION_CANCEL) { if (action == ACTION_UP || action == ACTION_CANCEL) {
mInputFocusTransferStarted = false; mInputFocusTransferStarted = false;
if (!mFeatureFlags.isEnabled(Flags.SCENE_CONTAINER)) {
float velocity = (event.getY() - mInputFocusTransferStartY) float velocity = (event.getY() - mInputFocusTransferStartY)
/ (event.getEventTime() - mInputFocusTransferStartMillis); / (event.getEventTime() - mInputFocusTransferStartMillis);
centralSurfaces.onInputFocusTransfer(mInputFocusTransferStarted, centralSurfaces.onInputFocusTransfer(mInputFocusTransferStarted,
action == ACTION_CANCEL, action == ACTION_CANCEL,
velocity); velocity);
} }
}
event.recycle(); event.recycle();
}); });
}); });
@@ -552,6 +571,7 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis
NavigationModeController navModeController, NavigationModeController navModeController,
NotificationShadeWindowController statusBarWinController, NotificationShadeWindowController statusBarWinController,
SysUiState sysUiState, SysUiState sysUiState,
Provider<SceneInteractor> sceneInteractor,
UserTracker userTracker, UserTracker userTracker,
ScreenLifecycle screenLifecycle, ScreenLifecycle screenLifecycle,
WakefulnessLifecycle wakefulnessLifecycle, WakefulnessLifecycle wakefulnessLifecycle,
@@ -559,6 +579,7 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis
DisplayTracker displayTracker, DisplayTracker displayTracker,
KeyguardUnlockAnimationController sysuiUnlockAnimationController, KeyguardUnlockAnimationController sysuiUnlockAnimationController,
AssistUtils assistUtils, AssistUtils assistUtils,
FeatureFlags featureFlags,
DumpManager dumpManager, DumpManager dumpManager,
Optional<UnfoldTransitionProgressForwarder> unfoldTransitionProgressForwarder Optional<UnfoldTransitionProgressForwarder> unfoldTransitionProgressForwarder
) { ) {
@@ -568,6 +589,7 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis
} }
mContext = context; mContext = context;
mFeatureFlags = featureFlags;
mMainExecutor = mainExecutor; mMainExecutor = mainExecutor;
mShellInterface = shellInterface; mShellInterface = shellInterface;
mCentralSurfacesOptionalLazy = centralSurfacesOptionalLazy; mCentralSurfacesOptionalLazy = centralSurfacesOptionalLazy;
@@ -575,6 +597,7 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis
mHandler = new Handler(); mHandler = new Handler();
mNavBarControllerLazy = navBarControllerLazy; mNavBarControllerLazy = navBarControllerLazy;
mStatusBarWinController = statusBarWinController; mStatusBarWinController = statusBarWinController;
mSceneInteractor = sceneInteractor;
mUserTracker = userTracker; mUserTracker = userTracker;
mConnectionBackoffAttempts = 0; mConnectionBackoffAttempts = 0;
mRecentsComponentName = ComponentName.unflattenFromString(context.getString( mRecentsComponentName = ComponentName.unflattenFromString(context.getString(

View File

@@ -18,11 +18,14 @@ package com.android.systemui.scene.domain.interactor
import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.scene.data.repository.SceneContainerRepository import com.android.systemui.scene.data.repository.SceneContainerRepository
import com.android.systemui.scene.shared.model.RemoteUserInput
import com.android.systemui.scene.shared.model.SceneKey import com.android.systemui.scene.shared.model.SceneKey
import com.android.systemui.scene.shared.model.SceneModel import com.android.systemui.scene.shared.model.SceneModel
import com.android.systemui.scene.shared.model.SceneTransitionModel import com.android.systemui.scene.shared.model.SceneTransitionModel
import javax.inject.Inject import javax.inject.Inject
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
/** /**
* Generic business logic and app state accessors for the scene framework. * Generic business logic and app state accessors for the scene framework.
@@ -92,4 +95,14 @@ constructor(
fun sceneTransitions(containerName: String): StateFlow<SceneTransitionModel?> { fun sceneTransitions(containerName: String): StateFlow<SceneTransitionModel?> {
return repository.sceneTransitions(containerName) return repository.sceneTransitions(containerName)
} }
private val _remoteUserInput: MutableStateFlow<RemoteUserInput?> = MutableStateFlow(null)
/** A flow of motion events originating from outside of the scene framework. */
val remoteUserInput: StateFlow<RemoteUserInput?> = _remoteUserInput.asStateFlow()
/** Handles a remote user input. */
fun onRemoteUserInput(input: RemoteUserInput) {
_remoteUserInput.value = input
}
} }

View File

@@ -0,0 +1,35 @@
package com.android.systemui.scene.shared.model
import android.view.MotionEvent
/** A representation of user input that is used by the scene framework. */
data class RemoteUserInput(
val x: Float,
val y: Float,
val action: RemoteUserInputAction,
) {
companion object {
fun translateMotionEvent(event: MotionEvent): RemoteUserInput {
return RemoteUserInput(
x = event.x,
y = event.y,
action =
when (event.actionMasked) {
MotionEvent.ACTION_DOWN -> RemoteUserInputAction.DOWN
MotionEvent.ACTION_MOVE -> RemoteUserInputAction.MOVE
MotionEvent.ACTION_UP -> RemoteUserInputAction.UP
MotionEvent.ACTION_CANCEL -> RemoteUserInputAction.CANCEL
else -> RemoteUserInputAction.UNKNOWN
}
)
}
}
}
enum class RemoteUserInputAction {
DOWN,
MOVE,
UP,
CANCEL,
UNKNOWN,
}

View File

@@ -2,6 +2,7 @@ package com.android.systemui.scene.ui.view
import android.content.Context import android.content.Context
import android.util.AttributeSet import android.util.AttributeSet
import android.view.MotionEvent
import android.view.View import android.view.View
import com.android.systemui.scene.shared.model.Scene import com.android.systemui.scene.shared.model.Scene
import com.android.systemui.scene.shared.model.SceneContainerConfig import com.android.systemui.scene.shared.model.SceneContainerConfig
@@ -16,11 +17,15 @@ class SceneWindowRootView(
context, context,
attrs, attrs,
) { ) {
private lateinit var viewModel: SceneContainerViewModel
fun init( fun init(
viewModel: SceneContainerViewModel, viewModel: SceneContainerViewModel,
containerConfig: SceneContainerConfig, containerConfig: SceneContainerConfig,
scenes: Set<Scene>, scenes: Set<Scene>,
) { ) {
this.viewModel = viewModel
SceneWindowRootViewBinder.bind( SceneWindowRootViewBinder.bind(
view = this@SceneWindowRootView, view = this@SceneWindowRootView,
viewModel = viewModel, viewModel = viewModel,
@@ -32,6 +37,14 @@ class SceneWindowRootView(
) )
} }
override fun onTouchEvent(event: MotionEvent?): Boolean {
return event?.let {
viewModel.onRemoteUserInput(event)
true
}
?: false
}
override fun setVisibility(visibility: Int) { override fun setVisibility(visibility: Int) {
// Do nothing. We don't want external callers to invoke this. Instead, we drive our own // Do nothing. We don't want external callers to invoke this. Instead, we drive our own
// visibility from our view-binder. // visibility from our view-binder.

View File

@@ -16,7 +16,9 @@
package com.android.systemui.scene.ui.viewmodel package com.android.systemui.scene.ui.viewmodel
import android.view.MotionEvent
import com.android.systemui.scene.domain.interactor.SceneInteractor import com.android.systemui.scene.domain.interactor.SceneInteractor
import com.android.systemui.scene.shared.model.RemoteUserInput
import com.android.systemui.scene.shared.model.SceneKey import com.android.systemui.scene.shared.model.SceneKey
import com.android.systemui.scene.shared.model.SceneModel import com.android.systemui.scene.shared.model.SceneModel
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
@@ -26,6 +28,9 @@ class SceneContainerViewModel(
private val interactor: SceneInteractor, private val interactor: SceneInteractor,
val containerName: String, val containerName: String,
) { ) {
/** A flow of motion events originating from outside of the scene framework. */
val remoteUserInput: StateFlow<RemoteUserInput?> = interactor.remoteUserInput
/** /**
* Keys of all scenes in the container. * Keys of all scenes in the container.
* *
@@ -49,4 +54,9 @@ class SceneContainerViewModel(
fun setSceneTransitionProgress(progress: Float) { fun setSceneTransitionProgress(progress: Float) {
interactor.setSceneTransitionProgress(containerName, progress) interactor.setSceneTransitionProgress(containerName, progress)
} }
/** Handles a [MotionEvent] representing remote user input. */
fun onRemoteUserInput(event: MotionEvent) {
interactor.onRemoteUserInput(RemoteUserInput.translateMotionEvent(event))
}
} }

View File

@@ -28,6 +28,9 @@ import com.android.systemui.Gefingerpoken
import com.android.systemui.R import com.android.systemui.R
import com.android.systemui.flags.FeatureFlags import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags import com.android.systemui.flags.Flags
import com.android.systemui.scene.domain.interactor.SceneInteractor
import com.android.systemui.scene.shared.model.RemoteUserInput
import com.android.systemui.scene.shared.model.SceneContainerNames
import com.android.systemui.shade.ShadeController import com.android.systemui.shade.ShadeController
import com.android.systemui.shade.ShadeLogger import com.android.systemui.shade.ShadeLogger
import com.android.systemui.shade.ShadeViewController import com.android.systemui.shade.ShadeViewController
@@ -43,6 +46,7 @@ import com.android.systemui.util.view.ViewUtil
import java.util.Optional import java.util.Optional
import javax.inject.Inject import javax.inject.Inject
import javax.inject.Named import javax.inject.Named
import javax.inject.Provider
private const val TAG = "PhoneStatusBarViewController" private const val TAG = "PhoneStatusBarViewController"
@@ -53,10 +57,12 @@ class PhoneStatusBarViewController private constructor(
private val centralSurfaces: CentralSurfaces, private val centralSurfaces: CentralSurfaces,
private val shadeController: ShadeController, private val shadeController: ShadeController,
private val shadeViewController: ShadeViewController, private val shadeViewController: ShadeViewController,
private val sceneInteractor: Provider<SceneInteractor>,
private val shadeLogger: ShadeLogger, private val shadeLogger: ShadeLogger,
private val moveFromCenterAnimationController: StatusBarMoveFromCenterAnimationController?, private val moveFromCenterAnimationController: StatusBarMoveFromCenterAnimationController?,
private val userChipViewModel: StatusBarUserChipViewModel, private val userChipViewModel: StatusBarUserChipViewModel,
private val viewUtil: ViewUtil, private val viewUtil: ViewUtil,
private val featureFlags: FeatureFlags,
private val configurationController: ConfigurationController private val configurationController: ConfigurationController
) : ViewController<PhoneStatusBarView>(view) { ) : ViewController<PhoneStatusBarView>(view) {
@@ -164,6 +170,16 @@ class PhoneStatusBarViewController private constructor(
return false return false
} }
// If scene framework is enabled, route the touch to it and
// ignore the rest of the gesture.
if (featureFlags.isEnabled(Flags.SCENE_CONTAINER)) {
sceneInteractor.get()
.onRemoteUserInput(RemoteUserInput.translateMotionEvent(event))
// TODO(b/291965119): remove once view is expanded to cover the status bar
sceneInteractor.get().setVisible(SceneContainerNames.SYSTEM_UI_DEFAULT, true)
return false
}
if (event.action == MotionEvent.ACTION_DOWN) { if (event.action == MotionEvent.ACTION_DOWN) {
// If the view that would receive the touch is disabled, just have status // If the view that would receive the touch is disabled, just have status
// bar eat the gesture. // bar eat the gesture.
@@ -225,6 +241,7 @@ class PhoneStatusBarViewController private constructor(
private val centralSurfaces: CentralSurfaces, private val centralSurfaces: CentralSurfaces,
private val shadeController: ShadeController, private val shadeController: ShadeController,
private val shadeViewController: ShadeViewController, private val shadeViewController: ShadeViewController,
private val sceneInteractor: Provider<SceneInteractor>,
private val shadeLogger: ShadeLogger, private val shadeLogger: ShadeLogger,
private val viewUtil: ViewUtil, private val viewUtil: ViewUtil,
private val configurationController: ConfigurationController, private val configurationController: ConfigurationController,
@@ -245,10 +262,12 @@ class PhoneStatusBarViewController private constructor(
centralSurfaces, centralSurfaces,
shadeController, shadeController,
shadeViewController, shadeViewController,
sceneInteractor,
shadeLogger, shadeLogger,
statusBarMoveFromCenterAnimationController, statusBarMoveFromCenterAnimationController,
userChipViewModel, userChipViewModel,
viewUtil, viewUtil,
featureFlags,
configurationController configurationController
) )
} }

View File

@@ -34,15 +34,21 @@ import com.android.systemui.Dumpable;
import com.android.systemui.R; import com.android.systemui.R;
import com.android.systemui.ScreenDecorations; import com.android.systemui.ScreenDecorations;
import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.flags.Flags;
import com.android.systemui.scene.domain.interactor.SceneInteractor;
import com.android.systemui.scene.shared.model.SceneContainerNames;
import com.android.systemui.shade.ShadeExpansionStateManager; import com.android.systemui.shade.ShadeExpansionStateManager;
import com.android.systemui.statusbar.NotificationShadeWindowController; import com.android.systemui.statusbar.NotificationShadeWindowController;
import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener; import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener; import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
import com.android.systemui.util.kotlin.JavaAdapter;
import java.io.PrintWriter; import java.io.PrintWriter;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Provider;
/** /**
* Manages what parts of the status bar are touchable. Clients are primarily UI that display in the * Manages what parts of the status bar are touchable. Clients are primarily UI that display in the
@@ -78,6 +84,9 @@ public final class StatusBarTouchableRegionManager implements Dumpable {
ConfigurationController configurationController, ConfigurationController configurationController,
HeadsUpManagerPhone headsUpManager, HeadsUpManagerPhone headsUpManager,
ShadeExpansionStateManager shadeExpansionStateManager, ShadeExpansionStateManager shadeExpansionStateManager,
Provider<SceneInteractor> sceneInteractor,
Provider<JavaAdapter> javaAdapter,
FeatureFlags featureFlags,
UnlockedScreenOffAnimationController unlockedScreenOffAnimationController UnlockedScreenOffAnimationController unlockedScreenOffAnimationController
) { ) {
mContext = context; mContext = context;
@@ -115,6 +124,12 @@ public final class StatusBarTouchableRegionManager implements Dumpable {
mUnlockedScreenOffAnimationController = unlockedScreenOffAnimationController; mUnlockedScreenOffAnimationController = unlockedScreenOffAnimationController;
shadeExpansionStateManager.addFullExpansionListener(this::onShadeExpansionFullyChanged); shadeExpansionStateManager.addFullExpansionListener(this::onShadeExpansionFullyChanged);
if (featureFlags.isEnabled(Flags.SCENE_CONTAINER)) {
javaAdapter.get().alwaysCollectFlow(
sceneInteractor.get().isVisible(SceneContainerNames.SYSTEM_UI_DEFAULT),
this::onShadeExpansionFullyChanged);
}
mOnComputeInternalInsetsListener = this::onComputeInternalInsets; mOnComputeInternalInsetsListener = this::onComputeInternalInsets;
} }

View File

@@ -29,6 +29,7 @@ import com.android.internal.logging.UiEventLogger
import com.android.systemui.SysuiTestCase import com.android.systemui.SysuiTestCase
import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.dump.DumpManager import com.android.systemui.dump.DumpManager
import com.android.systemui.flags.FakeFeatureFlags
import com.android.systemui.keyguard.KeyguardUnlockAnimationController import com.android.systemui.keyguard.KeyguardUnlockAnimationController
import com.android.systemui.keyguard.ScreenLifecycle import com.android.systemui.keyguard.ScreenLifecycle
import com.android.systemui.keyguard.WakefulnessLifecycle import com.android.systemui.keyguard.WakefulnessLifecycle
@@ -49,11 +50,11 @@ import com.android.systemui.statusbar.CommandQueue
import com.android.systemui.statusbar.NotificationShadeWindowController import com.android.systemui.statusbar.NotificationShadeWindowController
import com.android.systemui.statusbar.phone.CentralSurfaces import com.android.systemui.statusbar.phone.CentralSurfaces
import com.android.systemui.unfold.progress.UnfoldTransitionProgressForwarder import com.android.systemui.unfold.progress.UnfoldTransitionProgressForwarder
import com.android.systemui.util.mockito.mock
import com.android.systemui.util.mockito.whenever import com.android.systemui.util.mockito.whenever
import com.android.systemui.util.time.FakeSystemClock import com.android.systemui.util.time.FakeSystemClock
import com.android.wm.shell.sysui.ShellInterface import com.android.wm.shell.sysui.ShellInterface
import com.google.common.util.concurrent.MoreExecutors import com.google.common.util.concurrent.MoreExecutors
import dagger.Lazy
import java.util.Optional import java.util.Optional
import java.util.concurrent.Executor import java.util.concurrent.Executor
import org.junit.After import org.junit.After
@@ -82,6 +83,7 @@ class OverviewProxyServiceTest : SysuiTestCase() {
private val displayTracker = FakeDisplayTracker(mContext) private val displayTracker = FakeDisplayTracker(mContext)
private val fakeSystemClock = FakeSystemClock() private val fakeSystemClock = FakeSystemClock()
private val sysUiState = SysUiState(displayTracker) private val sysUiState = SysUiState(displayTracker)
private val featureFlags = FakeFeatureFlags()
private val screenLifecycle = ScreenLifecycle(dumpManager) private val screenLifecycle = ScreenLifecycle(dumpManager)
private val wakefulnessLifecycle = private val wakefulnessLifecycle =
WakefulnessLifecycle(mContext, null, fakeSystemClock, dumpManager) WakefulnessLifecycle(mContext, null, fakeSystemClock, dumpManager)
@@ -132,12 +134,13 @@ class OverviewProxyServiceTest : SysuiTestCase() {
executor, executor,
commandQueue, commandQueue,
shellInterface, shellInterface,
Lazy { navBarController }, { navBarController },
Lazy { Optional.of(centralSurfaces) }, { Optional.of(centralSurfaces) },
Lazy { shadeViewController }, { shadeViewController },
navModeController, navModeController,
statusBarWinController, statusBarWinController,
sysUiState, sysUiState,
mock(),
userTracker, userTracker,
screenLifecycle, screenLifecycle,
wakefulnessLifecycle, wakefulnessLifecycle,
@@ -145,6 +148,7 @@ class OverviewProxyServiceTest : SysuiTestCase() {
displayTracker, displayTracker,
sysuiUnlockAnimationController, sysuiUnlockAnimationController,
assistUtils, assistUtils,
featureFlags,
dumpManager, dumpManager,
unfoldTransitionProgressForwarder unfoldTransitionProgressForwarder
) )

View File

@@ -100,4 +100,15 @@ class SceneInteractorTest : SysuiTestCase() {
) )
) )
} }
@Test
fun remoteUserInput() = runTest {
val remoteUserInput by collectLastValue(underTest.remoteUserInput)
assertThat(remoteUserInput).isNull()
for (input in SceneTestUtils.REMOTE_INPUT_DOWN_GESTURE) {
underTest.onRemoteUserInput(input)
assertThat(remoteUserInput).isEqualTo(input)
}
}
} }

View File

@@ -18,14 +18,19 @@
package com.android.systemui.scene.ui.viewmodel package com.android.systemui.scene.ui.viewmodel
import android.view.MotionEvent
import androidx.test.filters.SmallTest import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.scene.SceneTestUtils import com.android.systemui.scene.SceneTestUtils
import com.android.systemui.scene.shared.model.RemoteUserInput
import com.android.systemui.scene.shared.model.RemoteUserInputAction
import com.android.systemui.scene.shared.model.SceneKey import com.android.systemui.scene.shared.model.SceneKey
import com.android.systemui.scene.shared.model.SceneModel import com.android.systemui.scene.shared.model.SceneModel
import com.google.common.truth.Truth.assertThat import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.currentTime
import kotlinx.coroutines.test.runTest import kotlinx.coroutines.test.runTest
import org.junit.Test import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
@@ -68,4 +73,35 @@ class SceneContainerViewModelTest : SysuiTestCase() {
underTest.setCurrentScene(SceneModel(SceneKey.Shade)) underTest.setCurrentScene(SceneModel(SceneKey.Shade))
assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Shade)) assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Shade))
} }
@Test
fun onRemoteUserInput() = runTest {
val remoteUserInput by collectLastValue(underTest.remoteUserInput)
assertThat(remoteUserInput).isNull()
val inputs =
SceneTestUtils.REMOTE_INPUT_DOWN_GESTURE.map { remoteUserInputToMotionEvent(it) }
inputs.forEachIndexed { index, input ->
underTest.onRemoteUserInput(input)
assertThat(remoteUserInput).isEqualTo(SceneTestUtils.REMOTE_INPUT_DOWN_GESTURE[index])
}
}
private fun TestScope.remoteUserInputToMotionEvent(input: RemoteUserInput): MotionEvent {
return MotionEvent.obtain(
currentTime,
currentTime,
when (input.action) {
RemoteUserInputAction.DOWN -> MotionEvent.ACTION_DOWN
RemoteUserInputAction.MOVE -> MotionEvent.ACTION_MOVE
RemoteUserInputAction.UP -> MotionEvent.ACTION_UP
RemoteUserInputAction.CANCEL -> MotionEvent.ACTION_CANCEL
RemoteUserInputAction.UNKNOWN -> MotionEvent.ACTION_OUTSIDE
},
input.x,
input.y,
0
)
}
} }

View File

@@ -27,6 +27,7 @@ import com.android.systemui.R
import com.android.systemui.SysuiTestCase import com.android.systemui.SysuiTestCase
import com.android.systemui.flags.FeatureFlags import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags import com.android.systemui.flags.Flags
import com.android.systemui.scene.domain.interactor.SceneInteractor
import com.android.systemui.shade.ShadeControllerImpl import com.android.systemui.shade.ShadeControllerImpl
import com.android.systemui.shade.ShadeLogger import com.android.systemui.shade.ShadeLogger
import com.android.systemui.shade.ShadeViewController import com.android.systemui.shade.ShadeViewController
@@ -50,6 +51,7 @@ import org.mockito.Mockito.verify
import org.mockito.Mockito.`when` import org.mockito.Mockito.`when`
import org.mockito.MockitoAnnotations import org.mockito.MockitoAnnotations
import java.util.Optional import java.util.Optional
import javax.inject.Provider
@SmallTest @SmallTest
class PhoneStatusBarViewControllerTest : SysuiTestCase() { class PhoneStatusBarViewControllerTest : SysuiTestCase() {
@@ -73,6 +75,8 @@ class PhoneStatusBarViewControllerTest : SysuiTestCase() {
@Mock @Mock
private lateinit var shadeControllerImpl: ShadeControllerImpl private lateinit var shadeControllerImpl: ShadeControllerImpl
@Mock @Mock
private lateinit var sceneInteractor: Provider<SceneInteractor>
@Mock
private lateinit var shadeLogger: ShadeLogger private lateinit var shadeLogger: ShadeLogger
@Mock @Mock
private lateinit var viewUtil: ViewUtil private lateinit var viewUtil: ViewUtil
@@ -197,6 +201,7 @@ class PhoneStatusBarViewControllerTest : SysuiTestCase() {
centralSurfacesImpl, centralSurfacesImpl,
shadeControllerImpl, shadeControllerImpl,
shadeViewController, shadeViewController,
sceneInteractor,
shadeLogger, shadeLogger,
viewUtil, viewUtil,
configurationController configurationController

View File

@@ -38,6 +38,8 @@ import com.android.systemui.keyguard.shared.model.WakefulnessModel
import com.android.systemui.keyguard.shared.model.WakefulnessState import com.android.systemui.keyguard.shared.model.WakefulnessState
import com.android.systemui.scene.data.repository.SceneContainerRepository import com.android.systemui.scene.data.repository.SceneContainerRepository
import com.android.systemui.scene.domain.interactor.SceneInteractor import com.android.systemui.scene.domain.interactor.SceneInteractor
import com.android.systemui.scene.shared.model.RemoteUserInput
import com.android.systemui.scene.shared.model.RemoteUserInputAction
import com.android.systemui.scene.shared.model.SceneContainerConfig import com.android.systemui.scene.shared.model.SceneContainerConfig
import com.android.systemui.scene.shared.model.SceneContainerNames import com.android.systemui.scene.shared.model.SceneContainerNames
import com.android.systemui.scene.shared.model.SceneKey import com.android.systemui.scene.shared.model.SceneKey
@@ -217,5 +219,14 @@ class SceneTestUtils(
companion object { companion object {
const val CONTAINER_1 = SceneContainerNames.SYSTEM_UI_DEFAULT const val CONTAINER_1 = SceneContainerNames.SYSTEM_UI_DEFAULT
const val CONTAINER_2 = "container2" const val CONTAINER_2 = "container2"
val REMOTE_INPUT_DOWN_GESTURE =
listOf(
RemoteUserInput(10f, 10f, RemoteUserInputAction.DOWN),
RemoteUserInput(10f, 20f, RemoteUserInputAction.MOVE),
RemoteUserInput(10f, 30f, RemoteUserInputAction.MOVE),
RemoteUserInput(10f, 40f, RemoteUserInputAction.MOVE),
RemoteUserInput(10f, 40f, RemoteUserInputAction.UP),
)
} }
} }