Merge "Remove CommunalContainer touch forwarding" into main
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 d47527a..2fea6a5 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,7 +7,6 @@
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
@@ -21,10 +20,8 @@
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
@@ -41,7 +38,6 @@
import com.android.systemui.communal.shared.model.CommunalSceneKey
import com.android.systemui.communal.shared.model.ObservableCommunalTransitionState
import com.android.systemui.communal.ui.viewmodel.BaseCommunalViewModel
-import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.transform
@@ -66,7 +62,6 @@
* 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, ExperimentalCoroutinesApi::class)
@Composable
fun CommunalContainer(
modifier: Modifier = Modifier,
@@ -83,8 +78,8 @@
transitions = sceneTransitions,
)
- // 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.
+ // Don't show hub mode UI if keyguard is not 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)
// Failsafe to hide the whole SceneTransitionLayout in case of bugginess.
@@ -102,56 +97,30 @@
onDispose { viewModel.setTransitionState(null) }
}
- Box(modifier = modifier.fillMaxSize()) {
- SceneTransitionLayout(
- state = sceneTransitionLayoutState,
- modifier = Modifier.fillMaxSize(),
- edgeDetector = FixedSizeEdgeDetector(ContainerDimensions.EdgeSwipeSize),
+ SceneTransitionLayout(
+ state = sceneTransitionLayoutState,
+ modifier = modifier.fillMaxSize(),
+ edgeDetector = FixedSizeEdgeDetector(ContainerDimensions.EdgeSwipeSize),
+ ) {
+ scene(
+ TransitionSceneKey.Blank,
+ userActions =
+ mapOf(
+ Swipe(SwipeDirection.Left, fromEdge = Edge.Right) to TransitionSceneKey.Communal
+ )
) {
- 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)
- }
+ BlankScene { showSceneTransitionLayout = false }
}
- // 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
- }
- )
+ scene(
+ TransitionSceneKey.Communal,
+ userActions =
+ mapOf(
+ Swipe(SwipeDirection.Right, fromEdge = Edge.Left) to TransitionSceneKey.Blank
+ ),
+ ) {
+ CommunalScene(viewModel, modifier = modifier)
+ }
}
}
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 ff6fd43..54510a8 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
@@ -21,7 +21,6 @@
import android.app.smartspace.SmartspaceTarget
import android.appwidget.AppWidgetHost
import android.content.ComponentName
-import android.os.PowerManager
import android.provider.Settings
import android.widget.RemoteViews
import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -41,13 +40,11 @@
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
import com.android.systemui.kosmos.testScope
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.testKosmos
import com.android.systemui.util.mockito.mock
import com.android.systemui.util.mockito.whenever
import com.google.common.truth.Truth.assertThat
-import javax.inject.Provider
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
@@ -64,8 +61,6 @@
@RunWith(AndroidJUnit4::class)
class CommunalEditModeViewModelTest : SysuiTestCase() {
@Mock private lateinit var mediaHost: MediaHost
- @Mock private lateinit var shadeViewController: ShadeViewController
- @Mock private lateinit var powerManager: PowerManager
@Mock private lateinit var appWidgetHost: AppWidgetHost
@Mock private lateinit var uiEventLogger: UiEventLogger
@@ -97,8 +92,6 @@
CommunalEditModeViewModel(
withDeps.communalInteractor,
appWidgetHost,
- Provider { shadeViewController },
- powerManager,
mediaHost,
uiEventLogger,
)
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 8e3f664..a776062 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,7 +17,6 @@
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
@@ -36,12 +35,10 @@
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
import com.google.common.truth.Truth.assertThat
-import javax.inject.Provider
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.advanceTimeBy
@@ -58,8 +55,6 @@
@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
@@ -92,8 +87,6 @@
withDeps.communalInteractor,
WidgetInteractionHandler(mock()),
withDeps.tutorialInteractor,
- Provider { shadeViewController },
- powerManager,
mediaHost,
)
}
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 28f48ce..84708a4 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
@@ -17,17 +17,12 @@
package com.android.systemui.communal.ui.viewmodel
import android.content.ComponentName
-import android.os.PowerManager
-import android.os.SystemClock
-import android.view.MotionEvent
import android.widget.RemoteViews
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.communal.shared.model.ObservableCommunalTransitionState
import com.android.systemui.media.controls.ui.MediaHost
-import com.android.systemui.shade.ShadeViewController
-import javax.inject.Provider
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.flowOf
@@ -35,8 +30,6 @@
/** The base view model for the communal hub. */
abstract class BaseCommunalViewModel(
private val communalInteractor: CommunalInteractor,
- private val shadeViewController: Provider<ShadeViewController>,
- private val powerManager: PowerManager,
val mediaHost: MediaHost,
) {
val isKeyguardVisible: Flow<Boolean> = communalInteractor.isKeyguardVisible
@@ -71,26 +64,6 @@
return true
}
- // 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.get().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 0cbf3f13..7faf653 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
@@ -23,7 +23,6 @@
import android.appwidget.AppWidgetHost
import android.content.ActivityNotFoundException
import android.content.ComponentName
-import android.os.PowerManager
import android.widget.RemoteViews
import com.android.internal.logging.UiEventLogger
import com.android.systemui.communal.domain.interactor.CommunalInteractor
@@ -32,11 +31,9 @@
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 com.android.systemui.util.nullableAtomicReference
import javax.inject.Inject
import javax.inject.Named
-import javax.inject.Provider
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableSharedFlow
@@ -49,11 +46,9 @@
constructor(
private val communalInteractor: CommunalInteractor,
private val appWidgetHost: AppWidgetHost,
- shadeViewController: Provider<ShadeViewController>,
- powerManager: PowerManager,
@Named(MediaModule.COMMUNAL_HUB) mediaHost: MediaHost,
private val uiEventLogger: UiEventLogger,
-) : BaseCommunalViewModel(communalInteractor, shadeViewController, powerManager, mediaHost) {
+) : BaseCommunalViewModel(communalInteractor, mediaHost) {
private companion object {
private const val KEY_SPLASH_SCREEN_STYLE = "android.activity.splashScreenStyle"
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 1c69685..7a96fab 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,7 +16,6 @@
package com.android.systemui.communal.ui.viewmodel
-import android.os.PowerManager
import android.widget.RemoteViews
import com.android.systemui.communal.domain.interactor.CommunalInteractor
import com.android.systemui.communal.domain.interactor.CommunalTutorialInteractor
@@ -26,10 +25,8 @@
import com.android.systemui.dagger.qualifiers.Application
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 javax.inject.Provider
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.Job
@@ -51,10 +48,8 @@
private val communalInteractor: CommunalInteractor,
private val interactionHandler: WidgetInteractionHandler,
tutorialInteractor: CommunalTutorialInteractor,
- shadeViewController: Provider<ShadeViewController>,
- powerManager: PowerManager,
@Named(MediaModule.COMMUNAL_HUB) mediaHost: MediaHost,
-) : BaseCommunalViewModel(communalInteractor, shadeViewController, powerManager, mediaHost) {
+) : BaseCommunalViewModel(communalInteractor, mediaHost) {
@OptIn(ExperimentalCoroutinesApi::class)
override val communalContent: Flow<List<CommunalContentModel>> =
tutorialInteractor.isTutorialAvailable.flatMapLatest { isTutorialMode ->
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaHierarchyManager.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaHierarchyManager.kt
index 0385aeb..523414c 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaHierarchyManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaHierarchyManager.kt
@@ -1153,7 +1153,7 @@
qsExpansion > 0.4f && onLockscreen -> LOCATION_QS
onLockscreen && isSplitShadeExpanding() -> LOCATION_QS
onLockscreen && isTransformingToFullShadeAndInQQS() -> LOCATION_QQS
- // TODO(b/308813166): revisit logic once interactions between the hub and
+ // TODO(b/311234666): revisit logic once interactions between the hub and
// shade/keyguard state are finalized
isCommunalShowing && communalInteractor.isCommunalEnabled -> LOCATION_COMMUNAL_HUB
onLockscreen && allowMediaPlayerOnLockScreen -> LOCATION_LOCKSCREEN
diff --git a/packages/SystemUI/src/com/android/systemui/shade/GlanceableHubContainerController.kt b/packages/SystemUI/src/com/android/systemui/shade/GlanceableHubContainerController.kt
index 3be60b7..782d651 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/GlanceableHubContainerController.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/GlanceableHubContainerController.kt
@@ -17,6 +17,8 @@
package com.android.systemui.shade
import android.content.Context
+import android.os.PowerManager
+import android.os.SystemClock
import android.view.GestureDetector
import android.view.MotionEvent
import android.view.View
@@ -44,6 +46,7 @@
private val communalViewModel: CommunalViewModel,
private val keyguardTransitionInteractor: KeyguardTransitionInteractor,
private val shadeInteractor: ShadeInteractor,
+ private val powerManager: PowerManager,
) {
/** The container view for the hub. This will not be initialized until [initView] is called. */
private lateinit var communalContainerView: View
@@ -157,7 +160,7 @@
// If the hub is fully visible, send all touch events to it.
val communalVisible = hubShowing && !hubOccluded
if (communalVisible) {
- communalContainerView.dispatchTouchEvent(ev)
+ dispatchTouchEvent(ev)
// Return true regardless of dispatch result as some touches at the start of a gesture
// may return false from dispatchTouchEvent.
return true
@@ -175,7 +178,7 @@
x >= communalContainerView.width - edgeSwipeRegionWidth
if (inOpeningSwipeRegion && !hubOccluded) {
isTrackingOpenGesture = true
- communalContainerView.dispatchTouchEvent(ev)
+ dispatchTouchEvent(ev)
// Return true regardless of dispatch result as some touches at the start of a
// gesture may return false from dispatchTouchEvent.
return true
@@ -184,7 +187,7 @@
if (isUp || isCancel) {
isTrackingOpenGesture = false
}
- communalContainerView.dispatchTouchEvent(ev)
+ dispatchTouchEvent(ev)
// Return true regardless of dispatch result as some touches at the start of a gesture
// may return false from dispatchTouchEvent.
return true
@@ -192,4 +195,17 @@
return false
}
+
+ /**
+ * Dispatches the touch event to the communal container and sends a user activity event to reset
+ * the screen timeout.
+ */
+ private fun dispatchTouchEvent(ev: MotionEvent) {
+ communalContainerView.dispatchTouchEvent(ev)
+ powerManager.userActivity(
+ SystemClock.uptimeMillis(),
+ PowerManager.USER_ACTIVITY_EVENT_TOUCH,
+ 0
+ )
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/GlanceableHubContainerControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/GlanceableHubContainerControllerTest.kt
index 5569ca9..b7a9ea7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/GlanceableHubContainerControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/GlanceableHubContainerControllerTest.kt
@@ -16,6 +16,7 @@
package com.android.systemui.shade
+import android.os.PowerManager
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
import android.testing.ViewUtils
@@ -43,6 +44,8 @@
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
+import org.mockito.Mockito.times
+import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
@RunWith(AndroidTestingRunner::class)
@@ -52,6 +55,7 @@
@Mock private lateinit var communalViewModel: CommunalViewModel
@Mock private lateinit var keyguardTransitionInteractor: KeyguardTransitionInteractor
@Mock private lateinit var shadeInteractor: ShadeInteractor
+ @Mock private lateinit var powerManager: PowerManager
private lateinit var containerView: View
private lateinit var testableLooper: TestableLooper
@@ -76,7 +80,8 @@
communalInteractor,
communalViewModel,
keyguardTransitionInteractor,
- shadeInteractor
+ shadeInteractor,
+ powerManager
)
testableLooper = TestableLooper.get(this)
@@ -90,14 +95,14 @@
}
@Test
- fun isEnabled_interactorEnabled_returnsTrue() {
+ fun isEnabled_interactorEnabled_interceptsTouches() {
communalRepository.setIsCommunalEnabled(true)
assertThat(underTest.isEnabled()).isTrue()
}
@Test
- fun isEnabled_interactorDisabled_returnsFalse() {
+ fun isEnabled_interactorDisabled_doesNotIntercept() {
communalRepository.setIsCommunalEnabled(false)
assertThat(underTest.isEnabled()).isFalse()
@@ -120,7 +125,7 @@
}
@Test
- fun onTouchEvent_touchInsideGestureRegion_returnsTrue() {
+ fun onTouchEvent_touchInsideGestureRegion_interceptsTouches() {
// Communal is open.
communalRepository.setDesiredScene(CommunalSceneKey.Communal)
@@ -131,7 +136,7 @@
}
@Test
- fun onTouchEvent_subsequentTouchesAfterGestureStart_returnsTrue() {
+ fun onTouchEvent_subsequentTouchesAfterGestureStart_interceptsTouches() {
// Communal is open.
communalRepository.setDesiredScene(CommunalSceneKey.Communal)
@@ -146,7 +151,7 @@
}
@Test
- fun onTouchEvent_communalOpen_returnsTrue() {
+ fun onTouchEvent_communalOpen_interceptsTouches() {
// Communal is open.
communalRepository.setDesiredScene(CommunalSceneKey.Communal)
@@ -155,10 +160,12 @@
// Touch events are intercepted.
assertThat(underTest.onTouchEvent(DOWN_EVENT)).isTrue()
+ // User activity sent to PowerManager.
+ verify(powerManager).userActivity(any(), any(), any())
}
@Test
- fun onTouchEvent_communalAndBouncerShowing_returnsFalse() {
+ fun onTouchEvent_communalAndBouncerShowing_doesNotIntercept() {
// Communal is open.
communalRepository.setDesiredScene(CommunalSceneKey.Communal)
@@ -170,10 +177,12 @@
// Touch events are not intercepted.
assertThat(underTest.onTouchEvent(DOWN_EVENT)).isFalse()
+ // User activity is not sent to PowerManager.
+ verify(powerManager, times(0)).userActivity(any(), any(), any())
}
@Test
- fun onTouchEvent_communalAndShadeShowing_returnsFalse() {
+ fun onTouchEvent_communalAndShadeShowing_doesNotIntercept() {
// Communal is open.
communalRepository.setDesiredScene(CommunalSceneKey.Communal)