• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
<lambda>null2  * Copyright (C) 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.wm.shell.compatui.impl
18 
19 import com.android.wm.shell.common.ShellExecutor
20 import com.android.wm.shell.compatui.api.CompatUIComponentFactory
21 import com.android.wm.shell.compatui.api.CompatUIComponentIdGenerator
22 import com.android.wm.shell.compatui.api.CompatUIEvent
23 import com.android.wm.shell.compatui.api.CompatUIHandler
24 import com.android.wm.shell.compatui.api.CompatUIInfo
25 import com.android.wm.shell.compatui.api.CompatUIRepository
26 import com.android.wm.shell.compatui.api.CompatUIRequest
27 import com.android.wm.shell.compatui.api.CompatUIState
28 import java.util.function.Consumer
29 
30 /**
31  * Default implementation of {@link CompatUIHandler} to handle CompatUI components
32  */
33 class DefaultCompatUIHandler(
34     private val compatUIRepository: CompatUIRepository,
35     private val compatUIState: CompatUIState,
36     private val componentIdGenerator: CompatUIComponentIdGenerator,
37     private val componentFactory: CompatUIComponentFactory,
38     private val executor: ShellExecutor
39 ) : CompatUIHandler {
40 
41     private var compatUIEventSender: Consumer<CompatUIEvent>? = null
42 
43     override fun onCompatInfoChanged(compatUIInfo: CompatUIInfo) {
44         compatUIRepository.iterateOn { spec ->
45             // We get the identifier for the component depending on the task and spec
46             val componentId = componentIdGenerator.generateId(compatUIInfo, spec)
47             spec.log("Evaluating component $componentId")
48             // We check in the state if the component does not yet exist
49             var component = compatUIState.getUIComponent(componentId)
50             if (component == null) {
51                 spec.log("Component $componentId not present")
52                 // We evaluate the predicate
53                 if (spec.lifecycle.creationPredicate(compatUIInfo, compatUIState.sharedState)) {
54                     spec.log("Component $componentId should be created")
55                     // We create the component and store in the
56                     // global state
57                     component =
58                         componentFactory.create(spec, componentId, compatUIState, compatUIInfo)
59                     spec.log("Component $componentId created $component")
60                     // We initialize the state for the component
61                     val compState = spec.lifecycle.stateBuilder(
62                         compatUIInfo,
63                         compatUIState.sharedState
64                     )
65                     spec.log("Component $componentId initial state $compState")
66                     compatUIState.registerUIComponent(componentId, component, compState)
67                     spec.log("Component $componentId registered")
68                     // We initialize the layout for the component
69                     component.initLayout(compatUIInfo)
70                     spec.log("Component $componentId layout created")
71                     // Now we can invoke the update passing the shared state and
72                     // the state specific to the component
73                     executor.execute {
74                         component.update(compatUIInfo)
75                         spec.log("Component $componentId updated with $compatUIInfo")
76                     }
77                 }
78             } else {
79                 // The component is present. We check if we need to remove it
80                 if (spec.lifecycle.removalPredicate(
81                         compatUIInfo,
82                         compatUIState.sharedState,
83                         compatUIState.stateForComponent(componentId)
84                     )) {
85                     spec.log("Component $componentId should be removed")
86                     // We clean the component
87                     component.release()
88                     spec.log("Component $componentId released")
89                     compatUIState.unregisterUIComponent(componentId)
90                     spec.log("Component $componentId removed from registry")
91                 } else {
92                     executor.execute {
93                         // The component exists so we need to invoke the update methods
94                         component.update(compatUIInfo)
95                         spec.log("Component $componentId updated with $compatUIInfo")
96                     }
97                 }
98             }
99         }
100         // Empty at the moment
101     }
102 
103     override fun setCallback(compatUIEventSender: Consumer<CompatUIEvent>?) {
104         this.compatUIEventSender = compatUIEventSender
105     }
106 
107     override fun sendCompatUIRequest(compatUIRequest: CompatUIRequest) {}
108 }
109