<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.flow.MutableStateFlow
18
19 /** A root view of the main SysUI window that supports scenes. */
20 class SceneWindowRootView(context: Context, attrs: AttributeSet?) : WindowRootView(context, attrs) {
21
22 private var motionEventHandler: SceneContainerViewModel.MotionEventHandler? = null
23 // TODO(b/298525212): remove once Compose exposes window inset bounds.
24 private val windowInsets: MutableStateFlow<WindowInsets?> = MutableStateFlow(null)
25
26 fun init(
27 viewModelFactory: SceneContainerViewModel.Factory,
28 containerConfig: SceneContainerConfig,
29 sharedNotificationContainer: SharedNotificationContainer,
30 scenes: Set<Scene>,
31 overlays: Set<Overlay>,
32 layoutInsetController: LayoutInsetsController,
33 sceneDataSourceDelegator: SceneDataSourceDelegator,
34 qsSceneAdapter: Provider<QSSceneAdapter>,
35 sceneJankMonitorFactory: SceneJankMonitor.Factory,
36 windowRootViewKeyEventHandler: WindowRootViewKeyEventHandler,
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 sceneJankMonitorFactory = sceneJankMonitorFactory,
56 )
57 setWindowRootViewKeyEventHandler(windowRootViewKeyEventHandler)
58 }
59
60 override fun setVisibility(visibility: Int) {
61 // Do nothing. We don't want external callers to invoke this. Instead, we drive our own
62 // visibility from our view-binder.
63 }
64
65 // TODO(b/298525212): remove once Compose exposes window inset bounds.
66 override fun onApplyWindowInsets(windowInsets: WindowInsets): WindowInsets {
67 this.windowInsets.value = windowInsets
68 return windowInsets
69 }
70
71 override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
72 motionEventHandler?.onMotionEvent(ev)
73 return super.dispatchTouchEvent(ev).also {
74 TouchLogger.logDispatchTouch(TAG, ev, it)
75 motionEventHandler?.onMotionEventComplete()
76 }
77 }
78
79 override fun onTouchEvent(event: MotionEvent?): Boolean {
80 event?.let { motionEventHandler?.onEmptySpaceMotionEvent(it) }
81 return super.onTouchEvent(event)
82 }
83
84 companion object {
85 private const val TAG = "SceneWindowRootView"
86 }
87 }
88