summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author William Xiao <wxyz@google.com> 2023-11-30 17:26:52 -0800
committer William Xiao <wxyz@google.com> 2023-12-04 09:29:00 -0800
commitc7f9b63ea0f6198e5753c9e2159e17bdde6bb1a8 (patch)
treeec627d0431787f5642d1647c4c00ac7efbcd9b2e
parent0eb4962e8755a7379c10a0d25bf822f31557bfa4 (diff)
Forward CommunalContainer touches when hub mode closed
CommunalContainer is currently placed above keyguard in the SysUI window. Our SceneContainerLayout consumes all touches it receives even when hub mode is closed and only the edge swipe gesture is active. This also causes the screen timeout to not be refreshed for touches in hub mode. This change forwards touches outside the edge swipe zone to the ShadeViewController so that some basics like swipe down to open the notifications or up to show the bouncer will work. We also send a user activity event to PowerManager to refresh the screen timeout. This is only intended as a temporary improvement while we figure out the details of moving CommunalContainer to a lower z-order, where it will no longer block touches. Note that taps and gestures on lock screen notifications or in the notification shade still do not work as those are not handled by ShadeViewController. DefaultCommunalHubSection is cleaned up a bit as it causes a circular dependency otherwise. It is slated for deletion in b/306485186. Bug: 308813166 Bug: 309170620 Fixed: 309170620 Flag: ACONFIG com.android.systemui.communal_hub DEVELOPMENT Test: atest CommunalViewModelTest CommunalEditModeViewModelTest also manually verified on device that swipe up/down work on lock screen with communal_hub flag on Change-Id: I231b150f42c10f7973a721e0b92e895f36999ff1
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContainer.kt79
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalEditModeViewModelTest.kt6
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalViewModelTest.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/ui/view/layout/sections/DefaultCommunalHubSection.kt55
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/BaseCommunalViewModel.kt26
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalEditModeViewModel.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt6
7 files changed, 108 insertions, 76 deletions
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContainer.kt b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContainer.kt
index 2c4dc806f468..185a06c70f9e 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContainer.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContainer.kt
@@ -7,6 +7,7 @@ import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.width
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Close
@@ -19,8 +20,10 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
+import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.input.pointer.pointerInteropFilter
import androidx.compose.ui.unit.dp
import com.android.compose.animation.scene.Edge
import com.android.compose.animation.scene.ElementKey
@@ -28,6 +31,7 @@ import com.android.compose.animation.scene.FixedSizeEdgeDetector
import com.android.compose.animation.scene.SceneKey
import com.android.compose.animation.scene.SceneScope
import com.android.compose.animation.scene.SceneTransitionLayout
+import com.android.compose.animation.scene.SceneTransitionLayoutState
import com.android.compose.animation.scene.Swipe
import com.android.compose.animation.scene.SwipeDirection
import com.android.compose.animation.scene.transitions
@@ -56,6 +60,7 @@ val sceneTransitions = transitions {
* This is a temporary container to allow the communal UI to use [SceneTransitionLayout] for gesture
* handling and transitions before the full Flexiglass layout is ready.
*/
+@OptIn(ExperimentalComposeUiApi::class)
@Composable
fun CommunalContainer(
modifier: Modifier = Modifier,
@@ -65,6 +70,7 @@ fun CommunalContainer(
viewModel.currentScene
.transform<CommunalSceneKey, SceneKey> { value -> value.toTransitionSceneKey() }
.collectAsState(TransitionSceneKey.Blank)
+ val sceneTransitionLayoutState = remember { SceneTransitionLayoutState(currentScene) }
// Don't show hub mode UI if keyguard is present. This is important since we're in the shade,
// which can be opened from many locations.
val isKeyguardShowing by viewModel.isKeyguardVisible.collectAsState(initial = false)
@@ -75,32 +81,59 @@ fun CommunalContainer(
return
}
- SceneTransitionLayout(
- modifier = modifier.fillMaxSize(),
- currentScene = currentScene,
- onChangeScene = { sceneKey -> viewModel.onSceneChanged(sceneKey.toCommunalSceneKey()) },
- transitions = sceneTransitions,
- edgeDetector = FixedSizeEdgeDetector(ContainerDimensions.EdgeSwipeSize)
- ) {
- scene(
- TransitionSceneKey.Blank,
- userActions =
- mapOf(
- Swipe(SwipeDirection.Left, fromEdge = Edge.Right) to TransitionSceneKey.Communal
- )
+ Box(modifier = modifier.fillMaxSize()) {
+ SceneTransitionLayout(
+ modifier = Modifier.fillMaxSize(),
+ currentScene = currentScene,
+ onChangeScene = { sceneKey -> viewModel.onSceneChanged(sceneKey.toCommunalSceneKey()) },
+ transitions = sceneTransitions,
+ state = sceneTransitionLayoutState,
+ edgeDetector = FixedSizeEdgeDetector(ContainerDimensions.EdgeSwipeSize)
) {
- BlankScene { showSceneTransitionLayout = false }
- }
+ scene(
+ TransitionSceneKey.Blank,
+ userActions =
+ mapOf(
+ Swipe(SwipeDirection.Left, fromEdge = Edge.Right) to
+ TransitionSceneKey.Communal
+ )
+ ) {
+ BlankScene { showSceneTransitionLayout = false }
+ }
- scene(
- TransitionSceneKey.Communal,
- userActions =
- mapOf(
- Swipe(SwipeDirection.Right, fromEdge = Edge.Left) to TransitionSceneKey.Blank
- ),
- ) {
- CommunalScene(viewModel, modifier = modifier)
+ scene(
+ TransitionSceneKey.Communal,
+ userActions =
+ mapOf(
+ Swipe(SwipeDirection.Right, fromEdge = Edge.Left) to
+ TransitionSceneKey.Blank
+ ),
+ ) {
+ CommunalScene(viewModel, modifier = modifier)
+ }
}
+
+ // TODO(b/308813166): remove once CommunalContainer is moved lower in z-order and doesn't
+ // block touches anymore.
+ Box(
+ modifier =
+ Modifier.fillMaxSize()
+ // Offsetting to the left so that edge swipe to open the hub still works. This
+ // does mean that the very right edge of the hub won't refresh the screen
+ // timeout, but should be good enough for a temporary solution.
+ .offset(x = -ContainerDimensions.EdgeSwipeSize)
+ .pointerInteropFilter {
+ viewModel.onUserActivity()
+ if (
+ sceneTransitionLayoutState.transitionState.currentScene ==
+ TransitionSceneKey.Blank
+ ) {
+ viewModel.onOuterTouch(it)
+ return@pointerInteropFilter true
+ }
+ false
+ }
+ )
}
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalEditModeViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalEditModeViewModelTest.kt
index ce7db80db7da..ea3006f0b502 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalEditModeViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalEditModeViewModelTest.kt
@@ -17,6 +17,7 @@
package com.android.systemui.communal.view.viewmodel
import android.app.smartspace.SmartspaceTarget
+import android.os.PowerManager
import android.provider.Settings
import android.widget.RemoteViews
import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -33,6 +34,7 @@ import com.android.systemui.communal.ui.viewmodel.CommunalEditModeViewModel
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
import com.android.systemui.media.controls.ui.MediaHost
+import com.android.systemui.shade.ShadeViewController
import com.android.systemui.smartspace.data.repository.FakeSmartspaceRepository
import com.android.systemui.util.mockito.mock
import com.android.systemui.util.mockito.whenever
@@ -50,6 +52,8 @@ import org.mockito.MockitoAnnotations
@RunWith(AndroidJUnit4::class)
class CommunalEditModeViewModelTest : SysuiTestCase() {
@Mock private lateinit var mediaHost: MediaHost
+ @Mock private lateinit var shadeViewController: ShadeViewController
+ @Mock private lateinit var powerManager: PowerManager
private lateinit var testScope: TestScope
@@ -79,6 +83,8 @@ class CommunalEditModeViewModelTest : SysuiTestCase() {
underTest =
CommunalEditModeViewModel(
withDeps.communalInteractor,
+ shadeViewController,
+ powerManager,
mediaHost,
)
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalViewModelTest.kt
index 32f4d075a873..9bd083501780 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalViewModelTest.kt
@@ -17,6 +17,7 @@
package com.android.systemui.communal.view.viewmodel
import android.app.smartspace.SmartspaceTarget
+import android.os.PowerManager
import android.provider.Settings
import android.widget.RemoteViews
import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -33,6 +34,7 @@ import com.android.systemui.communal.ui.viewmodel.CommunalViewModel
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
import com.android.systemui.media.controls.ui.MediaHost
+import com.android.systemui.shade.ShadeViewController
import com.android.systemui.smartspace.data.repository.FakeSmartspaceRepository
import com.android.systemui.util.mockito.mock
import com.android.systemui.util.mockito.whenever
@@ -50,6 +52,8 @@ import org.mockito.MockitoAnnotations
@RunWith(AndroidJUnit4::class)
class CommunalViewModelTest : SysuiTestCase() {
@Mock private lateinit var mediaHost: MediaHost
+ @Mock private lateinit var shadeViewController: ShadeViewController
+ @Mock private lateinit var powerManager: PowerManager
private lateinit var testScope: TestScope
@@ -80,6 +84,8 @@ class CommunalViewModelTest : SysuiTestCase() {
CommunalViewModel(
withDeps.communalInteractor,
withDeps.tutorialInteractor,
+ shadeViewController,
+ powerManager,
mediaHost,
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/ui/view/layout/sections/DefaultCommunalHubSection.kt b/packages/SystemUI/src/com/android/systemui/communal/ui/view/layout/sections/DefaultCommunalHubSection.kt
index ad02f6280a64..4219d6d6f397 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/ui/view/layout/sections/DefaultCommunalHubSection.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/ui/view/layout/sections/DefaultCommunalHubSection.kt
@@ -2,63 +2,16 @@ package com.android.systemui.communal.ui.view.layout.sections
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.constraintlayout.widget.ConstraintSet
-import com.android.systemui.communal.ui.viewmodel.CommunalViewModel
-import com.android.systemui.compose.ComposeFacade
import com.android.systemui.keyguard.shared.model.KeyguardSection
-import com.android.systemui.keyguard.ui.view.layout.sections.removeView
-import com.android.systemui.res.R
import javax.inject.Inject
/** A keyguard section that hosts the communal hub. */
-class DefaultCommunalHubSection
-@Inject
-constructor(
- private val viewModel: CommunalViewModel,
-) : KeyguardSection() {
- private val communalHubViewId = R.id.communal_hub
-
- override fun addViews(constraintLayout: ConstraintLayout) {
- constraintLayout.addView(
- ComposeFacade.createCommunalView(
- context = constraintLayout.context,
- viewModel = viewModel,
- )
- .apply { id = communalHubViewId },
- )
- }
+class DefaultCommunalHubSection @Inject constructor() : KeyguardSection() {
+ override fun addViews(constraintLayout: ConstraintLayout) {}
override fun bindData(constraintLayout: ConstraintLayout) {}
- override fun applyConstraints(constraintSet: ConstraintSet) {
- constraintSet.apply {
- connect(
- communalHubViewId,
- ConstraintSet.START,
- ConstraintSet.PARENT_ID,
- ConstraintSet.START,
- )
- connect(
- communalHubViewId,
- ConstraintSet.TOP,
- ConstraintSet.PARENT_ID,
- ConstraintSet.TOP,
- )
- connect(
- communalHubViewId,
- ConstraintSet.END,
- ConstraintSet.PARENT_ID,
- ConstraintSet.END,
- )
- connect(
- communalHubViewId,
- ConstraintSet.BOTTOM,
- ConstraintSet.PARENT_ID,
- ConstraintSet.BOTTOM,
- )
- }
- }
+ override fun applyConstraints(constraintSet: ConstraintSet) {}
- override fun removeViews(constraintLayout: ConstraintLayout) {
- constraintLayout.removeView(communalHubViewId)
- }
+ override fun removeViews(constraintLayout: ConstraintLayout) {}
}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/BaseCommunalViewModel.kt b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/BaseCommunalViewModel.kt
index 4d8e893cb747..bed42833a1d4 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/BaseCommunalViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/BaseCommunalViewModel.kt
@@ -16,16 +16,22 @@
package com.android.systemui.communal.ui.viewmodel
+import android.os.PowerManager
+import android.os.SystemClock
+import android.view.MotionEvent
import com.android.systemui.communal.domain.interactor.CommunalInteractor
import com.android.systemui.communal.domain.model.CommunalContentModel
import com.android.systemui.communal.shared.model.CommunalSceneKey
import com.android.systemui.media.controls.ui.MediaHost
+import com.android.systemui.shade.ShadeViewController
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.StateFlow
/** The base view model for the communal hub. */
abstract class BaseCommunalViewModel(
private val communalInteractor: CommunalInteractor,
+ private val shadeViewController: ShadeViewController,
+ private val powerManager: PowerManager,
val mediaHost: MediaHost,
) {
val isKeyguardVisible: Flow<Boolean> = communalInteractor.isKeyguardVisible
@@ -36,6 +42,26 @@ abstract class BaseCommunalViewModel(
communalInteractor.onSceneChanged(scene)
}
+ // TODO(b/308813166): remove once CommunalContainer is moved lower in z-order and doesn't block
+ // touches anymore.
+ /** Called when a touch is received outside the edge swipe area when hub mode is closed. */
+ fun onOuterTouch(motionEvent: MotionEvent) {
+ // Forward the touch to the shade so that basic gestures like swipe up/down for
+ // shade/bouncer work.
+ shadeViewController.handleExternalTouch(motionEvent)
+ }
+
+ // TODO(b/308813166): remove once CommunalContainer is moved lower in z-order and doesn't block
+ // touches anymore.
+ /** Called to refresh the screen timeout when a user touch is received. */
+ fun onUserActivity() {
+ powerManager.userActivity(
+ SystemClock.uptimeMillis(),
+ PowerManager.USER_ACTIVITY_EVENT_TOUCH,
+ 0
+ )
+ }
+
/** A list of all the communal content to be displayed in the communal hub. */
abstract val communalContent: Flow<List<CommunalContentModel>>
diff --git a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalEditModeViewModel.kt b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalEditModeViewModel.kt
index 111f8b4ca48f..b6843c529180 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalEditModeViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalEditModeViewModel.kt
@@ -16,11 +16,13 @@
package com.android.systemui.communal.ui.viewmodel
+import android.os.PowerManager
import com.android.systemui.communal.domain.interactor.CommunalInteractor
import com.android.systemui.communal.domain.model.CommunalContentModel
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.media.controls.ui.MediaHost
import com.android.systemui.media.dagger.MediaModule
+import com.android.systemui.shade.ShadeViewController
import javax.inject.Inject
import javax.inject.Named
import kotlinx.coroutines.flow.Flow
@@ -31,8 +33,10 @@ class CommunalEditModeViewModel
@Inject
constructor(
private val communalInteractor: CommunalInteractor,
+ shadeViewController: ShadeViewController,
+ powerManager: PowerManager,
@Named(MediaModule.COMMUNAL_HUB) mediaHost: MediaHost,
-) : BaseCommunalViewModel(communalInteractor, mediaHost) {
+) : BaseCommunalViewModel(communalInteractor, shadeViewController, powerManager, mediaHost) {
override val isEditMode = true
diff --git a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt
index 11bde6bd7af0..d7dcdb9ea4f0 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt
@@ -16,12 +16,14 @@
package com.android.systemui.communal.ui.viewmodel
+import android.os.PowerManager
import com.android.systemui.communal.domain.interactor.CommunalInteractor
import com.android.systemui.communal.domain.interactor.CommunalTutorialInteractor
import com.android.systemui.communal.domain.model.CommunalContentModel
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.media.controls.ui.MediaHost
import com.android.systemui.media.dagger.MediaModule
+import com.android.systemui.shade.ShadeViewController
import javax.inject.Inject
import javax.inject.Named
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -37,8 +39,10 @@ class CommunalViewModel
constructor(
private val communalInteractor: CommunalInteractor,
tutorialInteractor: CommunalTutorialInteractor,
+ shadeViewController: ShadeViewController,
+ powerManager: PowerManager,
@Named(MediaModule.COMMUNAL_HUB) mediaHost: MediaHost,
-) : BaseCommunalViewModel(communalInteractor, mediaHost) {
+) : BaseCommunalViewModel(communalInteractor, shadeViewController, powerManager, mediaHost) {
@OptIn(ExperimentalCoroutinesApi::class)
override val communalContent: Flow<List<CommunalContentModel>> =
tutorialInteractor.isTutorialAvailable.flatMapLatest { isTutorialMode ->