<lambda>null1 package com.android.systemui.scene.ui.view
2
3 import android.content.Context
4 import android.util.AttributeSet
5 import android.view.MotionEvent
6 import android.view.View
7 import android.view.WindowInsets
8 import com.android.systemui.qs.ui.adapter.QSSceneAdapter
9 import com.android.systemui.scene.shared.model.SceneContainerConfig
10 import com.android.systemui.scene.shared.model.SceneDataSourceDelegator
11 import com.android.systemui.scene.ui.composable.Overlay
12 import com.android.systemui.scene.ui.composable.Scene
13 import com.android.systemui.scene.ui.viewmodel.SceneContainerViewModel
14 import com.android.systemui.shade.TouchLogger
15 import com.android.systemui.statusbar.notification.stack.ui.view.SharedNotificationContainer
16 import javax.inject.Provider
17 import kotlinx.coroutines.ExperimentalCoroutinesApi
18 import kotlinx.coroutines.flow.MutableStateFlow
19
20 /** A root view of the main SysUI window that supports scenes. */
21 @ExperimentalCoroutinesApi
22 class SceneWindowRootView(context: Context, attrs: AttributeSet?) : WindowRootView(context, attrs) {
23
24 private var motionEventHandler: SceneContainerViewModel.MotionEventHandler? = null
25 // TODO(b/298525212): remove once Compose exposes window inset bounds.
26 private val windowInsets: MutableStateFlow<WindowInsets?> = MutableStateFlow(null)
27
28 fun init(
29 viewModelFactory: SceneContainerViewModel.Factory,
30 containerConfig: SceneContainerConfig,
31 sharedNotificationContainer: SharedNotificationContainer,
32 scenes: Set<Scene>,
33 overlays: Set<Overlay>,
34 layoutInsetController: LayoutInsetsController,
35 sceneDataSourceDelegator: SceneDataSourceDelegator,
36 qsSceneAdapter: Provider<QSSceneAdapter>,
37 ) {
38 setLayoutInsetsController(layoutInsetController)
39 SceneWindowRootViewBinder.bind(
40 view = this@SceneWindowRootView,
41 viewModelFactory = viewModelFactory,
42 motionEventHandlerReceiver = { motionEventHandler ->
43 this.motionEventHandler = motionEventHandler
44 },
45 windowInsets = windowInsets,
46 containerConfig = containerConfig,
47 sharedNotificationContainer = sharedNotificationContainer,
48 scenes = scenes,
49 overlays = overlays,
50 onVisibilityChangedInternal = { isVisible ->
51 super.setVisibility(if (isVisible) View.VISIBLE else View.INVISIBLE)
52 },
53 dataSourceDelegator = sceneDataSourceDelegator,
54 qsSceneAdapter = qsSceneAdapter,
55 )
56 }
57
58 override fun setVisibility(visibility: Int) {
59 // Do nothing. We don't want external callers to invoke this. Instead, we drive our own
60 // visibility from our view-binder.
61 }
62
63 // TODO(b/298525212): remove once Compose exposes window inset bounds.
64 override fun onApplyWindowInsets(windowInsets: WindowInsets): WindowInsets {
65 this.windowInsets.value = windowInsets
66 return windowInsets
67 }
68
69 override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
70 motionEventHandler?.onMotionEvent(ev)
71 return super.dispatchTouchEvent(ev).also {
72 TouchLogger.logDispatchTouch(TAG, ev, it)
73 motionEventHandler?.onMotionEventComplete()
74 }
75 }
76
77 override fun onTouchEvent(event: MotionEvent?): Boolean {
78 event?.let { motionEventHandler?.onEmptySpaceMotionEvent(it) }
79 return super.onTouchEvent(event)
80 }
81
82 companion object {
83 private const val TAG = "SceneWindowRootView"
84 }
85 }
86