Add tests for Flexiglass sim pin.
Add SimPinInteractorTest and SimPinRepositoryTest. Also update all of
the test infra to accomodate simpin integration. Update all relevant
tests for upstream CL.
Fixes: 291970178
Flag: NONE
Test: atest SystemUiRoboTest
Change-Id: Ic9989693a5194695a59bbeddcf14f1a56ca888a4
diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp
index 80fd516..cf51e21 100644
--- a/packages/SystemUI/Android.bp
+++ b/packages/SystemUI/Android.bp
@@ -246,11 +246,9 @@
srcs: [
/* Status bar fakes */
"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/wifi/data/repository/FakeWifiRepository.kt",
+ "tests/src/com/android/systemui/statusbar/pipeline/mobile/util/FakeSubscriptionManagerProxy.kt",
/* QS fakes */
"tests/src/com/android/systemui/qs/pipeline/domain/interactor/FakeQSTile.kt",
@@ -263,6 +261,7 @@
srcs: [
/* Keyguard converted tests */
// 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/FlashlightQuickAffordanceConfigTest.kt",
"tests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigTest.kt",
@@ -285,6 +284,7 @@
"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/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/KeyguardLongPressInteractorTest.kt",
"tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt",
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/util/FakeMobileMappingsProxy.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/util/FakeMobileMappingsProxy.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/util/FakeMobileMappingsProxy.kt
rename to packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/util/FakeMobileMappingsProxy.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/authentication/data/repository/AuthenticationRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/authentication/data/repository/AuthenticationRepositoryTest.kt
index 87ab5b0..64ddbc7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/authentication/data/repository/AuthenticationRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/authentication/data/repository/AuthenticationRepositoryTest.kt
@@ -29,7 +29,10 @@
import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.coroutines.collectValues
+import com.android.systemui.log.table.TableLogBuffer
import com.android.systemui.scene.SceneTestUtils
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeMobileConnectionsRepository
+import com.android.systemui.statusbar.pipeline.mobile.util.FakeMobileMappingsProxy
import com.android.systemui.user.data.repository.FakeUserRepository
import com.android.systemui.util.mockito.whenever
import com.google.common.truth.Truth.assertThat
@@ -51,10 +54,12 @@
@Mock private lateinit var lockPatternUtils: LockPatternUtils
@Mock private lateinit var getSecurityMode: Function<Int, KeyguardSecurityModel.SecurityMode>
+ @Mock private lateinit var tableLogger: TableLogBuffer
private val testUtils = SceneTestUtils(this)
private val testScope = testUtils.testScope
private val userRepository = FakeUserRepository()
+ private lateinit var mobileConnectionsRepository: FakeMobileConnectionsRepository
private lateinit var underTest: AuthenticationRepository
@@ -67,6 +72,8 @@
userRepository.setUserInfos(USER_INFOS)
runBlocking { userRepository.setSelectedUserInfo(USER_INFOS[0]) }
whenever(getSecurityMode.apply(anyInt())).thenAnswer { currentSecurityMode }
+ mobileConnectionsRepository =
+ FakeMobileConnectionsRepository(FakeMobileMappingsProxy(), tableLogger)
underTest =
AuthenticationRepositoryImpl(
@@ -76,6 +83,7 @@
userRepository = userRepository,
lockPatternUtils = lockPatternUtils,
broadcastDispatcher = fakeBroadcastDispatcher,
+ mobileConnectionsRepository = mobileConnectionsRepository,
)
}
@@ -97,6 +105,11 @@
assertThat(authMethod).isEqualTo(AuthenticationMethodModel.None)
assertThat(underTest.getAuthenticationMethod())
.isEqualTo(AuthenticationMethodModel.None)
+
+ currentSecurityMode = KeyguardSecurityModel.SecurityMode.SimPin
+ mobileConnectionsRepository.isAnySimSecure.value = true
+ assertThat(authMethod).isEqualTo(AuthenticationMethodModel.Sim)
+ assertThat(underTest.getAuthenticationMethod()).isEqualTo(AuthenticationMethodModel.Sim)
}
@Test
@@ -157,8 +170,7 @@
userRepository.setSelectedUserInfo(USER_INFOS[1])
assertThat(values.last()).isTrue()
-
- }
+ }
private fun setSecurityModeAndDispatchBroadcast(
securityMode: KeyguardSecurityModel.SecurityMode,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/data/repository/SimBouncerRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bouncer/data/repository/SimBouncerRepositoryTest.kt
new file mode 100644
index 0000000..b391b5a
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/bouncer/data/repository/SimBouncerRepositoryTest.kt
@@ -0,0 +1,201 @@
+/*
+ * 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.repository
+
+import android.telephony.TelephonyManager
+import android.telephony.euicc.EuiccManager
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.keyguard.KeyguardUpdateMonitor
+import com.android.keyguard.KeyguardUpdateMonitorCallback
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.statusbar.pipeline.mobile.util.FakeSubscriptionManagerProxy
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.whenever
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.Flow
+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
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito.anyInt
+import org.mockito.MockitoAnnotations
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class SimBouncerRepositoryTest : SysuiTestCase() {
+ @Mock lateinit var euiccManager: EuiccManager
+ @Mock lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor
+
+ private val dispatcher = StandardTestDispatcher()
+ private val testScope = TestScope(dispatcher)
+ private val fakeSubscriptionManagerProxy = FakeSubscriptionManagerProxy()
+ private val keyguardUpdateMonitorCallbacks = mutableListOf<KeyguardUpdateMonitorCallback>()
+
+ private lateinit var underTest: SimBouncerRepositoryImpl
+
+ @Before
+ fun setup() {
+ MockitoAnnotations.initMocks(/* testClass = */ this)
+ whenever(keyguardUpdateMonitor.registerCallback(any())).thenAnswer {
+ val cb = it.arguments[0] as KeyguardUpdateMonitorCallback
+ keyguardUpdateMonitorCallbacks.add(cb)
+ }
+ whenever(keyguardUpdateMonitor.removeCallback(any())).thenAnswer {
+ keyguardUpdateMonitorCallbacks.remove(it.arguments[0])
+ }
+ underTest =
+ SimBouncerRepositoryImpl(
+ applicationScope = testScope.backgroundScope,
+ backgroundDispatcher = dispatcher,
+ resources = context.resources,
+ keyguardUpdateMonitor = keyguardUpdateMonitor,
+ subscriptionManager = fakeSubscriptionManagerProxy,
+ broadcastDispatcher = fakeBroadcastDispatcher,
+ euiccManager = euiccManager,
+ )
+ }
+
+ @Test
+ fun subscriptionId() =
+ testScope.runTest {
+ val subscriptionId =
+ emitSubscriptionIdAndCollectLastValue(underTest.subscriptionId, subId = 2)
+ assertThat(subscriptionId).isEqualTo(2)
+ }
+
+ @Test
+ fun activeSubscriptionInfo() =
+ testScope.runTest {
+ fakeSubscriptionManagerProxy.setActiveSubscriptionInfo(subId = 2)
+ val activeSubscriptionInfo =
+ emitSubscriptionIdAndCollectLastValue(underTest.activeSubscriptionInfo, subId = 2)
+
+ assertThat(activeSubscriptionInfo?.subscriptionId).isEqualTo(2)
+ }
+
+ @Test
+ fun isLockedEsim_initialValue_isNull() =
+ testScope.runTest {
+ val isLockedEsim by collectLastValue(underTest.isLockedEsim)
+ assertThat(isLockedEsim).isNull()
+ }
+
+ @Test
+ fun isLockedEsim() =
+ testScope.runTest {
+ whenever(euiccManager.isEnabled).thenReturn(true)
+ fakeSubscriptionManagerProxy.setActiveSubscriptionInfo(subId = 2, isEmbedded = true)
+ val isLockedEsim =
+ emitSubscriptionIdAndCollectLastValue(underTest.isLockedEsim, subId = 2)
+ assertThat(isLockedEsim).isTrue()
+ }
+
+ @Test
+ fun isLockedEsim_notEmbedded() =
+ testScope.runTest {
+ fakeSubscriptionManagerProxy.setActiveSubscriptionInfo(subId = 2, isEmbedded = false)
+ val isLockedEsim =
+ emitSubscriptionIdAndCollectLastValue(underTest.isLockedEsim, subId = 2)
+ assertThat(isLockedEsim).isFalse()
+ }
+
+ @Test
+ fun isSimPukLocked() =
+ testScope.runTest {
+ val isSimPukLocked =
+ emitSubscriptionIdAndCollectLastValue(
+ underTest.isSimPukLocked,
+ subId = 2,
+ isSimPuk = true
+ )
+ assertThat(isSimPukLocked).isTrue()
+ }
+
+ @Test
+ fun setSimPukUserInput() {
+ val pukCode = "00000000"
+ val pinCode = "1234"
+ underTest.setSimPukUserInput(pukCode, pinCode)
+ assertThat(underTest.simPukInputModel.enteredSimPuk).isEqualTo(pukCode)
+ assertThat(underTest.simPukInputModel.enteredSimPin).isEqualTo(pinCode)
+ }
+
+ @Test
+ fun setSimPukUserInput_nullPuk() {
+ val pukCode = null
+ val pinCode = "1234"
+ underTest.setSimPukUserInput(pukCode, pinCode)
+ assertThat(underTest.simPukInputModel.enteredSimPuk).isNull()
+ assertThat(underTest.simPukInputModel.enteredSimPin).isEqualTo(pinCode)
+ }
+
+ @Test
+ fun setSimPukUserInput_nullPin() {
+ val pukCode = "00000000"
+ val pinCode = null
+ underTest.setSimPukUserInput(pukCode, pinCode)
+ assertThat(underTest.simPukInputModel.enteredSimPuk).isEqualTo(pukCode)
+ assertThat(underTest.simPukInputModel.enteredSimPin).isNull()
+ }
+
+ @Test
+ fun setSimPukUserInput_nullCodes() {
+ underTest.setSimPukUserInput()
+ assertThat(underTest.simPukInputModel.enteredSimPuk).isNull()
+ assertThat(underTest.simPukInputModel.enteredSimPin).isNull()
+ }
+
+ @Test
+ fun setSimPinVerificationErrorMessage() =
+ testScope.runTest {
+ val errorMsg = "error"
+ underTest.setSimVerificationErrorMessage(errorMsg)
+ val msg by collectLastValue(underTest.errorDialogMessage)
+ assertThat(msg).isEqualTo(errorMsg)
+ }
+
+ /** Emits a new sim card state and collects the last value of the flow argument. */
+ @OptIn(ExperimentalCoroutinesApi::class)
+ private fun <T> TestScope.emitSubscriptionIdAndCollectLastValue(
+ flow: Flow<T>,
+ subId: Int = 1,
+ isSimPuk: Boolean = false
+ ): T? {
+ val value by collectLastValue(flow)
+ runCurrent()
+ val simState =
+ if (isSimPuk) {
+ TelephonyManager.SIM_STATE_PUK_REQUIRED
+ } else {
+ TelephonyManager.SIM_STATE_PIN_REQUIRED
+ }
+ whenever(keyguardUpdateMonitor.getNextSubIdForState(anyInt())).thenReturn(-1)
+ whenever(keyguardUpdateMonitor.getNextSubIdForState(simState)).thenReturn(subId)
+ keyguardUpdateMonitorCallbacks.forEach {
+ it.onSimStateChanged(subId, /* slotId= */ 0, simState)
+ }
+ runCurrent()
+ return value
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorTest.kt
index 296f966..6e2e637 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/BouncerInteractorTest.kt
@@ -88,6 +88,19 @@
}
@Test
+ fun pinAuthMethod_sim_skipsAuthentication() =
+ testScope.runTest {
+ utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Sim)
+ runCurrent()
+
+ // We rely on TelephonyManager to authenticate the sim card.
+ // Additionally, authenticating the sim card does not unlock the device.
+ // Thus, when auth method is sim, we expect to skip here.
+ assertThat(underTest.authenticate(FakeAuthenticationRepository.DEFAULT_PIN))
+ .isEqualTo(AuthenticationResult.SKIPPED)
+ }
+
+ @Test
fun pinAuthMethod_tryAutoConfirm_withAutoConfirmPin() =
testScope.runTest {
val isAutoConfirmEnabled by collectLastValue(underTest.isAutoConfirmEnabled)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/SimBouncerInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/SimBouncerInteractorTest.kt
new file mode 100644
index 0000000..8c53c0e
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/SimBouncerInteractorTest.kt
@@ -0,0 +1,351 @@
+/*
+ * 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.domain.interactor
+
+import android.content.res.Resources
+import android.telephony.PinResult
+import android.telephony.SubscriptionInfo
+import android.telephony.TelephonyManager
+import android.telephony.euicc.EuiccManager
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.keyguard.KeyguardUpdateMonitor
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.bouncer.data.repository.FakeSimBouncerRepository
+import com.android.systemui.bouncer.domain.interactor.SimBouncerInteractor.Companion.INVALID_SUBSCRIPTION_ID
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.res.R
+import com.android.systemui.scene.SceneTestUtils
+import com.android.systemui.util.mockito.whenever
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers
+import org.mockito.ArgumentMatchers.anyInt
+import org.mockito.ArgumentMatchers.anyString
+import org.mockito.ArgumentMatchers.eq
+import org.mockito.Mock
+import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+@OptIn(ExperimentalCoroutinesApi::class)
+class SimBouncerInteractorTest : SysuiTestCase() {
+ @Mock lateinit var telephonyManager: TelephonyManager
+ @Mock lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor
+ @Mock lateinit var euiccManager: EuiccManager
+
+ private val utils = SceneTestUtils(this)
+ private val bouncerSimRepository = FakeSimBouncerRepository()
+ private val resources: Resources = context.resources
+ private val testScope = utils.testScope
+
+ private lateinit var underTest: SimBouncerInteractor
+
+ @Before
+ fun setup() {
+ MockitoAnnotations.initMocks(this)
+ underTest =
+ SimBouncerInteractor(
+ context,
+ testScope.backgroundScope,
+ utils.testDispatcher,
+ bouncerSimRepository,
+ telephonyManager,
+ resources,
+ keyguardUpdateMonitor,
+ euiccManager,
+ utils.mobileConnectionsRepository,
+ )
+ }
+
+ @Test
+ fun getDefaultMessage() {
+ bouncerSimRepository.setSubscriptionId(1)
+ bouncerSimRepository.setActiveSubscriptionInfo(
+ SubscriptionInfo.Builder().setDisplayName("sim").build()
+ )
+ whenever(telephonyManager.activeModemCount).thenReturn(1)
+
+ assertThat(underTest.getDefaultMessage())
+ .isEqualTo(resources.getString(R.string.kg_sim_pin_instructions))
+ }
+
+ @Test
+ fun getDefaultMessage_isPuk() {
+ bouncerSimRepository.setSimPukLocked(true)
+ bouncerSimRepository.setSubscriptionId(1)
+ bouncerSimRepository.setActiveSubscriptionInfo(
+ SubscriptionInfo.Builder().setDisplayName("sim").build()
+ )
+ whenever(telephonyManager.activeModemCount).thenReturn(1)
+
+ assertThat(underTest.getDefaultMessage())
+ .isEqualTo(resources.getString(R.string.kg_puk_enter_puk_hint))
+ }
+
+ @Test
+ fun getDefaultMessage_isEsimLocked() {
+ bouncerSimRepository.setLockedEsim(true)
+ bouncerSimRepository.setSubscriptionId(1)
+ bouncerSimRepository.setActiveSubscriptionInfo(
+ SubscriptionInfo.Builder().setDisplayName("sim").build()
+ )
+ whenever(telephonyManager.activeModemCount).thenReturn(1)
+
+ val msg = resources.getString(R.string.kg_sim_pin_instructions)
+ assertThat(underTest.getDefaultMessage())
+ .isEqualTo(resources.getString(R.string.kg_sim_lock_esim_instructions, msg))
+ }
+
+ @Test
+ fun getDefaultMessage_multipleSims() {
+ bouncerSimRepository.setSubscriptionId(1)
+ bouncerSimRepository.setActiveSubscriptionInfo(
+ SubscriptionInfo.Builder().setDisplayName("sim").build()
+ )
+ whenever(telephonyManager.activeModemCount).thenReturn(2)
+
+ assertThat(underTest.getDefaultMessage())
+ .isEqualTo(resources.getString(R.string.kg_sim_pin_instructions_multi, "sim"))
+ }
+
+ @Test
+ fun getDefaultMessage_multipleSims_isPuk() {
+ bouncerSimRepository.setSimPukLocked(true)
+ bouncerSimRepository.setSubscriptionId(1)
+ bouncerSimRepository.setActiveSubscriptionInfo(
+ SubscriptionInfo.Builder().setDisplayName("sim").build()
+ )
+ whenever(telephonyManager.activeModemCount).thenReturn(2)
+
+ assertThat(underTest.getDefaultMessage())
+ .isEqualTo(resources.getString(R.string.kg_puk_enter_puk_hint_multi, "sim"))
+ }
+
+ @Test
+ fun getDefaultMessage_multipleSims_emptyDisplayName() {
+ bouncerSimRepository.setSubscriptionId(1)
+ bouncerSimRepository.setActiveSubscriptionInfo(SubscriptionInfo.Builder().build())
+ whenever(telephonyManager.activeModemCount).thenReturn(2)
+
+ assertThat(underTest.getDefaultMessage())
+ .isEqualTo(resources.getString(R.string.kg_sim_pin_instructions))
+ }
+
+ @Test
+ fun getDefaultMessage_multipleSims_emptyDisplayName_isPuk() {
+ bouncerSimRepository.setSimPukLocked(true)
+ bouncerSimRepository.setSubscriptionId(1)
+ bouncerSimRepository.setActiveSubscriptionInfo(SubscriptionInfo.Builder().build())
+ whenever(telephonyManager.activeModemCount).thenReturn(2)
+
+ assertThat(underTest.getDefaultMessage())
+ .isEqualTo(resources.getString(R.string.kg_puk_enter_puk_hint))
+ }
+
+ @Test
+ fun resetSimPukUserInput() {
+ bouncerSimRepository.setSimPukUserInput("00000000", "1234")
+
+ assertThat(bouncerSimRepository.simPukInputModel.enteredSimPuk).isEqualTo("00000000")
+ assertThat(bouncerSimRepository.simPukInputModel.enteredSimPin).isEqualTo("1234")
+
+ underTest.resetSimPukUserInput()
+
+ assertThat(bouncerSimRepository.simPukInputModel.enteredSimPuk).isNull()
+ assertThat(bouncerSimRepository.simPukInputModel.enteredSimPin).isNull()
+ }
+
+ @Test
+ fun disableEsim() =
+ testScope.runTest {
+ val portIndex = 1
+ bouncerSimRepository.setActiveSubscriptionInfo(
+ SubscriptionInfo.Builder().setPortIndex(portIndex).build()
+ )
+
+ underTest.disableEsim()
+ runCurrent()
+
+ verify(euiccManager)
+ .switchToSubscription(
+ eq(INVALID_SUBSCRIPTION_ID),
+ eq(portIndex),
+ ArgumentMatchers.any()
+ )
+ }
+
+ @Test
+ fun verifySimPin() =
+ testScope.runTest {
+ bouncerSimRepository.setSubscriptionId(1)
+ bouncerSimRepository.setSimPukLocked(false)
+ whenever(telephonyManager.createForSubscriptionId(anyInt()))
+ .thenReturn(telephonyManager)
+ whenever(telephonyManager.supplyIccLockPin(anyString()))
+ .thenReturn(PinResult(PinResult.PIN_RESULT_TYPE_SUCCESS, 1))
+
+ val msg: String? = underTest.verifySim(listOf(0, 0, 0, 0))
+ runCurrent()
+ assertThat(msg).isNull()
+
+ verify(keyguardUpdateMonitor).reportSimUnlocked(1)
+ }
+
+ @Test
+ fun verifySimPin_incorrect_oneRemainingAttempt() =
+ testScope.runTest {
+ bouncerSimRepository.setSubscriptionId(1)
+ bouncerSimRepository.setSimPukLocked(false)
+ whenever(telephonyManager.createForSubscriptionId(anyInt()))
+ .thenReturn(telephonyManager)
+ whenever(telephonyManager.supplyIccLockPin(anyString()))
+ .thenReturn(
+ PinResult(
+ PinResult.PIN_RESULT_TYPE_INCORRECT,
+ 1,
+ )
+ )
+
+ val msg: String? = underTest.verifySim(listOf(0, 0, 0, 0))
+ runCurrent()
+
+ assertThat(msg).isNull()
+ val errorDialogMessage by collectLastValue(bouncerSimRepository.errorDialogMessage)
+ assertThat(errorDialogMessage)
+ .isEqualTo(
+ "Enter SIM PIN. You have 1 remaining attempt before you must contact" +
+ " your carrier to unlock your device."
+ )
+ }
+
+ @Test
+ fun verifySimPin_incorrect_threeRemainingAttempts() =
+ testScope.runTest {
+ bouncerSimRepository.setSubscriptionId(1)
+ bouncerSimRepository.setSimPukLocked(false)
+ whenever(telephonyManager.createForSubscriptionId(anyInt()))
+ .thenReturn(telephonyManager)
+ whenever(telephonyManager.supplyIccLockPin(anyString()))
+ .thenReturn(
+ PinResult(
+ PinResult.PIN_RESULT_TYPE_INCORRECT,
+ 3,
+ )
+ )
+
+ val msg = underTest.verifySim(listOf(0, 0, 0, 0))
+ runCurrent()
+
+ assertThat(msg).isEqualTo("Enter SIM PIN. You have 3 remaining attempts.")
+ }
+
+ @Test
+ fun verifySimPin_notCorrectLength_tooShort() =
+ testScope.runTest {
+ bouncerSimRepository.setSubscriptionId(1)
+ bouncerSimRepository.setSimPukLocked(false)
+
+ val msg = underTest.verifySim(listOf(0))
+
+ assertThat(msg).isEqualTo(resources.getString(R.string.kg_invalid_sim_pin_hint))
+ }
+
+ @Test
+ fun verifySimPin_notCorrectLength_tooLong() =
+ testScope.runTest {
+ bouncerSimRepository.setSubscriptionId(1)
+ bouncerSimRepository.setSimPukLocked(false)
+
+ val msg = underTest.verifySim(listOf(0, 0, 0, 0, 0, 0, 0, 0, 0))
+
+ assertThat(msg).isEqualTo(resources.getString(R.string.kg_invalid_sim_pin_hint))
+ }
+
+ @Test
+ fun verifySimPuk() =
+ testScope.runTest {
+ whenever(telephonyManager.createForSubscriptionId(anyInt()))
+ .thenReturn(telephonyManager)
+ whenever(telephonyManager.supplyIccLockPuk(anyString(), anyString()))
+ .thenReturn(PinResult(PinResult.PIN_RESULT_TYPE_SUCCESS, 1))
+ bouncerSimRepository.setSubscriptionId(1)
+ bouncerSimRepository.setSimPukLocked(true)
+
+ var msg = underTest.verifySim(listOf(0, 0, 0, 0, 0, 0, 0, 0, 0))
+ assertThat(msg).isEqualTo(resources.getString(R.string.kg_puk_enter_pin_hint))
+
+ msg = underTest.verifySim(listOf(0, 0, 0, 0))
+ assertThat(msg).isEqualTo(resources.getString(R.string.kg_enter_confirm_pin_hint))
+
+ msg = underTest.verifySim(listOf(0, 0, 0, 0))
+ assertThat(msg).isNull()
+
+ runCurrent()
+ verify(keyguardUpdateMonitor).reportSimUnlocked(1)
+ }
+
+ @Test
+ fun verifySimPuk_inputTooShort() =
+ testScope.runTest {
+ bouncerSimRepository.setSubscriptionId(1)
+ bouncerSimRepository.setSimPukLocked(true)
+ val msg = underTest.verifySim(listOf(0, 0, 0, 0))
+ assertThat(msg).isEqualTo(resources.getString(R.string.kg_invalid_sim_puk_hint))
+ }
+
+ @Test
+ fun verifySimPuk_pinNotCorrectLength() =
+ testScope.runTest {
+ bouncerSimRepository.setSubscriptionId(1)
+ bouncerSimRepository.setSimPukLocked(true)
+
+ underTest.verifySim(listOf(0, 0, 0, 0, 0, 0, 0, 0, 0))
+
+ val msg = underTest.verifySim(listOf(0, 0, 0))
+ assertThat(msg).isEqualTo(resources.getString(R.string.kg_invalid_sim_pin_hint))
+ }
+
+ @Test
+ fun verifySimPuk_confirmedPinDoesNotMatch() =
+ testScope.runTest {
+ bouncerSimRepository.setSubscriptionId(1)
+ bouncerSimRepository.setSimPukLocked(true)
+
+ underTest.verifySim(listOf(0, 0, 0, 0, 0, 0, 0, 0, 0))
+ underTest.verifySim(listOf(0, 0, 0, 0))
+
+ val msg = underTest.verifySim(listOf(0, 0, 0, 1))
+ assertThat(msg).isEqualTo(resources.getString(R.string.kg_puk_enter_pin_hint))
+ }
+
+ @Test
+ fun onErrorDialogDismissed_clearsErrorDialogMessageInRepository() {
+ bouncerSimRepository.setSimVerificationErrorMessage("abc")
+ assertThat(bouncerSimRepository.errorDialogMessage.value).isNotNull()
+
+ underTest.onErrorDialogDismissed()
+
+ assertThat(bouncerSimRepository.errorDialogMessage.value).isNull()
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/AuthMethodBouncerViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/AuthMethodBouncerViewModelTest.kt
index cfcb545..63c992b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/AuthMethodBouncerViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/AuthMethodBouncerViewModelTest.kt
@@ -48,6 +48,8 @@
viewModelScope = testScope.backgroundScope,
interactor = bouncerInteractor,
isInputEnabled = MutableStateFlow(true),
+ simBouncerInteractor = utils.simBouncerInteractor,
+ authenticationMethod = AuthenticationMethodModel.Pin,
)
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelTest.kt
index f4346b5..75d6a00 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelTest.kt
@@ -233,6 +233,7 @@
AuthenticationMethodModel.Pin,
AuthenticationMethodModel.Password,
AuthenticationMethodModel.Pattern,
+ AuthenticationMethodModel.Sim,
)
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModelTest.kt
index 7a9cb6c..52844cf 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModelTest.kt
@@ -63,6 +63,8 @@
viewModelScope = testScope.backgroundScope,
interactor = bouncerInteractor,
isInputEnabled = MutableStateFlow(true).asStateFlow(),
+ simBouncerInteractor = utils.simBouncerInteractor,
+ authenticationMethod = AuthenticationMethodModel.Pin,
)
@Before
@@ -92,6 +94,52 @@
}
@Test
+ fun simBouncerViewModel_simAreaIsVisible() =
+ testScope.runTest {
+ val underTest =
+ PinBouncerViewModel(
+ applicationContext = context,
+ viewModelScope = testScope.backgroundScope,
+ interactor = bouncerInteractor,
+ isInputEnabled = MutableStateFlow(true).asStateFlow(),
+ simBouncerInteractor = utils.simBouncerInteractor,
+ authenticationMethod = AuthenticationMethodModel.Sim,
+ )
+
+ assertThat(underTest.isSimAreaVisible).isTrue()
+ }
+
+ @Test
+ fun onErrorDialogDismissed_clearsDialogMessage() =
+ testScope.runTest {
+ val dialogMessage by collectLastValue(underTest.errorDialogMessage)
+ utils.simBouncerRepository.setSimVerificationErrorMessage("abc")
+ assertThat(dialogMessage).isEqualTo("abc")
+
+ underTest.onErrorDialogDismissed()
+
+ assertThat(dialogMessage).isNull()
+ }
+
+ @Test
+ fun simBouncerViewModel_autoConfirmEnabled_hintedPinLengthIsNull() =
+ testScope.runTest {
+ val underTest =
+ PinBouncerViewModel(
+ applicationContext = context,
+ viewModelScope = testScope.backgroundScope,
+ interactor = bouncerInteractor,
+ isInputEnabled = MutableStateFlow(true).asStateFlow(),
+ simBouncerInteractor = utils.simBouncerInteractor,
+ authenticationMethod = AuthenticationMethodModel.Sim,
+ )
+ utils.authenticationRepository.setAutoConfirmFeatureEnabled(true)
+ val hintedPinLength by collectLastValue(underTest.hintedPinLength)
+
+ assertThat(hintedPinLength).isNull()
+ }
+
+ @Test
fun onPinButtonClicked() =
testScope.runTest {
val currentScene by collectLastValue(sceneInteractor.desiredScene)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorTest.kt
index abd9f28..0004f52 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorTest.kt
@@ -90,6 +90,16 @@
}
@Test
+ fun isUnlocked_whenAuthMethodIsSimAndUnlocked_isFalse() =
+ testScope.runTest {
+ utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Sim)
+ utils.deviceEntryRepository.setUnlocked(true)
+
+ val isUnlocked by collectLastValue(underTest.isUnlocked)
+ assertThat(isUnlocked).isFalse()
+ }
+
+ @Test
fun isDeviceEntered_onLockscreenWithSwipe_isFalse() =
testScope.runTest {
val isDeviceEntered by collectLastValue(underTest.isDeviceEntered)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt b/packages/SystemUI/tests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt
index cef888b..6a054cd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt
@@ -256,6 +256,8 @@
falsingCollector = utils.falsingCollector(),
powerInteractor = powerInteractor,
bouncerInteractor = bouncerInteractor,
+ simBouncerInteractor = utils.simBouncerInteractor,
+ authenticationInteractor = utils.authenticationInteractor()
)
startable.start()
@@ -483,6 +485,32 @@
verify(telecomManager).showInCallScreen(any())
}
+ @Test
+ fun showBouncer_whenLockedSimIntroduced() =
+ testScope.runTest {
+ setAuthMethod(AuthenticationMethodModel.None)
+ introduceLockedSim()
+ assertCurrentScene(SceneKey.Bouncer)
+ }
+
+ @Test
+ fun goesToGone_whenSimUnlocked_whileDeviceUnlocked() =
+ testScope.runTest {
+ introduceLockedSim()
+ emulateUiSceneTransition(expectedVisible = true)
+ enterSimPin(authMethodAfterSimUnlock = AuthenticationMethodModel.None)
+ assertCurrentScene(SceneKey.Gone)
+ }
+
+ @Test
+ fun showLockscreen_whenSimUnlocked_whileDeviceLocked() =
+ testScope.runTest {
+ introduceLockedSim()
+ emulateUiSceneTransition(expectedVisible = true)
+ enterSimPin(authMethodAfterSimUnlock = AuthenticationMethodModel.Pin)
+ assertCurrentScene(SceneKey.Lockscreen)
+ }
+
/**
* Asserts that the current scene in the view-model matches what's expected.
*
@@ -683,6 +711,35 @@
runCurrent()
}
+ /**
+ * Enters the correct PIN in the sim bouncer UI.
+ *
+ * Asserts that the current scene is [SceneKey.Bouncer] and that the current bouncer UI is a PIN
+ * before proceeding.
+ *
+ * Does not assert that the device is locked or unlocked.
+ */
+ private fun TestScope.enterSimPin(
+ authMethodAfterSimUnlock: AuthenticationMethodModel = AuthenticationMethodModel.None
+ ) {
+ assertWithMessage("Cannot enter PIN when not on the Bouncer scene!")
+ .that(getCurrentSceneInUi())
+ .isEqualTo(SceneKey.Bouncer)
+ val authMethodViewModel by collectLastValue(bouncerViewModel.authMethodViewModel)
+ assertWithMessage("Cannot enter PIN when not using a PIN authentication method!")
+ .that(authMethodViewModel)
+ .isInstanceOf(PinBouncerViewModel::class.java)
+
+ val pinBouncerViewModel = authMethodViewModel as PinBouncerViewModel
+ FakeAuthenticationRepository.DEFAULT_PIN.forEach { digit ->
+ pinBouncerViewModel.onPinButtonClicked(digit)
+ }
+ pinBouncerViewModel.onAuthenticateButtonClicked()
+ setAuthMethod(authMethodAfterSimUnlock)
+ utils.mobileConnectionsRepository.isAnySimSecure.value = false
+ runCurrent()
+ }
+
/** Changes device wakefulness state from asleep to awake, going through intermediary states. */
private fun TestScope.wakeUpDevice() {
val wakefulnessModel = powerInteractor.detailedWakefulness.value
@@ -723,4 +780,10 @@
runCurrent()
}
}
+
+ private fun TestScope.introduceLockedSim() {
+ setAuthMethod(AuthenticationMethodModel.Sim)
+ utils.mobileConnectionsRepository.isAnySimSecure.value = true
+ runCurrent()
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt b/packages/SystemUI/tests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt
index 2f654e2..c4ec56c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt
@@ -89,6 +89,8 @@
falsingCollector = falsingCollector,
powerInteractor = powerInteractor,
bouncerInteractor = bouncerInteractor,
+ simBouncerInteractor = utils.simBouncerInteractor,
+ authenticationInteractor = authenticationInteractor,
)
@Before
@@ -587,6 +589,64 @@
verify(falsingCollector, times(2)).onBouncerHidden()
}
+ @Test
+ fun switchesToBouncer_whenSimBecomesLocked() =
+ testScope.runTest {
+ val currentSceneKey by collectLastValue(sceneInteractor.desiredScene.map { it.key })
+
+ prepareState(
+ initialSceneKey = SceneKey.Lockscreen,
+ authenticationMethod = AuthenticationMethodModel.Pin,
+ isDeviceUnlocked = false,
+ )
+ underTest.start()
+ runCurrent()
+
+ utils.mobileConnectionsRepository.isAnySimSecure.value = true
+ runCurrent()
+
+ assertThat(currentSceneKey).isEqualTo(SceneKey.Bouncer)
+ }
+
+ @Test
+ fun switchesToLockscreen_whenSimBecomesUnlocked() =
+ testScope.runTest {
+ utils.mobileConnectionsRepository.isAnySimSecure.value = true
+ val currentSceneKey by collectLastValue(sceneInteractor.desiredScene.map { it.key })
+
+ prepareState(
+ initialSceneKey = SceneKey.Bouncer,
+ authenticationMethod = AuthenticationMethodModel.Pin,
+ isDeviceUnlocked = false,
+ )
+ underTest.start()
+ runCurrent()
+ utils.mobileConnectionsRepository.isAnySimSecure.value = false
+ runCurrent()
+
+ assertThat(currentSceneKey).isEqualTo(SceneKey.Lockscreen)
+ }
+
+ @Test
+ fun switchesToGone_whenSimBecomesUnlocked_ifDeviceUnlockedAndLockscreenDisabled() =
+ testScope.runTest {
+ utils.mobileConnectionsRepository.isAnySimSecure.value = true
+ val currentSceneKey by collectLastValue(sceneInteractor.desiredScene.map { it.key })
+
+ prepareState(
+ initialSceneKey = SceneKey.Lockscreen,
+ authenticationMethod = AuthenticationMethodModel.None,
+ isDeviceUnlocked = true,
+ isLockscreenEnabled = false,
+ )
+ underTest.start()
+ runCurrent()
+ utils.mobileConnectionsRepository.isAnySimSecure.value = false
+ runCurrent()
+
+ assertThat(currentSceneKey).isEqualTo(SceneKey.Gone)
+ }
+
private fun TestScope.prepareState(
isDeviceUnlocked: Boolean = false,
isBypassEnabled: Boolean = false,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/util/FakeSubscriptionManagerProxy.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/util/FakeSubscriptionManagerProxy.kt
index 3dc7de6..a802381 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/util/FakeSubscriptionManagerProxy.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/util/FakeSubscriptionManagerProxy.kt
@@ -16,12 +16,28 @@
package com.android.systemui.statusbar.pipeline.mobile.util
+import android.telephony.SubscriptionInfo
import android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID
/** Fake of [SubscriptionManagerProxy] for easy testing */
class FakeSubscriptionManagerProxy(
/** Set the default data subId to be returned in [getDefaultDataSubscriptionId] */
- var defaultDataSubId: Int = INVALID_SUBSCRIPTION_ID
+ var defaultDataSubId: Int = INVALID_SUBSCRIPTION_ID,
+ var activeSubscriptionInfo: SubscriptionInfo? = null
) : SubscriptionManagerProxy {
override fun getDefaultDataSubscriptionId(): Int = defaultDataSubId
+
+ override fun isValidSubscriptionId(subId: Int): Boolean {
+ return subId > -1
+ }
+
+ override suspend fun getActiveSubscriptionInfo(subId: Int): SubscriptionInfo? {
+ return activeSubscriptionInfo
+ }
+
+ /** Sets the active subscription info. */
+ fun setActiveSubscriptionInfo(subId: Int, isEmbedded: Boolean = false) {
+ activeSubscriptionInfo =
+ SubscriptionInfo.Builder().setId(subId).setEmbedded(isEmbedded).build()
+ }
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/authentication/data/repository/FakeAuthenticationRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/authentication/data/repository/FakeAuthenticationRepository.kt
index af1930e..c0dbeca 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/authentication/data/repository/FakeAuthenticationRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/authentication/data/repository/FakeAuthenticationRepository.kt
@@ -178,6 +178,7 @@
is AuthenticationMethodModel.Password -> SecurityMode.Password
is AuthenticationMethodModel.Pattern -> SecurityMode.Pattern
is AuthenticationMethodModel.None -> SecurityMode.None
+ is AuthenticationMethodModel.Sim -> SecurityMode.SimPin
}
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/data/repository/FakeSimBouncerRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/data/repository/FakeSimBouncerRepository.kt
new file mode 100644
index 0000000..890e69d
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/data/repository/FakeSimBouncerRepository.kt
@@ -0,0 +1,68 @@
+/*
+ * Copyright 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.repository
+
+import android.telephony.SubscriptionInfo
+import com.android.systemui.bouncer.data.model.SimPukInputModel
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.StateFlow
+
+/** Fakes the SimBouncerRepository. */
+class FakeSimBouncerRepository : SimBouncerRepository {
+ private val _subscriptionId: MutableStateFlow<Int> = MutableStateFlow(-1)
+ override val subscriptionId: StateFlow<Int> = _subscriptionId
+ private val _activeSubscriptionInfo: MutableStateFlow<SubscriptionInfo?> =
+ MutableStateFlow(null)
+ override val activeSubscriptionInfo: StateFlow<SubscriptionInfo?> = _activeSubscriptionInfo
+ private val _isLockedEsim: MutableStateFlow<Boolean?> = MutableStateFlow(null)
+ override val isLockedEsim: StateFlow<Boolean?> = _isLockedEsim
+ private val _isSimPukLocked: MutableStateFlow<Boolean> = MutableStateFlow(false)
+ override val isSimPukLocked: StateFlow<Boolean> = _isSimPukLocked
+ private val _errorDialogMessage: MutableStateFlow<String?> = MutableStateFlow(null)
+ override val errorDialogMessage: StateFlow<String?> = _errorDialogMessage
+ private var _simPukInputModel = SimPukInputModel()
+ override val simPukInputModel: SimPukInputModel
+ get() = _simPukInputModel
+
+ fun setSubscriptionId(subId: Int) {
+ _subscriptionId.value = subId
+ }
+
+ fun setActiveSubscriptionInfo(subscriptioninfo: SubscriptionInfo) {
+ _activeSubscriptionInfo.value = subscriptioninfo
+ }
+
+ fun setLockedEsim(isLockedEsim: Boolean) {
+ _isLockedEsim.value = isLockedEsim
+ }
+
+ fun setSimPukLocked(isSimPukLocked: Boolean) {
+ _isSimPukLocked.value = isSimPukLocked
+ }
+
+ fun setErrorDialogMessage(msg: String?) {
+ _errorDialogMessage.value = msg
+ }
+
+ override fun setSimPukUserInput(enteredSimPuk: String?, enteredSimPin: String?) {
+ _simPukInputModel = SimPukInputModel(enteredSimPuk, enteredSimPin)
+ }
+
+ override fun setSimVerificationErrorMessage(msg: String?) {
+ _errorDialogMessage.value = msg
+ }
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/SceneTestUtils.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/SceneTestUtils.kt
index c8869aa..29e73b5 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/SceneTestUtils.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/SceneTestUtils.kt
@@ -23,6 +23,10 @@
import android.graphics.Bitmap
import android.graphics.drawable.BitmapDrawable
import android.telecom.TelecomManager
+import android.telephony.PinResult
+import android.telephony.PinResult.PIN_RESULT_TYPE_SUCCESS
+import android.telephony.TelephonyManager
+import android.telephony.euicc.EuiccManager
import com.android.internal.logging.MetricsLogger
import com.android.internal.util.EmergencyAffordanceManager
import com.android.systemui.SysuiTestCase
@@ -32,9 +36,11 @@
import com.android.systemui.bouncer.data.repository.BouncerRepository
import com.android.systemui.bouncer.data.repository.EmergencyServicesRepository
import com.android.systemui.bouncer.data.repository.FakeKeyguardBouncerRepository
+import com.android.systemui.bouncer.data.repository.FakeSimBouncerRepository
import com.android.systemui.bouncer.domain.interactor.BouncerActionButtonInteractor
import com.android.systemui.bouncer.domain.interactor.BouncerInteractor
import com.android.systemui.bouncer.domain.interactor.EmergencyDialerIntentFactory
+import com.android.systemui.bouncer.domain.interactor.SimBouncerInteractor
import com.android.systemui.bouncer.ui.viewmodel.BouncerViewModel
import com.android.systemui.classifier.FalsingCollector
import com.android.systemui.classifier.FalsingCollectorFake
@@ -73,6 +79,7 @@
import com.android.systemui.scene.shared.model.SceneKey
import com.android.systemui.shade.data.repository.FakeShadeRepository
import com.android.systemui.statusbar.phone.ScreenOffAnimationController
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeMobileConnectionsRepository
import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionsRepository
import com.android.systemui.telephony.data.repository.FakeTelephonyRepository
import com.android.systemui.telephony.data.repository.TelephonyRepository
@@ -89,6 +96,9 @@
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.test.currentTime
+import org.mockito.ArgumentMatchers.anyInt
+import org.mockito.ArgumentMatchers.anyString
+import org.mockito.Mockito
/**
* Utilities for creating scene container framework related repositories, interactors, and
@@ -127,9 +137,33 @@
}
val telephonyRepository: FakeTelephonyRepository by lazy { FakeTelephonyRepository() }
+ val bouncerRepository = BouncerRepository(featureFlags)
val communalRepository: FakeCommunalRepository by lazy { FakeCommunalRepository() }
val keyguardRepository: FakeKeyguardRepository by lazy { FakeKeyguardRepository() }
val powerRepository: FakePowerRepository by lazy { FakePowerRepository() }
+ val simBouncerRepository: FakeSimBouncerRepository by lazy { FakeSimBouncerRepository() }
+ val telephonyManager: TelephonyManager =
+ Mockito.mock(TelephonyManager::class.java).apply {
+ whenever(createForSubscriptionId(anyInt())).thenReturn(this)
+ whenever(supplyIccLockPin(anyString()))
+ .thenReturn(PinResult(PIN_RESULT_TYPE_SUCCESS, 3))
+ }
+ val mobileConnectionsRepository: FakeMobileConnectionsRepository by lazy {
+ FakeMobileConnectionsRepository(mock(), mock())
+ }
+
+ val simBouncerInteractor =
+ SimBouncerInteractor(
+ applicationContext = context,
+ backgroundDispatcher = testDispatcher,
+ applicationScope = applicationScope(),
+ repository = simBouncerRepository,
+ telephonyManager = telephonyManager,
+ resources = context.resources,
+ keyguardUpdateMonitor = mock(),
+ euiccManager = context.getSystemService(Context.EUICC_SERVICE) as EuiccManager,
+ mobileConnectionsRepository = mobileConnectionsRepository,
+ )
val userRepository: UserRepository by lazy {
FakeUserRepository().apply {
@@ -228,11 +262,12 @@
return BouncerInteractor(
applicationScope = applicationScope(),
applicationContext = context,
- repository = BouncerRepository(featureFlags),
+ repository = bouncerRepository,
authenticationInteractor = authenticationInteractor,
flags = sceneContainerFlags,
falsingInteractor = falsingInteractor(),
- powerInteractor = powerInteractor()
+ powerInteractor = powerInteractor(),
+ simBouncerInteractor = simBouncerInteractor,
)
}
@@ -253,6 +288,7 @@
users = flowOf(users),
userSwitcherMenu = flowOf(createMenuActions()),
actionButtonInteractor = actionButtonInteractor,
+ simBouncerInteractor = simBouncerInteractor,
)
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionRepository.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionRepository.kt
rename to packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionRepository.kt
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionsRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionsRepository.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionsRepository.kt
rename to packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/FakeMobileConnectionsRepository.kt