1 /*
2 * Copyright (C) 2020 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.systemui.controls.controller
18
19 import android.content.ComponentName
20 import android.service.controls.Control
21 import android.service.controls.ControlsProviderService
22 import android.service.controls.actions.ControlAction
23 import com.android.systemui.controls.ControlStatus
24 import com.android.systemui.util.UserAwareController
25 import com.android.systemui.controls.management.ControlsFavoritingActivity
26 import com.android.systemui.controls.ui.ControlsUiController
27 import java.util.function.Consumer
28
29 /**
30 * Controller to handle communication between different parts of the controls system.
31 *
32 * This controller is in charge of:
33 * * Keeping track of favorites
34 * * Determining and keeping track of whether controls are enabled
35 * * Listening for user change and propagating that message in the system
36 * * Communicate between the UI and the [ControlsBindingController]
37 *
38 * This controller being a [UserAwareController] means that all operations will be conducted on
39 * information for the current user only.
40 */
41 interface ControlsController : UserAwareController {
42
43 // SERVICE COMMUNICATION
44
45 /**
46 * Load all available [Control] for a given service.
47 *
48 * @param componentName the [ComponentName] of the [ControlsProviderService] to load from
49 * @param dataCallback a callback in which to retrieve the result
50 * @param cancelWrapper a callback to receive a [Runnable] that can be run to cancel the
51 * request
52 */
loadForComponentnull53 fun loadForComponent(
54 componentName: ComponentName,
55 dataCallback: Consumer<LoadData>,
56 cancelWrapper: Consumer<Runnable>
57 )
58
59 /**
60 * Request to subscribe for favorited controls per structure
61 *
62 * @param structureInfo structure to limit the subscription to
63 * @see [ControlsBindingController.subscribe]
64 */
65 fun subscribeToFavorites(structureInfo: StructureInfo)
66
67 /**
68 * Request to unsubscribe to the current provider.
69 *
70 * @see [ControlsBindingController.unsubscribe]
71 */
72 fun unsubscribe()
73
74 /**
75 * Notify a [ControlsProviderService] that an action has been performed on a [Control].
76 *
77 * @param componentName the name of the service that provides the [Control]
78 * @param controlInfo information of the [Control] receiving the action
79 * @param action action performed on the [Control]
80 * @see [ControlsBindingController.action]
81 */
82 fun action(componentName: ComponentName, controlInfo: ControlInfo, action: ControlAction)
83
84 /**
85 * Refresh the status of a [Control] with information provided from the service.
86 *
87 * @param componentName the name of the service that provides the [Control]
88 * @param control a stateful [Control] with updated information
89 * @see [ControlsUiController.onRefreshState]
90 */
91 fun refreshStatus(componentName: ComponentName, control: Control)
92
93 /**
94 * Indicate the result of a [ControlAction] performed on a [Control].
95 *
96 * @param componentName the name of the service that provides the [Control]
97 * @param controlId the id of the [Control] the actioned was performed on
98 * @param response the result of the action.
99 * @see [ControlsUiController.onActionResponse]
100 */
101 fun onActionResponse(
102 componentName: ComponentName,
103 controlId: String,
104 @ControlAction.ResponseResult response: Int
105 )
106
107 // FAVORITE MANAGEMENT
108
109 /**
110 * Send a request to seed favorites into the persisted XML file
111 *
112 * @param componentNames the list of components to seed controls from
113 * @param callback one [SeedResponse] per componentName
114 */
115 fun seedFavoritesForComponents(
116 componentNames: List<ComponentName>,
117 callback: Consumer<SeedResponse>
118 )
119
120 /**
121 * Callback to be informed when the seeding process has finished
122 *
123 * @param callback consumer accepts true if successful
124 * @return true if seeding is in progress and the callback was added
125 */
126 fun addSeedingFavoritesCallback(callback: Consumer<Boolean>): Boolean
127
128 /**
129 * Get all the favorites.
130 *
131 * @return a list of the structures that have at least one favorited control
132 */
133 fun getFavorites(): List<StructureInfo>
134
135 /**
136 * Get all the favorites for a given component.
137 *
138 * @param componentName the name of the service that provides the [Control]
139 * @return a list of the structures that have at least one favorited control
140 */
141 fun getFavoritesForComponent(componentName: ComponentName): List<StructureInfo>
142
143 /**
144 * Get all the favorites for a given structure.
145 *
146 * @param componentName the name of the service that provides the [Control]
147 * @param structureName the name of the structure
148 * @return a list of the current favorites in that structure
149 */
150 fun getFavoritesForStructure(
151 componentName: ComponentName,
152 structureName: CharSequence
153 ): List<ControlInfo>
154
155 /**
156 * Adds a single favorite to a given component and structure
157 * @param componentName the name of the service that provides the [Control]
158 * @param structureName the name of the structure that holds the [Control]
159 * @param controlInfo persistent information about the [Control] to be added.
160 */
161 fun addFavorite(
162 componentName: ComponentName,
163 structureName: CharSequence,
164 controlInfo: ControlInfo
165 )
166
167 /**
168 * Replaces the favorites for the given structure.
169 *
170 * Calling this method will eliminate the previous selection of favorites and replace it with a
171 * new one.
172 *
173 * @param structureInfo common structure for all of the favorited controls
174 */
175 fun replaceFavoritesForStructure(structureInfo: StructureInfo)
176
177 /**
178 * Return the number of favorites for a given component.
179 *
180 * This call returns the same as `getFavoritesForComponent(componentName).size`.
181 *
182 * @param componentName the name of the component
183 * @return the number of current favorites for the given component
184 */
185 fun countFavoritesForComponent(componentName: ComponentName): Int
186
187 /** See [ControlsUiController.getPreferredStructure]. */
188 fun getPreferredStructure(): StructureInfo
189
190 /**
191 * Interface for structure to pass data to [ControlsFavoritingActivity].
192 */
193 interface LoadData {
194 /**
195 * All of the available controls for the loaded [ControlsProviderService].
196 *
197 * This will indicate if they are currently a favorite and whether they were removed (a
198 * favorite but not retrieved on load).
199 */
200 val allControls: List<ControlStatus>
201
202 /**
203 * Ordered list of ids of favorite controls.
204 */
205 val favoritesIds: List<String>
206
207 /**
208 * Whether there was an error in loading.
209 *
210 * In this case, [allControls] will only contain those that were favorited and will not be
211 * marked as removed.
212 */
213 val errorOnLoad: Boolean
214 }
215 }
216
217 /**
218 * Creates a basic implementation of a [LoadData].
219 */
createLoadDataObjectnull220 fun createLoadDataObject(
221 allControls: List<ControlStatus>,
222 favorites: List<String>,
223 error: Boolean = false
224 ): ControlsController.LoadData {
225 return object : ControlsController.LoadData {
226 override val allControls = allControls
227 override val favoritesIds = favorites
228 override val errorOnLoad = error
229 }
230 }
231
232 data class SeedResponse(val packageName: String, val accepted: Boolean)
233