Loading packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainer.kt +8 −8 Original line number Diff line number Diff line Loading @@ -92,6 +92,14 @@ private fun Scene( onSceneChanged: (SceneModel) -> Unit, 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. Box(modifier) { Column( Loading @@ -103,14 +111,6 @@ private fun Scene( 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( horizontalArrangement = Arrangement.spacedBy(8.dp), ) { Loading packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java +31 −8 Original line number Diff line number Diff line Loading @@ -84,6 +84,8 @@ import com.android.systemui.Dumpable; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Main; 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.ScreenLifecycle; import com.android.systemui.keyguard.WakefulnessLifecycle; Loading @@ -94,6 +96,8 @@ import com.android.systemui.navigationbar.NavigationBarView; import com.android.systemui.navigationbar.NavigationModeController; import com.android.systemui.navigationbar.buttons.KeyButtonView; import com.android.systemui.recents.OverviewProxyService.OverviewProxyListener; import com.android.systemui.scene.domain.interactor.SceneInteractor; import com.android.systemui.scene.shared.model.SceneContainerNames; import com.android.systemui.settings.DisplayTracker; import com.android.systemui.settings.UserTracker; import com.android.systemui.shade.ShadeViewController; Loading @@ -120,6 +124,7 @@ import java.util.concurrent.Executor; import java.util.function.Supplier; import javax.inject.Inject; import javax.inject.Provider; /** * Class to send information from overview to launcher with a binder. Loading @@ -139,6 +144,7 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis private static final long MAX_BACKOFF_MILLIS = 10 * 60 * 1000; private final Context mContext; private final FeatureFlags mFeatureFlags; private final Executor mMainExecutor; private final ShellInterface mShellInterface; private final Lazy<Optional<CentralSurfaces>> mCentralSurfacesOptionalLazy; Loading @@ -147,6 +153,8 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis private final Handler mHandler; private final Lazy<NavigationBarController> mNavBarControllerLazy; private final NotificationShadeWindowController mStatusBarWinController; private final Provider<SceneInteractor> mSceneInteractor; private final Runnable mConnectionRunnable = () -> internalConnectToCurrentUser("runnable: startConnectionToCurrentUser"); private final ComponentName mRecentsComponentName; Loading Loading @@ -209,18 +217,29 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis mInputFocusTransferStarted = true; mInputFocusTransferStartY = event.getY(); 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( mInputFocusTransferStarted, false /* cancel */, 0 /* velocity */); } } if (action == ACTION_UP || action == ACTION_CANCEL) { mInputFocusTransferStarted = false; if (!mFeatureFlags.isEnabled(Flags.SCENE_CONTAINER)) { float velocity = (event.getY() - mInputFocusTransferStartY) / (event.getEventTime() - mInputFocusTransferStartMillis); centralSurfaces.onInputFocusTransfer(mInputFocusTransferStarted, action == ACTION_CANCEL, velocity); } } event.recycle(); }); }); Loading Loading @@ -552,6 +571,7 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis NavigationModeController navModeController, NotificationShadeWindowController statusBarWinController, SysUiState sysUiState, Provider<SceneInteractor> sceneInteractor, UserTracker userTracker, ScreenLifecycle screenLifecycle, WakefulnessLifecycle wakefulnessLifecycle, Loading @@ -559,6 +579,7 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis DisplayTracker displayTracker, KeyguardUnlockAnimationController sysuiUnlockAnimationController, AssistUtils assistUtils, FeatureFlags featureFlags, DumpManager dumpManager, Optional<UnfoldTransitionProgressForwarder> unfoldTransitionProgressForwarder ) { Loading @@ -568,6 +589,7 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis } mContext = context; mFeatureFlags = featureFlags; mMainExecutor = mainExecutor; mShellInterface = shellInterface; mCentralSurfacesOptionalLazy = centralSurfacesOptionalLazy; Loading @@ -575,6 +597,7 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis mHandler = new Handler(); mNavBarControllerLazy = navBarControllerLazy; mStatusBarWinController = statusBarWinController; mSceneInteractor = sceneInteractor; mUserTracker = userTracker; mConnectionBackoffAttempts = 0; mRecentsComponentName = ComponentName.unflattenFromString(context.getString( Loading packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneInteractor.kt +13 −0 Original line number Diff line number Diff line Loading @@ -18,11 +18,14 @@ package com.android.systemui.scene.domain.interactor import com.android.systemui.dagger.SysUISingleton 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.SceneModel import com.android.systemui.scene.shared.model.SceneTransitionModel import javax.inject.Inject import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow /** * Generic business logic and app state accessors for the scene framework. Loading Loading @@ -92,4 +95,14 @@ constructor( fun sceneTransitions(containerName: String): StateFlow<SceneTransitionModel?> { 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 } } packages/SystemUI/src/com/android/systemui/scene/shared/model/RemoteUserInput.kt 0 → 100644 +35 −0 Original line number Diff line number Diff line 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, } packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootView.kt +13 −0 Original line number Diff line number Diff line Loading @@ -2,6 +2,7 @@ package com.android.systemui.scene.ui.view import android.content.Context import android.util.AttributeSet import android.view.MotionEvent import android.view.View import com.android.systemui.scene.shared.model.Scene import com.android.systemui.scene.shared.model.SceneContainerConfig Loading @@ -16,11 +17,15 @@ class SceneWindowRootView( context, attrs, ) { private lateinit var viewModel: SceneContainerViewModel fun init( viewModel: SceneContainerViewModel, containerConfig: SceneContainerConfig, scenes: Set<Scene>, ) { this.viewModel = viewModel SceneWindowRootViewBinder.bind( view = this@SceneWindowRootView, viewModel = viewModel, Loading @@ -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) { // Do nothing. We don't want external callers to invoke this. Instead, we drive our own // visibility from our view-binder. Loading Loading
packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainer.kt +8 −8 Original line number Diff line number Diff line Loading @@ -92,6 +92,14 @@ private fun Scene( onSceneChanged: (SceneModel) -> Unit, 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. Box(modifier) { Column( Loading @@ -103,14 +111,6 @@ private fun Scene( 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( horizontalArrangement = Arrangement.spacedBy(8.dp), ) { Loading
packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java +31 −8 Original line number Diff line number Diff line Loading @@ -84,6 +84,8 @@ import com.android.systemui.Dumpable; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Main; 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.ScreenLifecycle; import com.android.systemui.keyguard.WakefulnessLifecycle; Loading @@ -94,6 +96,8 @@ import com.android.systemui.navigationbar.NavigationBarView; import com.android.systemui.navigationbar.NavigationModeController; import com.android.systemui.navigationbar.buttons.KeyButtonView; import com.android.systemui.recents.OverviewProxyService.OverviewProxyListener; import com.android.systemui.scene.domain.interactor.SceneInteractor; import com.android.systemui.scene.shared.model.SceneContainerNames; import com.android.systemui.settings.DisplayTracker; import com.android.systemui.settings.UserTracker; import com.android.systemui.shade.ShadeViewController; Loading @@ -120,6 +124,7 @@ import java.util.concurrent.Executor; import java.util.function.Supplier; import javax.inject.Inject; import javax.inject.Provider; /** * Class to send information from overview to launcher with a binder. Loading @@ -139,6 +144,7 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis private static final long MAX_BACKOFF_MILLIS = 10 * 60 * 1000; private final Context mContext; private final FeatureFlags mFeatureFlags; private final Executor mMainExecutor; private final ShellInterface mShellInterface; private final Lazy<Optional<CentralSurfaces>> mCentralSurfacesOptionalLazy; Loading @@ -147,6 +153,8 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis private final Handler mHandler; private final Lazy<NavigationBarController> mNavBarControllerLazy; private final NotificationShadeWindowController mStatusBarWinController; private final Provider<SceneInteractor> mSceneInteractor; private final Runnable mConnectionRunnable = () -> internalConnectToCurrentUser("runnable: startConnectionToCurrentUser"); private final ComponentName mRecentsComponentName; Loading Loading @@ -209,18 +217,29 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis mInputFocusTransferStarted = true; mInputFocusTransferStartY = event.getY(); 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( mInputFocusTransferStarted, false /* cancel */, 0 /* velocity */); } } if (action == ACTION_UP || action == ACTION_CANCEL) { mInputFocusTransferStarted = false; if (!mFeatureFlags.isEnabled(Flags.SCENE_CONTAINER)) { float velocity = (event.getY() - mInputFocusTransferStartY) / (event.getEventTime() - mInputFocusTransferStartMillis); centralSurfaces.onInputFocusTransfer(mInputFocusTransferStarted, action == ACTION_CANCEL, velocity); } } event.recycle(); }); }); Loading Loading @@ -552,6 +571,7 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis NavigationModeController navModeController, NotificationShadeWindowController statusBarWinController, SysUiState sysUiState, Provider<SceneInteractor> sceneInteractor, UserTracker userTracker, ScreenLifecycle screenLifecycle, WakefulnessLifecycle wakefulnessLifecycle, Loading @@ -559,6 +579,7 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis DisplayTracker displayTracker, KeyguardUnlockAnimationController sysuiUnlockAnimationController, AssistUtils assistUtils, FeatureFlags featureFlags, DumpManager dumpManager, Optional<UnfoldTransitionProgressForwarder> unfoldTransitionProgressForwarder ) { Loading @@ -568,6 +589,7 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis } mContext = context; mFeatureFlags = featureFlags; mMainExecutor = mainExecutor; mShellInterface = shellInterface; mCentralSurfacesOptionalLazy = centralSurfacesOptionalLazy; Loading @@ -575,6 +597,7 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis mHandler = new Handler(); mNavBarControllerLazy = navBarControllerLazy; mStatusBarWinController = statusBarWinController; mSceneInteractor = sceneInteractor; mUserTracker = userTracker; mConnectionBackoffAttempts = 0; mRecentsComponentName = ComponentName.unflattenFromString(context.getString( Loading
packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneInteractor.kt +13 −0 Original line number Diff line number Diff line Loading @@ -18,11 +18,14 @@ package com.android.systemui.scene.domain.interactor import com.android.systemui.dagger.SysUISingleton 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.SceneModel import com.android.systemui.scene.shared.model.SceneTransitionModel import javax.inject.Inject import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow /** * Generic business logic and app state accessors for the scene framework. Loading Loading @@ -92,4 +95,14 @@ constructor( fun sceneTransitions(containerName: String): StateFlow<SceneTransitionModel?> { 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 } }
packages/SystemUI/src/com/android/systemui/scene/shared/model/RemoteUserInput.kt 0 → 100644 +35 −0 Original line number Diff line number Diff line 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, }
packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootView.kt +13 −0 Original line number Diff line number Diff line Loading @@ -2,6 +2,7 @@ package com.android.systemui.scene.ui.view import android.content.Context import android.util.AttributeSet import android.view.MotionEvent import android.view.View import com.android.systemui.scene.shared.model.Scene import com.android.systemui.scene.shared.model.SceneContainerConfig Loading @@ -16,11 +17,15 @@ class SceneWindowRootView( context, attrs, ) { private lateinit var viewModel: SceneContainerViewModel fun init( viewModel: SceneContainerViewModel, containerConfig: SceneContainerConfig, scenes: Set<Scene>, ) { this.viewModel = viewModel SceneWindowRootViewBinder.bind( view = this@SceneWindowRootView, viewModel = viewModel, Loading @@ -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) { // Do nothing. We don't want external callers to invoke this. Instead, we drive our own // visibility from our view-binder. Loading