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

Commit 7173a3fa authored by Fabian Kozynski's avatar Fabian Kozynski
Browse files

Bind panels with lower priority flags

When showing a panel in device controls, bind to it (but with lower
priority flags). That way, the application is kept in memory and results
in shorter latency when relaunching the panel with the TaskView.

Use BIND_NOT_PERCEPTIBLE so it will be at lower priority from SystemUI.
However, don't use WAIVE_PRIORITY, as by itself, it will kill the app
once the Task is finished in the device controls panel.

Test: manual
Test: atest com.android.systemui.controls
Fixes: 263790347

Change-Id: Ia99ade528bfdbfe2f67ecfe78f687f18df8b6cfd
parent a9a57f05
Loading
Loading
Loading
Loading
+10 −1
Original line number Diff line number Diff line
@@ -51,12 +51,21 @@ interface ControlsBindingController : UserAwareController {
    fun bindAndLoadSuggested(component: ComponentName, callback: LoadCallback)

    /**
     * Request to bind to the given service.
     * Request to bind to the given service. This should only be used for services using the full
     * [ControlsProviderService] API, where SystemUI renders the devices' UI.
     *
     * @param component The [ComponentName] of the service to bind
     */
    fun bindService(component: ComponentName)

    /**
     * Bind to a service that provides a Device Controls panel (embedded activity). This will allow
     * the app to remain "warm", and reduce latency.
     *
     * @param component The [ComponentName] of the [ControlsProviderService] to bind.
     */
    fun bindServiceForPanel(component: ComponentName)

    /**
     * Send a subscribe message to retrieve status of a set of controls.
     *
+4 −0
Original line number Diff line number Diff line
@@ -170,6 +170,10 @@ open class ControlsBindingControllerImpl @Inject constructor(
        retrieveLifecycleManager(component).bindService()
    }

    override fun bindServiceForPanel(component: ComponentName) {
        retrieveLifecycleManager(component).bindServiceForPanel()
    }

    override fun changeUser(newUser: UserHandle) {
        if (newUser == currentUser) return

+8 −0
Original line number Diff line number Diff line
@@ -188,6 +188,14 @@ interface ControlsController : UserAwareController {
    /** See [ControlsUiController.getPreferredSelectedItem]. */
    fun getPreferredSelection(): SelectedItem

    /**
     * Bind to a service that provides a Device Controls panel (embedded activity). This will allow
     * the app to remain "warm", and reduce latency.
     *
     * @param component The [ComponentName] of the [ControlsProviderService] to bind.
     */
    fun bindComponentForPanel(componentName: ComponentName)

    /**
     * Interface for structure to pass data to [ControlsFavoritingActivity].
     */
+4 −0
Original line number Diff line number Diff line
@@ -477,6 +477,10 @@ class ControlsControllerImpl @Inject constructor (
        bindingController.unsubscribe()
    }

    override fun bindComponentForPanel(componentName: ComponentName) {
        bindingController.bindServiceForPanel(componentName)
    }

    override fun addFavorite(
        componentName: ComponentName,
        structureName: CharSequence,
+12 −3
Original line number Diff line number Diff line
@@ -78,6 +78,10 @@ class ControlsProviderLifecycleManager(
        private const val DEBUG = true
        private val BIND_FLAGS = Context.BIND_AUTO_CREATE or Context.BIND_FOREGROUND_SERVICE or
            Context.BIND_NOT_PERCEPTIBLE
        // Use BIND_NOT_PERCEPTIBLE so it will be at lower priority from SystemUI.
        // However, don't use WAIVE_PRIORITY, as by itself, it will kill the app
        // once the Task is finished in the device controls panel.
        private val BIND_FLAGS_PANEL = Context.BIND_AUTO_CREATE or Context.BIND_NOT_PERCEPTIBLE
    }

    private val intent = Intent().apply {
@@ -87,18 +91,19 @@ class ControlsProviderLifecycleManager(
        })
    }

    private fun bindService(bind: Boolean) {
    private fun bindService(bind: Boolean, forPanel: Boolean = false) {
        executor.execute {
            requiresBound = bind
            if (bind) {
                if (bindTryCount != MAX_BIND_RETRIES) {
                if (bindTryCount != MAX_BIND_RETRIES && wrapper == null) {
                    if (DEBUG) {
                        Log.d(TAG, "Binding service $intent")
                    }
                    bindTryCount++
                    try {
                        val flags = if (forPanel) BIND_FLAGS_PANEL else BIND_FLAGS
                        val bound = context
                            .bindServiceAsUser(intent, serviceConnection, BIND_FLAGS, user)
                                .bindServiceAsUser(intent, serviceConnection, flags, user)
                        if (!bound) {
                            context.unbindService(serviceConnection)
                        }
@@ -279,6 +284,10 @@ class ControlsProviderLifecycleManager(
        bindService(true)
    }

    fun bindServiceForPanel() {
        bindService(bind = true, forPanel = true)
    }

    /**
     * Request unbind from the service.
     */
Loading