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

Commit 865d8ce1 authored by Lucas Silva's avatar Lucas Silva
Browse files

Only listen to AppWidgetHost if communal is showing

Didn't notice any significant latency when doing this on tablet +
mobile, but wrapped in a flag anyways to test the behavior.

Bug: 406044666
Test: atest CommunalAppWidgetHostStartableTest
Flag: com.android.systemui.restrict_communal_app_widget_host_listening
Change-Id: Iaf357542d72f0c9152d4fe5c5e5673eaec9ad572
parent c5718c45
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -1314,6 +1314,16 @@ flag {
  is_fixed_read_only: true
}

flag {
  name: "restrict_communal_app_widget_host_listening"
  namespace: "systemui"
  description: "Only listens to AppWidgetHost when the communal hub is showing"
  bug: "406044666"
  metadata {
    purpose: PURPOSE_BUGFIX
  }
}

flag {
    name: "dream_overlay_updated_font"
    namespace: "systemui"
+36 −3
Original line number Diff line number Diff line
@@ -18,15 +18,20 @@ package com.android.systemui.communal.widgets

import android.appwidget.AppWidgetProviderInfo
import android.content.pm.UserInfo
import android.platform.test.annotations.DisableFlags
import android.platform.test.annotations.EnableFlags
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.Flags.FLAG_COMMUNAL_HUB
import com.android.systemui.Flags.FLAG_RESTRICT_COMMUNAL_APP_WIDGET_HOST_LISTENING
import com.android.systemui.SysuiTestCase
import com.android.systemui.communal.data.repository.fakeCommunalWidgetRepository
import com.android.systemui.communal.domain.interactor.CommunalInteractor
import com.android.systemui.communal.domain.interactor.communalInteractor
import com.android.systemui.communal.domain.interactor.communalSceneInteractor
import com.android.systemui.communal.domain.interactor.communalSettingsInteractor
import com.android.systemui.communal.domain.interactor.setCommunalEnabled
import com.android.systemui.communal.shared.model.CommunalScenes
import com.android.systemui.communal.shared.model.FakeGlanceableHubMultiUserHelper
import com.android.systemui.communal.shared.model.fakeGlanceableHubMultiUserHelper
import com.android.systemui.coroutines.collectLastValue
@@ -35,12 +40,13 @@ import com.android.systemui.flags.fakeFeatureFlagsClassic
import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
import com.android.systemui.keyguard.domain.interactor.keyguardInteractor
import com.android.systemui.kosmos.applicationCoroutineScope
import com.android.systemui.kosmos.runCurrent
import com.android.systemui.kosmos.runTest
import com.android.systemui.kosmos.testDispatcher
import com.android.systemui.kosmos.testScope
import com.android.systemui.settings.fakeUserTracker
import com.android.systemui.testKosmos
import com.android.systemui.user.data.repository.fakeUserRepository
import com.android.systemui.user.domain.interactor.userLockedInteractor
import com.android.systemui.util.mockito.whenever
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.flow.MutableSharedFlow
@@ -96,7 +102,6 @@ class CommunalAppWidgetHostStartableTest : SysuiTestCase() {
                kosmos.testDispatcher,
                { widgetManager },
                helper,
                kosmos.userLockedInteractor,
            )
    }

@@ -122,7 +127,8 @@ class CommunalAppWidgetHostStartableTest : SysuiTestCase() {
        }

    @Test
    fun communalShowingStartsAppWidgetHost() =
    @DisableFlags(FLAG_RESTRICT_COMMUNAL_APP_WIDGET_HOST_LISTENING)
    fun communalAvailableStartsAppWidgetHost() =
        with(kosmos) {
            testScope.runTest {
                setCommunalAvailable(true)
@@ -142,6 +148,33 @@ class CommunalAppWidgetHostStartableTest : SysuiTestCase() {
            }
        }

    @Test
    @EnableFlags(FLAG_RESTRICT_COMMUNAL_APP_WIDGET_HOST_LISTENING)
    fun communalShowingStartsAppWidgetHost() =
        kosmos.runTest {
            setCommunalAvailable(true)
            communalInteractor.setEditModeOpen(false)

            verify(appWidgetHost, never()).startListening()

            underTest.start()
            runCurrent()

            verify(appWidgetHost, never()).startListening()
            verify(appWidgetHost, never()).stopListening()

            communalSceneInteractor.changeScene(CommunalScenes.Communal, "test")
            runCurrent()

            verify(appWidgetHost).startListening()
            verify(appWidgetHost, never()).stopListening()

            communalSceneInteractor.changeScene(CommunalScenes.Blank, "test")
            runCurrent()

            verify(appWidgetHost).stopListening()
        }

    @Test
    fun communalAndEditModeNotShowingNeverStartListening() =
        with(kosmos) {
+11 −9
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.systemui.communal.widgets

import android.appwidget.AppWidgetProviderInfo
import com.android.systemui.CoreStartable
import com.android.systemui.Flags.restrictCommunalAppWidgetHostListening
import com.android.systemui.communal.domain.interactor.CommunalInteractor
import com.android.systemui.communal.domain.interactor.CommunalSettingsInteractor
import com.android.systemui.communal.shared.model.CommunalWidgetContentModel
@@ -27,11 +28,9 @@ import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
import com.android.systemui.settings.UserTracker
import com.android.systemui.user.domain.interactor.UserLockedInteractor
import com.android.systemui.util.kotlin.BooleanFlowOperators.allOf
import com.android.systemui.util.kotlin.BooleanFlowOperators.anyOf
import com.android.systemui.util.kotlin.BooleanFlowOperators.not
import com.android.systemui.util.kotlin.pairwise
import com.android.systemui.util.kotlin.sample
import dagger.Lazy
import javax.inject.Inject
@@ -60,7 +59,6 @@ constructor(
    @Main private val uiDispatcher: CoroutineDispatcher,
    private val glanceableHubWidgetManagerLazy: Lazy<GlanceableHubWidgetManager>,
    private val glanceableHubMultiUserHelper: GlanceableHubMultiUserHelper,
    private val userLockedInteractor: UserLockedInteractor,
) : CoreStartable {

    private val appWidgetHost by lazy { appWidgetHostLazy.get() }
@@ -92,14 +90,18 @@ constructor(
            !glanceableHubMultiUserHelper.glanceableHubHsumFlagEnabled ||
                !glanceableHubMultiUserHelper.isHeadlessSystemUserMode()
        ) {
            anyOf(communalInteractor.isCommunalAvailable, communalInteractor.editModeOpen)
            val listenFlow =
                if (restrictCommunalAppWidgetHostListening()) {
                    communalInteractor.isCommunalShowing
                } else {
                    communalInteractor.isCommunalAvailable
                }
            anyOf(listenFlow, communalInteractor.editModeOpen)
                // Only trigger updates on state changes, ignoring the initial false value.
                .pairwise(false)
                .filter { (previous, new) -> previous != new }
                .onEach { (_, shouldListen) -> updateAppWidgetHostActive(shouldListen) }
                .dropWhile { !it }
                .onEach { shouldListen -> updateAppWidgetHostActive(shouldListen) }
                .sample(communalInteractor.communalWidgets, ::Pair)
                .onEach { (withPrev, widgets) ->
                    val (_, isActive) = withPrev
                .onEach { (isActive, widgets) ->
                    // The validation is performed once the hub becomes active.
                    if (isActive) {
                        removeNotLockscreenWidgets(widgets)