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

Commit 5b9ddcd5 authored by Aaron Liu's avatar Aaron Liu
Browse files

Make KeyguardBlueprint flow a state flow

To simplify the flow, make keyguardblueprint a stateflow and use a
shared flow in order to propagate a refresh.

Bug: 308957334
Test: change orientation on tablet device. Switch between blueprints
using adb.
Flag: NONE

Change-Id: I379bd80aa71313a6af9061bd9c2b9073bb3aae20
parent 384523ff
Loading
Loading
Loading
Loading
+14 −14
Original line number Diff line number Diff line
@@ -28,7 +28,7 @@ import java.util.TreeMap
import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow

/**
 * Manages blueprint changes for the lockscreen.
@@ -48,17 +48,14 @@ constructor(
    configurationRepository: ConfigurationRepository,
    blueprints: Set<@JvmSuppressWildcards KeyguardBlueprint>,
) {
    private val blueprintIdMap: TreeMap<String, KeyguardBlueprint> = TreeMap()
    private val _blueprint: MutableSharedFlow<KeyguardBlueprint> = MutableSharedFlow(replay = 1)
    val blueprint: Flow<KeyguardBlueprint> = _blueprint.asSharedFlow()

    // This is TreeMap so that we can order the blueprints and assign numerical values to the
    // blueprints in the adb tool.
    private val blueprintIdMap: TreeMap<String, KeyguardBlueprint> =
        TreeMap<String, KeyguardBlueprint>().apply { putAll(blueprints.associateBy { it.id }) }
    val blueprint: MutableStateFlow<KeyguardBlueprint> = MutableStateFlow(blueprintIdMap[DEFAULT]!!)
    val refreshBluePrint: MutableSharedFlow<Unit> = MutableSharedFlow(extraBufferCapacity = 1)
    val configurationChange: Flow<Unit> = configurationRepository.onAnyConfigurationChange

    init {
        blueprintIdMap.putAll(blueprints.associateBy { it.id })
        applyBlueprint(blueprintIdMap[DEFAULT]!!)
    }

    /**
     * Emits the blueprint value to the collectors.
     *
@@ -96,14 +93,17 @@ constructor(

    /** Emits the blueprint value to the collectors. */
    fun applyBlueprint(blueprint: KeyguardBlueprint?) {
        blueprint?.let { _blueprint.tryEmit(it) }
        if (blueprint == this.blueprint.value) {
            refreshBlueprint()
            return
        }

        blueprint?.let { this.blueprint.value = it }
    }

    /** Re-emits the last emitted blueprint value if possible. */
    fun refreshBlueprint() {
        if (_blueprint.replayCache.isNotEmpty()) {
            _blueprint.tryEmit(_blueprint.replayCache.last())
        }
        refreshBluePrint.tryEmit(Unit)
    }

    /** Prints all available blueprints to the PrintWriter. */
+20 −1
Original line number Diff line number Diff line
@@ -21,11 +21,15 @@ import android.content.Context
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.keyguard.data.repository.KeyguardBlueprintRepository
import com.android.systemui.keyguard.shared.model.KeyguardBlueprint
import com.android.systemui.keyguard.ui.view.layout.blueprints.DefaultKeyguardBlueprint
import com.android.systemui.keyguard.ui.view.layout.blueprints.SplitShadeKeyguardBlueprint
import com.android.systemui.statusbar.policy.SplitShadeStateController
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.merge
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.launch

@@ -39,7 +43,18 @@ constructor(
    private val splitShadeStateController: SplitShadeStateController,
) {

    val blueprint = keyguardBlueprintRepository.blueprint
    /**
     * The current blueprint for the lockscreen.
     *
     * This flow can also emit the same blueprint value if refreshBlueprint is emitted.
     */
    val blueprint: Flow<KeyguardBlueprint> =
        merge(
            keyguardBlueprintRepository.blueprint,
            keyguardBlueprintRepository.refreshBluePrint.map {
                keyguardBlueprintRepository.blueprint.value
            }
        )

    init {
        applicationScope.launch {
@@ -91,4 +106,8 @@ constructor(
    fun refreshBlueprint() {
        keyguardBlueprintRepository.refreshBlueprint()
    }

    fun getCurrentBlueprint(): KeyguardBlueprint {
        return keyguardBlueprintRepository.blueprint.value
    }
}
+17 −0
Original line number Diff line number Diff line
@@ -15,6 +15,8 @@
 *
 */

@file:OptIn(ExperimentalCoroutinesApi::class)

package com.android.systemui.keyguard.data.repository

import androidx.test.filters.SmallTest
@@ -25,8 +27,10 @@ import com.android.systemui.keyguard.ui.view.layout.blueprints.DefaultKeyguardBl
import com.android.systemui.keyguard.ui.view.layout.blueprints.DefaultKeyguardBlueprint.Companion.DEFAULT
import com.android.systemui.util.mockito.whenever
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.StandardTestDispatcher
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
@@ -76,8 +80,21 @@ class KeyguardBlueprintRepositoryTest : SysuiTestCase() {
    fun testTransitionToLayout_validId() {
        assertThat(underTest.applyBlueprint(DEFAULT)).isTrue()
    }

    @Test
    fun testTransitionToLayout_invalidId() {
        assertThat(underTest.applyBlueprint("abc")).isFalse()
    }

    @Test
    fun testTransitionToSameBlueprint_refreshesBlueprint() =
        testScope.runTest {
            val refreshBlueprint by collectLastValue(underTest.refreshBluePrint)
            runCurrent()

            underTest.applyBlueprint(defaultLockscreenBlueprint)
            runCurrent()

            assertThat(refreshBlueprint).isNotNull()
        }
}