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

Commit 05470397 authored by Aaron Liu's avatar Aaron Liu Committed by Android (Google) Code Review
Browse files

Merge changes from topic "flexi-simpin" into main

* changes:
  Add tests for Flexiglass sim pin.
  SimPin for Flexiglass
parents 0c890ab4 feef99d7
Loading
Loading
Loading
Loading
+3 −3
Original line number Original line Diff line number Diff line
@@ -246,11 +246,9 @@ filegroup {
    srcs: [
    srcs: [
        /* Status bar fakes */
        /* Status bar fakes */
        "tests/src/com/android/systemui/statusbar/pipeline/airplane/data/repository/FakeAirplaneModeRepository.kt",
        "tests/src/com/android/systemui/statusbar/pipeline/airplane/data/repository/FakeAirplaneModeRepository.kt",
        "tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionRepository.kt",
        "tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionsRepository.kt",
        "tests/src/com/android/systemui/statusbar/pipeline/mobile/util/FakeMobileMappingsProxy.kt",
        "tests/src/com/android/systemui/statusbar/pipeline/shared/data/repository/FakeConnectivityRepository.kt",
        "tests/src/com/android/systemui/statusbar/pipeline/shared/data/repository/FakeConnectivityRepository.kt",
        "tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/FakeWifiRepository.kt",
        "tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/FakeWifiRepository.kt",
        "tests/src/com/android/systemui/statusbar/pipeline/mobile/util/FakeSubscriptionManagerProxy.kt",


        /* QS fakes */
        /* QS fakes */
        "tests/src/com/android/systemui/qs/pipeline/domain/interactor/FakeQSTile.kt",
        "tests/src/com/android/systemui/qs/pipeline/domain/interactor/FakeQSTile.kt",
@@ -263,6 +261,7 @@ filegroup {
    srcs: [
    srcs: [
        /* Keyguard converted tests */
        /* Keyguard converted tests */
        // data
        // data
        "tests/src/com/android/systemui/bouncer/data/repository/SimBouncerRepositoryTest.kt",
        "tests/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfigTest.kt",
        "tests/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfigTest.kt",
        "tests/src/com/android/systemui/keyguard/data/quickaffordance/FlashlightQuickAffordanceConfigTest.kt",
        "tests/src/com/android/systemui/keyguard/data/quickaffordance/FlashlightQuickAffordanceConfigTest.kt",
        "tests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigTest.kt",
        "tests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigTest.kt",
@@ -285,6 +284,7 @@ filegroup {
        "tests/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractorTest.kt",
        "tests/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractorTest.kt",
        "tests/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerCallbackInteractorTest.kt",
        "tests/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerCallbackInteractorTest.kt",
        "tests/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerInteractorWithCoroutinesTest.kt",
        "tests/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerInteractorWithCoroutinesTest.kt",
        "tests/src/com/android/systemui/bouncer/domain/interactor/SimBouncerInteractorTest.kt",
        "tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorTest.kt",
        "tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorTest.kt",
        "tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorTest.kt",
        "tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorTest.kt",
        "tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt",
        "tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt",
+109 −0
Original line number Original line Diff line number Diff line
@@ -18,6 +18,11 @@


package com.android.systemui.bouncer.ui.composable
package com.android.systemui.bouncer.ui.composable


import android.app.AlertDialog
import android.app.Dialog
import android.view.Gravity
import android.view.WindowManager
import android.widget.TextView
import androidx.compose.animation.core.Animatable
import androidx.compose.animation.core.Animatable
import androidx.compose.animation.core.VectorConverter
import androidx.compose.animation.core.VectorConverter
import androidx.compose.animation.core.tween
import androidx.compose.animation.core.tween
@@ -26,11 +31,16 @@ import androidx.compose.animation.graphics.res.animatedVectorResource
import androidx.compose.animation.graphics.res.rememberAnimatedVectorPainter
import androidx.compose.animation.graphics.res.rememberAnimatedVectorPainter
import androidx.compose.animation.graphics.vector.AnimatedImageVector
import androidx.compose.animation.graphics.vector.AnimatedImageVector
import androidx.compose.foundation.Image
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.getValue
@@ -41,14 +51,21 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.runtime.setValue
import androidx.compose.runtime.snapshotFlow
import androidx.compose.runtime.snapshotFlow
import androidx.compose.runtime.toMutableStateList
import androidx.compose.runtime.toMutableStateList
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.layout.layout
import androidx.compose.ui.layout.layout
import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.dimensionResource
import androidx.compose.ui.res.dimensionResource
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.Constraints
import androidx.compose.ui.unit.Constraints
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Dialog
import com.android.compose.PlatformOutlinedButton
import com.android.compose.animation.Easings
import com.android.compose.animation.Easings
import com.android.keyguard.PinShapeAdapter
import com.android.keyguard.PinShapeAdapter
import com.android.systemui.bouncer.ui.viewmodel.EntryToken.Digit
import com.android.systemui.bouncer.ui.viewmodel.EntryToken.Digit
@@ -189,6 +206,10 @@ private fun RegularPinInputDisplay(
    shapeAnimations: ShapeAnimations,
    shapeAnimations: ShapeAnimations,
    modifier: Modifier = Modifier,
    modifier: Modifier = Modifier,
) {
) {
    if (viewModel.isSimAreaVisible) {
        SimArea(viewModel = viewModel)
    }

    // Holds all currently [VisiblePinEntry] composables. This cannot be simply derived from
    // Holds all currently [VisiblePinEntry] composables. This cannot be simply derived from
    // `viewModel.pinInput` at composition, since deleting a pin entry needs to play a remove
    // `viewModel.pinInput` at composition, since deleting a pin entry needs to play a remove
    // animation, thus the composable to be removed has to remain in the composition until fully
    // animation, thus the composable to be removed has to remain in the composition until fully
@@ -234,6 +255,94 @@ private fun RegularPinInputDisplay(
    pinInputRow.Content(modifier)
    pinInputRow.Content(modifier)
}
}


@Composable
private fun SimArea(viewModel: PinBouncerViewModel) {
    val isLockedEsim by viewModel.isLockedEsim.collectAsState()
    val isSimUnlockingDialogVisible by viewModel.isSimUnlockingDialogVisible.collectAsState()
    val errorDialogMessage by viewModel.errorDialogMessage.collectAsState()
    var unlockDialog: Dialog? by remember { mutableStateOf(null) }
    var errorDialog: Dialog? by remember { mutableStateOf(null) }
    val context = LocalView.current.context

    DisposableEffect(isSimUnlockingDialogVisible) {
        if (isSimUnlockingDialogVisible) {
            val builder =
                AlertDialog.Builder(context).apply {
                    setMessage(context.getString(R.string.kg_sim_unlock_progress_dialog_message))
                    setCancelable(false)
                }
            unlockDialog =
                builder.create().apply {
                    window?.setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG)
                    show()
                    findViewById<TextView>(android.R.id.message)?.gravity = Gravity.CENTER
                }
        } else {
            unlockDialog?.hide()
            unlockDialog = null
        }

        onDispose {
            unlockDialog?.hide()
            unlockDialog = null
        }
    }

    DisposableEffect(errorDialogMessage) {
        if (errorDialogMessage != null) {
            val builder = AlertDialog.Builder(context)
            builder.setMessage(errorDialogMessage)
            builder.setCancelable(false)
            builder.setNeutralButton(R.string.ok, null)
            errorDialog =
                builder.create().apply {
                    window?.setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG)
                    setOnDismissListener { viewModel.onErrorDialogDismissed() }
                    show()
                }
        } else {
            errorDialog?.hide()
            errorDialog = null
        }

        onDispose {
            errorDialog?.hide()
            errorDialog = null
        }
    }

    Box(modifier = Modifier.padding(bottom = 20.dp)) {
        // If isLockedEsim is null, then we do not show anything.
        if (isLockedEsim == true) {
            PlatformOutlinedButton(
                onClick = { viewModel.onDisableEsimButtonClicked() },
            ) {
                Row(
                    horizontalArrangement = Arrangement.spacedBy(10.dp),
                    verticalAlignment = Alignment.CenterVertically
                ) {
                    Image(
                        painter = painterResource(id = R.drawable.ic_no_sim),
                        contentDescription = null,
                        colorFilter = ColorFilter.tint(MaterialTheme.colorScheme.onSurface)
                    )
                    Text(
                        text = stringResource(R.string.disable_carrier_button_text),
                        style = MaterialTheme.typography.bodyMedium,
                        color = MaterialTheme.colorScheme.onSurface,
                    )
                }
            }
        } else if (isLockedEsim == false) {
            Image(
                painter = painterResource(id = R.drawable.ic_lockscreen_sim),
                contentDescription = null,
                colorFilter = ColorFilter.tint(colorResource(id = R.color.background_protected))
            )
        }
    }
}

private class PinInputRow(
private class PinInputRow(
    val shapeAnimations: ShapeAnimations,
    val shapeAnimations: ShapeAnimations,
) {
) {
+10 −5
Original line number Original line Diff line number Diff line
@@ -32,6 +32,7 @@ import com.android.systemui.broadcast.BroadcastDispatcher
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.dagger.qualifiers.Background
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionsRepository
import com.android.systemui.user.data.repository.UserRepository
import com.android.systemui.user.data.repository.UserRepository
import com.android.systemui.util.kotlin.pairwise
import com.android.systemui.util.kotlin.pairwise
import com.android.systemui.util.time.SystemClock
import com.android.systemui.util.time.SystemClock
@@ -168,6 +169,7 @@ constructor(
    private val userRepository: UserRepository,
    private val userRepository: UserRepository,
    private val lockPatternUtils: LockPatternUtils,
    private val lockPatternUtils: LockPatternUtils,
    broadcastDispatcher: BroadcastDispatcher,
    broadcastDispatcher: BroadcastDispatcher,
    mobileConnectionsRepository: MobileConnectionsRepository,
) : AuthenticationRepository {
) : AuthenticationRepository {


    override val isAutoConfirmFeatureEnabled: StateFlow<Boolean> =
    override val isAutoConfirmFeatureEnabled: StateFlow<Boolean> =
@@ -192,9 +194,11 @@ constructor(
        get() = getSelectedUserInfo().id
        get() = getSelectedUserInfo().id


    override val authenticationMethod: Flow<AuthenticationMethodModel> =
    override val authenticationMethod: Flow<AuthenticationMethodModel> =
        userRepository.selectedUserInfo
        combine(userRepository.selectedUserInfo, mobileConnectionsRepository.isAnySimSecure) {
            .map { it.id }
                selectedUserInfo,
            .distinctUntilChanged()
                _ ->
                selectedUserInfo.id
            }
            .flatMapLatest { selectedUserId ->
            .flatMapLatest { selectedUserId ->
                broadcastDispatcher
                broadcastDispatcher
                    .broadcastFlow(
                    .broadcastFlow(
@@ -212,6 +216,7 @@ constructor(
                    blockingAuthenticationMethodInternal(selectedUserId)
                    blockingAuthenticationMethodInternal(selectedUserId)
                }
                }
            }
            }
            .distinctUntilChanged()


    override val minPatternLength: Int = LockPatternUtils.MIN_LOCK_PATTERN_SIZE
    override val minPatternLength: Int = LockPatternUtils.MIN_LOCK_PATTERN_SIZE


@@ -354,9 +359,9 @@ constructor(
        userId: Int,
        userId: Int,
    ): AuthenticationMethodModel {
    ): AuthenticationMethodModel {
        return when (getSecurityMode.apply(userId)) {
        return when (getSecurityMode.apply(userId)) {
            KeyguardSecurityModel.SecurityMode.PIN,
            KeyguardSecurityModel.SecurityMode.PIN -> AuthenticationMethodModel.Pin
            KeyguardSecurityModel.SecurityMode.SimPin,
            KeyguardSecurityModel.SecurityMode.SimPin,
            KeyguardSecurityModel.SecurityMode.SimPuk -> AuthenticationMethodModel.Pin
            KeyguardSecurityModel.SecurityMode.SimPuk -> AuthenticationMethodModel.Sim
            KeyguardSecurityModel.SecurityMode.Password -> AuthenticationMethodModel.Password
            KeyguardSecurityModel.SecurityMode.Password -> AuthenticationMethodModel.Password
            KeyguardSecurityModel.SecurityMode.Pattern -> AuthenticationMethodModel.Pattern
            KeyguardSecurityModel.SecurityMode.Pattern -> AuthenticationMethodModel.Pattern
            KeyguardSecurityModel.SecurityMode.None -> AuthenticationMethodModel.None
            KeyguardSecurityModel.SecurityMode.None -> AuthenticationMethodModel.None
+2 −0
Original line number Original line Diff line number Diff line
@@ -37,4 +37,6 @@ sealed class AuthenticationMethodModel(
    object Password : AuthenticationMethodModel(isSecure = true)
    object Password : AuthenticationMethodModel(isSecure = true)


    object Pattern : AuthenticationMethodModel(isSecure = true)
    object Pattern : AuthenticationMethodModel(isSecure = true)

    object Sim : AuthenticationMethodModel(isSecure = true)
}
}
+20 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2023 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.bouncer.data.model

/** Represents the locked sim card in the Bouncer. */
data class SimBouncerModel(val isSimPukLocked: Boolean, val subscriptionId: Int)
Loading