Loading packages/SystemUI/src/com/android/systemui/controls/controller/ControlsBindingControllerImpl.kt +72 −22 Original line number Original line Diff line number Diff line Loading @@ -45,7 +45,7 @@ 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 = 4L private const val SUGGESTED_CONTROLS_REQUEST = 6L } } private var currentUser = UserHandle.of(ActivityManager.getCurrentUser()) private var currentUser = UserHandle.of(ActivityManager.getCurrentUser()) Loading @@ -61,6 +61,11 @@ open class ControlsBindingControllerImpl @Inject constructor( */ */ private var statefulControlSubscriber: StatefulControlSubscriber? = null private var statefulControlSubscriber: StatefulControlSubscriber? = null /* * Will track any active load subscriber. Only one can be active at any time. */ private var loadSubscriber: LoadSubscriber? = null private val actionCallbackService = object : IControlsActionCallback.Stub() { private val actionCallbackService = object : IControlsActionCallback.Stub() { override fun accept( override fun accept( token: IBinder, token: IBinder, Loading Loading @@ -99,17 +104,24 @@ open class ControlsBindingControllerImpl @Inject constructor( component: ComponentName, component: ComponentName, callback: ControlsBindingController.LoadCallback callback: ControlsBindingController.LoadCallback ): Runnable { ): Runnable { val subscriber = LoadSubscriber(callback, MAX_CONTROLS_REQUEST) loadSubscriber?.loadCancel() retrieveLifecycleManager(component).maybeBindAndLoad(subscriber) return subscriber.loadCancel() val ls = LoadSubscriber(callback, MAX_CONTROLS_REQUEST) loadSubscriber = ls retrieveLifecycleManager(component).maybeBindAndLoad(ls) return ls.loadCancel() } } override fun bindAndLoadSuggested( override fun bindAndLoadSuggested( component: ComponentName, component: ComponentName, callback: ControlsBindingController.LoadCallback callback: ControlsBindingController.LoadCallback ) { ) { val subscriber = LoadSubscriber(callback, SUGGESTED_CONTROLS_REQUEST) loadSubscriber?.loadCancel() retrieveLifecycleManager(component).maybeBindAndLoadSuggested(subscriber) val ls = LoadSubscriber(callback, SUGGESTED_CONTROLS_REQUEST) loadSubscriber = ls retrieveLifecycleManager(component).maybeBindAndLoadSuggested(ls) } } override fun subscribe(structureInfo: StructureInfo) { override fun subscribe(structureInfo: StructureInfo) { Loading Loading @@ -152,13 +164,16 @@ open class ControlsBindingControllerImpl @Inject constructor( override fun changeUser(newUser: UserHandle) { override fun changeUser(newUser: UserHandle) { if (newUser == currentUser) return if (newUser == currentUser) return unsubscribe() unbind() unbind() currentProvider = null currentUser = newUser currentUser = newUser } } private fun unbind() { private fun unbind() { unsubscribe() loadSubscriber?.loadCancel() loadSubscriber = null currentProvider?.unbindService() currentProvider?.unbindService() currentProvider = null currentProvider = null } } Loading Loading @@ -210,6 +225,20 @@ open class ControlsBindingControllerImpl @Inject constructor( val callback: ControlsBindingController.LoadCallback val callback: ControlsBindingController.LoadCallback ) : CallbackRunnable(token) { ) : CallbackRunnable(token) { override fun doRun() { override fun doRun() { Log.d(TAG, "LoadSubscription: Complete and loading controls") callback.accept(list) } } private inner class OnCancelAndLoadRunnable( token: IBinder, val list: List<Control>, val subscription: IControlsSubscription, val callback: ControlsBindingController.LoadCallback ) : CallbackRunnable(token) { override fun doRun() { Log.d(TAG, "LoadSubscription: Canceling and loading controls") provider?.cancelSubscription(subscription) callback.accept(list) callback.accept(list) } } } } Loading @@ -220,6 +249,7 @@ open class ControlsBindingControllerImpl @Inject constructor( val requestLimit: Long val requestLimit: Long ) : CallbackRunnable(token) { ) : CallbackRunnable(token) { override fun doRun() { override fun doRun() { Log.d(TAG, "LoadSubscription: Starting subscription") provider?.startSubscription(subscription, requestLimit) provider?.startSubscription(subscription, requestLimit) } } } } Loading Loading @@ -254,34 +284,54 @@ open class ControlsBindingControllerImpl @Inject constructor( val requestLimit: Long val requestLimit: Long ) : IControlsSubscriber.Stub() { ) : IControlsSubscriber.Stub() { val loadedControls = ArrayList<Control>() val loadedControls = ArrayList<Control>() var hasError = false private var isTerminated = false private var _loadCancelInternal: (() -> Unit)? = null private var _loadCancelInternal: (() -> Unit)? = null private lateinit var subscription: IControlsSubscription fun loadCancel() = Runnable { fun loadCancel() = Runnable { Log.d(TAG, "Cancel load requested") Log.d(TAG, "Cancel load requested") _loadCancelInternal?.invoke() _loadCancelInternal?.invoke() } } override fun onSubscribe(token: IBinder, subs: IControlsSubscription) { override fun onSubscribe(token: IBinder, subs: IControlsSubscription) { _loadCancelInternal = subs::cancel subscription = subs _loadCancelInternal = { currentProvider?.cancelSubscription(subscription) } backgroundExecutor.execute(OnSubscribeRunnable(token, subs, requestLimit)) backgroundExecutor.execute(OnSubscribeRunnable(token, subs, requestLimit)) } } override fun onNext(token: IBinder, c: Control) { override fun onNext(token: IBinder, c: Control) { backgroundExecutor.execute { loadedControls.add(c) } backgroundExecutor.execute { if (isTerminated) return@execute loadedControls.add(c) // Once we have reached our requestLimit, send a request to cancel, and immediately // load the results. Calls to onError() and onComplete() are not required after // cancel. if (loadedControls.size >= requestLimit) { maybeTerminateAndRun( OnCancelAndLoadRunnable(token, loadedControls, subscription, callback) ) } } } } override fun onError(token: IBinder, s: String) { override fun onError(token: IBinder, s: String) { hasError = true maybeTerminateAndRun(OnLoadErrorRunnable(token, s, callback)) _loadCancelInternal = {} currentProvider?.cancelLoadTimeout() backgroundExecutor.execute(OnLoadErrorRunnable(token, s, callback)) } } override fun onComplete(token: IBinder) { override fun onComplete(token: IBinder) { maybeTerminateAndRun(OnLoadRunnable(token, loadedControls, callback)) } private fun maybeTerminateAndRun(postTerminateFn: Runnable) { if (isTerminated) return isTerminated = true _loadCancelInternal = {} _loadCancelInternal = {} if (!hasError) { currentProvider?.cancelLoadTimeout() currentProvider?.cancelLoadTimeout() backgroundExecutor.execute(OnLoadRunnable(token, loadedControls, callback)) } backgroundExecutor.execute(postTerminateFn) } } } } } } Loading packages/SystemUI/src/com/android/systemui/controls/controller/ControlsController.kt +5 −0 Original line number Original line Diff line number Diff line Loading @@ -179,6 +179,11 @@ interface ControlsController : UserAwareController { */ */ fun countFavoritesForComponent(componentName: ComponentName): Int fun countFavoritesForComponent(componentName: ComponentName): Int /** * TEMPORARY for testing */ fun resetFavorites() /** /** * Interface for structure to pass data to [ControlsFavoritingActivity]. * Interface for structure to pass data to [ControlsFavoritingActivity]. */ */ Loading packages/SystemUI/src/com/android/systemui/controls/controller/ControlsControllerImpl.kt +9 −0 Original line number Original line Diff line number Diff line Loading @@ -365,6 +365,8 @@ class ControlsControllerImpl @Inject constructor ( componentName: ComponentName, componentName: ComponentName, callback: Consumer<Boolean> callback: Consumer<Boolean> ) { ) { if (seedingInProgress) return Log.i(TAG, "Beginning request to seed favorites for: $componentName") Log.i(TAG, "Beginning request to seed favorites for: $componentName") if (!confirmAvailability()) { if (!confirmAvailability()) { if (userChanging) { if (userChanging) { Loading Loading @@ -495,6 +497,13 @@ class ControlsControllerImpl @Inject constructor ( } } } } override fun resetFavorites() { executor.execute { Favorites.clear() persistenceWrapper.storeFavorites(Favorites.getAllStructures()) } } override fun refreshStatus(componentName: ComponentName, control: Control) { override fun refreshStatus(componentName: ComponentName, control: Control) { if (!confirmAvailability()) { if (!confirmAvailability()) { Log.d(TAG, "Controls not available") Log.d(TAG, "Controls not available") Loading packages/SystemUI/src/com/android/systemui/controls/controller/ControlsProviderLifecycleManager.kt +3 −20 Original line number Original line Diff line number Diff line Loading @@ -63,8 +63,6 @@ class ControlsProviderLifecycleManager( ) : IBinder.DeathRecipient { ) : IBinder.DeathRecipient { val token: IBinder = Binder() val token: IBinder = Binder() @GuardedBy("subscriptions") private val subscriptions = mutableListOf<IControlsSubscription>() private var requiresBound = false private var requiresBound = false @GuardedBy("queuedServiceMethods") @GuardedBy("queuedServiceMethods") private val queuedServiceMethods: MutableSet<ServiceMethod> = ArraySet() private val queuedServiceMethods: MutableSet<ServiceMethod> = ArraySet() Loading Loading @@ -194,7 +192,7 @@ class ControlsProviderLifecycleManager( * Request a call to [IControlsProvider.loadSuggested]. * Request a call to [IControlsProvider.loadSuggested]. * * * If the service is not bound, the call will be queued and the service will be bound first. * If the service is not bound, the call will be queued and the service will be bound first. * The service will be unbound after the controls are returned or the call times out. * The service will be unbound if the call times out. * * * @param subscriber the subscriber that manages coordination for loading controls * @param subscriber the subscriber that manages coordination for loading controls */ */ Loading Loading @@ -245,9 +243,7 @@ class ControlsProviderLifecycleManager( if (DEBUG) { if (DEBUG) { Log.d(TAG, "startSubscription: $subscription") Log.d(TAG, "startSubscription: $subscription") } } synchronized(subscriptions) { subscriptions.add(subscription) } wrapper?.request(subscription, requestLimit) wrapper?.request(subscription, requestLimit) } } Loading @@ -261,9 +257,7 @@ class ControlsProviderLifecycleManager( if (DEBUG) { if (DEBUG) { Log.d(TAG, "cancelSubscription: $subscription") Log.d(TAG, "cancelSubscription: $subscription") } } synchronized(subscriptions) { subscriptions.remove(subscription) } wrapper?.cancel(subscription) wrapper?.cancel(subscription) } } Loading @@ -281,17 +275,6 @@ class ControlsProviderLifecycleManager( onLoadCanceller?.run() onLoadCanceller?.run() onLoadCanceller = null onLoadCanceller = null // be sure to cancel all subscriptions val subs = synchronized(subscriptions) { ArrayList(subscriptions).also { subscriptions.clear() } } subs.forEach { wrapper?.cancel(it) } bindService(false) bindService(false) } } Loading packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt +61 −2 Original line number Original line Diff line number Diff line Loading @@ -16,18 +16,26 @@ package com.android.systemui.controls.ui package com.android.systemui.controls.ui import android.animation.Animator import android.animation.AnimatorListenerAdapter import android.animation.ObjectAnimator import android.app.AlertDialog import android.app.Dialog import android.app.Dialog import android.content.ComponentName import android.content.ComponentName import android.content.Context import android.content.Context import android.content.DialogInterface import android.content.Intent import android.content.Intent import android.content.SharedPreferences import android.content.SharedPreferences import android.content.res.Configuration import android.content.res.Configuration import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable import android.graphics.drawable.LayerDrawable import android.graphics.drawable.LayerDrawable import android.os.Process import android.service.controls.Control import android.service.controls.Control import android.service.controls.actions.ControlAction import android.service.controls.actions.ControlAction import android.util.TypedValue import android.util.TypedValue import android.util.Log import android.util.Log import android.view.animation.AccelerateInterpolator import android.view.animation.DecelerateInterpolator import android.view.ContextThemeWrapper import android.view.ContextThemeWrapper import android.view.LayoutInflater import android.view.LayoutInflater import android.view.View import android.view.View Loading Loading @@ -77,6 +85,8 @@ class ControlsUiControllerImpl @Inject constructor ( private const val PREF_COMPONENT = "controls_component" private const val PREF_COMPONENT = "controls_component" private const val PREF_STRUCTURE = "controls_structure" private const val PREF_STRUCTURE = "controls_structure" private const val FADE_IN_MILLIS = 225L private val EMPTY_COMPONENT = ComponentName("", "") private val EMPTY_COMPONENT = ComponentName("", "") private val EMPTY_STRUCTURE = StructureInfo( private val EMPTY_STRUCTURE = StructureInfo( EMPTY_COMPONENT, EMPTY_COMPONENT, Loading Loading @@ -153,7 +163,20 @@ class ControlsUiControllerImpl @Inject constructor ( private fun reload(parent: ViewGroup) { private fun reload(parent: ViewGroup) { if (hidden) return if (hidden) return val fadeAnim = ObjectAnimator.ofFloat(parent, "alpha", 1.0f, 0.0f) fadeAnim.setInterpolator(AccelerateInterpolator(1.0f)) fadeAnim.setDuration(FADE_IN_MILLIS) fadeAnim.addListener(object : AnimatorListenerAdapter() { override fun onAnimationEnd(animation: Animator) { show(parent) show(parent) val showAnim = ObjectAnimator.ofFloat(parent, "alpha", 0.0f, 1.0f) showAnim.setInterpolator(DecelerateInterpolator(1.0f)) showAnim.setDuration(FADE_IN_MILLIS) showAnim.start() } }) fadeAnim.start() } } private fun showSeedingView(items: List<SelectionItem>) { private fun showSeedingView(items: List<SelectionItem>) { Loading Loading @@ -229,7 +252,8 @@ class ControlsUiControllerImpl @Inject constructor ( private fun createMenu() { private fun createMenu() { val items = arrayOf( val items = arrayOf( context.resources.getString(R.string.controls_menu_add) context.resources.getString(R.string.controls_menu_add), "Reset" ) ) var adapter = ArrayAdapter<String>(context, R.layout.controls_more_item, items) var adapter = ArrayAdapter<String>(context, R.layout.controls_more_item, items) Loading @@ -249,6 +273,8 @@ class ControlsUiControllerImpl @Inject constructor ( when (pos) { when (pos) { // 0: Add Control // 0: Add Control 0 -> startFavoritingActivity(view.context, selectedStructure) 0 -> startFavoritingActivity(view.context, selectedStructure) // 1: TEMPORARY for reset controls 1 -> showResetConfirmation() else -> Log.w(ControlsUiController.TAG, else -> Log.w(ControlsUiController.TAG, "Unsupported index ($pos) on 'more' menu selection") "Unsupported index ($pos) on 'more' menu selection") } } Loading @@ -275,6 +301,39 @@ class ControlsUiControllerImpl @Inject constructor ( }) }) } } private fun showResetConfirmation() { val builder = AlertDialog.Builder( context, android.R.style.Theme_DeviceDefault_Dialog_Alert ).apply { setMessage("For testing purposes: Would you like to " + "reset your favorited device controls?") setPositiveButton( android.R.string.ok, DialogInterface.OnClickListener { dialog, _ -> val userHandle = Process.myUserHandle() val userContext = context.createContextAsUser(userHandle, 0) val prefs = userContext.getSharedPreferences( "controls_prefs", Context.MODE_PRIVATE) prefs.edit().putBoolean("ControlsSeedingCompleted", false).apply() controlsController.get().resetFavorites() dialog.dismiss() context.sendBroadcast(Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)) }) setNegativeButton( android.R.string.cancel, DialogInterface.OnClickListener { dialog, _ -> dialog.cancel() } ) } builder.create().apply { getWindow().apply { setType(WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY) } }.show() } private fun createDropDown(items: List<SelectionItem>) { private fun createDropDown(items: List<SelectionItem>) { items.forEach { items.forEach { RenderInfo.registerComponentIcon(it.componentName, it.icon) RenderInfo.registerComponentIcon(it.componentName, it.icon) Loading Loading
packages/SystemUI/src/com/android/systemui/controls/controller/ControlsBindingControllerImpl.kt +72 −22 Original line number Original line Diff line number Diff line Loading @@ -45,7 +45,7 @@ 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 = 4L private const val SUGGESTED_CONTROLS_REQUEST = 6L } } private var currentUser = UserHandle.of(ActivityManager.getCurrentUser()) private var currentUser = UserHandle.of(ActivityManager.getCurrentUser()) Loading @@ -61,6 +61,11 @@ open class ControlsBindingControllerImpl @Inject constructor( */ */ private var statefulControlSubscriber: StatefulControlSubscriber? = null private var statefulControlSubscriber: StatefulControlSubscriber? = null /* * Will track any active load subscriber. Only one can be active at any time. */ private var loadSubscriber: LoadSubscriber? = null private val actionCallbackService = object : IControlsActionCallback.Stub() { private val actionCallbackService = object : IControlsActionCallback.Stub() { override fun accept( override fun accept( token: IBinder, token: IBinder, Loading Loading @@ -99,17 +104,24 @@ open class ControlsBindingControllerImpl @Inject constructor( component: ComponentName, component: ComponentName, callback: ControlsBindingController.LoadCallback callback: ControlsBindingController.LoadCallback ): Runnable { ): Runnable { val subscriber = LoadSubscriber(callback, MAX_CONTROLS_REQUEST) loadSubscriber?.loadCancel() retrieveLifecycleManager(component).maybeBindAndLoad(subscriber) return subscriber.loadCancel() val ls = LoadSubscriber(callback, MAX_CONTROLS_REQUEST) loadSubscriber = ls retrieveLifecycleManager(component).maybeBindAndLoad(ls) return ls.loadCancel() } } override fun bindAndLoadSuggested( override fun bindAndLoadSuggested( component: ComponentName, component: ComponentName, callback: ControlsBindingController.LoadCallback callback: ControlsBindingController.LoadCallback ) { ) { val subscriber = LoadSubscriber(callback, SUGGESTED_CONTROLS_REQUEST) loadSubscriber?.loadCancel() retrieveLifecycleManager(component).maybeBindAndLoadSuggested(subscriber) val ls = LoadSubscriber(callback, SUGGESTED_CONTROLS_REQUEST) loadSubscriber = ls retrieveLifecycleManager(component).maybeBindAndLoadSuggested(ls) } } override fun subscribe(structureInfo: StructureInfo) { override fun subscribe(structureInfo: StructureInfo) { Loading Loading @@ -152,13 +164,16 @@ open class ControlsBindingControllerImpl @Inject constructor( override fun changeUser(newUser: UserHandle) { override fun changeUser(newUser: UserHandle) { if (newUser == currentUser) return if (newUser == currentUser) return unsubscribe() unbind() unbind() currentProvider = null currentUser = newUser currentUser = newUser } } private fun unbind() { private fun unbind() { unsubscribe() loadSubscriber?.loadCancel() loadSubscriber = null currentProvider?.unbindService() currentProvider?.unbindService() currentProvider = null currentProvider = null } } Loading Loading @@ -210,6 +225,20 @@ open class ControlsBindingControllerImpl @Inject constructor( val callback: ControlsBindingController.LoadCallback val callback: ControlsBindingController.LoadCallback ) : CallbackRunnable(token) { ) : CallbackRunnable(token) { override fun doRun() { override fun doRun() { Log.d(TAG, "LoadSubscription: Complete and loading controls") callback.accept(list) } } private inner class OnCancelAndLoadRunnable( token: IBinder, val list: List<Control>, val subscription: IControlsSubscription, val callback: ControlsBindingController.LoadCallback ) : CallbackRunnable(token) { override fun doRun() { Log.d(TAG, "LoadSubscription: Canceling and loading controls") provider?.cancelSubscription(subscription) callback.accept(list) callback.accept(list) } } } } Loading @@ -220,6 +249,7 @@ open class ControlsBindingControllerImpl @Inject constructor( val requestLimit: Long val requestLimit: Long ) : CallbackRunnable(token) { ) : CallbackRunnable(token) { override fun doRun() { override fun doRun() { Log.d(TAG, "LoadSubscription: Starting subscription") provider?.startSubscription(subscription, requestLimit) provider?.startSubscription(subscription, requestLimit) } } } } Loading Loading @@ -254,34 +284,54 @@ open class ControlsBindingControllerImpl @Inject constructor( val requestLimit: Long val requestLimit: Long ) : IControlsSubscriber.Stub() { ) : IControlsSubscriber.Stub() { val loadedControls = ArrayList<Control>() val loadedControls = ArrayList<Control>() var hasError = false private var isTerminated = false private var _loadCancelInternal: (() -> Unit)? = null private var _loadCancelInternal: (() -> Unit)? = null private lateinit var subscription: IControlsSubscription fun loadCancel() = Runnable { fun loadCancel() = Runnable { Log.d(TAG, "Cancel load requested") Log.d(TAG, "Cancel load requested") _loadCancelInternal?.invoke() _loadCancelInternal?.invoke() } } override fun onSubscribe(token: IBinder, subs: IControlsSubscription) { override fun onSubscribe(token: IBinder, subs: IControlsSubscription) { _loadCancelInternal = subs::cancel subscription = subs _loadCancelInternal = { currentProvider?.cancelSubscription(subscription) } backgroundExecutor.execute(OnSubscribeRunnable(token, subs, requestLimit)) backgroundExecutor.execute(OnSubscribeRunnable(token, subs, requestLimit)) } } override fun onNext(token: IBinder, c: Control) { override fun onNext(token: IBinder, c: Control) { backgroundExecutor.execute { loadedControls.add(c) } backgroundExecutor.execute { if (isTerminated) return@execute loadedControls.add(c) // Once we have reached our requestLimit, send a request to cancel, and immediately // load the results. Calls to onError() and onComplete() are not required after // cancel. if (loadedControls.size >= requestLimit) { maybeTerminateAndRun( OnCancelAndLoadRunnable(token, loadedControls, subscription, callback) ) } } } } override fun onError(token: IBinder, s: String) { override fun onError(token: IBinder, s: String) { hasError = true maybeTerminateAndRun(OnLoadErrorRunnable(token, s, callback)) _loadCancelInternal = {} currentProvider?.cancelLoadTimeout() backgroundExecutor.execute(OnLoadErrorRunnable(token, s, callback)) } } override fun onComplete(token: IBinder) { override fun onComplete(token: IBinder) { maybeTerminateAndRun(OnLoadRunnable(token, loadedControls, callback)) } private fun maybeTerminateAndRun(postTerminateFn: Runnable) { if (isTerminated) return isTerminated = true _loadCancelInternal = {} _loadCancelInternal = {} if (!hasError) { currentProvider?.cancelLoadTimeout() currentProvider?.cancelLoadTimeout() backgroundExecutor.execute(OnLoadRunnable(token, loadedControls, callback)) } backgroundExecutor.execute(postTerminateFn) } } } } } } Loading
packages/SystemUI/src/com/android/systemui/controls/controller/ControlsController.kt +5 −0 Original line number Original line Diff line number Diff line Loading @@ -179,6 +179,11 @@ interface ControlsController : UserAwareController { */ */ fun countFavoritesForComponent(componentName: ComponentName): Int fun countFavoritesForComponent(componentName: ComponentName): Int /** * TEMPORARY for testing */ fun resetFavorites() /** /** * Interface for structure to pass data to [ControlsFavoritingActivity]. * Interface for structure to pass data to [ControlsFavoritingActivity]. */ */ Loading
packages/SystemUI/src/com/android/systemui/controls/controller/ControlsControllerImpl.kt +9 −0 Original line number Original line Diff line number Diff line Loading @@ -365,6 +365,8 @@ class ControlsControllerImpl @Inject constructor ( componentName: ComponentName, componentName: ComponentName, callback: Consumer<Boolean> callback: Consumer<Boolean> ) { ) { if (seedingInProgress) return Log.i(TAG, "Beginning request to seed favorites for: $componentName") Log.i(TAG, "Beginning request to seed favorites for: $componentName") if (!confirmAvailability()) { if (!confirmAvailability()) { if (userChanging) { if (userChanging) { Loading Loading @@ -495,6 +497,13 @@ class ControlsControllerImpl @Inject constructor ( } } } } override fun resetFavorites() { executor.execute { Favorites.clear() persistenceWrapper.storeFavorites(Favorites.getAllStructures()) } } override fun refreshStatus(componentName: ComponentName, control: Control) { override fun refreshStatus(componentName: ComponentName, control: Control) { if (!confirmAvailability()) { if (!confirmAvailability()) { Log.d(TAG, "Controls not available") Log.d(TAG, "Controls not available") Loading
packages/SystemUI/src/com/android/systemui/controls/controller/ControlsProviderLifecycleManager.kt +3 −20 Original line number Original line Diff line number Diff line Loading @@ -63,8 +63,6 @@ class ControlsProviderLifecycleManager( ) : IBinder.DeathRecipient { ) : IBinder.DeathRecipient { val token: IBinder = Binder() val token: IBinder = Binder() @GuardedBy("subscriptions") private val subscriptions = mutableListOf<IControlsSubscription>() private var requiresBound = false private var requiresBound = false @GuardedBy("queuedServiceMethods") @GuardedBy("queuedServiceMethods") private val queuedServiceMethods: MutableSet<ServiceMethod> = ArraySet() private val queuedServiceMethods: MutableSet<ServiceMethod> = ArraySet() Loading Loading @@ -194,7 +192,7 @@ class ControlsProviderLifecycleManager( * Request a call to [IControlsProvider.loadSuggested]. * Request a call to [IControlsProvider.loadSuggested]. * * * If the service is not bound, the call will be queued and the service will be bound first. * If the service is not bound, the call will be queued and the service will be bound first. * The service will be unbound after the controls are returned or the call times out. * The service will be unbound if the call times out. * * * @param subscriber the subscriber that manages coordination for loading controls * @param subscriber the subscriber that manages coordination for loading controls */ */ Loading Loading @@ -245,9 +243,7 @@ class ControlsProviderLifecycleManager( if (DEBUG) { if (DEBUG) { Log.d(TAG, "startSubscription: $subscription") Log.d(TAG, "startSubscription: $subscription") } } synchronized(subscriptions) { subscriptions.add(subscription) } wrapper?.request(subscription, requestLimit) wrapper?.request(subscription, requestLimit) } } Loading @@ -261,9 +257,7 @@ class ControlsProviderLifecycleManager( if (DEBUG) { if (DEBUG) { Log.d(TAG, "cancelSubscription: $subscription") Log.d(TAG, "cancelSubscription: $subscription") } } synchronized(subscriptions) { subscriptions.remove(subscription) } wrapper?.cancel(subscription) wrapper?.cancel(subscription) } } Loading @@ -281,17 +275,6 @@ class ControlsProviderLifecycleManager( onLoadCanceller?.run() onLoadCanceller?.run() onLoadCanceller = null onLoadCanceller = null // be sure to cancel all subscriptions val subs = synchronized(subscriptions) { ArrayList(subscriptions).also { subscriptions.clear() } } subs.forEach { wrapper?.cancel(it) } bindService(false) bindService(false) } } Loading
packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt +61 −2 Original line number Original line Diff line number Diff line Loading @@ -16,18 +16,26 @@ package com.android.systemui.controls.ui package com.android.systemui.controls.ui import android.animation.Animator import android.animation.AnimatorListenerAdapter import android.animation.ObjectAnimator import android.app.AlertDialog import android.app.Dialog import android.app.Dialog import android.content.ComponentName import android.content.ComponentName import android.content.Context import android.content.Context import android.content.DialogInterface import android.content.Intent import android.content.Intent import android.content.SharedPreferences import android.content.SharedPreferences import android.content.res.Configuration import android.content.res.Configuration import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable import android.graphics.drawable.LayerDrawable import android.graphics.drawable.LayerDrawable import android.os.Process import android.service.controls.Control import android.service.controls.Control import android.service.controls.actions.ControlAction import android.service.controls.actions.ControlAction import android.util.TypedValue import android.util.TypedValue import android.util.Log import android.util.Log import android.view.animation.AccelerateInterpolator import android.view.animation.DecelerateInterpolator import android.view.ContextThemeWrapper import android.view.ContextThemeWrapper import android.view.LayoutInflater import android.view.LayoutInflater import android.view.View import android.view.View Loading Loading @@ -77,6 +85,8 @@ class ControlsUiControllerImpl @Inject constructor ( private const val PREF_COMPONENT = "controls_component" private const val PREF_COMPONENT = "controls_component" private const val PREF_STRUCTURE = "controls_structure" private const val PREF_STRUCTURE = "controls_structure" private const val FADE_IN_MILLIS = 225L private val EMPTY_COMPONENT = ComponentName("", "") private val EMPTY_COMPONENT = ComponentName("", "") private val EMPTY_STRUCTURE = StructureInfo( private val EMPTY_STRUCTURE = StructureInfo( EMPTY_COMPONENT, EMPTY_COMPONENT, Loading Loading @@ -153,7 +163,20 @@ class ControlsUiControllerImpl @Inject constructor ( private fun reload(parent: ViewGroup) { private fun reload(parent: ViewGroup) { if (hidden) return if (hidden) return val fadeAnim = ObjectAnimator.ofFloat(parent, "alpha", 1.0f, 0.0f) fadeAnim.setInterpolator(AccelerateInterpolator(1.0f)) fadeAnim.setDuration(FADE_IN_MILLIS) fadeAnim.addListener(object : AnimatorListenerAdapter() { override fun onAnimationEnd(animation: Animator) { show(parent) show(parent) val showAnim = ObjectAnimator.ofFloat(parent, "alpha", 0.0f, 1.0f) showAnim.setInterpolator(DecelerateInterpolator(1.0f)) showAnim.setDuration(FADE_IN_MILLIS) showAnim.start() } }) fadeAnim.start() } } private fun showSeedingView(items: List<SelectionItem>) { private fun showSeedingView(items: List<SelectionItem>) { Loading Loading @@ -229,7 +252,8 @@ class ControlsUiControllerImpl @Inject constructor ( private fun createMenu() { private fun createMenu() { val items = arrayOf( val items = arrayOf( context.resources.getString(R.string.controls_menu_add) context.resources.getString(R.string.controls_menu_add), "Reset" ) ) var adapter = ArrayAdapter<String>(context, R.layout.controls_more_item, items) var adapter = ArrayAdapter<String>(context, R.layout.controls_more_item, items) Loading @@ -249,6 +273,8 @@ class ControlsUiControllerImpl @Inject constructor ( when (pos) { when (pos) { // 0: Add Control // 0: Add Control 0 -> startFavoritingActivity(view.context, selectedStructure) 0 -> startFavoritingActivity(view.context, selectedStructure) // 1: TEMPORARY for reset controls 1 -> showResetConfirmation() else -> Log.w(ControlsUiController.TAG, else -> Log.w(ControlsUiController.TAG, "Unsupported index ($pos) on 'more' menu selection") "Unsupported index ($pos) on 'more' menu selection") } } Loading @@ -275,6 +301,39 @@ class ControlsUiControllerImpl @Inject constructor ( }) }) } } private fun showResetConfirmation() { val builder = AlertDialog.Builder( context, android.R.style.Theme_DeviceDefault_Dialog_Alert ).apply { setMessage("For testing purposes: Would you like to " + "reset your favorited device controls?") setPositiveButton( android.R.string.ok, DialogInterface.OnClickListener { dialog, _ -> val userHandle = Process.myUserHandle() val userContext = context.createContextAsUser(userHandle, 0) val prefs = userContext.getSharedPreferences( "controls_prefs", Context.MODE_PRIVATE) prefs.edit().putBoolean("ControlsSeedingCompleted", false).apply() controlsController.get().resetFavorites() dialog.dismiss() context.sendBroadcast(Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)) }) setNegativeButton( android.R.string.cancel, DialogInterface.OnClickListener { dialog, _ -> dialog.cancel() } ) } builder.create().apply { getWindow().apply { setType(WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY) } }.show() } private fun createDropDown(items: List<SelectionItem>) { private fun createDropDown(items: List<SelectionItem>) { items.forEach { items.forEach { RenderInfo.registerComponentIcon(it.componentName, it.icon) RenderInfo.registerComponentIcon(it.componentName, it.icon) Loading