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

Commit 302650a8 authored by Chandru S's avatar Chandru S Committed by Automerger Merge Worker
Browse files

Merge "Add onTrustManagedChanged state to TrustRepository" into udc-dev am:...

Merge "Add onTrustManagedChanged state to TrustRepository" into udc-dev am: 81beed54 am: cb716de5

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/22906407



Change-Id: I3007a8c144bb84285457699e9d95c3917692746b
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents 1c79a07e cb716de5
Loading
Loading
Loading
Loading
+33 −3
Original line number Diff line number Diff line
@@ -17,9 +17,11 @@
package com.android.keyguard.logging

import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.keyguard.shared.model.TrustManagedModel
import com.android.systemui.keyguard.shared.model.TrustModel
import com.android.systemui.log.LogBuffer
import com.android.systemui.log.LogLevel
import com.android.systemui.log.LogLevel.DEBUG
import com.android.systemui.log.dagger.KeyguardUpdateMonitorLog
import javax.inject.Inject

@@ -39,7 +41,7 @@ constructor(
    ) {
        logBuffer.log(
            TAG,
            LogLevel.DEBUG,
            DEBUG,
            {
                bool1 = enabled
                bool2 = newlyUnlocked
@@ -65,7 +67,7 @@ constructor(
    fun trustModelEmitted(value: TrustModel) {
        logBuffer.log(
            TAG,
            LogLevel.DEBUG,
            DEBUG,
            {
                int1 = value.userId
                bool1 = value.isTrusted
@@ -77,12 +79,40 @@ constructor(
    fun isCurrentUserTrusted(isCurrentUserTrusted: Boolean) {
        logBuffer.log(
            TAG,
            LogLevel.DEBUG,
            DEBUG,
            { bool1 = isCurrentUserTrusted },
            { "isCurrentUserTrusted emitted: $bool1" }
        )
    }

    fun isCurrentUserTrustManaged(isTrustManaged: Boolean) {
        logBuffer.log(TAG, DEBUG, { bool1 = isTrustManaged }, { "isTrustManaged emitted: $bool1" })
    }

    fun onTrustManagedChanged(trustManaged: Boolean, userId: Int) {
        logBuffer.log(
            TAG,
            DEBUG,
            {
                bool1 = trustManaged
                int1 = userId
            },
            { "onTrustManagedChanged isTrustManaged: $bool1 for user: $int1" }
        )
    }

    fun trustManagedModelEmitted(it: TrustManagedModel) {
        logBuffer.log(
            TAG,
            DEBUG,
            {
                bool1 = it.isTrustManaged
                int1 = it.userId
            },
            { "trustManagedModel emitted: userId: $int1, isTrustManaged: $bool1" }
        )
    }

    companion object {
        const val TAG = "TrustRepositoryLog"
    }
+49 −11
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLoggin
import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.keyguard.shared.model.TrustManagedModel
import com.android.systemui.keyguard.shared.model.TrustModel
import com.android.systemui.user.data.repository.UserRepository
import javax.inject.Inject
@@ -37,6 +38,7 @@ import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.flow.shareIn
import kotlinx.coroutines.flow.stateIn

/** Encapsulates any state relevant to trust agents and trust grants. */
interface TrustRepository {
@@ -45,6 +47,9 @@ interface TrustRepository {

    /** Flow representing whether active unlock is available for the current user. */
    val isCurrentUserActiveUnlockAvailable: StateFlow<Boolean>

    /** Reports that whether trust is managed has changed for the current user. */
    val isCurrentUserTrustManaged: StateFlow<Boolean>
}

@SysUISingleton
@@ -57,6 +62,7 @@ constructor(
    private val logger: TrustRepositoryLogger,
) : TrustRepository {
    private val latestTrustModelForUser = mutableMapOf<Int, TrustModel>()
    private val trustManagedForUser = mutableMapOf<Int, TrustManagedModel>()

    private val trust =
        conflatedCallbackFlow {
@@ -79,9 +85,16 @@ constructor(

                        override fun onTrustError(message: CharSequence?) = Unit

                        override fun onTrustManagedChanged(enabled: Boolean, userId: Int) = Unit

                        override fun onEnabledTrustAgentsChanged(userId: Int) = Unit

                        override fun onTrustManagedChanged(isTrustManaged: Boolean, userId: Int) {
                            logger.onTrustManagedChanged(isTrustManaged, userId)
                            trySendWithFailureLogging(
                                TrustManagedModel(userId, isTrustManaged),
                                TrustRepositoryLogger.TAG,
                                "onTrustManagedChanged"
                            )
                        }
                    }
                trustManager.registerTrustListener(callback)
                logger.trustListenerRegistered()
@@ -91,18 +104,43 @@ constructor(
                }
            }
            .onEach {
                when (it) {
                    is TrustModel -> {
                        latestTrustModelForUser[it.userId] = it
                        logger.trustModelEmitted(it)
                    }
                    is TrustManagedModel -> {
                        trustManagedForUser[it.userId] = it
                        logger.trustManagedModelEmitted(it)
                    }
                }
            }
            .shareIn(applicationScope, started = SharingStarted.Eagerly, replay = 1)

    override val isCurrentUserTrusted: Flow<Boolean> =
    // TODO: Implement based on TrustManager callback b/267322286
    override val isCurrentUserActiveUnlockAvailable: StateFlow<Boolean> = MutableStateFlow(true)

    override val isCurrentUserTrustManaged: StateFlow<Boolean>
        get() =
            combine(trust, userRepository.selectedUserInfo, ::Pair)
                .map { isUserTrustManaged(it.second.id) }
                .distinctUntilChanged()
                .onEach { logger.isCurrentUserTrustManaged(it) }
                .onStart { emit(false) }
                .stateIn(
                    scope = applicationScope,
                    started = SharingStarted.WhileSubscribed(),
                    initialValue = false
                )

    private fun isUserTrustManaged(userId: Int) =
        trustManagedForUser[userId]?.isTrustManaged ?: false

    override val isCurrentUserTrusted: Flow<Boolean>
        get() =
            combine(trust, userRepository.selectedUserInfo, ::Pair)
                .map { latestTrustModelForUser[it.second.id]?.isTrusted ?: false }
                .distinctUntilChanged()
                .onEach { logger.isCurrentUserTrusted(it) }
                .onStart { emit(false) }

    // TODO: Implement based on TrustManager callback b/267322286
    override val isCurrentUserActiveUnlockAvailable: StateFlow<Boolean> = MutableStateFlow(true)
}
+9 −1
Original line number Diff line number Diff line
@@ -16,10 +16,18 @@

package com.android.systemui.keyguard.shared.model

sealed class TrustMessage

/** Represents the trust state */
data class TrustModel(
    /** If true, the system believes the environment to be trusted. */
    val isTrusted: Boolean,
    /** The user, for which the trust changed. */
    val userId: Int,
)
) : TrustMessage()

/** Represents where trust agents are enabled for a particular user. */
data class TrustManagedModel(
    val userId: Int,
    val isTrustManaged: Boolean,
) : TrustMessage()
+91 −29
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import androidx.test.filters.SmallTest
import com.android.keyguard.logging.TrustRepositoryLogger
import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.FlowValue
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.log.LogBuffer
import com.android.systemui.log.LogcatEchoTracker
@@ -48,12 +49,14 @@ import org.mockito.MockitoAnnotations
@RunWith(AndroidJUnit4::class)
class TrustRepositoryTest : SysuiTestCase() {
    @Mock private lateinit var trustManager: TrustManager
    @Captor private lateinit var listenerCaptor: ArgumentCaptor<TrustManager.TrustListener>
    @Captor private lateinit var listener: ArgumentCaptor<TrustManager.TrustListener>
    private lateinit var userRepository: FakeUserRepository
    private lateinit var testScope: TestScope
    private val users = listOf(UserInfo(1, "user 1", 0), UserInfo(2, "user 1", 0))

    private lateinit var underTest: TrustRepository
    private lateinit var isCurrentUserTrusted: FlowValue<Boolean?>
    private lateinit var isCurrentUserTrustManaged: FlowValue<Boolean?>

    @Before
    fun setUp() {
@@ -70,21 +73,90 @@ class TrustRepositoryTest : SysuiTestCase() {
            TrustRepositoryImpl(testScope.backgroundScope, userRepository, trustManager, logger)
    }

    fun TestScope.init() {
        runCurrent()
        verify(trustManager).registerTrustListener(listener.capture())
        isCurrentUserTrustManaged = collectLastValue(underTest.isCurrentUserTrustManaged)
        isCurrentUserTrusted = collectLastValue(underTest.isCurrentUserTrusted)
    }

    @Test
    fun isCurrentUserTrusted_whenTrustChanges_emitsLatestValue() =
    fun isCurrentUserTrustManaged_whenItChanges_emitsLatestValue() =
        testScope.runTest {
            init()

            val currentUserId = users[0].id
            userRepository.setSelectedUserInfo(users[0])

            listener.value.onTrustManagedChanged(true, currentUserId)
            assertThat(isCurrentUserTrustManaged()).isTrue()

            listener.value.onTrustManagedChanged(false, currentUserId)

            assertThat(isCurrentUserTrustManaged()).isFalse()
        }

    @Test
    fun isCurrentUserTrustManaged_isFalse_byDefault() =
        testScope.runTest {
            runCurrent()
            verify(trustManager).registerTrustListener(listenerCaptor.capture())
            val listener = listenerCaptor.value

            assertThat(collectLastValue(underTest.isCurrentUserTrustManaged)()).isFalse()
        }

    @Test
    fun isCurrentUserTrustManaged_whenItChangesForDifferentUser_noops() =
        testScope.runTest {
            init()
            userRepository.setSelectedUserInfo(users[0])

            // current user's trust is managed.
            listener.value.onTrustManagedChanged(true, users[0].id)
            // some other user's trust is not managed.
            listener.value.onTrustManagedChanged(false, users[1].id)

            assertThat(isCurrentUserTrustManaged()).isTrue()
        }

    @Test
    fun isCurrentUserTrustManaged_whenUserChangesWithoutRecentTrustChange_defaultsToFalse() =
        testScope.runTest {
            init()

            userRepository.setSelectedUserInfo(users[0])
            listener.value.onTrustManagedChanged(true, users[0].id)

            userRepository.setSelectedUserInfo(users[1])

            assertThat(isCurrentUserTrustManaged()).isFalse()
        }

    @Test
    fun isCurrentUserTrustManaged_itChangesFirstBeforeUserInfoChanges_emitsCorrectValue() =
        testScope.runTest {
            init()
            userRepository.setSelectedUserInfo(users[1])

            listener.value.onTrustManagedChanged(true, users[0].id)
            assertThat(isCurrentUserTrustManaged()).isFalse()

            userRepository.setSelectedUserInfo(users[0])

            assertThat(isCurrentUserTrustManaged()).isTrue()
        }

    @Test
    fun isCurrentUserTrusted_whenTrustChanges_emitsLatestValue() =
        testScope.runTest {
            init()

            val currentUserId = users[0].id
            userRepository.setSelectedUserInfo(users[0])
            val isCurrentUserTrusted = collectLastValue(underTest.isCurrentUserTrusted)

            listener.onTrustChanged(true, false, currentUserId, 0, emptyList())
            listener.value.onTrustChanged(true, false, currentUserId, 0, emptyList())
            assertThat(isCurrentUserTrusted()).isTrue()

            listener.onTrustChanged(false, false, currentUserId, 0, emptyList())
            listener.value.onTrustChanged(false, false, currentUserId, 0, emptyList())

            assertThat(isCurrentUserTrusted()).isFalse()
        }
@@ -102,16 +174,14 @@ class TrustRepositoryTest : SysuiTestCase() {
    @Test
    fun isCurrentUserTrusted_whenTrustChangesForDifferentUser_noop() =
        testScope.runTest {
            runCurrent()
            verify(trustManager).registerTrustListener(listenerCaptor.capture())
            init()

            userRepository.setSelectedUserInfo(users[0])
            val listener = listenerCaptor.value

            val isCurrentUserTrusted = collectLastValue(underTest.isCurrentUserTrusted)
            // current user is trusted.
            listener.onTrustChanged(true, true, users[0].id, 0, emptyList())
            listener.value.onTrustChanged(true, true, users[0].id, 0, emptyList())
            // some other user is not trusted.
            listener.onTrustChanged(false, false, users[1].id, 0, emptyList())
            listener.value.onTrustChanged(false, false, users[1].id, 0, emptyList())

            assertThat(isCurrentUserTrusted()).isTrue()
        }
@@ -119,29 +189,24 @@ class TrustRepositoryTest : SysuiTestCase() {
    @Test
    fun isCurrentUserTrusted_whenTrustChangesForCurrentUser_emitsNewValue() =
        testScope.runTest {
            runCurrent()
            verify(trustManager).registerTrustListener(listenerCaptor.capture())
            val listener = listenerCaptor.value
            init()
            userRepository.setSelectedUserInfo(users[0])

            val isCurrentUserTrusted = collectLastValue(underTest.isCurrentUserTrusted)
            listener.onTrustChanged(true, true, users[0].id, 0, emptyList())
            listener.value.onTrustChanged(true, true, users[0].id, 0, emptyList())
            assertThat(isCurrentUserTrusted()).isTrue()

            listener.onTrustChanged(false, true, users[0].id, 0, emptyList())
            listener.value.onTrustChanged(false, true, users[0].id, 0, emptyList())
            assertThat(isCurrentUserTrusted()).isFalse()
        }

    @Test
    fun isCurrentUserTrusted_whenUserChangesWithoutRecentTrustChange_defaultsToFalse() =
        testScope.runTest {
            runCurrent()
            verify(trustManager).registerTrustListener(listenerCaptor.capture())
            val listener = listenerCaptor.value
            init()

            userRepository.setSelectedUserInfo(users[0])
            listener.onTrustChanged(true, true, users[0].id, 0, emptyList())
            listener.value.onTrustChanged(true, true, users[0].id, 0, emptyList())

            val isCurrentUserTrusted = collectLastValue(underTest.isCurrentUserTrusted)
            userRepository.setSelectedUserInfo(users[1])

            assertThat(isCurrentUserTrusted()).isFalse()
@@ -150,12 +215,9 @@ class TrustRepositoryTest : SysuiTestCase() {
    @Test
    fun isCurrentUserTrusted_trustChangesFirstBeforeUserInfoChanges_emitsCorrectValue() =
        testScope.runTest {
            runCurrent()
            verify(trustManager).registerTrustListener(listenerCaptor.capture())
            val listener = listenerCaptor.value
            val isCurrentUserTrusted = collectLastValue(underTest.isCurrentUserTrusted)
            init()

            listener.onTrustChanged(true, true, users[0].id, 0, emptyList())
            listener.value.onTrustChanged(true, true, users[0].id, 0, emptyList())
            assertThat(isCurrentUserTrusted()).isFalse()

            userRepository.setSelectedUserInfo(users[0])
+8 −0
Original line number Diff line number Diff line
@@ -31,10 +31,18 @@ class FakeTrustRepository : TrustRepository {
    override val isCurrentUserActiveUnlockAvailable: StateFlow<Boolean> =
        _isCurrentUserActiveUnlockAvailable.asStateFlow()

    private val _isCurrentUserTrustManaged = MutableStateFlow(false)
    override val isCurrentUserTrustManaged: StateFlow<Boolean>
        get() = _isCurrentUserTrustManaged

    fun setCurrentUserTrusted(trust: Boolean) {
        _isCurrentUserTrusted.value = trust
    }

    fun setCurrentUserTrustManaged(value: Boolean) {
        _isCurrentUserTrustManaged.value = value
    }

    fun setCurrentUserActiveUnlockAvailable(available: Boolean) {
        _isCurrentUserActiveUnlockAvailable.value = available
    }