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

Commit 1b433c6a authored by Steve Elliott's avatar Steve Elliott
Browse files

Fix heads up isolated notif icon race condition

If the HeadsUpAppearanceController reported that there is an isolated
notification icon *before* the heads up StatusBarIconView is inflated by
the NotifPipeline, then the isolated icon would fail to show.

This is fixed by combining both the renderList and isolatedIcon states,
as opposed to sampling the former when the latter changes.

Flag: ACONFIG com.android.systemui.notifications_icon_container_refactor DEVELOPMENT
Bug: 278765923
Test: atest SystemUITests
Change-Id: If4897d973bfa301fe65ba9428289b3b4e0bb8685
parent 5df1df82
Loading
Loading
Loading
Loading
+10 −10
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ import com.android.systemui.util.ui.toAnimatedValueFlow
import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.map

@@ -83,19 +84,18 @@ constructor(
    /** An Icon to show "isolated" in the IconContainer. */
    val isolatedIcon: Flow<AnimatedValue<NotificationIconInfo?>> =
        headsUpIconInteractor.isolatedNotification
            .pairwise(initialValue = null)
            .sample(combine(icons, shadeInteractor.shadeExpansion, ::Pair)) {
                (prev, isolatedNotif),
                (iconsViewData, shadeExpansion),
                ->
                val iconInfo =
            .combine(icons) { isolatedNotif, iconsViewData ->
                isolatedNotif?.let {
                    iconsViewData.visibleKeys.firstOrNull { it.notifKey == isolatedNotif }
                }
            }
            .pairwise(initialValue = null)
            .distinctUntilChanged()
            .sample(shadeInteractor.shadeExpansion) { (prev, iconInfo), shadeExpansion ->
                val animate =
                    when {
                        isolatedNotif == prev -> false
                        isolatedNotif == null || prev == null -> shadeExpansion == 0f
                        iconInfo?.notifKey == prev?.notifKey -> false
                        iconInfo == null || prev == null -> shadeExpansion == 0f
                        else -> false
                    }
                AnimatableEvent(iconInfo, animate)
+1 −1
Original line number Diff line number Diff line
@@ -252,7 +252,7 @@ public class HeadsUpAppearanceController extends ViewController<HeadsUpStatusBar
            }
            if (NotificationIconContainerRefactor.isEnabled()) {
                mHeadsUpNotificationIconInteractor.setIsolatedIconNotificationKey(
                        newEntry == null ? null : newEntry.getKey());
                        newEntry == null ? null : newEntry.getRepresentativeEntry().getKey());
            } else {
                updateIsolatedIconLocation(false /* requireUpdate */);
                mNotificationIconAreaController.showIconIsolated(newEntry == null ? null
+27 −0
Original line number Diff line number Diff line
@@ -389,4 +389,31 @@ class NotificationIconContainerStatusBarViewModelTest : SysuiTestCase() {
            assertThat(isolatedIcon?.value?.notifKey).isEqualTo("notif1")
            assertThat(isolatedIcon?.isAnimating).isFalse()
        }

    @Test
    fun isolatedIcon_updateWhenIconDataChanges() =
        testComponent.runTest {
            val icon: Icon = mock()
            val isolatedIcon by collectLastValue(underTest.isolatedIcon)
            runCurrent()

            headsUpViewStateRepository.isolatedNotification.value = "notif1"
            runCurrent()

            activeNotificationsRepository.activeNotifications.value =
                ActiveNotificationsStore.Builder()
                    .apply {
                        addIndividualNotif(
                            activeNotificationModel(
                                key = "notif1",
                                groupKey = "group",
                                statusBarIcon = icon
                            )
                        )
                    }
                    .build()
            runCurrent()

            assertThat(isolatedIcon?.value?.notifKey).isEqualTo("notif1")
        }
}