Ensure that GADLite is destroyed.

The FooterActionsController asks for a new
GlobalActionsDialogLite each time it is attached, and then that
it properly destroyes the GADLite each time it is detached.

GADLite registers listeners each time it is constructed. Prior to this
change, GADLite was constructed with each FooterActionsController, but
never had its #destroy method called. For the sake of semantic
correctness, we never reuse the GAD and instead create new one when
it is needed.

Fixes: 219535221
Test: manual && atest SystemUITests

Change-Id: Iab9aeb294e5995944a7c619013adccb8b36a3df9
This commit is contained in:
Dave Mankoff
2022-02-18 12:41:25 -05:00
parent bfdb2defa9
commit ec4b69a991
2 changed files with 49 additions and 10 deletions

View File

@@ -50,6 +50,7 @@ import com.android.systemui.util.ViewController
import com.android.systemui.util.settings.GlobalSettings
import javax.inject.Inject
import javax.inject.Named
import javax.inject.Provider
/**
* Manages [FooterActionsView] behaviour, both when it's placed in QS or QQS (split shade).
@@ -69,7 +70,7 @@ internal class FooterActionsController @Inject constructor(
private val fgsManagerFooterController: QSFgsManagerFooter,
private val falsingManager: FalsingManager,
private val metricsLogger: MetricsLogger,
private val globalActionsDialog: GlobalActionsDialogLite,
private val globalActionsDialogProvider: Provider<GlobalActionsDialogLite>,
private val uiEventLogger: UiEventLogger,
@Named(PM_LITE_ENABLED) private val showPMLiteButton: Boolean,
private val globalSetting: GlobalSettings,
@@ -77,6 +78,8 @@ internal class FooterActionsController @Inject constructor(
private val featureFlags: FeatureFlags
) : ViewController<FooterActionsView>(view) {
private var globalActionsDialog: GlobalActionsDialogLite? = null
private var lastExpansion = -1f
private var listening: Boolean = false
@@ -131,7 +134,7 @@ internal class FooterActionsController @Inject constructor(
startSettingsActivity()
} else if (v === powerMenuLite) {
uiEventLogger.log(GlobalActionsDialogLite.GlobalActionsEvent.GA_OPEN_QS)
globalActionsDialog.showOrHideDialog(false, true, v)
globalActionsDialog?.showOrHideDialog(false, true, v)
}
}
@@ -158,6 +161,7 @@ internal class FooterActionsController @Inject constructor(
@VisibleForTesting
public override fun onViewAttached() {
globalActionsDialog = globalActionsDialogProvider.get()
if (showPMLiteButton) {
powerMenuLite.visibility = View.VISIBLE
powerMenuLite.setOnClickListener(onClickListener)
@@ -215,6 +219,8 @@ internal class FooterActionsController @Inject constructor(
}
override fun onViewDetached() {
globalActionsDialog?.destroy()
globalActionsDialog = null
setListening(false)
multiUserSetting.isListening = false
}

View File

@@ -33,12 +33,15 @@ import org.mockito.ArgumentMatchers.any
import org.mockito.ArgumentMatchers.anyBoolean
import org.mockito.Mock
import org.mockito.Mockito
import org.mockito.Mockito.never
import org.mockito.Mockito.reset
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
import javax.inject.Provider
import org.mockito.Mockito.`when` as whenever
@SmallTest
@TestableLooper.RunWithLooper
@TestableLooper.RunWithLooper(setAsMainLooper = true)
@RunWith(AndroidTestingRunner::class)
class FooterActionsControllerTest : LeakCheckedTest() {
@Mock
@@ -56,6 +59,8 @@ class FooterActionsControllerTest : LeakCheckedTest() {
@Mock
private lateinit var multiUserSwitchController: MultiUserSwitchController
@Mock
private lateinit var globalActionsDialogProvider: Provider<GlobalActionsDialogLite>
@Mock
private lateinit var globalActionsDialog: GlobalActionsDialogLite
@Mock
private lateinit var uiEventLogger: UiEventLogger
@@ -83,15 +88,11 @@ class FooterActionsControllerTest : LeakCheckedTest() {
whenever(multiUserSwitchControllerFactory.create(any()))
.thenReturn(multiUserSwitchController)
whenever(featureFlags.isEnabled(Flags.NEW_FOOTER)).thenReturn(false)
whenever(globalActionsDialogProvider.get()).thenReturn(globalActionsDialog)
view = LayoutInflater.from(context)
.inflate(R.layout.footer_actions, null) as FooterActionsView
view = inflateView()
controller = FooterActionsController(view, multiUserSwitchControllerFactory,
activityStarter, userManager, userTracker, userInfoController,
deviceProvisionedController, securityFooterController, fgsManagerController,
falsingManager, metricsLogger, globalActionsDialog, uiEventLogger,
showPMLiteButton = true, fakeSettings, Handler(testableLooper.looper), featureFlags)
controller = constructFooterActionsController(view)
controller.init()
ViewUtils.attachView(view)
// View looper is the testable looper associated with the test
@@ -177,4 +178,36 @@ class FooterActionsControllerTest : LeakCheckedTest() {
assertThat(multiUserSwitch.visibility).isNotEqualTo(View.VISIBLE)
}
@Test
fun testCleanUpGAD() {
reset(globalActionsDialogProvider)
whenever(globalActionsDialogProvider.get()).thenReturn(globalActionsDialog)
val view = inflateView()
controller = constructFooterActionsController(view)
controller.init()
verify(globalActionsDialogProvider, never()).get()
// GAD is constructed during attachment
ViewUtils.attachView(view)
testableLooper.processAllMessages()
verify(globalActionsDialogProvider).get()
ViewUtils.detachView(view)
testableLooper.processAllMessages()
verify(globalActionsDialog).destroy()
}
private fun inflateView(): FooterActionsView {
return LayoutInflater.from(context)
.inflate(R.layout.footer_actions, null) as FooterActionsView
}
private fun constructFooterActionsController(view: FooterActionsView): FooterActionsController {
return FooterActionsController(view, multiUserSwitchControllerFactory,
activityStarter, userManager, userTracker, userInfoController,
deviceProvisionedController, securityFooterController, fgsManagerController,
falsingManager, metricsLogger, globalActionsDialogProvider, uiEventLogger,
showPMLiteButton = true, fakeSettings, Handler(testableLooper.looper), featureFlags)
}
}