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

Commit 5c8750ae authored by Automerger Merge Worker's avatar Automerger Merge Worker Committed by Android (Google) Code Review
Browse files

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

Merge "Merge "Add onTrustManagedChanged state to TrustRepository" into udc-dev am: 81beed54 am: cb716de5" into udc-d1-dev-plus-aosp
parents c1ca16c0 302650a8
Loading
Loading
Loading
Loading
+33 −3
Original line number Original line Diff line number Diff line
@@ -17,9 +17,11 @@
package com.android.keyguard.logging
package com.android.keyguard.logging


import com.android.systemui.dagger.SysUISingleton
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.keyguard.shared.model.TrustModel
import com.android.systemui.log.LogBuffer
import com.android.systemui.log.LogBuffer
import com.android.systemui.log.LogLevel
import com.android.systemui.log.LogLevel
import com.android.systemui.log.LogLevel.DEBUG
import com.android.systemui.log.dagger.KeyguardUpdateMonitorLog
import com.android.systemui.log.dagger.KeyguardUpdateMonitorLog
import javax.inject.Inject
import javax.inject.Inject


@@ -39,7 +41,7 @@ constructor(
    ) {
    ) {
        logBuffer.log(
        logBuffer.log(
            TAG,
            TAG,
            LogLevel.DEBUG,
            DEBUG,
            {
            {
                bool1 = enabled
                bool1 = enabled
                bool2 = newlyUnlocked
                bool2 = newlyUnlocked
@@ -65,7 +67,7 @@ constructor(
    fun trustModelEmitted(value: TrustModel) {
    fun trustModelEmitted(value: TrustModel) {
        logBuffer.log(
        logBuffer.log(
            TAG,
            TAG,
            LogLevel.DEBUG,
            DEBUG,
            {
            {
                int1 = value.userId
                int1 = value.userId
                bool1 = value.isTrusted
                bool1 = value.isTrusted
@@ -77,12 +79,40 @@ constructor(
    fun isCurrentUserTrusted(isCurrentUserTrusted: Boolean) {
    fun isCurrentUserTrusted(isCurrentUserTrusted: Boolean) {
        logBuffer.log(
        logBuffer.log(
            TAG,
            TAG,
            LogLevel.DEBUG,
            DEBUG,
            { bool1 = isCurrentUserTrusted },
            { bool1 = isCurrentUserTrusted },
            { "isCurrentUserTrusted emitted: $bool1" }
            { "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 {
    companion object {
        const val TAG = "TrustRepositoryLog"
        const val TAG = "TrustRepositoryLog"
    }
    }
+49 −11
Original line number Original line 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.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
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.keyguard.shared.model.TrustModel
import com.android.systemui.user.data.repository.UserRepository
import com.android.systemui.user.data.repository.UserRepository
import javax.inject.Inject
import javax.inject.Inject
@@ -37,6 +38,7 @@ import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.flow.shareIn
import kotlinx.coroutines.flow.shareIn
import kotlinx.coroutines.flow.stateIn


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


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

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


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


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


                        override fun onTrustError(message: CharSequence?) = Unit
                        override fun onTrustError(message: CharSequence?) = Unit


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

                        override fun onEnabledTrustAgentsChanged(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)
                trustManager.registerTrustListener(callback)
                logger.trustListenerRegistered()
                logger.trustListenerRegistered()
@@ -91,18 +104,43 @@ constructor(
                }
                }
            }
            }
            .onEach {
            .onEach {
                when (it) {
                    is TrustModel -> {
                        latestTrustModelForUser[it.userId] = it
                        latestTrustModelForUser[it.userId] = it
                        logger.trustModelEmitted(it)
                        logger.trustModelEmitted(it)
                    }
                    }
                    is TrustManagedModel -> {
                        trustManagedForUser[it.userId] = it
                        logger.trustManagedModelEmitted(it)
                    }
                }
            }
            .shareIn(applicationScope, started = SharingStarted.Eagerly, replay = 1)
            .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)
            combine(trust, userRepository.selectedUserInfo, ::Pair)
                .map { latestTrustModelForUser[it.second.id]?.isTrusted ?: false }
                .map { latestTrustModelForUser[it.second.id]?.isTrusted ?: false }
                .distinctUntilChanged()
                .distinctUntilChanged()
                .onEach { logger.isCurrentUserTrusted(it) }
                .onEach { logger.isCurrentUserTrusted(it) }
                .onStart { emit(false) }
                .onStart { emit(false) }

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


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


sealed class TrustMessage

/** Represents the trust state */
/** Represents the trust state */
data class TrustModel(
data class TrustModel(
    /** If true, the system believes the environment to be trusted. */
    /** If true, the system believes the environment to be trusted. */
    val isTrusted: Boolean,
    val isTrusted: Boolean,
    /** The user, for which the trust changed. */
    /** The user, for which the trust changed. */
    val userId: Int,
    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 Original line Diff line number Diff line
@@ -23,6 +23,7 @@ import androidx.test.filters.SmallTest
import com.android.keyguard.logging.TrustRepositoryLogger
import com.android.keyguard.logging.TrustRepositoryLogger
import com.android.systemui.RoboPilotTest
import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.FlowValue
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.log.LogBuffer
import com.android.systemui.log.LogBuffer
import com.android.systemui.log.LogcatEchoTracker
import com.android.systemui.log.LogcatEchoTracker
@@ -48,12 +49,14 @@ import org.mockito.MockitoAnnotations
@RunWith(AndroidJUnit4::class)
@RunWith(AndroidJUnit4::class)
class TrustRepositoryTest : SysuiTestCase() {
class TrustRepositoryTest : SysuiTestCase() {
    @Mock private lateinit var trustManager: TrustManager
    @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 userRepository: FakeUserRepository
    private lateinit var testScope: TestScope
    private lateinit var testScope: TestScope
    private val users = listOf(UserInfo(1, "user 1", 0), UserInfo(2, "user 1", 0))
    private val users = listOf(UserInfo(1, "user 1", 0), UserInfo(2, "user 1", 0))


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


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


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

    @Test
    @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 {
        testScope.runTest {
            runCurrent()
            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
            val currentUserId = users[0].id
            userRepository.setSelectedUserInfo(users[0])
            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()
            assertThat(isCurrentUserTrusted()).isTrue()


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


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

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


            val isCurrentUserTrusted = collectLastValue(underTest.isCurrentUserTrusted)
            // current user is trusted.
            // 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.
            // 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()
            assertThat(isCurrentUserTrusted()).isTrue()
        }
        }
@@ -119,29 +189,24 @@ class TrustRepositoryTest : SysuiTestCase() {
    @Test
    @Test
    fun isCurrentUserTrusted_whenTrustChangesForCurrentUser_emitsNewValue() =
    fun isCurrentUserTrusted_whenTrustChangesForCurrentUser_emitsNewValue() =
        testScope.runTest {
        testScope.runTest {
            runCurrent()
            init()
            verify(trustManager).registerTrustListener(listenerCaptor.capture())
            val listener = listenerCaptor.value
            userRepository.setSelectedUserInfo(users[0])
            userRepository.setSelectedUserInfo(users[0])


            val isCurrentUserTrusted = collectLastValue(underTest.isCurrentUserTrusted)
            listener.value.onTrustChanged(true, true, users[0].id, 0, emptyList())
            listener.onTrustChanged(true, true, users[0].id, 0, emptyList())
            assertThat(isCurrentUserTrusted()).isTrue()
            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()
            assertThat(isCurrentUserTrusted()).isFalse()
        }
        }


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

            val listener = listenerCaptor.value
            userRepository.setSelectedUserInfo(users[0])
            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])
            userRepository.setSelectedUserInfo(users[1])


            assertThat(isCurrentUserTrusted()).isFalse()
            assertThat(isCurrentUserTrusted()).isFalse()
@@ -150,12 +215,9 @@ class TrustRepositoryTest : SysuiTestCase() {
    @Test
    @Test
    fun isCurrentUserTrusted_trustChangesFirstBeforeUserInfoChanges_emitsCorrectValue() =
    fun isCurrentUserTrusted_trustChangesFirstBeforeUserInfoChanges_emitsCorrectValue() =
        testScope.runTest {
        testScope.runTest {
            runCurrent()
            init()
            verify(trustManager).registerTrustListener(listenerCaptor.capture())
            val listener = listenerCaptor.value
            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()).isFalse()
            assertThat(isCurrentUserTrusted()).isFalse()


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


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

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


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

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