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

Commit efa0a41f authored by Fabian Kozynski's avatar Fabian Kozynski
Browse files

Specify the parent viewgroup that should hide controls

Without this, launching ControlsActivtiy while it's running may cause to
two instances of it existing for a brief moment. As the new instance
will call `show` before the old instance calls `hide`, this will cause
everything to be hidden (and all listeners removed).

Instead, specify what parent view is calling hide. This makes it so we
can decide whether to completely hide `ControlsUiControllerImpl` or just
remove the views from the old parent.

Test: atest ControlsUiControllerImplTest
Test: manual, launch from LS and then from QS
Test: heapdump: old ControlsActivity is released
Bug: 267949140
Change-Id: I86a323cf25e5da81e610a21c4426872ef8684480
parent 7bf32dfd
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -134,7 +134,8 @@ class ControlsActivity @Inject constructor(
        super.onStop()
        mExitToDream = false

        uiController.hide()
        // parent is set in onStart, so the field is initialized when we get here
        uiController.hide(parent)
        controlsSettingsDialogManager.closeDialog()
    }

+7 −1
Original line number Diff line number Diff line
@@ -31,7 +31,13 @@ interface ControlsUiController {
    }

    fun show(parent: ViewGroup, onDismiss: Runnable, activityContext: Context)
    fun hide()

    /**
     * Hide the controls content if it's attached to this parent.
     */
    fun hide(parent: ViewGroup)

    val isShowing: Boolean

    /**
     * Returns the preferred activity to start, depending on if the user has favorited any
+20 −11
Original line number Diff line number Diff line
@@ -168,6 +168,9 @@ class ControlsUiControllerImpl @Inject constructor (
    private lateinit var activityContext: Context
    private lateinit var listingCallback: ControlsListingController.ControlsListingCallback

    override val isShowing: Boolean
        get() = !hidden

    init {
        dumpManager.registerDumpable(javaClass.name, this)
    }
@@ -727,7 +730,12 @@ class ControlsUiControllerImpl @Inject constructor (
        controlActionCoordinator.closeDialogs()
    }

    override fun hide() {
    override fun hide(parent: ViewGroup) {
        // We need to check for the parent because it's possible that  we have started showing in a
        // different activity. In that case, make sure to only clear things associated with the
        // passed parent
        if (parent == this.parent) {
            Log.d(ControlsUiController.TAG, "hide()")
            hidden = true

            closeDialogs(true)
@@ -735,7 +743,6 @@ class ControlsUiControllerImpl @Inject constructor (
            taskViewController?.dismiss()
            taskViewController = null

        parent.removeAllViews()
            controlsById.clear()
            controlViewsById.clear()

@@ -743,6 +750,8 @@ class ControlsUiControllerImpl @Inject constructor (

            if (!retainCache) RenderInfo.clearCache()
        }
        parent.removeAllViews()
    }

    override fun onRefreshState(componentName: ComponentName, controls: List<Control>) {
        val isLocked = !keyguardStateController.isUnlocked()
+24 −1
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import android.testing.TestableLooper
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
import androidx.test.filters.SmallTest
import com.android.systemui.R
@@ -328,7 +329,7 @@ class ControlsUiControllerImplTest : SysuiTestCase() {
            )
            .isTrue()

        underTest.hide()
        underTest.hide(parent)

        clearInvocations(controlsListingController, taskViewFactory)
        controlsSettingsRepository.setAllowActionOnTrivialControlsInLockscreen(false)
@@ -387,6 +388,28 @@ class ControlsUiControllerImplTest : SysuiTestCase() {
        assertThat(underTest.resolveActivity()).isEqualTo(ControlsActivity::class.java)
    }

    @Test
    fun testRemoveViewsOnlyForParentPassedInHide() {
        underTest.show(parent, {}, context)
        parent.addView(View(context))

        val mockParent: ViewGroup = mock()

        underTest.hide(mockParent)

        verify(mockParent).removeAllViews()
        assertThat(parent.childCount).isGreaterThan(0)
    }

    @Test
    fun testHideDifferentParentDoesntCancelListeners() {
        underTest.show(parent, {}, context)
        underTest.hide(mock())

        verify(controlsController, never()).unsubscribe()
        verify(controlsListingController, never()).removeCallback(any())
    }

    private fun setUpPanel(panel: SelectedItem.PanelItem): ControlsServiceInfo {
        val activity = ComponentName("pkg", "activity")
        sharedPreferences