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;
18 
19 import android.app.admin.DevicePolicyManager;
20 import android.content.Context;
21 import android.content.Intent;
22 import android.content.res.Resources;
23 import android.os.Bundle;
24 import android.os.UserHandle;
25 import android.support.v14.preference.PreferenceFragment;
26 import android.support.v7.preference.Preference;
27 import android.support.v7.widget.RecyclerView;
28 import android.view.LayoutInflater;
29 import android.view.View;
30 import android.view.ViewGroup;
31 import android.widget.LinearLayout;
32 
33 import com.android.internal.widget.LockPatternUtils;
34 import com.android.settings.fingerprint.SetupFingerprintEnrollFindSensor;
35 import com.android.settings.fingerprint.SetupSkipDialog;
36 import com.android.settings.utils.SettingsDividerItemDecoration;
37 import com.android.setupwizardlib.GlifPreferenceLayout;
38 
39 /**
40  * Setup Wizard's version of ChooseLockGeneric screen. It inherits the logic and basic structure
41  * from ChooseLockGeneric class, and should remain similar to that behaviorally. This class should
42  * only overload base methods for minor theme and behavior differences specific to Setup Wizard.
43  * Other changes should be done to ChooseLockGeneric class instead and let this class inherit
44  * those changes.
45  */
46 public class SetupChooseLockGeneric extends ChooseLockGeneric {
47 
48     private static final String KEY_UNLOCK_SET_DO_LATER = "unlock_set_do_later";
49 
50     @Override
isValidFragment(String fragmentName)51     protected boolean isValidFragment(String fragmentName) {
52         return SetupChooseLockGenericFragment.class.getName().equals(fragmentName);
53     }
54 
55     @Override
getFragmentClass()56     /* package */ Class<? extends PreferenceFragment> getFragmentClass() {
57         return SetupChooseLockGenericFragment.class;
58     }
59 
60     @Override
onApplyThemeResource(Resources.Theme theme, int resid, boolean first)61     protected void onApplyThemeResource(Resources.Theme theme, int resid, boolean first) {
62         resid = SetupWizardUtils.getTheme(getIntent());
63         super.onApplyThemeResource(theme, resid, first);
64     }
65 
66     @Override
onCreate(Bundle savedInstance)67     protected void onCreate(Bundle savedInstance) {
68         super.onCreate(savedInstance);
69         LinearLayout layout = (LinearLayout) findViewById(R.id.content_parent);
70         layout.setFitsSystemWindows(false);
71     }
72 
73     public static class SetupChooseLockGenericFragment extends ChooseLockGenericFragment {
74 
75         public static final String EXTRA_PASSWORD_QUALITY = ":settings:password_quality";
76 
77         @Override
onViewCreated(View view, Bundle savedInstanceState)78         public void onViewCreated(View view, Bundle savedInstanceState) {
79             super.onViewCreated(view, savedInstanceState);
80 
81             GlifPreferenceLayout layout = (GlifPreferenceLayout) view;
82             layout.setDividerItemDecoration(new SettingsDividerItemDecoration(getContext()));
83             layout.setDividerInset(getContext().getResources().getDimensionPixelSize(
84                     R.dimen.suw_items_glif_text_divider_inset));
85 
86             layout.setIcon(getContext().getDrawable(R.drawable.ic_lock));
87 
88             int titleResource = mForFingerprint ?
89                     R.string.lock_settings_picker_title : R.string.setup_lock_settings_picker_title;
90             if (getActivity() != null) {
91                 getActivity().setTitle(titleResource);
92             }
93 
94             layout.setHeaderText(titleResource);
95             // Use the dividers in SetupWizardRecyclerLayout. Suppress the dividers in
96             // PreferenceFragment.
97             setDivider(null);
98         }
99 
100         @Override
addHeaderView()101         protected void addHeaderView() {
102             if (mForFingerprint) {
103                 setHeaderView(R.layout.setup_choose_lock_generic_fingerprint_header);
104             } else {
105                 setHeaderView(R.layout.setup_choose_lock_generic_header);
106             }
107         }
108 
109         @Override
onActivityResult(int requestCode, int resultCode, Intent data)110         public void onActivityResult(int requestCode, int resultCode, Intent data) {
111             if (resultCode != RESULT_CANCELED) {
112                 if (data == null) {
113                     data = new Intent();
114                 }
115                 // Add the password quality extra to the intent data that will be sent back for
116                 // Setup Wizard.
117                 LockPatternUtils lockPatternUtils = new LockPatternUtils(getActivity());
118                 data.putExtra(EXTRA_PASSWORD_QUALITY,
119                         lockPatternUtils.getKeyguardStoredPasswordQuality(UserHandle.myUserId()));
120 
121                 super.onActivityResult(requestCode, resultCode, data);
122             }
123             // If the started activity was cancelled (e.g. the user presses back), then this
124             // activity will be resumed to foreground.
125         }
126 
127         @Override
onCreateRecyclerView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState)128         public RecyclerView onCreateRecyclerView(LayoutInflater inflater, ViewGroup parent,
129                 Bundle savedInstanceState) {
130             GlifPreferenceLayout layout = (GlifPreferenceLayout) parent;
131             return layout.onCreateRecyclerView(inflater, parent, savedInstanceState);
132         }
133 
134         /***
135          * Disables preferences that are less secure than required quality and shows only secure
136          * screen lock options here.
137          *
138          * @param quality the requested quality.
139          */
140         @Override
disableUnusablePreferences(final int quality, boolean hideDisabled)141         protected void disableUnusablePreferences(final int quality, boolean hideDisabled) {
142             // At this part of the flow, the user has already indicated they want to add a pin,
143             // pattern or password, so don't show "None" or "Slide". We disable them here and set
144             // the HIDE_DISABLED flag to true to hide them. This only happens for setup wizard.
145             // We do the following max check here since the device may already have a Device Admin
146             // installed with a policy we need to honor.
147             final int newQuality = Math.max(quality,
148                     DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
149             super.disableUnusablePreferencesImpl(newQuality, true /* hideDisabled */);
150         }
151 
152         @Override
addPreferences()153         protected void addPreferences() {
154             if (mForFingerprint) {
155                 super.addPreferences();
156             } else {
157                 addPreferencesFromResource(R.xml.setup_security_settings_picker);
158             }
159         }
160 
161         @Override
onPreferenceTreeClick(Preference preference)162         public boolean onPreferenceTreeClick(Preference preference) {
163             final String key = preference.getKey();
164             if (KEY_UNLOCK_SET_DO_LATER.equals(key)) {
165                 // show warning.
166                 SetupSkipDialog dialog = SetupSkipDialog.newInstance(getActivity().getIntent()
167                         .getBooleanExtra(SetupSkipDialog.EXTRA_FRP_SUPPORTED, false));
168                 dialog.show(getFragmentManager());
169                 return true;
170             }
171             return super.onPreferenceTreeClick(preference);
172         }
173 
174         @Override
getLockPasswordIntent(Context context, int quality, int minLength, final int maxLength, boolean requirePasswordToDecrypt, boolean confirmCredentials, int userId)175         protected Intent getLockPasswordIntent(Context context, int quality,
176                 int minLength, final int maxLength,
177                 boolean requirePasswordToDecrypt, boolean confirmCredentials, int userId) {
178             final Intent intent = SetupChooseLockPassword.createIntent(context, quality, minLength,
179                     maxLength, requirePasswordToDecrypt, confirmCredentials);
180             SetupWizardUtils.copySetupExtras(getActivity().getIntent(), intent);
181             return intent;
182         }
183 
184         @Override
getLockPasswordIntent(Context context, int quality, int minLength, final int maxLength, boolean requirePasswordToDecrypt, long challenge, int userId)185         protected Intent getLockPasswordIntent(Context context, int quality,
186                 int minLength, final int maxLength,
187                 boolean requirePasswordToDecrypt, long challenge, int userId) {
188             final Intent intent = SetupChooseLockPassword.createIntent(context, quality, minLength,
189                     maxLength, requirePasswordToDecrypt, challenge);
190             SetupWizardUtils.copySetupExtras(getActivity().getIntent(), intent);
191             return intent;
192         }
193 
194         @Override
getLockPasswordIntent(Context context, int quality, int minLength, int maxLength, boolean requirePasswordToDecrypt, String password, int userId)195         protected Intent getLockPasswordIntent(Context context, int quality, int minLength,
196                 int maxLength, boolean requirePasswordToDecrypt, String password, int userId) {
197             final Intent intent = SetupChooseLockPassword.createIntent(context, quality, minLength,
198                     maxLength, requirePasswordToDecrypt, password);
199             SetupWizardUtils.copySetupExtras(getActivity().getIntent(), intent);
200             return intent;
201         }
202 
203         @Override
getLockPatternIntent(Context context, final boolean requirePassword, final boolean confirmCredentials, int userId)204         protected Intent getLockPatternIntent(Context context, final boolean requirePassword,
205                 final boolean confirmCredentials, int userId) {
206             final Intent intent = SetupChooseLockPattern.createIntent(context, requirePassword,
207                     confirmCredentials);
208             SetupWizardUtils.copySetupExtras(getActivity().getIntent(), intent);
209             return intent;
210         }
211 
212         @Override
getLockPatternIntent(Context context, final boolean requirePassword, long challenge, int userId)213         protected Intent getLockPatternIntent(Context context, final boolean requirePassword,
214                 long challenge, int userId) {
215             final Intent intent = SetupChooseLockPattern.createIntent(context, requirePassword,
216                     challenge);
217             SetupWizardUtils.copySetupExtras(getActivity().getIntent(), intent);
218             return intent;
219         }
220 
221         @Override
getLockPatternIntent(Context context, final boolean requirePassword, final String pattern, int userId)222         protected Intent getLockPatternIntent(Context context, final boolean requirePassword,
223                 final String pattern, int userId) {
224             final Intent intent = SetupChooseLockPattern.createIntent(context, requirePassword,
225                     pattern);
226             SetupWizardUtils.copySetupExtras(getActivity().getIntent(), intent);
227             return intent;
228         }
229 
230         @Override
getEncryptionInterstitialIntent(Context context, int quality, boolean required, Intent unlockMethodIntent)231         protected Intent getEncryptionInterstitialIntent(Context context, int quality,
232                 boolean required, Intent unlockMethodIntent) {
233             Intent intent = SetupEncryptionInterstitial.createStartIntent(context, quality,
234                     required, unlockMethodIntent);
235             SetupWizardUtils.copySetupExtras(getActivity().getIntent(), intent);
236             return intent;
237         }
238 
239         @Override
getFindSensorIntent(Context context)240         protected Intent getFindSensorIntent(Context context) {
241             final Intent intent = new Intent(context, SetupFingerprintEnrollFindSensor.class);
242             SetupWizardUtils.copySetupExtras(getActivity().getIntent(), intent);
243             return intent;
244         }
245     }
246 }
247