1 /*
2  * Copyright (C) 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.settings.biometrics2.factory;
18 
19 import android.app.Application;
20 import android.util.Log;
21 
22 import androidx.annotation.NonNull;
23 import androidx.lifecycle.ViewModel;
24 import androidx.lifecycle.ViewModelProvider;
25 import androidx.lifecycle.ViewModelProvider.AndroidViewModelFactory;
26 import androidx.lifecycle.viewmodel.CreationExtras;
27 
28 import com.android.internal.widget.LockPatternUtils;
29 import com.android.settings.biometrics.fingerprint.FingerprintUpdater;
30 import com.android.settings.biometrics2.data.repository.FingerprintRepository;
31 import com.android.settings.biometrics2.ui.model.CredentialModel;
32 import com.android.settings.biometrics2.ui.model.EnrollmentRequest;
33 import com.android.settings.biometrics2.ui.viewmodel.AutoCredentialViewModel;
34 import com.android.settings.biometrics2.ui.viewmodel.AutoCredentialViewModel.ChallengeGenerator;
35 import com.android.settings.biometrics2.ui.viewmodel.DeviceFoldedViewModel;
36 import com.android.settings.biometrics2.ui.viewmodel.DeviceRotationViewModel;
37 import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel;
38 import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollErrorDialogViewModel;
39 import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollFindSensorViewModel;
40 import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollFinishViewModel;
41 import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollIntroViewModel;
42 import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollProgressViewModel;
43 import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollmentViewModel;
44 import com.android.settings.overlay.FeatureFactory;
45 import com.android.systemui.unfold.compat.ScreenSizeFoldProvider;
46 
47 /**
48  * View model factory for biometric enrollment fragment
49  */
50 public class BiometricsViewModelFactory implements ViewModelProvider.Factory {
51 
52     private static final String TAG = "BiometricsViewModelFactory";
53 
54     public static final CreationExtras.Key<ChallengeGenerator> CHALLENGE_GENERATOR_KEY =
55             new CreationExtras.Key<ChallengeGenerator>() {};
56     public static final CreationExtras.Key<EnrollmentRequest> ENROLLMENT_REQUEST_KEY =
57             new CreationExtras.Key<EnrollmentRequest>() {};
58     public static final CreationExtras.Key<CredentialModel> CREDENTIAL_MODEL_KEY =
59             new CreationExtras.Key<CredentialModel>() {};
60 
61     @NonNull
62     @Override
63     @SuppressWarnings("unchecked")
create(@onNull Class<T> modelClass, @NonNull CreationExtras extras)64     public <T extends ViewModel> T create(@NonNull Class<T> modelClass,
65             @NonNull CreationExtras extras) {
66         final Application application = extras.get(AndroidViewModelFactory.APPLICATION_KEY);
67 
68         if (application == null) {
69             Log.w(TAG, "create, null application");
70             return create(modelClass);
71         }
72         final FeatureFactory featureFactory = FeatureFactory.getFeatureFactory();
73         final BiometricsRepositoryProvider provider =
74                 featureFactory.getBiometricsRepositoryProvider();
75 
76         if (modelClass.isAssignableFrom(AutoCredentialViewModel.class)) {
77             final LockPatternUtils lockPatternUtils =
78                     featureFactory.getSecurityFeatureProvider().getLockPatternUtils(application);
79             final ChallengeGenerator challengeGenerator = extras.get(CHALLENGE_GENERATOR_KEY);
80             final CredentialModel credentialModel = extras.get(CREDENTIAL_MODEL_KEY);
81             if (challengeGenerator != null && credentialModel != null) {
82                 return (T) new AutoCredentialViewModel(application, lockPatternUtils,
83                         challengeGenerator, credentialModel);
84             }
85         } else if (modelClass.isAssignableFrom(DeviceFoldedViewModel.class)) {
86             return (T) new DeviceFoldedViewModel(new ScreenSizeFoldProvider(application),
87                     application.getMainExecutor());
88         } else if (modelClass.isAssignableFrom(DeviceRotationViewModel.class)) {
89             return (T) new DeviceRotationViewModel(application);
90         } else if (modelClass.isAssignableFrom(FingerprintEnrollFindSensorViewModel.class)) {
91             final EnrollmentRequest request = extras.get(ENROLLMENT_REQUEST_KEY);
92             if (request != null) {
93                 return (T) new FingerprintEnrollFindSensorViewModel(application, request.isSuw());
94             }
95         } else if (modelClass.isAssignableFrom(FingerprintEnrollIntroViewModel.class)) {
96             final FingerprintRepository repository = provider.getFingerprintRepository(application);
97             final EnrollmentRequest request = extras.get(ENROLLMENT_REQUEST_KEY);
98             final CredentialModel credentialModel = extras.get(CREDENTIAL_MODEL_KEY);
99             if (repository != null && request != null && credentialModel != null) {
100                 return (T) new FingerprintEnrollIntroViewModel(application, repository, request,
101                         credentialModel.getUserId());
102             }
103         } else if (modelClass.isAssignableFrom(FingerprintEnrollmentViewModel.class)) {
104             final FingerprintRepository repository = provider.getFingerprintRepository(application);
105             final EnrollmentRequest request = extras.get(ENROLLMENT_REQUEST_KEY);
106             if (repository != null && request != null) {
107                 return (T) new FingerprintEnrollmentViewModel(application, repository, request);
108             }
109         } else if (modelClass.isAssignableFrom(FingerprintEnrollProgressViewModel.class)) {
110             final CredentialModel credentialModel = extras.get(CREDENTIAL_MODEL_KEY);
111             if (credentialModel != null) {
112                 return (T) new FingerprintEnrollProgressViewModel(application,
113                         new FingerprintUpdater(application), credentialModel.getUserId());
114             }
115         } else if (modelClass.isAssignableFrom(FingerprintEnrollEnrollingViewModel.class)) {
116             final CredentialModel credentialModel = extras.get(CREDENTIAL_MODEL_KEY);
117             final FingerprintRepository fingerprint = provider.getFingerprintRepository(
118                     application);
119             if (fingerprint != null && credentialModel != null) {
120                 return (T) new FingerprintEnrollEnrollingViewModel(application,
121                         credentialModel.getUserId(), fingerprint);
122             }
123         } else if (modelClass.isAssignableFrom(FingerprintEnrollFinishViewModel.class)) {
124             final CredentialModel credentialModel = extras.get(CREDENTIAL_MODEL_KEY);
125             final EnrollmentRequest request = extras.get(ENROLLMENT_REQUEST_KEY);
126             final FingerprintRepository fingerprint = provider.getFingerprintRepository(
127                     application);
128             if (fingerprint != null && credentialModel != null && request != null) {
129                 return (T) new FingerprintEnrollFinishViewModel(application,
130                         credentialModel.getUserId(), request, fingerprint);
131             }
132         } else if (modelClass.isAssignableFrom(FingerprintEnrollErrorDialogViewModel.class)) {
133             final EnrollmentRequest request = extras.get(ENROLLMENT_REQUEST_KEY);
134             if (request != null) {
135                 return (T) new FingerprintEnrollErrorDialogViewModel(application, request.isSuw());
136             }
137         }
138         return create(modelClass);
139     }
140 }
141