1# Quick Settings Tiles (almost all there is to know about them) 2 3[TOC] 4 5## About this document 6 7This document is a more or less comprehensive summary of the state and infrastructure used by Quick 8Settings tiles. It provides descriptions about the lifecycle of a tile, how to create new tiles and 9how SystemUI manages and displays tiles, among other topics. 10 11## What are Quick Settings Tiles? 12 13Quick Settings (from now on, QS) is the expanded panel that contains shortcuts for the user to 14toggle many settings. This is opened by expanding the notification drawer twice (or once when phone 15is locked). Quick Quick Settings (QQS) is the smaller panel that appears on top of the notifications 16before expanding twice and contains some of the toggles with no secondary line. 17 18Each of these toggles that appear either in QS or QQS are called Quick Settings Tiles (or tiles for 19short). They allow the user to enable or disable settings quickly and sometimes provides access to 20more comprehensive settings pages. 21 22The following image shows QQS on the left and QS on the right, with the tiles highlighted. 23 24![QQS on the left, QS on the right](QS-QQS.png) 25 26QS Tiles usually depend on one or more Controllers that bind the tile with the necessary service. 27Controllers are obtained by the backend and used for communication between the user and the device. 28 29### A note on multi-user support 30 31All the classes described in this document that live inside SystemUI are only instantiated in the 32process of user 0. The different controllers that back the QS Tiles (also instantiated just in user 330) are user aware and provide an illusion of different instances for different users. 34 35For an example on this, 36see [`RotationLockController`](/packages/SystemUI/src/com/android/systemui/statusbar/policy/RotationLockControllerImpl.java). 37This controller for the `RotationLockTile` listens to changes in all users. 38 39## What are tiles made of? 40 41### Tile backend 42 43QS Tiles are composed of the following backend classes. 44 45* [`QSTile`](/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java): Interface 46 providing common behavior for all Tiles. This class also contains some useful utility classes 47 needed for the tiles. 48 * `Icon`: Defines the basic interface for an icon as used by the tiles. 49 * `State`: Encapsulates the state of the Tile in order to communicate between the backend and 50 the UI. 51* [`QSTileImpl`](/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java): Abstract 52 implementation of `QSTile`, providing basic common behavior for all tiles. Also implements 53 extensions for different types of `Icon`. All tiles currently defined in SystemUI subclass from 54 this implementation. 55* [`SystemUI/src/com/android/systemui/qs/tiles`](/packages/SystemUI/src/com/android/systemui/qs/tiles): 56 Each tile from SystemUI is defined here by a class that extends `QSTileImpl`. These 57 implementations connect to corresponding controllers. The controllers serve two purposes: 58 * track the state of the device and notify the tile when a change has occurred (for example, 59 bluetooth connected to a device) 60 * accept actions from the tiles to modify the state of the phone (for example, enablind and 61 disabling wifi). 62* [`CustomTile`](/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java): 63 Equivalent to the tiles in the previous item, but used for 3rd party tiles. In depth information 64 to be found in [`CustomTile`](#customtile) 65 66All the elements in SystemUI that work with tiles operate on `QSTile` or the interfaces defined in 67it. However, all the current implementations of tiles in SystemUI subclass from `QSTileImpl`, as it 68takes care of many common situations. Throughout this document, we will focus on `QSTileImpl` as 69examples of tiles. 70 71The interfaces in `QSTile` as well as other interfaces described in this document can be used to 72implement plugins to add additional tiles or different behavior. For more information, 73see [plugins.md](plugins.md) 74 75#### Tile State 76 77Each tile has an associated `State` object that is used to communicate information to the 78corresponding view. The base class `State` has (among others) the following fields: 79 80* **`state`**: one of `Tile#STATE_UNAVAILABLE`, `Tile#STATE_ACTIVE`, `Tile#STATE_INACTIVE`. 81* **`icon`**; icon to display. It may depend on the current state. 82* **`label`**: usually the name of the tile. 83* **`secondaryLabel`**: text to display in a second line. Usually extra state information. 84* **`contentDescription`** 85* **`expandedAccessibilityClassName`**: usually `Switch.class.getName()` for boolean Tiles. This 86 will make screen readers read the current state of the tile as well as the new state when it's 87 toggled. For this, the Tile has to use `BooleanState`. 88* **`handlesLongClick`**: whether the Tile will handle long click. If it won't, it should be set 89 to `false` so it will not be announced for accessibility. 90 91Setting any of these fields during `QSTileImpl#handleUpdateState` will update the UI after it. 92 93Additionally. `BooleanState` has a `value` boolean field that usually would be set 94to `state == Tile#STATE_ACTIVE`. This is used by accessibility services along 95with `expandedAccessibilityClassName`. 96 97#### SystemUI tiles 98 99Each tile defined in SystemUI extends `QSTileImpl`. This abstract class implements some common 100functions and leaves others to be implemented by each tile, in particular those that determine how 101to handle different events (refresh, click, etc.). 102 103For more information on how to implement a tile in SystemUI, 104see [Implementing a SystemUI tile](#implementing-a-systemui-tile). 105 106### Tile views 107 108Each Tile has a couple of associated views for displaying it in QS and QQS. These views are updated 109after the backend updates the `State` using `QSTileImpl#handleUpdateState`. 110 111* **[`QSTileView`](/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTileView.java)**: 112 Abstract class that provides basic Tile functionality. These allows 113 external [Factories](#qsfactory) to create Tiles. 114* **[`QSTileViewImpl`](/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.java)**: 115 Implementation of `QSTileView`. It takes care of the following: 116 * Holding the icon 117 * Background color and shape 118 * Ripple 119 * Click listening 120 * Labels 121* **[`QSIconView`](/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSIconView.java)** 122* **[`QSIconViewImpl`](/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSIconViewImpl.java)** 123 124#### QSIconView and QSIconViewImpl 125 126`QSIconView` is an interface that define the basic actions that icons have to respond to. Its base 127implementation in SystemUI is `QSIconViewImpl` and it and its subclasses are used by all QS tiles. 128 129This `ViewGroup` is a container for the icon used in each tile. It has methods to apply the 130current `State` of the tile, modifying the icon (color and animations). Classes that inherit from 131this can add other details that are modified when the `State` changes. 132 133Each `QSTileImpl` can specify that they use a particular implementation of this class when creating 134an icon. 135 136### How are the backend and the views related? 137 138The backend of the tiles (all the implementations of `QSTileImpl`) communicate with the views by 139using a `State`. The backend populates the state, and then the view maps the state to a visual 140representation. 141 142It's important to notice that the state of the tile (internal or visual) is not directly modified by 143a user action like clicking on the tile. Instead, acting on a tile produces internal state changes 144on the device, and those trigger the changes on the tile state and UI. 145 146When a container for tiles (`QuickQSPanel` or `QSPanel`) has to display tiles, they create 147a [`TileRecord`](/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java). This associates the 148corresponding `QSTile` with its `QSTileView`, doing the following: 149 150* Create the corresponding `QSTileView` to display in that container. 151* Create a callback for `QSTile` to call when its state changes. Note that a single tile will 152 normally have up to two callbacks: one for QS and one for QQS. 153 154#### Life of a tile click 155 156This is a brief run-down of what happens when a user clicks on a tile. Internal changes on the 157device (for example, changes from Settings) will trigger this process starting in step 3. Throughout 158this section, we assume that we are dealing with a `QSTileImpl`. 159 1601. User clicks on tile. The following calls happen in sequence: 161 1. `QSTileViewImpl#onClickListener`. 162 2. `QSTile#click`. 163 3. `QSTileImpl#handleClick`. This last call sets the new state for the device by using the 164 associated controller. 1652. State in the device changes. This is normally outside of SystemUI's control. 1663. Controller receives a callback (or `Intent`) indicating the change in the device. The following 167 calls happen: 168 1. `QSTileImpl#refreshState`, maybe passing an object with necessary information regarding the 169 new state. 170 2. `QSTileImpl#handleRefreshState` 1714. `QSTileImpl#handleUpdateState` is called to update the state with the new information. This 172 information can be obtained both from the `Object` passed to `refreshState` as well as from the 173 controller. 1745. If the state has changed (in at least one element), `QSTileImpl#handleStateChanged` is called. 175 This will trigger a call to all the associated `QSTile.Callback#onStateChanged`, passing the 176 new `State`. 1776. `QSTileView#onStateChanged` is called and this calls `QSTileView#handleStateChanged`. This method 178 maps the state into the view: 179 * The tile colors change to match the new state. 180 * `QSIconView.setIcon` is called to apply the correct state to the icon and the correct icon to 181 the view. 182 * The tile labels change to match the new state. 183 184## Third party tiles (TileService) 185 186A third party tile is any Quick Settings tile that is provided by an app (that's not SystemUI). This 187is implemented by developers 188subclassing [`TileService`](/core/java/android/service/quicksettings/TileService.java) and 189interacting with its API. 190 191### API classes 192 193The classes that define the public API are 194in [core/java/android/service/quicksettings](/core/java/android/service/quicksettings). 195 196#### Tile 197 198Parcelable class used to communicate information about the state between the external app and 199SystemUI. The class supports the following fields: 200 201* Label 202* Subtitle 203* Icon 204* State (`Tile#STATE_ACTIVE`, `Tile#STATE_INACTIVE`, `Tile#STATE_UNAVAILABLE`) 205* Content description 206 207Additionally, it provides a method to notify SystemUI that the information may have changed and the 208tile should be refreshed. 209 210#### TileService 211 212This is an abstract Service that needs to be implemented by the developer. The Service manifest must 213have the permission `android.permission.BIND_QUICK_SETTINGS_TILE` and must respond to the 214action `android.service.quicksettings.action.QS_TILE`. This will allow SystemUI to find the 215available tiles and display them to the user. 216 217The implementer is responsible for creating the methods that will respond to the following calls 218from SystemUI: 219 220* **`onTileAdded`**: called when the tile is added to QS. 221* **`onTileRemoved`**: called when the tile is removed from QS. 222* **`onStartListening`**: called when QS is opened and the tile is showing. This marks the start of 223 the window when calling `getQSTile` is safe and will provide the correct object. 224* **`onStopListening`**: called when QS is closed or the tile is no longer visible by the user. This 225 marks the end of the window described in `onStartListening`. 226* **`onClick`**: called when the user clicks on the tile. 227 228Additionally, the following final methods are provided: 229 230* ```java 231 public final Tile getQsTile() 232 ``` 233 234 Provides the tile object that can be modified. This should only be called in the window 235 between `onStartListening` and `onStopListening`. 236 237* ```java 238 public final boolean isLocked() 239 240 public final boolean isSecure() 241 ``` 242 243 Provide information about the secure state of the device. This can be used by the tile to accept 244 or reject actions on the tile. 245 246* ```java 247 public final void unlockAndRun(Runnable) 248 ``` 249 250 May prompt the user to unlock the device if locked. Once the device is unlocked, it runs the 251 given `Runnable`. 252 253* ```java 254 public final void showDialog(Dialog) 255 ``` 256 257 Shows the provided dialog. 258 259##### Binding 260 261When the Service is bound, a callback Binder is provided by SystemUI for all the callbacks, as well 262as an identifier token (`Binder`). This token is used in the callbacks to identify 263this `TileService` and match it to the corresponding tile. 264 265The tiles are bound once immediately on creation. After that, the tile is bound whenever it should 266start listening. When the panels are closed, and the tile is set to stop listening, it will be 267unbound after a delay of `TileServiceManager#UNBIND_DELAY` (30s), if it's not set to listening 268again. 269 270##### Active tile 271 272A `TileService` can be declared as an active tile by adding specific meta-data to its manifest ( 273see [TileService#META_DATA_ACTIVE_TILE](https://developer.android.com/reference/android/service/quicksettings/TileService#META_DATA_ACTIVE_TILE)). 274In this case, it won't receive a call of `onStartListening` when QS is opened. Instead, the tile 275must request listening status by making a call to `TileService#requestListeningState` with its 276component name. This will initiate a window that will last until the tile is updated. 277 278The tile will also be granted listening status if it's clicked by the user. 279 280### SystemUI classes 281 282The following sections describe the classes that live in SystemUI to support third party tiles. 283These classes live 284in [SystemUI/src/com/android/systemui/qs/external](/packages/SystemUI/src/com/android/systemui/qs/external/) 285 286#### CustomTile 287 288This class is an subclass of `QSTileImpl` to be used with third party tiles. It provides similar 289behavior to SystemUI tiles as well as handling exclusive behavior like lifting default icons and 290labels from the application manifest. 291 292#### TileServices 293 294This class is the central controller for all tile services that are currently in Quick Settings as 295well as provides the support for starting new ones. It is also an implementation of the `Binder` 296that receives all calls from current `TileService` components and dispatches them to SystemUI or the 297corresponding `CustomTile`. 298 299Whenever a binder call is made to this class, it matches the corresponding token assigned to 300the `TileService` with the `ComponentName` and verifies that the call comes from the right UID to 301prevent spoofing. 302 303As this class is the only one that's aware of every `TileService` that's currently bound, it is also 304in charge of requesting some to be unbound whenever there is a low memory situation. 305 306#### TileLifecycleManager 307 308This class is in charge of binding and unbinding to a particular `TileService` when necessary, as 309well as sending the corresponding binder calls. It does not decide whether the tile should be bound 310or unbound, unless it's requested to process a message. It additionally handles errors in 311the `Binder` as well as changes in the corresponding component (like updates and enable/disable). 312 313The class has a queue that stores requests while the service is not bound, to be processed as soon 314as the service is bound. 315 316Each `TileService` gets assigned an exclusive `TileLifecycleManager` when its corresponding tile is 317added to the set of current ones and kept as long as the tile is available to the user. 318 319#### TileServiceManager 320 321Each instance of this class is an intermediary between the `TileServices` controller and 322a `TileLifecycleManager` corresponding to a particular `TileService`. 323 324This class handles management of the service, including: 325 326* Deciding when to bind and unbind, requesting it to the `TileLifecycleManager`. 327* Relaying messages to the `TileService` through the `TileLifecycleManager`. 328* Determining the service's bind priority (to deal with OOM situations). 329* Detecting when the package/component has been removed in order to remove the tile and references 330 to it. 331 332## How are tiles created/instantiated? 333 334This section describes the classes that aid in the creation of each tile as well as the complete 335lifecycle of a tile. The current system makes use of flows to propagate information downstream. 336 337First we describe three important interfaces/classes. 338 339### TileSpecRepository (and UserTileSpecRepository) 340 341These classes keep track of the current tiles for each user, as a list of Tile specs. While the 342device is running, this is the source of truth of tiles for that user. 343 344The list is persisted to `Settings.Secure` every time it changes so it will be available upon 345restart or backup. In particular, any changes in the secure setting while this repository is 346tracking the list of tiles will be reverted. 347 348The class provides a `Flow<List<TileSpec>>` for each user that can be collected to keep track of the 349current list of tiles. 350 351#### Tile specs 352 353Each single tile is identified by a spec, which is a unique String for that type of tile. The 354current tiles are stored as a Setting string of comma separated values of these specs. Additionally, 355the default tiles (that appear on a fresh system) configuration value is stored likewise. 356 357SystemUI tile specs are usually a single simple word identifying the tile (like `wifi` 358or `battery`). Custom tile specs are always a string of the form `custom(...)` where the ellipsis is 359a flattened String representing the `ComponentName` for the corresponding `TileService`. 360 361We represent these internally using a `TileSpec` class that can distinguish between platform tiles 362and custom tiles. 363 364### CurrentTilesInteractor 365 366This class consumes the lists of specs provided by `TileSpecRepository` and produces a 367`Flow<List<Pair<TileSpec, QSTile>>>` with the current tiles for the current user. 368 369Internally, whenever the list of tiles changes, the following operation is performed: 370* Properly dispose of tiles that are no longer in the current list. 371* Properly dispose of tiles that are no longer available. 372* If the user has changed, relay the new user to the platform tiles and destroy any custom tiles. 373* Create new tiles as needed, disposing those that are not available or when the corresponding 374 service does not exist. 375* Reorder the tiles. 376 377Also, when this is completed, we pass the final list back to the repository so it matches the 378correct list of tiles. 379 380### QSFactory 381 382This interface provides a way of creating tiles and views from a spec. It can be used in plugins to 383provide different definitions for tiles. 384 385In SystemUI there is only one implementation of this factory and that is the default 386factory (`QSFactoryImpl`) in `CurrentTilesInteractorImpl`. 387 388#### QSFactoryImpl 389 390This class implements the following method as specified in the `QSFactory` interface: 391 392* ```java 393 public QSTile createTile(String) 394 ``` 395 396 Creates a tile (backend) from a given spec. The factory has a map with providers for all of the 397 SystemUI tiles, returning one when the correct spec is used. 398 399 If the spec is not recognized but it has the `custom(` prefix, the factory tries to create 400 a `CustomTile` for the component in the spec. 401 402 As part of filtering not valid tiles, custom tiles that don't have a corresponding valid service 403 component are never instantiated. 404 405### Lifecycle of a Tile 406 407We describe first the parts of the lifecycle that are common to SystemUI tiles and third party 408tiles. Following that, there will be a section with the steps that are exclusive to third party 409tiles. 410 4111. The tile is added through the QS customizer by the user. This will send the new list of tiles to 412 `TileSpecRepository` which will update its internal state and also store the new value in the 413 secure setting `sysui_qs_tiles`. This step could also happen if `StatusBar` adds tiles (either 414 through adb, or through its service interface as with the `DevelopmentTiles`). 4152. This updates the flow that `CurrentTilesInteractor` is collecting from, triggering the process 416 described above. 4173. `CurrentTilesInteractor` calls the available `QSFactory` classes in order to find one that will 418 be able to create a tile with that spec. Assuming that `QSFactoryImpl` managed to create the 419 tile, which is some implementation of `QSTile` (either a SystemUI subclass 420 of `QSTileImpl` or a `CustomTile`) it will be added to the current list. 421 If the tile is available, it's stored in a map and things proceed forward. 4224. `CurrentTilesInteractor` updates its flow and classes collecting from it will be notified of the 423 change. In particular, `QSPanel` and `QuickQSPanel` receive this call with the full list of 424 tiles. We will focus on these two classes. 4255. For each tile in this list, a `QSTileView` is created (collapsed or expanded) and attached to 426 a `TileRecord` containing the tile backend and the view. Additionally: 427 * a callback is attached to the tile to communicate between the backend and the view or the 428 panel. 429 * the click listeners in the tile are attached to those of the view. 4306. The tile view is added to the corresponding layout. 431 432When the tile is removed from the list of current tiles, all these classes are properly disposed 433including removing the callbacks and making sure that the backends remove themselves from the 434controllers they were listening to. 435 436#### Lifecycle of a CustomTile 437 438In step 3 of the previous process, when a `CustomTile` is created, additional steps are taken to 439ensure the proper binding to the service as described 440in [Third party tiles (TileService)](#third-party-tiles-tileservice). 441 4421. The `CustomTile` obtains the `TileServices` class from the `QSTileHost` and request the creation 443 of a `TileServiceManager` with its token. As the spec for the `CustomTile` contains 444 the `ComponentName` of the associated service, this can be used to bind to it. 4452. The `TileServiceManager` creates its own `TileLifecycleManager` to take care of binding to the 446 service. 4473. `TileServices` creates maps between the token, the `CustomTile`, the `TileServiceManager`, the 448 token and the `ComponentName`. 449 450## Implementing a tile 451 452This section describes necessary and recommended steps when implementing a Quick Settings tile. Some 453of them are optional and depend on the requirements of the tile. 454 455### Implementing a SystemUI tile 456 4571. Create a class (preferably 458 in [`SystemUI/src/com/android/systemui/qs/tiles`](/packages/SystemUI/src/com/android/systemui/qs/tiles)) 459 implementing `QSTileImpl` with a particular type of `State` as a parameter. 4602. Create an injectable constructor taking a `QSHost` and whichever classes are needed for the 461 tile's operation. Normally this would be other SystemUI controllers. 4623. Implement the methods described 463 in [Abstract methods in QSTileImpl](#abstract-methods-in-qstileimpl). Look at other tiles for 464 help. Some considerations to have in mind: 465 * If the tile will not support long click (like the `FlashlightTile`), 466 set `state.handlesLongClick` to `false` (maybe in `newTileState`). 467 * Changes to the tile state (either from controllers or from clicks) should call `refreshState`. 468 * Use only `handleUpdateState` to modify the values of the state to the new ones. This can be 469 done by polling controllers or through the `arg` parameter. 470 * If the controller is not a `CallbackController`, respond to `handleSetListening` by 471 attaching/dettaching from controllers. 472 * Implement `isAvailable` so the tile will not be created when it's not necessary. 4734. Either create a new feature module or find an existing related feature module and add the 474 following binding method: 475 * ```kotlin 476 @Binds 477 @IntoMap 478 @StringKey(YourNewTile.TILE_SPEC) // A unique word that will map to YourNewTile 479 fun bindYourNewTile(yourNewTile: YourNewTile): QSTileImpl<*> 480 ``` 4815. In [SystemUI/res/values/config.xml](/packages/SystemUI/res/values/config.xml), 482 modify `quick_settings_tiles_stock` and add the spec defined in the previous step. If necessary, 483 add it also to `quick_settings_tiles_default`. The first one contains a list of all the tiles 484 that SystemUI knows how to create (to show to the user in the customization screen). The second 485 one contains only the default tiles that the user will experience on a fresh boot or after they 486 reset their tiles. 4876. In [SystemUI/res/values/tiles_states_strings.xml](/packages/SystemUI/res/values/tiles_states_strings.xml), 488add a new array for your tile. The name has to be `tile_states_<spec>`. Use a good description to 489help the translators. 4907. In [`SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt`](/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt), 491add a new element to the map in `SubtitleArrayMapping` corresponding to the resource created in the 492previous step. 493 494#### Abstract methods in QSTileImpl 495 496Following are methods that need to be implemented when creating a new SystemUI tile. `TState` is a 497type variable of type `State`. 498 499* ```java 500 public TState newTileState() 501 ``` 502 503 Creates a new `State` for this tile to use. Each time the state changes, it is copied into a new 504 one and the corresponding fields are modified. The framework provides `State`, `BooleanState` (has 505 an on and off state and provides this as a content description), `SignalState` (`BooleanState` 506 with `activityIn` and `activityOut`), and `SlashState` (can be rotated or slashed through). 507 508 If a tile has special behavior (no long click, no ripple), it can be set in its state here. 509 510* ```java 511 public void handleSetListening(boolean) 512 ``` 513 514 Initiates or terminates listening behavior, like listening to Callbacks from controllers. This 515 gets triggered when QS is expanded or collapsed (i.e., when the tile is visible and actionable). 516 Most tiles (like `WifiTile`) do not implement this. Instead, Tiles are LifecycleOwner and are 517 marked as `RESUMED` or `DESTROYED` in `QSTileImpl#handleListening` and handled as part of the 518 lifecycle 519 of [CallbackController](/packages/SystemUI/src/com/android/systemui/statusbar/policy/CallbackController.java) 520 521* ```java 522 public QSIconView createTileView(Context) 523 ``` 524 525 Allows a Tile to use a `QSIconView` different from `QSIconViewImpl` ( 526 see [Tile views](#tile-views)), which is the default defined in `QSTileImpl` 527 528* ```java 529 public Intent getLongClickIntent() 530 ``` 531 532 Determines the `Intent` launched when the Tile is long pressed. 533 534* ```java 535 protected void handleClick() 536 537 protected void handleSecondaryClick() 538 539 protected void handleLongClick() 540 ``` 541 542 Handles what to do when the Tile is clicked. In general, a Tile will make calls to its controller 543 here and maybe update its state immediately (by calling `QSTileImpl#refreshState`). A Tile can 544 also decide to ignore the click here, if it's `Tile#STATE_UNAVAILABLE`. 545 546 By default long click redirects to click and long click launches the intent defined 547 in `getLongClickIntent`. 548 549* ```java 550 protected void handleUpdateState(TState, Object) 551 ``` 552 553 Updates the `State` of the Tile based on the state of the device as provided by the respective 554 controller. It will be called every time the Tile becomes visible, is interacted with 555 or `QSTileImpl#refreshState` is called. After this is done, the updated state will be reflected in 556 the UI. 557 558* ```java 559 @Deprecated 560 public int getMetricsCategory() 561 ``` 562 563 ~~Identifier for this Tile, as defined 564 in [proto/src/metrics_constants/metrics_constants.proto](/proto/src/metrics_constants/metrics_constants.proto). 565 This is used to log events related to this Tile.~~ 566 This is now deprecated in favor of `UiEvent` that use the tile spec. 567 568* ```java 569 public boolean isAvailable() 570 ``` 571 572 Determines if a Tile is available to be used (for example, disable `WifiTile` in devices with no 573 Wifi support). If this is false, the Tile will be destroyed upon creation. 574 575* ```java 576 public CharSequence getTileLabel() 577 ``` 578 579 Provides a default label for this Tile. Used by the QS Panel customizer to show a name next to 580 each available tile. 581 582### Implementing a third party tile 583 584For information about this, use the Android Developer documentation 585for [TileService](https://developer.android.com/reference/android/service/quicksettings/TileService). 586 587## AutoAddable tiles 588 589AutoAddable tiles are tiles that are not part of the default set, but will be automatically added 590for the user, when the user enabled a feature for the first time. For example: 591* When the user creates a work profile, the work profile tile is automatically added. 592* When the user sets up a hotspot for the first time, the hotspot tile is automatically added. 593 594In order to declare a tile as auto-addable, there are two ways: 595 596* If the tile can be tied to a secure setting such that the tile should be auto added after that 597 setting has changed to a non-zero value for the first time, a new line can be added to the 598 string-array `config_quickSettingsAutoAdd` in [config.xml](/packages/SystemUI/res/values/config.xml). 599* If more specific behavior is needed, a new 600 [AutoAddable](/packages/SystemUI/src/com/android/systemui/qs/pipeline/domain/model/AutoAddable.kt) 601 can be added in the `autoaddables` package. This can have custom logic that produces a flow of 602 signals on when the tile should be auto-added (or auto-removed in special cases). 603 604 *Special case: If the data comes from a `CallbackController`, a special 605 `CallbackControllerAutoAddable` can be created instead that handles a lot of the common code.* 606 607### AutoAddRepository (and UserAutoAddRepository) 608 609These classes keep track of tiles that have been auto-added for each user, as a list of Tile specs. 610While the device is running, this is the source of truth of already auto-added tiles for that user. 611 612The list is persisted to `Settings.Secure` every time it changes so it will be available upon 613restart or backup. In particular, any changes in the secure setting while this repository is 614tracking the list of tiles will be reverted. 615 616The class provides a `Flow<Set<TileSpec>>` for each user that can be collected to keep track of the 617set of already auto added tiles. 618 619### AutoAddInteractor 620 621This class collects all registered (through Dagger) `AutoAddables` and merges all the signals for 622the current user. It will add/remove tiles as necessary and mark them as such in the 623`AutoAddRepository`. 624 625## Backup and restore 626 627It's important to point out that B&R of Quick Settings tiles only concerns itself with restoring, 628for each user, the list of current tiles and their order. The state of the tiles (or other things 629that can be accessed from them like list of WiFi networks) is the concern of each feature team and 630out of the scope of Quick Settings. 631 632In order to provide better support to restoring Quick Settings tiles and prevent overwritten or 633inconsistent data, the system has the following steps: 634 6351. When `Settings.Secure.SYSUI_QS_TILES` and `Settings.Secure.QS_AUTO_TILES` are restored, a 636 broadcast is sent to SystemUI. This is handled by 637 [SettingsHelper](/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java). 638 The broadcasts are received by [QSSettingsRestoredRepository](/packages/SystemUI/src/com/android/systemui/qs/pipeline/data/repository/QSSettingsRestoredRepository.kt) 639 and grouped by user into a data object. As described above, the change performed by the restore in 640 settings is overriden by the corresponding repositories. 6412. Once both settings have been restored, the data is reconciled with the current data, to account 642 for tiles that may have been auto-added between the start of SystemUI and the time the restore 643 happened. The guiding principles for the reconciliation are as follows: 644 * We assume that the user expects the restored tiles to be the ones to be present after restore, 645 so those are taken as the basis for the reconciliation. 646 * Any tile that was auto-added before the restore, but had not been auto-added in the source 647 device, is auto-added again (preferably in a similar position). 648 * Any tile that was auto-added before the restore, and it was also auto-added in the source 649 device, but not present in the restored tiles, is considered removed by the user and therefore 650 not restored. 651 * Every tile that was marked as auto-added (all tiles in source + tiles added before restore) 652 are set as auto-added. 653 654## Logs for debugging 655 656The following log buffers are used for Quick Settings debugging purposes: 657 658### QSLog 659 660Logs events in the individual tiles, like listening state, clicks, and status updates. 661 662### QSTileListLog 663 664Logs changes in the current set of tiles for each user, including when tiles are created or 665destroyed, and the reason for that. It also logs what operation caused the tiles to change 666(add, remove, change, restore). 667 668### QSAutoAddLog 669 670Logs operations of auto-add (or auto-remove) of tiles. 671 672### QSRestoreLog 673 674Logs the data obtained after a successful restore of the settings. This is the data that will be 675used for reconciliation.