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

Commit a1c57064 authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker
Browse files

Merge cherrypicks of ['googleplex-android-review.googlesource.com/29479089',...

Merge cherrypicks of ['googleplex-android-review.googlesource.com/29479089', 'googleplex-android-review.googlesource.com/29786736', 'googleplex-android-review.googlesource.com/29786429', 'googleplex-android-review.googlesource.com/29798985', 'googleplex-android-review.googlesource.com/29778785'] into 24Q4-release.

Change-Id: I9f97a0ef8388036950a01491eeb545f75aa826da
parents 95f2cf67 50655f73
Loading
Loading
Loading
Loading
+90 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.systemui.keyguard.ui.viewmodel

import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.biometrics.data.repository.fingerprintPropertyRepository
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.shared.model.TransitionState
import com.android.systemui.keyguard.shared.model.TransitionState.RUNNING
import com.android.systemui.keyguard.shared.model.TransitionState.STARTED
import com.android.systemui.keyguard.shared.model.TransitionStep
import com.android.systemui.kosmos.testScope
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import org.junit.Test
import org.junit.runner.RunWith

@ExperimentalCoroutinesApi
@SmallTest
@RunWith(AndroidJUnit4::class)
class DeviceEntryBackgroundViewModelTest : SysuiTestCase() {
    private val kosmos = testKosmos()
    private val testScope = kosmos.testScope
    private val underTest: DeviceEntryBackgroundViewModel by lazy {
        kosmos.deviceEntryBackgroundViewModel
    }

    @Test
    fun lockscreenToDozingTransitionChangesBackgroundViewAlphaToZero() =
        testScope.runTest {
            kosmos.fingerprintPropertyRepository.supportsUdfps()
            val alpha by collectLastValue(underTest.alpha)

            kosmos.fakeKeyguardTransitionRepository.sendTransitionSteps(
                listOf(dozingToLockscreen(0f, STARTED), dozingToLockscreen(0.1f)),
                testScope,
            )
            runCurrent()
            assertThat(alpha).isEqualTo(1.0f)

            kosmos.fakeKeyguardTransitionRepository.sendTransitionSteps(
                listOf(lockscreenToDozing(0f, STARTED)),
                testScope,
            )
            runCurrent()

            assertThat(alpha).isEqualTo(0.0f)
        }

    private fun lockscreenToDozing(value: Float, state: TransitionState = RUNNING): TransitionStep {
        return TransitionStep(
            from = KeyguardState.LOCKSCREEN,
            to = KeyguardState.DOZING,
            value = value,
            transitionState = state,
            ownerName = "DeviceEntryBackgroundViewModelTest",
        )
    }

    private fun dozingToLockscreen(value: Float, state: TransitionState = RUNNING): TransitionStep {
        return TransitionStep(
            from = KeyguardState.DOZING,
            to = KeyguardState.LOCKSCREEN,
            value = value,
            transitionState = state,
            ownerName = "DeviceEntryBackgroundViewModelTest",
        )
    }
}
+6 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.systemui.bouncer.domain.interactor

import android.util.Log
import com.android.keyguard.KeyguardUpdateMonitor
import com.android.systemui.biometrics.data.repository.FingerprintPropertyRepository
import com.android.systemui.bouncer.data.repository.KeyguardBouncerRepository
@@ -46,6 +47,7 @@ import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.stateIn

/** Encapsulates business logic for interacting with the lock-screen alternate bouncer. */
@@ -137,6 +139,8 @@ constructor(
                    flowOf(false)
                }
            }
            .distinctUntilChanged()
            .onEach { Log.d(TAG, "canShowAlternateBouncer changed to $it") }
            .stateIn(
                scope = scope,
                started = WhileSubscribed(),
@@ -234,5 +238,7 @@ constructor(

    companion object {
        private const val MIN_VISIBILITY_DURATION_UNTIL_TOUCHES_DISMISS_ALTERNATE_BOUNCER_MS = 200L

        private const val TAG = "AlternateBouncerInteractor"
    }
}
+2 −0
Original line number Diff line number Diff line
@@ -59,6 +59,7 @@ constructor(
    primaryBouncerToAodTransitionViewModel: PrimaryBouncerToAodTransitionViewModel,
    primaryBouncerToDozingTransitionViewModel: PrimaryBouncerToDozingTransitionViewModel,
    primaryBouncerToLockscreenTransitionViewModel: PrimaryBouncerToLockscreenTransitionViewModel,
    lockscreenToDozingTransitionViewModel: LockscreenToDozingTransitionViewModel,
) {
    val color: Flow<Int> =
        deviceEntryIconViewModel.useBackgroundProtection.flatMapLatest { useBackground ->
@@ -103,6 +104,7 @@ constructor(
                        primaryBouncerToLockscreenTransitionViewModel
                            .deviceEntryBackgroundViewAlpha,
                        occludedToDozingTransitionViewModel.deviceEntryBackgroundViewAlpha,
                        lockscreenToDozingTransitionViewModel.deviceEntryBackgroundViewAlpha,
                    )
                    .merge()
                    .onStart {
+4 −4
Original line number Diff line number Diff line
@@ -55,16 +55,16 @@ constructor(
            onCancel = { 1f },
        )

    val deviceEntryBackgroundViewAlpha: Flow<Float> =
        transitionAnimation.immediatelyTransitionTo(0f)

    override val deviceEntryParentViewAlpha: Flow<Float> =
        deviceEntryUdfpsInteractor.isUdfpsEnrolledAndEnabled.flatMapLatest {
            isUdfpsEnrolledAndEnabled ->
            if (isUdfpsEnrolledAndEnabled) {
                transitionAnimation.immediatelyTransitionTo(1f)
            } else {
                transitionAnimation.sharedFlow(
                    duration = 250.milliseconds,
                    onStep = { 1f - it },
                )
                transitionAnimation.sharedFlow(duration = 250.milliseconds, onStep = { 1f - it })
            }
        }
}
+13 −11
Original line number Diff line number Diff line
@@ -90,7 +90,7 @@ internal object SingleLineViewInflater {
                notification = notification,
                isGroupConversation = isGroupConversation,
                builder = builder,
                systemUiContext = systemUiContext
                systemUiContext = systemUiContext,
            )

        val conversationData =
@@ -98,7 +98,7 @@ internal object SingleLineViewInflater {
                // We don't show the sender's name for one-to-one conversation
                conversationSenderName =
                    if (isGroupConversation) conversationTextData?.senderName else null,
                avatar = conversationAvatar
                avatar = conversationAvatar,
            )

        return SingleLineViewModel(
@@ -111,7 +111,7 @@ internal object SingleLineViewInflater {
    @JvmStatic
    fun inflateRedactedSingleLineViewModel(
        context: Context,
        isConversation: Boolean = false
        isConversation: Boolean = false,
    ): SingleLineViewModel {
        val conversationData =
            if (isConversation) {
@@ -122,7 +122,7 @@ internal object SingleLineViewInflater {
                            com.android.systemui.res.R.drawable
                                .ic_redacted_notification_single_line_icon
                        )
                    )
                    ),
                )
            } else {
                null
@@ -134,7 +134,7 @@ internal object SingleLineViewInflater {
            context.getString(
                com.android.systemui.res.R.string.redacted_notification_single_line_text
            ),
            conversationData
            conversationData,
        )
    }

@@ -159,11 +159,13 @@ internal object SingleLineViewInflater {
        }

        // load the sender's name to display
        val name = lastMessage.senderPerson?.name
        // null senderPerson means the current user.
        val name = lastMessage.senderPerson?.name ?: user.name

        val senderName =
            systemUiContext.resources.getString(
                R.string.conversation_single_line_name_display,
                if (Flags.cleanUpSpansAndNewLines()) name?.toString() else name
                if (Flags.cleanUpSpansAndNewLines()) name?.toString() else name,
            )

        // We need to find back-up values for those texts if they are needed and empty
@@ -333,7 +335,7 @@ internal object SingleLineViewInflater {
                        sender.icon
                            ?: builder.getDefaultAvatar(
                                name = sender.name,
                                uniqueNames = uniqueNames
                                uniqueNames = uniqueNames,
                            )
                    lastKey = senderKey
                } else {
@@ -341,7 +343,7 @@ internal object SingleLineViewInflater {
                        sender.icon
                            ?: builder.getDefaultAvatar(
                                name = sender.name,
                                uniqueNames = uniqueNames
                                uniqueNames = uniqueNames,
                            )
                    break
                }
@@ -424,7 +426,7 @@ internal object SingleLineViewInflater {

    private fun Notification.Builder.getDefaultAvatar(
        name: CharSequence?,
        uniqueNames: PeopleHelper.NameToPrefixMap? = null
        uniqueNames: PeopleHelper.NameToPrefixMap? = null,
    ): Icon {
        val layoutColor = getSmallIconColor(/* isHeader= */ false)
        if (!name.isNullOrEmpty()) {
@@ -432,7 +434,7 @@ internal object SingleLineViewInflater {
            return peopleHelper.createAvatarSymbol(
                /* name = */ name,
                /* symbol = */ symbol,
                /* layoutColor = */ layoutColor
                /* layoutColor = */ layoutColor,
            )
        }
        // If name is null, create default avatar with background color
Loading