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 */ 53 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 */ 220 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