• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2014 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.password;
18 
19 import static android.Manifest.permission.REQUEST_PASSWORD_COMPLEXITY;
20 import static android.app.admin.DevicePolicyManager.EXTRA_PASSWORD_COMPLEXITY;
21 
22 import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_REQUESTED_MIN_COMPLEXITY;
23 
24 import android.app.RemoteServiceException.MissingRequestPasswordComplexityPermissionException;
25 import android.content.Context;
26 import android.content.Intent;
27 import android.graphics.Color;
28 import android.graphics.drawable.ColorDrawable;
29 import android.os.Bundle;
30 import android.os.IBinder;
31 import android.os.UserHandle;
32 import android.view.LayoutInflater;
33 import android.view.View;
34 import android.view.ViewGroup;
35 
36 import androidx.fragment.app.Fragment;
37 import androidx.preference.Preference;
38 import androidx.preference.PreferenceFragmentCompat;
39 import androidx.recyclerview.widget.RecyclerView;
40 
41 import com.android.internal.widget.LockPatternUtils;
42 import com.android.settings.R;
43 import com.android.settings.SetupEncryptionInterstitial;
44 import com.android.settings.SetupWizardUtils;
45 import com.android.settings.utils.SettingsDividerItemDecoration;
46 
47 import com.google.android.setupdesign.GlifPreferenceLayout;
48 import com.google.android.setupdesign.util.ThemeHelper;
49 
50 import org.jetbrains.annotations.NotNull;
51 
52 /**
53  * Setup Wizard's version of ChooseLockGeneric screen. It inherits the logic and basic structure
54  * from ChooseLockGeneric class, and should remain similar to that behaviorally. This class should
55  * only overload base methods for minor theme and behavior differences specific to Setup Wizard.
56  * Other changes should be done to ChooseLockGeneric class instead and let this class inherit
57  * those changes.
58  */
59 // TODO(b/123225425): Restrict SetupChooseLockGeneric to be accessible by SUW only
60 public class SetupChooseLockGeneric extends ChooseLockGeneric {
61 
62     private static final String KEY_UNLOCK_SET_DO_LATER = "unlock_set_do_later";
63 
64     @Override
isValidFragment(String fragmentName)65     protected boolean isValidFragment(String fragmentName) {
66         return SetupChooseLockGenericFragment.class.getName().equals(fragmentName);
67     }
68 
69     @Override
getFragmentClass()70     /* package */ Class<? extends PreferenceFragmentCompat> getFragmentClass() {
71         return SetupChooseLockGenericFragment.class;
72     }
73 
74     @Override
onCreate(Bundle savedInstance)75     protected void onCreate(Bundle savedInstance) {
76         setTheme(SetupWizardUtils.getTheme(this, getIntent()));
77         ThemeHelper.trySetDynamicColor(this);
78         super.onCreate(savedInstance);
79 
80         if(getIntent().hasExtra(EXTRA_KEY_REQUESTED_MIN_COMPLEXITY)) {
81             IBinder activityToken = getActivityToken();
82             boolean hasPermission = PasswordUtils.isCallingAppPermitted(
83                     this, activityToken, REQUEST_PASSWORD_COMPLEXITY);
84             if (!hasPermission) {
85                 PasswordUtils.crashCallingApplication(activityToken,
86                         "Must have permission " + REQUEST_PASSWORD_COMPLEXITY
87                                 + " to use extra " + EXTRA_PASSWORD_COMPLEXITY,
88                         MissingRequestPasswordComplexityPermissionException.TYPE_ID);
89                 finish();
90                 return;
91             }
92         }
93 
94         findViewById(R.id.content_parent).setFitsSystemWindows(false);
95     }
96 
97     @Override
isToolbarEnabled()98     protected boolean isToolbarEnabled() {
99         // Hide the action bar from this page.
100         return false;
101     }
102 
103     public static class SetupChooseLockGenericFragment extends ChooseLockGenericFragment {
104 
105         public static final String EXTRA_PASSWORD_QUALITY = ":settings:password_quality";
106 
107         @Override
onViewCreated(View view, Bundle savedInstanceState)108         public void onViewCreated(View view, Bundle savedInstanceState) {
109             super.onViewCreated(view, savedInstanceState);
110 
111             GlifPreferenceLayout layout = (GlifPreferenceLayout) view;
112             layout.setDescriptionText(loadDescriptionText());
113             layout.setDividerItemDecoration(new SettingsDividerItemDecoration(getContext()));
114             layout.setDividerInset(getContext().getResources().getDimensionPixelSize(
115                     R.dimen.sud_items_glif_text_divider_inset));
116 
117             layout.setIcon(getContext().getDrawable(R.drawable.ic_lock));
118 
119             int titleResource = isForBiometric() ?
120                     R.string.lock_settings_picker_title : R.string.setup_lock_settings_picker_title;
121             if (getActivity() != null) {
122                 getActivity().setTitle(titleResource);
123             }
124 
125             layout.setHeaderText(titleResource);
126             // Use the dividers in SetupWizardRecyclerLayout. Suppress the dividers in
127             // PreferenceFragment.
128             setDivider(null);
129         }
130 
131         @Override
addHeaderView()132         protected void addHeaderView() {
133             // The original logic has been moved to onViewCreated and
134             // uses GlifLayout#setDescriptionText instead,
135             // keep empty body here since we won't call super method.
136         }
137 
138         @Override
onActivityResult(int requestCode, int resultCode, Intent data)139         public void onActivityResult(int requestCode, int resultCode, Intent data) {
140             if (data == null) {
141                 data = new Intent();
142             }
143             // Add the password quality extra to the intent data that will be sent back for
144             // Setup Wizard.
145             LockPatternUtils lockPatternUtils = new LockPatternUtils(getActivity());
146             data.putExtra(EXTRA_PASSWORD_QUALITY,
147                     lockPatternUtils.getKeyguardStoredPasswordQuality(UserHandle.myUserId()));
148 
149             super.onActivityResult(requestCode, resultCode, data);
150         }
151 
152         @Override
onCreateRecyclerView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState)153         public RecyclerView onCreateRecyclerView(LayoutInflater inflater, ViewGroup parent,
154                 Bundle savedInstanceState) {
155             GlifPreferenceLayout layout = (GlifPreferenceLayout) parent;
156             return layout.onCreateRecyclerView(inflater, parent, savedInstanceState);
157         }
158 
159         @Override
canRunBeforeDeviceProvisioned()160         protected boolean canRunBeforeDeviceProvisioned() {
161             return true;
162         }
163 
164         @Override
getInternalActivityClass()165         protected Class<? extends ChooseLockGeneric.InternalActivity> getInternalActivityClass() {
166             return SetupChooseLockGeneric.InternalActivity.class;
167         }
168 
169         @Override
alwaysHideInsecureScreenLockTypes()170         protected boolean alwaysHideInsecureScreenLockTypes() {
171             // At this part of the flow, the user has already indicated they want to add a pin,
172             // pattern or password, so don't show "None" or "Slide". We disable them here.
173             // This only happens for setup wizard.
174             return true;
175         }
176 
177         @Override
addPreferences()178         protected void addPreferences() {
179             if (isForBiometric()) {
180                 super.addPreferences();
181             } else {
182                 addPreferencesFromResource(R.xml.setup_security_settings_picker);
183             }
184         }
185 
186         @Override
onPreferenceTreeClick(Preference preference)187         public boolean onPreferenceTreeClick(Preference preference) {
188             final String key = preference.getKey();
189             if (KEY_UNLOCK_SET_DO_LATER.equals(key)) {
190                 // show warning.
191                 SetupSkipDialog dialog = SetupSkipDialog.newInstance(
192                         getActivity().getIntent()
193                                 .getBooleanExtra(SetupSkipDialog.EXTRA_FRP_SUPPORTED, false),
194                         /* isPatternMode= */ false,
195                         /* isAlphaMode= */ false,
196                         /* forFingerprint= */ false,
197                         /* forFace= */ false,
198                         /* forBiometrics= */ false
199                 );
200                 dialog.show(getFragmentManager());
201                 return true;
202             }
203             return super.onPreferenceTreeClick(preference);
204         }
205 
206         @Override
getLockPasswordIntent(int quality)207         protected Intent getLockPasswordIntent(int quality) {
208             final Intent intent = SetupChooseLockPassword.modifyIntentForSetup(
209                     getContext(), super.getLockPasswordIntent(quality));
210             SetupWizardUtils.copySetupExtras(getActivity().getIntent(), intent);
211             return intent;
212         }
213 
214         @Override
getLockPatternIntent()215         protected Intent getLockPatternIntent() {
216             final Intent intent = SetupChooseLockPattern.modifyIntentForSetup(
217                     getContext(), super.getLockPatternIntent());
218             SetupWizardUtils.copySetupExtras(getActivity().getIntent(), intent);
219             return intent;
220         }
221 
222         @Override
getEncryptionInterstitialIntent(Context context, int quality, boolean required, Intent unlockMethodIntent)223         protected Intent getEncryptionInterstitialIntent(Context context, int quality,
224                 boolean required, Intent unlockMethodIntent) {
225             Intent intent = SetupEncryptionInterstitial.createStartIntent(context, quality,
226                     required, unlockMethodIntent);
227             SetupWizardUtils.copySetupExtras(getActivity().getIntent(), intent);
228             return intent;
229         }
230 
231         @Override
getBiometricEnrollIntent(Context context)232         protected Intent getBiometricEnrollIntent(Context context) {
233             final Intent intent = super.getBiometricEnrollIntent(context);
234             SetupWizardUtils.copySetupExtras(getActivity().getIntent(), intent);
235             return intent;
236         }
237 
isForBiometric()238         private boolean isForBiometric() {
239             return mForFingerprint || mForFace || mForBiometrics;
240         }
241 
loadDescriptionText()242         String loadDescriptionText() {
243             return getString(isForBiometric()
244                     ? R.string.lock_settings_picker_biometrics_added_security_message
245                     : R.string.setup_lock_settings_picker_message);
246         }
247     }
248 
249     public static class InternalActivity extends ChooseLockGeneric.InternalActivity {
250         @Override
onCreate(Bundle savedState)251         protected void onCreate(Bundle savedState) {
252             setTheme(SetupWizardUtils.getTheme(this, getIntent()));
253             ThemeHelper.trySetDynamicColor(this);
254             super.onCreate(savedState);
255         }
256 
257         @Override
isValidFragment(String fragmentName)258         protected boolean isValidFragment(String fragmentName) {
259             return InternalSetupChooseLockGenericFragment.class.getName().equals(fragmentName);
260         }
261 
262         @Override
getFragmentClass()263         /* package */ Class<? extends Fragment> getFragmentClass() {
264             return InternalSetupChooseLockGenericFragment.class;
265         }
266 
267         public static class InternalSetupChooseLockGenericFragment
268                 extends ChooseLockGenericFragment {
269             @Override
canRunBeforeDeviceProvisioned()270             protected boolean canRunBeforeDeviceProvisioned() {
271                 return true;
272             }
273 
274             @Override
onViewCreated(@otNull View view, Bundle savedInstanceState)275             public void onViewCreated(@NotNull View view, Bundle savedInstanceState) {
276                 super.onViewCreated(view, savedInstanceState);
277 
278                 GlifPreferenceLayout layout = (GlifPreferenceLayout) view;
279                 int titleResource = R.string.lock_settings_picker_new_lock_title;
280 
281                 layout.setHeaderText(titleResource);
282                 setDivider(new ColorDrawable(Color.TRANSPARENT));
283                 setDividerHeight(0);
284                 getHeaderView().setVisible(false);
285             }
286 
287             @Override
getLockPasswordIntent(int quality)288             protected Intent getLockPasswordIntent(int quality) {
289                 final Intent intent = SetupChooseLockPassword.modifyIntentForSetup(
290                         getContext(), super.getLockPasswordIntent(quality));
291                 SetupWizardUtils.copySetupExtras(getIntent(), intent);
292                 return intent;
293             }
294 
295             @Override
getLockPatternIntent()296             protected Intent getLockPatternIntent() {
297                 final Intent intent = SetupChooseLockPattern.modifyIntentForSetup(
298                         getContext(), super.getLockPatternIntent());
299                 SetupWizardUtils.copySetupExtras(getIntent(), intent);
300                 return intent;
301             }
302 
303             @Override
getBiometricEnrollIntent(Context context)304             protected Intent getBiometricEnrollIntent(Context context) {
305                 final Intent intent = super.getBiometricEnrollIntent(context);
306                 SetupWizardUtils.copySetupExtras(getIntent(), intent);
307                 return intent;
308             }
309 
310             @Override
onCreateRecyclerView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState)311             public RecyclerView onCreateRecyclerView(LayoutInflater inflater, ViewGroup parent,
312                     Bundle savedInstanceState) {
313                 GlifPreferenceLayout layout = (GlifPreferenceLayout) parent;
314                 return layout.onCreateRecyclerView(inflater, parent, savedInstanceState);
315             }
316         }
317     }
318 }
319