• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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 package com.android.settings.biometrics.combination;
17 
18 import static com.android.settings.biometrics.activeunlock.ActiveUnlockStatusPreferenceController.KEY_ACTIVE_UNLOCK_SETTINGS;
19 import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_GK_PW_HANDLE;
20 
21 import android.app.settings.SettingsEnums;
22 import android.content.Context;
23 import android.content.Intent;
24 import android.os.Bundle;
25 import android.os.UserHandle;
26 
27 import androidx.activity.result.ActivityResult;
28 import androidx.activity.result.ActivityResultLauncher;
29 import androidx.activity.result.contract.ActivityResultContracts;
30 import androidx.annotation.Nullable;
31 import androidx.preference.Preference;
32 import androidx.preference.PreferenceCategory;
33 
34 import com.android.settings.R;
35 import com.android.settings.biometrics.BiometricEnrollBase;
36 import com.android.settings.biometrics.activeunlock.ActiveUnlockContentListener.OnContentChangedListener;
37 import com.android.settings.biometrics.activeunlock.ActiveUnlockDeviceNameListener;
38 import com.android.settings.biometrics.activeunlock.ActiveUnlockRequireBiometricSetup;
39 import com.android.settings.biometrics.activeunlock.ActiveUnlockStatusUtils;
40 import com.android.settings.flags.Flags;
41 import com.android.settings.search.BaseSearchIndexProvider;
42 import com.android.settingslib.search.SearchIndexable;
43 
44 /**
45  * Settings screen for multiple biometrics.
46  */
47 @SearchIndexable
48 public class CombinedBiometricSettings extends BiometricsSettingsBase {
49     private static final String TAG = "BiometricSettings";
50     private static final String KEY_FACE_SETTINGS = "biometric_face_settings";
51     private static final String KEY_FINGERPRINT_SETTINGS = "biometric_fingerprint_settings";
52     private static final String KEY_UNLOCK_PHONE = "biometric_settings_biometric_keyguard";
53     private static final String KEY_USE_IN_APPS = "biometric_settings_biometric_app";
54     private static final String KEY_INTRO_PREFERENCE = "biometric_intro";
55     private static final String KEY_USE_BIOMETRIC_PREFERENCE = "biometric_ways_to_use";
56 
57     private ActiveUnlockStatusUtils mActiveUnlockStatusUtils;
58     private CombinedBiometricStatusUtils mCombinedBiometricStatusUtils;
59     @Nullable private ActiveUnlockDeviceNameListener mActiveUnlockDeviceNameListener;
60 
61     private final ActivityResultLauncher<Intent> mActiveUnlockPreferenceLauncher =
62             registerForActivityResult(new ActivityResultContracts.StartActivityForResult(),
63                     this::onActiveUnlockPreferenceResult);
64 
65     @Override
onAttach(Context context)66     public void onAttach(Context context) {
67         super.onAttach(context);
68         use(BiometricSettingsKeyguardPreferenceController.class).setUserId(mUserId);
69         use(BiometricSettingsAppPreferenceController.class).setUserId(mUserId);
70     }
71 
72     @Override
onCreate(Bundle savedInstanceState)73     public void onCreate(Bundle savedInstanceState) {
74         super.onCreate(savedInstanceState);
75         mActiveUnlockStatusUtils = new ActiveUnlockStatusUtils(getActivity());
76         mCombinedBiometricStatusUtils = new CombinedBiometricStatusUtils(getActivity(), mUserId);
77         if (mActiveUnlockStatusUtils.isAvailable()) {
78             updateUiForActiveUnlock();
79         }
80         if (Flags.biometricsOnboardingEducation()) {
81             final PreferenceCategory category = findPreference(KEY_USE_BIOMETRIC_PREFERENCE);
82             if (category != null) {
83                 category.setVisible(false);
84             }
85         }
86     }
87 
updateUiForActiveUnlock()88     private void updateUiForActiveUnlock() {
89         OnContentChangedListener listener = new OnContentChangedListener() {
90             @Override
91             public void onContentChanged(String newValue) {
92                 updateUnlockPhonePreferenceSummary();
93             }
94         };
95 
96         mActiveUnlockDeviceNameListener =
97                 new ActiveUnlockDeviceNameListener(getActivity(), listener);
98         mActiveUnlockDeviceNameListener.subscribe();
99         final Preference introPreference = findPreference(KEY_INTRO_PREFERENCE);
100         if (introPreference != null) {
101             introPreference.setTitle(mActiveUnlockStatusUtils.getIntroForActiveUnlock());
102         }
103         final Preference useBiometricPreference = findPreference(KEY_USE_BIOMETRIC_PREFERENCE);
104         if (useBiometricPreference != null) {
105             useBiometricPreference.setTitle(
106                     mActiveUnlockStatusUtils.getUseBiometricTitleForActiveUnlock());
107         }
108         getActivity().setTitle(mActiveUnlockStatusUtils.getTitleForActiveUnlock());
109     }
110 
111     @Override
onDestroy()112     public void onDestroy() {
113         if (mActiveUnlockDeviceNameListener != null) {
114             mActiveUnlockDeviceNameListener.unsubscribe();
115         }
116         super.onDestroy();
117     }
118 
119     @Override
getPreferenceScreenResId()120     protected int getPreferenceScreenResId() {
121         return R.xml.security_settings_combined_biometric;
122     }
123 
124     @Override
getFacePreferenceKey()125     public String getFacePreferenceKey() {
126         return KEY_FACE_SETTINGS;
127     }
128 
129     @Override
getFingerprintPreferenceKey()130     public String getFingerprintPreferenceKey() {
131         return KEY_FINGERPRINT_SETTINGS;
132     }
133 
134     @Override
getUnlockPhonePreferenceKey()135     public String getUnlockPhonePreferenceKey() {
136         return KEY_UNLOCK_PHONE;
137     }
138 
139     @Override
getUseInAppsPreferenceKey()140     public String getUseInAppsPreferenceKey() {
141         return KEY_USE_IN_APPS;
142     }
143 
144     @Override
getLogTag()145     protected String getLogTag() {
146         return TAG;
147     }
148 
149     @Override
getMetricsCategory()150     public int getMetricsCategory() {
151         return SettingsEnums.COMBINED_BIOMETRIC;
152     }
153 
154     @Override
onRetryPreferenceTreeClick(Preference preference, final boolean retry)155     protected boolean onRetryPreferenceTreeClick(Preference preference, final boolean retry) {
156         if (!mActiveUnlockStatusUtils.isAvailable()
157                 || !KEY_ACTIVE_UNLOCK_SETTINGS.equals(preference.getKey())) {
158             return super.onRetryPreferenceTreeClick(preference, retry);
159         }
160         mDoNotFinishActivity = true;
161         Intent intent;
162         if (mActiveUnlockStatusUtils.useBiometricFailureLayout()
163                 && mActiveUnlockDeviceNameListener != null
164                 && !mActiveUnlockDeviceNameListener.hasEnrolled()
165                 && !mCombinedBiometricStatusUtils.hasEnrolled()) {
166             intent = new Intent(getActivity(), ActiveUnlockRequireBiometricSetup.class);
167             intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
168             int userId = mUserId;
169             if (mUserId != UserHandle.USER_NULL) {
170                 intent.putExtra(Intent.EXTRA_USER_ID, mUserId);
171             }
172             intent.putExtra(EXTRA_KEY_GK_PW_HANDLE, getGkPwHandle());
173         } else {
174             intent = mActiveUnlockStatusUtils.getIntent();
175         }
176         if (intent != null) {
177             if (Flags.activeUnlockFinishParent()) {
178                 mActiveUnlockPreferenceLauncher.launch(intent);
179             } else {
180                 startActivityForResult(intent, ACTIVE_UNLOCK_REQUEST);
181             }
182         }
183         return true;
184 
185     }
186 
onActiveUnlockPreferenceResult(@ullable ActivityResult result)187     private void onActiveUnlockPreferenceResult(@Nullable ActivityResult result) {
188         if (result != null && result.getResultCode() == BiometricEnrollBase.RESULT_TIMEOUT) {
189             mDoNotFinishActivity = false;
190             // When "Watch Unlock" is closed due to entering onStop(),
191             // "Face & Fingerprint Unlock" shall also close itself and back to "Security" page.
192             finish();
193         }
194     }
195 
196     @Override
getUseAnyBiometricSummary()197     protected String getUseAnyBiometricSummary() {
198         // either Active Unlock is not enabled or no device is enrolled.
199         if (mActiveUnlockDeviceNameListener == null
200                 || !mActiveUnlockDeviceNameListener.hasEnrolled()) {
201             return super.getUseAnyBiometricSummary();
202         }
203         return mActiveUnlockStatusUtils.getUnlockDeviceSummaryForActiveUnlock();
204     }
205 
206     public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
207             new CombinedBiometricSearchIndexProvider(R.xml.security_settings_combined_biometric) {
208                 @Override
209                 protected boolean isPageSearchEnabled(Context context) {
210                     return super.isPageSearchEnabled(context)
211                             && !Flags.biometricsOnboardingEducation();
212                 }
213             };
214 }
215