Loading core/java/android/service/controls/ControlsProviderService.java +6 −3 Original line number Original line Diff line number Diff line Loading @@ -98,9 +98,12 @@ public abstract class ControlsProviderService extends Service { * * * The service may be asked to provide a small number of recommended controls, in * The service may be asked to provide a small number of recommended controls, in * order to suggest some controls to the user for favoriting. The controls shall be built using * order to suggest some controls to the user for favoriting. The controls shall be built using * the stateless builder {@link Control.StatelessBuilder}. The number of controls requested * the stateless builder {@link Control.StatelessBuilder}. The total number of controls * through {@link Subscription#request} will be limited. Call {@link Subscriber#onComplete} * requested through {@link Subscription#request} will be restricted to a maximum. Within this * when done, or {@link Subscriber#onError} for error scenarios. * larger limit, only 6 controls per structure will be loaded. Therefore, it is advisable to * seed multiple structures if they exist. Any control sent over this limit will be discarded. * Call {@link Subscriber#onComplete} when done, or {@link Subscriber#onError} for error * scenarios. */ */ @Nullable @Nullable public Publisher<Control> createPublisherForSuggested() { public Publisher<Control> createPublisherForSuggested() { Loading packages/SystemUI/res/values/config.xml +3 −3 Original line number Original line Diff line number Diff line Loading @@ -564,10 +564,10 @@ <!-- Respect drawable/rounded.xml intrinsic size for multiple radius corner path customization --> <!-- Respect drawable/rounded.xml intrinsic size for multiple radius corner path customization --> <bool name="config_roundedCornerMultipleRadius">false</bool> <bool name="config_roundedCornerMultipleRadius">false</bool> <!-- Controls can query a preferred application for limited number of suggested controls. <!-- Controls can query 2 preferred applications for limited number of suggested controls. This config value should contain the package name of that preferred application. This config value should contain a list of package names of thoses preferred applications. --> --> <string translatable="false" name="config_controlsPreferredPackage"></string> <string-array translatable="false" name="config_controlsPreferredPackages" /> <!-- Max number of columns for quick controls area --> <!-- Max number of columns for quick controls area --> <integer name="controls_max_columns">2</integer> <integer name="controls_max_columns">2</integer> Loading packages/SystemUI/src/com/android/systemui/controls/controller/ControlsBindingControllerImpl.kt +3 −1 Original line number Original line Diff line number Diff line Loading @@ -46,7 +46,9 @@ open class ControlsBindingControllerImpl @Inject constructor( companion object { companion object { private const val TAG = "ControlsBindingControllerImpl" private const val TAG = "ControlsBindingControllerImpl" private const val MAX_CONTROLS_REQUEST = 100000L private const val MAX_CONTROLS_REQUEST = 100000L private const val SUGGESTED_CONTROLS_REQUEST = 6L private const val SUGGESTED_STRUCTURES = 6L private const val SUGGESTED_CONTROLS_REQUEST = ControlsControllerImpl.SUGGESTED_CONTROLS_PER_STRUCTURE * SUGGESTED_STRUCTURES } } private var currentUser = UserHandle.of(ActivityManager.getCurrentUser()) private var currentUser = UserHandle.of(ActivityManager.getCurrentUser()) Loading packages/SystemUI/src/com/android/systemui/controls/controller/ControlsController.kt +7 −5 Original line number Original line Diff line number Diff line Loading @@ -114,12 +114,12 @@ interface ControlsController : UserAwareController { /** /** * Send a request to seed favorites into the persisted XML file * Send a request to seed favorites into the persisted XML file * * * @param componentName the component to seed controls from * @param componentNames the list of components to seed controls from * @param callback true if the favorites were persisted * @param callback one [SeedResponse] per componentName */ */ fun seedFavoritesForComponent( fun seedFavoritesForComponents( componentName: ComponentName, componentNames: List<ComponentName>, callback: Consumer<Boolean> callback: Consumer<SeedResponse> ) ) /** /** Loading Loading @@ -235,3 +235,5 @@ fun createLoadDataObject( override val errorOnLoad = error override val errorOnLoad = error } } } } data class SeedResponse(val packageName: String, val accepted: Boolean) packages/SystemUI/src/com/android/systemui/controls/controller/ControlsControllerImpl.kt +35 −14 Original line number Original line Diff line number Diff line Loading @@ -72,6 +72,7 @@ class ControlsControllerImpl @Inject constructor ( private const val USER_CHANGE_RETRY_DELAY = 500L // ms private const val USER_CHANGE_RETRY_DELAY = 500L // ms private const val DEFAULT_ENABLED = 1 private const val DEFAULT_ENABLED = 1 private const val PERMISSION_SELF = "com.android.systemui.permission.SELF" private const val PERMISSION_SELF = "com.android.systemui.permission.SELF" const val SUGGESTED_CONTROLS_PER_STRUCTURE = 6 private fun isAvailable(userId: Int, cr: ContentResolver) = Settings.Secure.getIntForUser( private fun isAvailable(userId: Int, cr: ContentResolver) = Settings.Secure.getIntForUser( cr, CONTROLS_AVAILABLE, DEFAULT_ENABLED, userId) != 0 cr, CONTROLS_AVAILABLE, DEFAULT_ENABLED, userId) != 0 Loading Loading @@ -361,29 +362,47 @@ class ControlsControllerImpl @Inject constructor ( return true return true } } override fun seedFavoritesForComponent( override fun seedFavoritesForComponents( componentName: ComponentName, componentNames: List<ComponentName>, callback: Consumer<Boolean> callback: Consumer<SeedResponse> ) { ) { if (seedingInProgress) return if (seedingInProgress || componentNames.isEmpty()) return Log.i(TAG, "Beginning request to seed favorites for: $componentName") if (!confirmAvailability()) { if (!confirmAvailability()) { if (userChanging) { if (userChanging) { // Try again later, userChanging should not last forever. If so, we have bigger // Try again later, userChanging should not last forever. If so, we have bigger // problems. This will return a runnable that allows to cancel the delayed version, // problems. This will return a runnable that allows to cancel the delayed version, // it will not be able to cancel the load if // it will not be able to cancel the load if executor.executeDelayed( executor.executeDelayed( { seedFavoritesForComponent(componentName, callback) }, { seedFavoritesForComponents(componentNames, callback) }, USER_CHANGE_RETRY_DELAY, USER_CHANGE_RETRY_DELAY, TimeUnit.MILLISECONDS TimeUnit.MILLISECONDS ) ) } else { } else { callback.accept(false) componentNames.forEach { callback.accept(SeedResponse(it.packageName, false)) } } } return return } } seedingInProgress = true seedingInProgress = true startSeeding(componentNames, callback, false) } private fun startSeeding( remainingComponentNames: List<ComponentName>, callback: Consumer<SeedResponse>, didAnyFail: Boolean ) { if (remainingComponentNames.isEmpty()) { endSeedingCall(!didAnyFail) return } val componentName = remainingComponentNames[0] Log.d(TAG, "Beginning request to seed favorites for: $componentName") val remaining = remainingComponentNames.drop(1) bindingController.bindAndLoadSuggested( bindingController.bindAndLoadSuggested( componentName, componentName, object : ControlsBindingController.LoadCallback { object : ControlsBindingController.LoadCallback { Loading @@ -396,10 +415,12 @@ class ControlsControllerImpl @Inject constructor ( val structure = it.structure ?: "" val structure = it.structure ?: "" val list = structureToControls.get(structure) val list = structureToControls.get(structure) ?: mutableListOf<ControlInfo>() ?: mutableListOf<ControlInfo>() if (list.size < SUGGESTED_CONTROLS_PER_STRUCTURE) { list.add( list.add( ControlInfo(it.controlId, it.title, it.subtitle, it.deviceType)) ControlInfo(it.controlId, it.title, it.subtitle, it.deviceType)) structureToControls.put(structure, list) structureToControls.put(structure, list) } } } structureToControls.forEach { structureToControls.forEach { (s, cs) -> Favorites.replaceControls( (s, cs) -> Favorites.replaceControls( Loading @@ -407,16 +428,16 @@ class ControlsControllerImpl @Inject constructor ( } } persistenceWrapper.storeFavorites(Favorites.getAllStructures()) persistenceWrapper.storeFavorites(Favorites.getAllStructures()) callback.accept(true) callback.accept(SeedResponse(componentName.packageName, true)) endSeedingCall(true) startSeeding(remaining, callback, didAnyFail) } } } } override fun error(message: String) { override fun error(message: String) { Log.e(TAG, "Unable to seed favorites: $message") Log.e(TAG, "Unable to seed favorites: $message") executor.execute { executor.execute { callback.accept(false) callback.accept(SeedResponse(componentName.packageName, false)) endSeedingCall(false) startSeeding(remaining, callback, true) } } } } } } Loading Loading
core/java/android/service/controls/ControlsProviderService.java +6 −3 Original line number Original line Diff line number Diff line Loading @@ -98,9 +98,12 @@ public abstract class ControlsProviderService extends Service { * * * The service may be asked to provide a small number of recommended controls, in * The service may be asked to provide a small number of recommended controls, in * order to suggest some controls to the user for favoriting. The controls shall be built using * order to suggest some controls to the user for favoriting. The controls shall be built using * the stateless builder {@link Control.StatelessBuilder}. The number of controls requested * the stateless builder {@link Control.StatelessBuilder}. The total number of controls * through {@link Subscription#request} will be limited. Call {@link Subscriber#onComplete} * requested through {@link Subscription#request} will be restricted to a maximum. Within this * when done, or {@link Subscriber#onError} for error scenarios. * larger limit, only 6 controls per structure will be loaded. Therefore, it is advisable to * seed multiple structures if they exist. Any control sent over this limit will be discarded. * Call {@link Subscriber#onComplete} when done, or {@link Subscriber#onError} for error * scenarios. */ */ @Nullable @Nullable public Publisher<Control> createPublisherForSuggested() { public Publisher<Control> createPublisherForSuggested() { Loading
packages/SystemUI/res/values/config.xml +3 −3 Original line number Original line Diff line number Diff line Loading @@ -564,10 +564,10 @@ <!-- Respect drawable/rounded.xml intrinsic size for multiple radius corner path customization --> <!-- Respect drawable/rounded.xml intrinsic size for multiple radius corner path customization --> <bool name="config_roundedCornerMultipleRadius">false</bool> <bool name="config_roundedCornerMultipleRadius">false</bool> <!-- Controls can query a preferred application for limited number of suggested controls. <!-- Controls can query 2 preferred applications for limited number of suggested controls. This config value should contain the package name of that preferred application. This config value should contain a list of package names of thoses preferred applications. --> --> <string translatable="false" name="config_controlsPreferredPackage"></string> <string-array translatable="false" name="config_controlsPreferredPackages" /> <!-- Max number of columns for quick controls area --> <!-- Max number of columns for quick controls area --> <integer name="controls_max_columns">2</integer> <integer name="controls_max_columns">2</integer> Loading
packages/SystemUI/src/com/android/systemui/controls/controller/ControlsBindingControllerImpl.kt +3 −1 Original line number Original line Diff line number Diff line Loading @@ -46,7 +46,9 @@ open class ControlsBindingControllerImpl @Inject constructor( companion object { companion object { private const val TAG = "ControlsBindingControllerImpl" private const val TAG = "ControlsBindingControllerImpl" private const val MAX_CONTROLS_REQUEST = 100000L private const val MAX_CONTROLS_REQUEST = 100000L private const val SUGGESTED_CONTROLS_REQUEST = 6L private const val SUGGESTED_STRUCTURES = 6L private const val SUGGESTED_CONTROLS_REQUEST = ControlsControllerImpl.SUGGESTED_CONTROLS_PER_STRUCTURE * SUGGESTED_STRUCTURES } } private var currentUser = UserHandle.of(ActivityManager.getCurrentUser()) private var currentUser = UserHandle.of(ActivityManager.getCurrentUser()) Loading
packages/SystemUI/src/com/android/systemui/controls/controller/ControlsController.kt +7 −5 Original line number Original line Diff line number Diff line Loading @@ -114,12 +114,12 @@ interface ControlsController : UserAwareController { /** /** * Send a request to seed favorites into the persisted XML file * Send a request to seed favorites into the persisted XML file * * * @param componentName the component to seed controls from * @param componentNames the list of components to seed controls from * @param callback true if the favorites were persisted * @param callback one [SeedResponse] per componentName */ */ fun seedFavoritesForComponent( fun seedFavoritesForComponents( componentName: ComponentName, componentNames: List<ComponentName>, callback: Consumer<Boolean> callback: Consumer<SeedResponse> ) ) /** /** Loading Loading @@ -235,3 +235,5 @@ fun createLoadDataObject( override val errorOnLoad = error override val errorOnLoad = error } } } } data class SeedResponse(val packageName: String, val accepted: Boolean)
packages/SystemUI/src/com/android/systemui/controls/controller/ControlsControllerImpl.kt +35 −14 Original line number Original line Diff line number Diff line Loading @@ -72,6 +72,7 @@ class ControlsControllerImpl @Inject constructor ( private const val USER_CHANGE_RETRY_DELAY = 500L // ms private const val USER_CHANGE_RETRY_DELAY = 500L // ms private const val DEFAULT_ENABLED = 1 private const val DEFAULT_ENABLED = 1 private const val PERMISSION_SELF = "com.android.systemui.permission.SELF" private const val PERMISSION_SELF = "com.android.systemui.permission.SELF" const val SUGGESTED_CONTROLS_PER_STRUCTURE = 6 private fun isAvailable(userId: Int, cr: ContentResolver) = Settings.Secure.getIntForUser( private fun isAvailable(userId: Int, cr: ContentResolver) = Settings.Secure.getIntForUser( cr, CONTROLS_AVAILABLE, DEFAULT_ENABLED, userId) != 0 cr, CONTROLS_AVAILABLE, DEFAULT_ENABLED, userId) != 0 Loading Loading @@ -361,29 +362,47 @@ class ControlsControllerImpl @Inject constructor ( return true return true } } override fun seedFavoritesForComponent( override fun seedFavoritesForComponents( componentName: ComponentName, componentNames: List<ComponentName>, callback: Consumer<Boolean> callback: Consumer<SeedResponse> ) { ) { if (seedingInProgress) return if (seedingInProgress || componentNames.isEmpty()) return Log.i(TAG, "Beginning request to seed favorites for: $componentName") if (!confirmAvailability()) { if (!confirmAvailability()) { if (userChanging) { if (userChanging) { // Try again later, userChanging should not last forever. If so, we have bigger // Try again later, userChanging should not last forever. If so, we have bigger // problems. This will return a runnable that allows to cancel the delayed version, // problems. This will return a runnable that allows to cancel the delayed version, // it will not be able to cancel the load if // it will not be able to cancel the load if executor.executeDelayed( executor.executeDelayed( { seedFavoritesForComponent(componentName, callback) }, { seedFavoritesForComponents(componentNames, callback) }, USER_CHANGE_RETRY_DELAY, USER_CHANGE_RETRY_DELAY, TimeUnit.MILLISECONDS TimeUnit.MILLISECONDS ) ) } else { } else { callback.accept(false) componentNames.forEach { callback.accept(SeedResponse(it.packageName, false)) } } } return return } } seedingInProgress = true seedingInProgress = true startSeeding(componentNames, callback, false) } private fun startSeeding( remainingComponentNames: List<ComponentName>, callback: Consumer<SeedResponse>, didAnyFail: Boolean ) { if (remainingComponentNames.isEmpty()) { endSeedingCall(!didAnyFail) return } val componentName = remainingComponentNames[0] Log.d(TAG, "Beginning request to seed favorites for: $componentName") val remaining = remainingComponentNames.drop(1) bindingController.bindAndLoadSuggested( bindingController.bindAndLoadSuggested( componentName, componentName, object : ControlsBindingController.LoadCallback { object : ControlsBindingController.LoadCallback { Loading @@ -396,10 +415,12 @@ class ControlsControllerImpl @Inject constructor ( val structure = it.structure ?: "" val structure = it.structure ?: "" val list = structureToControls.get(structure) val list = structureToControls.get(structure) ?: mutableListOf<ControlInfo>() ?: mutableListOf<ControlInfo>() if (list.size < SUGGESTED_CONTROLS_PER_STRUCTURE) { list.add( list.add( ControlInfo(it.controlId, it.title, it.subtitle, it.deviceType)) ControlInfo(it.controlId, it.title, it.subtitle, it.deviceType)) structureToControls.put(structure, list) structureToControls.put(structure, list) } } } structureToControls.forEach { structureToControls.forEach { (s, cs) -> Favorites.replaceControls( (s, cs) -> Favorites.replaceControls( Loading @@ -407,16 +428,16 @@ class ControlsControllerImpl @Inject constructor ( } } persistenceWrapper.storeFavorites(Favorites.getAllStructures()) persistenceWrapper.storeFavorites(Favorites.getAllStructures()) callback.accept(true) callback.accept(SeedResponse(componentName.packageName, true)) endSeedingCall(true) startSeeding(remaining, callback, didAnyFail) } } } } override fun error(message: String) { override fun error(message: String) { Log.e(TAG, "Unable to seed favorites: $message") Log.e(TAG, "Unable to seed favorites: $message") executor.execute { executor.execute { callback.accept(false) callback.accept(SeedResponse(componentName.packageName, false)) endSeedingCall(false) startSeeding(remaining, callback, true) } } } } } } Loading