1 /*
2  * Copyright (C) 2018 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.car.settings.security;
18 
19 import android.app.admin.DevicePolicyManager;
20 import android.app.admin.PasswordMetrics;
21 import android.car.drivingstate.CarUxRestrictions;
22 import android.content.Context;
23 import android.content.Intent;
24 import android.os.UserHandle;
25 
26 import androidx.annotation.VisibleForTesting;
27 import androidx.preference.Preference;
28 
29 import com.android.car.settings.R;
30 import com.android.car.settings.common.ConfirmationDialogFragment;
31 import com.android.car.settings.common.FragmentController;
32 import com.android.internal.widget.LockPatternUtils;
33 import com.android.internal.widget.LockscreenCredential;
34 
35 /** Business logic for the no lock preference. */
36 public class NoLockPreferenceController extends LockTypeBasePreferenceController {
37 
38     private static final int[] ALLOWED_PASSWORD_QUALITIES =
39             new int[]{DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED};
40 
41     private final LockPatternUtils mLockPatternUtils;
42 
43     @VisibleForTesting
44     final ConfirmationDialogFragment.ConfirmListener mConfirmListener = arguments -> {
45         int userId = UserHandle.myUserId();
46         new LockPatternUtils(getContext()).setLockCredential(
47                 LockscreenCredential.createNone(), getCurrentPassword(), userId);
48         getFragmentController().goBack();
49     };
50 
NoLockPreferenceController(Context context, String preferenceKey, FragmentController fragmentController, CarUxRestrictions uxRestrictions)51     public NoLockPreferenceController(Context context, String preferenceKey,
52             FragmentController fragmentController, CarUxRestrictions uxRestrictions) {
53         super(context, preferenceKey, fragmentController, uxRestrictions);
54         mLockPatternUtils = new LockPatternUtils(context);
55     }
56 
57 
58     /**
59      * If the dialog to confirm removal of lock was open previously, make sure the listener is
60      * restored.
61      */
62     @Override
onCreateInternal()63     protected void onCreateInternal() {
64         super.onCreateInternal();
65         ConfirmationDialogFragment dialog =
66                 (ConfirmationDialogFragment) getFragmentController().findDialogByTag(
67                         ConfirmationDialogFragment.TAG);
68         ConfirmationDialogFragment.resetListeners(
69                 dialog,
70                 mConfirmListener,
71                 /* rejectListener= */ null,
72                 /* neutralListener= */ null);
73     }
74 
75     @Override
handlePreferenceClicked(Preference preference)76     protected boolean handlePreferenceClicked(Preference preference) {
77         if (isCurrentLock()) {
78             // No need to show dialog to confirm remove screen lock if screen lock is already
79             // removed, which is true if this controller is the current lock.
80             getFragmentController().goBack();
81         } else {
82             getFragmentController().showDialog(
83                 getConfirmRemoveScreenLockDialogFragment(),
84                 ConfirmationDialogFragment.TAG);
85         }
86         return true;
87     }
88 
89     @Override
activityToOpen()90     protected Intent activityToOpen() {
91         // Selecting this preference does not open a new activity. Instead it opens a dialog to
92         // confirm the removal of the existing lock screen.
93         return null;
94     }
95 
96     @Override
allowedPasswordQualities()97     protected int[] allowedPasswordQualities() {
98         return ALLOWED_PASSWORD_QUALITIES;
99     }
100 
101     @Override
updateState(Preference preference)102     protected void updateState(Preference preference) {
103         super.updateState(preference);
104 
105         PasswordMetrics metrics = mLockPatternUtils.getRequestedPasswordMetrics(
106                 UserHandle.myUserId(), /* deviceWideOnly= */ false);
107         preference.setEnabled(metrics.credType == LockPatternUtils.CREDENTIAL_TYPE_NONE);
108     }
109 
getConfirmRemoveScreenLockDialogFragment()110     private ConfirmationDialogFragment getConfirmRemoveScreenLockDialogFragment() {
111         return new ConfirmationDialogFragment.Builder(getContext())
112                 .setTitle(R.string.remove_screen_lock_title)
113                 .setMessage(R.string.remove_screen_lock_message)
114                 .setPositiveButton(R.string.remove_button, mConfirmListener)
115                 .setNegativeButton(android.R.string.cancel, /* rejectListener= */ null)
116                 .build();
117     }
118 }
119