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.settings.security;
18 
19 
20 import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;
21 
22 import android.content.Context;
23 import android.os.UserHandle;
24 import android.os.UserManager;
25 import android.util.Log;
26 
27 import androidx.preference.Preference;
28 import androidx.preference.PreferenceScreen;
29 
30 import com.android.internal.widget.LockPatternUtils;
31 import com.android.settings.Utils;
32 import com.android.settings.core.TogglePreferenceController;
33 import com.android.settings.overlay.FeatureFactory;
34 import com.android.settingslib.core.lifecycle.Lifecycle;
35 import com.android.settingslib.core.lifecycle.LifecycleObserver;
36 import com.android.settingslib.core.lifecycle.events.OnResume;
37 
38 import java.util.concurrent.ExecutionException;
39 import java.util.concurrent.FutureTask;
40 
41 public class VisiblePatternProfilePreferenceController extends TogglePreferenceController
42         implements LifecycleObserver, OnResume {
43 
44     private static final String KEY_VISIBLE_PATTERN_PROFILE = "visiblepattern_profile";
45     private static final String TAG = "VisPtnProfPrefCtrl";
46 
47     private final LockPatternUtils mLockPatternUtils;
48     private final UserManager mUm;
49     private final int mUserId = UserHandle.myUserId();
50     private final int mProfileChallengeUserId;
51 
52     private Preference mPreference;
53 
VisiblePatternProfilePreferenceController(Context context)54     public VisiblePatternProfilePreferenceController(Context context) {
55         this(context, null /* lifecycle */);
56     }
57 
58     // TODO (b/73074893) Replace this constructor without Lifecycle using setter method instead.
VisiblePatternProfilePreferenceController(Context context, Lifecycle lifecycle)59     public VisiblePatternProfilePreferenceController(Context context, Lifecycle lifecycle) {
60         super(context, KEY_VISIBLE_PATTERN_PROFILE);
61         mUm = (UserManager) context.getSystemService(Context.USER_SERVICE);
62         mLockPatternUtils = FeatureFactory.getFactory(context)
63                 .getSecurityFeatureProvider()
64                 .getLockPatternUtils(context);
65         mProfileChallengeUserId = Utils.getManagedProfileId(mUm, mUserId);
66         if (lifecycle != null) {
67             lifecycle.addObserver(this);
68         }
69     }
70 
71     @Override
getAvailabilityStatus()72     public int getAvailabilityStatus() {
73         final FutureTask<Integer> futureTask = new FutureTask<>(
74                 // Put the API call in a future to avoid StrictMode violation.
75                 () -> {
76                     final boolean isSecure = mLockPatternUtils.isSecure(mProfileChallengeUserId);
77                     final boolean hasPassword = mLockPatternUtils
78                             .getKeyguardStoredPasswordQuality(mProfileChallengeUserId)
79                             == PASSWORD_QUALITY_SOMETHING;
80                     if (isSecure && hasPassword) {
81                         return AVAILABLE;
82                     }
83                     return DISABLED_FOR_USER;
84                 });
85         try {
86             futureTask.run();
87             return futureTask.get();
88         } catch (InterruptedException | ExecutionException e) {
89             Log.w(TAG, "Error getting lock pattern state.");
90             return DISABLED_FOR_USER;
91         }
92     }
93 
94     @Override
isChecked()95     public boolean isChecked() {
96         return mLockPatternUtils.isVisiblePatternEnabled(
97                 mProfileChallengeUserId);
98     }
99 
100     @Override
setChecked(boolean isChecked)101     public boolean setChecked(boolean isChecked) {
102         if (Utils.startQuietModeDialogIfNecessary(mContext, mUm, mProfileChallengeUserId)) {
103             return false;
104         }
105         mLockPatternUtils.setVisiblePatternEnabled(isChecked, mProfileChallengeUserId);
106         return true;
107     }
108 
109     @Override
displayPreference(PreferenceScreen screen)110     public void displayPreference(PreferenceScreen screen) {
111         super.displayPreference(screen);
112         mPreference = screen.findPreference(getPreferenceKey());
113     }
114 
115     @Override
onResume()116     public void onResume() {
117         mPreference.setVisible(isAvailable());
118     }
119 }
120