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

Commit acb8be5d authored by Milton Wu's avatar Milton Wu
Browse files

[BiometricsV2] Refactor AutoCredentialViewModel

Refactor AutoCredentialViewModelTest and FingerprintEnrollmentViewModel
to kotlin and change LiveData to Flow

Bug: 286197659
Test: atest -m CredentialModelTest
Test: atest -m AutoCredentialViewModelTest
Test: atest -m FingerprintEnrollmentViewModelTest
Test: atest -m FingerprintEnrollmentActivityTest
Test: atest -m biometrics-enrollment-test
Change-Id: I84bab0b46e023303c0046a6ae6886ab1cf9458b8
parent 78f3760d
Loading
Loading
Loading
Loading
+20 −18
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import androidx.lifecycle.viewmodel.CreationExtras;
import com.android.internal.widget.LockPatternUtils;
import com.android.settings.biometrics.fingerprint.FingerprintUpdater;
import com.android.settings.biometrics2.data.repository.FingerprintRepository;
import com.android.settings.biometrics2.ui.model.CredentialModel;
import com.android.settings.biometrics2.ui.model.EnrollmentRequest;
import com.android.settings.biometrics2.ui.viewmodel.AutoCredentialViewModel;
import com.android.settings.biometrics2.ui.viewmodel.AutoCredentialViewModel.ChallengeGenerator;
@@ -54,8 +55,8 @@ public class BiometricsViewModelFactory implements ViewModelProvider.Factory {
            new CreationExtras.Key<ChallengeGenerator>() {};
    public static final CreationExtras.Key<EnrollmentRequest> ENROLLMENT_REQUEST_KEY =
            new CreationExtras.Key<EnrollmentRequest>() {};
    public static final CreationExtras.Key<Integer> USER_ID_KEY =
            new CreationExtras.Key<Integer>() {};
    public static final CreationExtras.Key<CredentialModel> CREDENTIAL_MODEL_KEY =
            new CreationExtras.Key<CredentialModel>() {};

    @NonNull
    @Override
@@ -76,9 +77,10 @@ public class BiometricsViewModelFactory implements ViewModelProvider.Factory {
            final LockPatternUtils lockPatternUtils =
                    featureFactory.getSecurityFeatureProvider().getLockPatternUtils(application);
            final ChallengeGenerator challengeGenerator = extras.get(CHALLENGE_GENERATOR_KEY);
            if (challengeGenerator != null) {
            final CredentialModel credentialModel = extras.get(CREDENTIAL_MODEL_KEY);
            if (challengeGenerator != null && credentialModel != null) {
                return (T) new AutoCredentialViewModel(application, lockPatternUtils,
                        challengeGenerator);
                        challengeGenerator, credentialModel);
            }
        } else if (modelClass.isAssignableFrom(DeviceFoldedViewModel.class)) {
            return (T) new DeviceFoldedViewModel(new ScreenSizeFoldProvider(application),
@@ -93,10 +95,10 @@ public class BiometricsViewModelFactory implements ViewModelProvider.Factory {
        } else if (modelClass.isAssignableFrom(FingerprintEnrollIntroViewModel.class)) {
            final FingerprintRepository repository = provider.getFingerprintRepository(application);
            final EnrollmentRequest request = extras.get(ENROLLMENT_REQUEST_KEY);
            final Integer userId = extras.get(USER_ID_KEY);
            if (repository != null && request != null && userId != null) {
            final CredentialModel credentialModel = extras.get(CREDENTIAL_MODEL_KEY);
            if (repository != null && request != null && credentialModel != null) {
                return (T) new FingerprintEnrollIntroViewModel(application, repository, request,
                        userId);
                        credentialModel.getUserId());
            }
        } else if (modelClass.isAssignableFrom(FingerprintEnrollmentViewModel.class)) {
            final FingerprintRepository repository = provider.getFingerprintRepository(application);
@@ -105,27 +107,27 @@ public class BiometricsViewModelFactory implements ViewModelProvider.Factory {
                return (T) new FingerprintEnrollmentViewModel(application, repository, request);
            }
        } else if (modelClass.isAssignableFrom(FingerprintEnrollProgressViewModel.class)) {
            final Integer userId = extras.get(USER_ID_KEY);
            if (userId != null) {
            final CredentialModel credentialModel = extras.get(CREDENTIAL_MODEL_KEY);
            if (credentialModel != null) {
                return (T) new FingerprintEnrollProgressViewModel(application,
                        new FingerprintUpdater(application), userId);
                        new FingerprintUpdater(application), credentialModel.getUserId());
            }
        } else if (modelClass.isAssignableFrom(FingerprintEnrollEnrollingViewModel.class)) {
            final Integer userId = extras.get(USER_ID_KEY);
            final CredentialModel credentialModel = extras.get(CREDENTIAL_MODEL_KEY);
            final FingerprintRepository fingerprint = provider.getFingerprintRepository(
                    application);
            if (fingerprint != null && userId != null) {
                return (T) new FingerprintEnrollEnrollingViewModel(application, userId,
                        fingerprint);
            if (fingerprint != null && credentialModel != null) {
                return (T) new FingerprintEnrollEnrollingViewModel(application,
                        credentialModel.getUserId(), fingerprint);
            }
        } else if (modelClass.isAssignableFrom(FingerprintEnrollFinishViewModel.class)) {
            final Integer userId = extras.get(USER_ID_KEY);
            final CredentialModel credentialModel = extras.get(CREDENTIAL_MODEL_KEY);
            final EnrollmentRequest request = extras.get(ENROLLMENT_REQUEST_KEY);
            final FingerprintRepository fingerprint = provider.getFingerprintRepository(
                    application);
            if (fingerprint != null && userId != null && request != null) {
                return (T) new FingerprintEnrollFinishViewModel(application, userId, request,
                        fingerprint);
            if (fingerprint != null && credentialModel != null && request != null) {
                return (T) new FingerprintEnrollFinishViewModel(application,
                        credentialModel.getUserId(), request, fingerprint);
            }
        } else if (modelClass.isAssignableFrom(FingerprintEnrollErrorDialogViewModel.class)) {
            final EnrollmentRequest request = extras.get(ENROLLMENT_REQUEST_KEY);
+0 −14
Original line number Diff line number Diff line
@@ -80,20 +80,6 @@ class CredentialModel(bundle: Bundle?, private val clock: Clock) {
    val isValidToken: Boolean
        get() = token != null

    val bundle: Bundle
        /**
         * Get a bundle which can be used to recreate CredentialModel
         */
        get() {
            val bundle = Bundle()
            bundle.putInt(EXTRA_USER_ID, userId)
            bundle.putLong(EXTRA_KEY_CHALLENGE, challenge)
            bundle.putByteArray(EXTRA_KEY_CHALLENGE_TOKEN, token)
            bundle.putLong(EXTRA_KEY_GK_PW_HANDLE, gkPwHandle)
            return bundle
        }


    /** Returns a string representation of the object */
    override fun toString(): String {
        val gkPwHandleLen = "$gkPwHandle".length
+44 −46
Original line number Diff line number Diff line
@@ -44,16 +44,13 @@ import com.android.settings.Utils
import com.android.settings.biometrics.BiometricEnrollBase
import com.android.settings.biometrics2.factory.BiometricsViewModelFactory
import com.android.settings.biometrics2.factory.BiometricsViewModelFactory.CHALLENGE_GENERATOR_KEY
import com.android.settings.biometrics2.factory.BiometricsViewModelFactory.CREDENTIAL_MODEL_KEY
import com.android.settings.biometrics2.factory.BiometricsViewModelFactory.ENROLLMENT_REQUEST_KEY
import com.android.settings.biometrics2.factory.BiometricsViewModelFactory.USER_ID_KEY
import com.android.settings.biometrics2.ui.model.CredentialModel
import com.android.settings.biometrics2.ui.model.EnrollmentRequest
import com.android.settings.biometrics2.ui.viewmodel.AutoCredentialViewModel
import com.android.settings.biometrics2.ui.viewmodel.AutoCredentialViewModel.CREDENTIAL_FAIL_NEED_TO_CHOOSE_LOCK
import com.android.settings.biometrics2.ui.viewmodel.AutoCredentialViewModel.CREDENTIAL_FAIL_NEED_TO_CONFIRM_LOCK
import com.android.settings.biometrics2.ui.viewmodel.AutoCredentialViewModel.CREDENTIAL_IS_GENERATING_CHALLENGE
import com.android.settings.biometrics2.ui.viewmodel.AutoCredentialViewModel.CREDENTIAL_VALID
import com.android.settings.biometrics2.ui.viewmodel.AutoCredentialViewModel.FingerprintChallengeGenerator
import com.android.settings.biometrics2.ui.viewmodel.CredentialAction
import com.android.settings.biometrics2.ui.viewmodel.DeviceFoldedViewModel
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel.FINGERPRINT_ENROLL_ENROLLING_ACTION_DONE
@@ -170,7 +167,6 @@ open class FingerprintEnrollmentActivity : FragmentActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        autoCredentialViewModel.setCredentialModel(savedInstanceState, intent)

        // Theme
        setTheme(viewModel.request.theme)
@@ -219,14 +215,23 @@ open class FingerprintEnrollmentActivity : FragmentActivity() {
            }
        }

        // observe LiveData
        viewModel.setResultLiveData.observe(this) {
            result: ActivityResult -> onSetActivityResult(result)
        }
        autoCredentialViewModel.generateChallengeFailedLiveData.observe(this) {
            _: Boolean -> onGenerateChallengeFailed()
        collectFlows()
    }

    private fun collectFlows() {
        lifecycleScope.launch {
            repeatOnLifecycle(Lifecycle.State.STARTED) {
                viewModel.setResultFlow.collect {
                    Log.d(TAG, "setResultLiveData($it)")
                    onSetActivityResult(it)
                }
            }
            repeatOnLifecycle(Lifecycle.State.STARTED) {
                autoCredentialViewModel.generateChallengeFailedFlow.collect {
                    Log.d(TAG, "generateChallengeFailedFlow($it)")
                    onSetActivityResult(ActivityResult(RESULT_CANCELED, null))
                }
            }
            repeatOnLifecycle(Lifecycle.State.STARTED) {
                errorDialogViewModel.newDialogFlow.collect {
                    Log.d(TAG, "newErrorDialogFlow($it)")
@@ -236,8 +241,6 @@ open class FingerprintEnrollmentActivity : FragmentActivity() {
                    )
                }
            }
        }
        lifecycleScope.launch {
            repeatOnLifecycle(Lifecycle.State.STARTED) {
                errorDialogViewModel.setResultFlow.collect {
                    Log.d(TAG, "errorDialogSetResultFlow($it)")
@@ -408,10 +411,6 @@ open class FingerprintEnrollmentActivity : FragmentActivity() {
        }
    }

    private fun onGenerateChallengeFailed() {
        onSetActivityResult(ActivityResult(RESULT_CANCELED, null))
    }

    private fun onSetActivityResult(result: ActivityResult) {
        val challengeExtras: Bundle? = autoCredentialViewModel.createGeneratingChallengeExtras()
        val overrideResult: ActivityResult = viewModel.getOverrideActivityResult(
@@ -428,8 +427,8 @@ open class FingerprintEnrollmentActivity : FragmentActivity() {
    }

    private fun checkCredential() {
        when (autoCredentialViewModel.checkCredential()) {
            CREDENTIAL_FAIL_NEED_TO_CHOOSE_LOCK -> {
        when (autoCredentialViewModel.checkCredential(lifecycleScope)) {
            CredentialAction.FAIL_NEED_TO_CHOOSE_LOCK -> {
                val intent: Intent = autoCredentialViewModel.createChooseLockIntent(
                    this,
                    viewModel.request.isSuw,
@@ -442,7 +441,7 @@ open class FingerprintEnrollmentActivity : FragmentActivity() {
                return
            }

            CREDENTIAL_FAIL_NEED_TO_CONFIRM_LOCK -> {
            CredentialAction.FAIL_NEED_TO_CONFIRM_LOCK -> {
                val launched: Boolean = autoCredentialViewModel.createConfirmLockLauncher(
                    this,
                    LAUNCH_CONFIRM_LOCK_ACTIVITY,
@@ -459,21 +458,24 @@ open class FingerprintEnrollmentActivity : FragmentActivity() {
                return
            }

            CREDENTIAL_VALID,
            CREDENTIAL_IS_GENERATING_CHALLENGE -> {}
            CredentialAction.CREDENTIAL_VALID,
            CredentialAction.IS_GENERATING_CHALLENGE -> {}
        }
    }

    private fun onChooseOrConfirmLockResult(isChooseLock: Boolean, activityResult: ActivityResult) {
    private fun onChooseOrConfirmLockResult(
        isChooseLock: Boolean,
        activityResult: ActivityResult
    ) {
        if (!viewModel.isWaitingActivityResult.compareAndSet(true, false)) {
            Log.w(TAG, "isChooseLock:$isChooseLock, fail to unset waiting flag")
        }
        if (autoCredentialViewModel.checkNewCredentialFromActivityResult(
                isChooseLock, activityResult
        if (!autoCredentialViewModel.generateChallengeAsCredentialActivityResult(
                isChooseLock,
                activityResult,
                lifecycleScope
            )
        ) {
            overridePendingTransition(R.anim.sud_slide_next_in, R.anim.sud_slide_next_out)
        } else {
            onSetActivityResult(activityResult)
        }
    }
@@ -573,7 +575,11 @@ open class FingerprintEnrollmentActivity : FragmentActivity() {

    override fun onPause() {
        super.onPause()
        viewModel.checkFinishActivityDuringOnPause(isFinishing, isChangingConfigurations)
        viewModel.checkFinishActivityDuringOnPause(
            isFinishing,
            isChangingConfigurations,
            lifecycleScope
        )
    }

    override fun onDestroy() {
@@ -596,17 +602,14 @@ open class FingerprintEnrollmentActivity : FragmentActivity() {
    }

    override val defaultViewModelCreationExtras: CreationExtras
        get() {
            val fingerprintRepository = featureFactory.biometricsRepositoryProvider
                .getFingerprintRepository(application)!!
            val credentialModel = CredentialModel(intent.extras, SystemClock.elapsedRealtimeClock())

            return MutableCreationExtras(super.defaultViewModelCreationExtras).also {
                it[CHALLENGE_GENERATOR_KEY] = FingerprintChallengeGenerator(fingerprintRepository)
        get() = MutableCreationExtras(super.defaultViewModelCreationExtras).also {
            it[CHALLENGE_GENERATOR_KEY] = FingerprintChallengeGenerator(
                featureFactory.biometricsRepositoryProvider.getFingerprintRepository(application)!!
            )
            it[ENROLLMENT_REQUEST_KEY] =
                EnrollmentRequest(intent, applicationContext, this is SetupActivity)
                it[USER_ID_KEY] = credentialModel.userId
            }
            it[CREDENTIAL_MODEL_KEY] =
                CredentialModel(intent.extras, SystemClock.elapsedRealtimeClock())
        }

    override val defaultViewModelProviderFactory: ViewModelProvider.Factory
@@ -630,11 +633,6 @@ open class FingerprintEnrollmentActivity : FragmentActivity() {
        super.onConfigurationChanged(newConfig)
    }

    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        autoCredentialViewModel.onSaveInstanceState(outState)
    }

    companion object {
        private const val DEBUG = false
        private const val TAG = "FingerprintEnrollmentActivity"
Loading