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 android.app.Activity;
20 import android.content.Context;
21 import android.content.Intent;
22 import android.os.Bundle;
23 import android.util.Log;
24 import android.view.View;
25 import android.view.inputmethod.InputMethodManager;
26 import android.widget.Button;
27 
28 import androidx.annotation.Nullable;
29 import androidx.fragment.app.Fragment;
30 
31 import com.android.settings.R;
32 import com.android.settings.SetupRedactionInterstitial;
33 import com.android.settings.password.ChooseLockTypeDialogFragment.OnLockTypeSelectedListener;
34 
35 /**
36  * Setup Wizard's version of ChooseLockPassword screen. It inherits the logic and basic structure
37  * from ChooseLockPassword class, and should remain similar to that behaviorally. This class should
38  * only overload base methods for minor theme and behavior differences specific to Setup Wizard.
39  * Other changes should be done to ChooseLockPassword class instead and let this class inherit
40  * those changes.
41  */
42 public class SetupChooseLockPassword extends ChooseLockPassword {
43 
44     private static final String TAG = "SetupChooseLockPassword";
45 
modifyIntentForSetup( Context context, Intent chooseLockPasswordIntent)46     public static Intent modifyIntentForSetup(
47             Context context,
48             Intent chooseLockPasswordIntent) {
49         chooseLockPasswordIntent.setClass(context, SetupChooseLockPassword.class);
50         chooseLockPasswordIntent.putExtra(EXTRA_PREFS_SHOW_BUTTON_BAR, false);
51         return chooseLockPasswordIntent;
52     }
53 
54     @Override
isValidFragment(String fragmentName)55     protected boolean isValidFragment(String fragmentName) {
56         return SetupChooseLockPasswordFragment.class.getName().equals(fragmentName);
57     }
58 
59     @Override
getFragmentClass()60     /* package */ Class<? extends Fragment> getFragmentClass() {
61         return SetupChooseLockPasswordFragment.class;
62     }
63 
64     @Override
onCreate(Bundle savedInstance)65     protected void onCreate(Bundle savedInstance) {
66         super.onCreate(savedInstance);
67         findViewById(R.id.content_parent).setFitsSystemWindows(false);
68     }
69 
70     public static class SetupChooseLockPasswordFragment extends ChooseLockPasswordFragment
71             implements OnLockTypeSelectedListener {
72 
73         private static final String TAG_SKIP_SCREEN_LOCK_DIALOG = "skip_screen_lock_dialog";
74 
75         @Nullable
76         private Button mOptionsButton;
77         private boolean mLeftButtonIsSkip;
78 
79         @Override
onViewCreated(View view, Bundle savedInstanceState)80         public void onViewCreated(View view, Bundle savedInstanceState) {
81             super.onViewCreated(view, savedInstanceState);
82             final Activity activity = getActivity();
83             ChooseLockGenericController chooseLockGenericController =
84                     new ChooseLockGenericController.Builder(activity, mUserId)
85                     .setHideInsecureScreenLockTypes(true)
86                     .build();
87             boolean anyOptionsShown = chooseLockGenericController
88                     .getVisibleAndEnabledScreenLockTypes().size() > 0;
89             boolean showOptionsButton = activity.getIntent().getBooleanExtra(
90                     ChooseLockGeneric.ChooseLockGenericFragment.EXTRA_SHOW_OPTIONS_BUTTON, false);
91             if (!anyOptionsShown) {
92                 Log.w(TAG, "Visible screen lock types is empty!");
93             }
94 
95             if (showOptionsButton && anyOptionsShown) {
96                 mOptionsButton = view.findViewById(R.id.screen_lock_options);
97                 mOptionsButton.setVisibility(View.VISIBLE);
98                 mOptionsButton.setOnClickListener((btn) ->
99                         ChooseLockTypeDialogFragment.newInstance(mUserId)
100                                 .show(getChildFragmentManager(), TAG_SKIP_SCREEN_LOCK_DIALOG));
101             }
102         }
103 
104         @Override
onSkipOrClearButtonClick(View view)105         protected void onSkipOrClearButtonClick(View view) {
106             if (mLeftButtonIsSkip) {
107                 final Intent intent = getActivity().getIntent();
108                 final boolean frpSupported = intent
109                         .getBooleanExtra(SetupSkipDialog.EXTRA_FRP_SUPPORTED, false);
110                 final boolean forFingerprint = intent
111                         .getBooleanExtra(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT, false);
112                 final boolean forFace = intent
113                         .getBooleanExtra(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FACE, false);
114                 final boolean forBiometrics = intent
115                         .getBooleanExtra(ChooseLockSettingsHelper.EXTRA_KEY_FOR_BIOMETRICS, false);
116                 final SetupSkipDialog dialog = SetupSkipDialog.newInstance(
117                         frpSupported,
118                         /* isPatternMode= */ false,
119                         mIsAlphaMode,
120                         forFingerprint,
121                         forFace,
122                         forBiometrics);
123 
124                 InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(
125                         Context.INPUT_METHOD_SERVICE);
126                 imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
127 
128                 dialog.show(getFragmentManager());
129                 return;
130             }
131             super.onSkipOrClearButtonClick(view);
132         }
133 
134         @Override
getRedactionInterstitialIntent(Context context)135         protected Intent getRedactionInterstitialIntent(Context context) {
136             // Setup wizard's redaction interstitial is deferred to optional step. Enable that
137             // optional step if the lock screen was set up.
138             SetupRedactionInterstitial.setEnabled(context, true);
139             return null;
140         }
141 
142         @Override
onLockTypeSelected(ScreenLockType lock)143         public void onLockTypeSelected(ScreenLockType lock) {
144             ScreenLockType currentLockType = mIsAlphaMode ?
145                     ScreenLockType.PASSWORD : ScreenLockType.PIN;
146             if (lock == currentLockType) {
147                 return;
148             }
149             startChooseLockActivity(lock, getActivity());
150         }
151 
152         @Override
getStageType()153         protected int getStageType() {
154             // Return TYPE_NONE to make generic lock screen launch in Setup wizard flow before
155             // fingerprint and face setup.
156             return Stage.TYPE_NONE;
157         }
158 
159         @Override
updateUi()160         protected void updateUi() {
161             super.updateUi();
162             // Show the skip button during SUW but not during Settings > Biometric Enrollment
163             if (mUiStage == Stage.Introduction) {
164                 mSkipOrClearButton.setText(getActivity(), R.string.skip_label);
165                 mLeftButtonIsSkip = true;
166             } else {
167                 mSkipOrClearButton.setText(getActivity(), R.string.lockpassword_clear_label);
168                 mLeftButtonIsSkip = false;
169             }
170 
171             if (mOptionsButton != null) {
172                 mOptionsButton.setVisibility(
173                         mUiStage == Stage.Introduction ? View.VISIBLE : View.GONE);
174             }
175         }
176     }
177 }
178