Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5d94c43a authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Automerger Merge Worker
Browse files

Merge "Controls UI - Add 'reset' option for seeding" into rvc-dev am:...

Merge "Controls UI - Add 'reset' option for seeding" into rvc-dev am: 7cbba76b am: ab9d7e12 am: a9bdac92 am: e07521d6

Change-Id: I4a9d819bc78e9e1d57ccc75f89239d1709380fc5
parents 9c205ff8 e07521d6
Loading
Loading
Loading
Loading
+72 −22
Original line number Original line Diff line number Diff line
@@ -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())
@@ -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,
@@ -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) {
@@ -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
    }
    }
@@ -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)
        }
        }
    }
    }
@@ -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)
        }
        }
    }
    }
@@ -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)
        }
        }
    }
    }
}
}
+5 −0
Original line number Original line Diff line number Diff line
@@ -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].
     */
     */
+9 −0
Original line number Original line Diff line number Diff line
@@ -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) {
@@ -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")
+3 −20
Original line number Original line Diff line number Diff line
@@ -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()
@@ -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
     */
     */
@@ -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)
    }
    }


@@ -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)
    }
    }


@@ -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)
    }
    }


+61 −2
Original line number Original line Diff line number Diff line
@@ -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
@@ -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,
@@ -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>) {
@@ -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)


@@ -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")
                            }
                            }
@@ -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