• 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 package com.android.settings.security;
17 
18 import android.app.admin.DevicePolicyManager;
19 import android.app.settings.SettingsEnums;
20 import android.content.Context;
21 import android.content.Intent;
22 import android.os.Bundle;
23 import android.os.UserHandle;
24 import android.provider.SearchIndexableResource;
25 import android.provider.Settings;
26 import android.view.LayoutInflater;
27 import android.view.View;
28 import android.view.ViewGroup;
29 import android.widget.Switch;
30 
31 import androidx.preference.Preference;
32 import androidx.preference.Preference.OnPreferenceChangeListener;
33 import androidx.preference.PreferenceScreen;
34 import androidx.preference.SwitchPreference;
35 
36 import com.android.internal.widget.LockPatternUtils;
37 import com.android.settings.R;
38 import com.android.settings.SettingsActivity;
39 import com.android.settings.SettingsPreferenceFragment;
40 import com.android.settings.password.ChooseLockGeneric;
41 import com.android.settings.search.BaseSearchIndexProvider;
42 import com.android.settings.widget.SwitchBar;
43 import com.android.settingslib.search.SearchIndexable;
44 
45 import java.util.Arrays;
46 import java.util.List;
47 
48 /**
49  * Screen pinning settings.
50  */
51 @SearchIndexable
52 public class ScreenPinningSettings extends SettingsPreferenceFragment
53         implements SwitchBar.OnSwitchChangeListener {
54 
55     private static final CharSequence KEY_USE_SCREEN_LOCK = "use_screen_lock";
56     private static final int CHANGE_LOCK_METHOD_REQUEST = 43;
57 
58     private SwitchBar mSwitchBar;
59     private SwitchPreference mUseScreenLock;
60     private LockPatternUtils mLockPatternUtils;
61 
62     @Override
getMetricsCategory()63     public int getMetricsCategory() {
64         return SettingsEnums.SCREEN_PINNING;
65     }
66 
67     @Override
onActivityCreated(Bundle savedInstanceState)68     public void onActivityCreated(Bundle savedInstanceState) {
69         super.onActivityCreated(savedInstanceState);
70 
71         final SettingsActivity activity = (SettingsActivity) getActivity();
72         activity.setTitle(R.string.screen_pinning_title);
73         mLockPatternUtils = new LockPatternUtils(activity);
74 
75 
76         mSwitchBar = activity.getSwitchBar();
77         mSwitchBar.addOnSwitchChangeListener(this);
78         mSwitchBar.show();
79         mSwitchBar.setChecked(isLockToAppEnabled(getActivity()));
80     }
81 
82     @Override
getHelpResource()83     public int getHelpResource() {
84         return R.string.help_url_screen_pinning;
85     }
86 
87     @Override
onViewCreated(View view, Bundle savedInstanceState)88     public void onViewCreated(View view, Bundle savedInstanceState) {
89         super.onViewCreated(view, savedInstanceState);
90         ViewGroup parent = (ViewGroup) view.findViewById(android.R.id.list_container);
91         View emptyView = LayoutInflater.from(getContext())
92                 .inflate(R.layout.screen_pinning_instructions, parent, false);
93         parent.addView(emptyView);
94         setEmptyView(emptyView);
95     }
96 
97     @Override
onDestroyView()98     public void onDestroyView() {
99         super.onDestroyView();
100 
101         mSwitchBar.removeOnSwitchChangeListener(this);
102         mSwitchBar.hide();
103     }
104 
isLockToAppEnabled(Context context)105     private static boolean isLockToAppEnabled(Context context) {
106         return Settings.System.getInt(context.getContentResolver(),
107                 Settings.System.LOCK_TO_APP_ENABLED, 0) != 0;
108     }
109 
setLockToAppEnabled(boolean isEnabled)110     private void setLockToAppEnabled(boolean isEnabled) {
111         Settings.System.putInt(getContentResolver(), Settings.System.LOCK_TO_APP_ENABLED,
112                 isEnabled ? 1 : 0);
113         if (isEnabled) {
114             // Set the value to match what we have defaulted to in the UI.
115             setScreenLockUsedSetting(isScreenLockUsed());
116         }
117     }
118 
isScreenLockUsed()119     private boolean isScreenLockUsed() {
120         // This functionality should be kept consistent with
121         // com.android.server.wm.LockTaskController (see b/127605586)
122         int defaultValueIfSettingNull = mLockPatternUtils.isSecure(UserHandle.myUserId()) ? 1 : 0;
123         return Settings.Secure.getInt(
124                 getContentResolver(),
125                 Settings.Secure.LOCK_TO_APP_EXIT_LOCKED,
126                 defaultValueIfSettingNull) != 0;
127     }
128 
setScreenLockUsed(boolean isEnabled)129     private boolean setScreenLockUsed(boolean isEnabled) {
130         if (isEnabled) {
131             LockPatternUtils lockPatternUtils = new LockPatternUtils(getActivity());
132             int passwordQuality = lockPatternUtils
133                     .getKeyguardStoredPasswordQuality(UserHandle.myUserId());
134             if (passwordQuality == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {
135                 Intent chooseLockIntent = new Intent(DevicePolicyManager.ACTION_SET_NEW_PASSWORD);
136                 chooseLockIntent.putExtra(
137                         ChooseLockGeneric.ChooseLockGenericFragment.MINIMUM_QUALITY_KEY,
138                         DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
139                 startActivityForResult(chooseLockIntent, CHANGE_LOCK_METHOD_REQUEST);
140                 return false;
141             }
142         }
143         setScreenLockUsedSetting(isEnabled);
144         return true;
145     }
146 
setScreenLockUsedSetting(boolean isEnabled)147     private void setScreenLockUsedSetting(boolean isEnabled) {
148         Settings.Secure.putInt(getContentResolver(), Settings.Secure.LOCK_TO_APP_EXIT_LOCKED,
149                 isEnabled ? 1 : 0);
150     }
151 
152     @Override
onActivityResult(int requestCode, int resultCode, Intent data)153     public void onActivityResult(int requestCode, int resultCode, Intent data) {
154         super.onActivityResult(requestCode, resultCode, data);
155         if (requestCode == CHANGE_LOCK_METHOD_REQUEST) {
156             LockPatternUtils lockPatternUtils = new LockPatternUtils(getActivity());
157             boolean validPassQuality = lockPatternUtils.getKeyguardStoredPasswordQuality(
158                     UserHandle.myUserId())
159                     != DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
160             setScreenLockUsed(validPassQuality);
161             // Make sure the screen updates.
162             mUseScreenLock.setChecked(validPassQuality);
163         }
164     }
165 
getCurrentSecurityTitle()166     private int getCurrentSecurityTitle() {
167         int quality = mLockPatternUtils.getKeyguardStoredPasswordQuality(
168                 UserHandle.myUserId());
169         switch (quality) {
170             case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
171             case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX:
172                 return R.string.screen_pinning_unlock_pin;
173             case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC:
174             case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC:
175             case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX:
176             case DevicePolicyManager.PASSWORD_QUALITY_MANAGED:
177                 return R.string.screen_pinning_unlock_password;
178             case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
179                 if (mLockPatternUtils.isLockPatternEnabled(UserHandle.myUserId())) {
180                     return R.string.screen_pinning_unlock_pattern;
181                 }
182         }
183         return R.string.screen_pinning_unlock_none;
184     }
185 
186     /**
187      * Listens to the state change of the lock-to-app master switch.
188      */
189     @Override
onSwitchChanged(Switch switchView, boolean isChecked)190     public void onSwitchChanged(Switch switchView, boolean isChecked) {
191         setLockToAppEnabled(isChecked);
192         updateDisplay();
193     }
194 
updateDisplay()195     public void updateDisplay() {
196         PreferenceScreen root = getPreferenceScreen();
197         if (root != null) {
198             root.removeAll();
199         }
200         if (isLockToAppEnabled(getActivity())) {
201             addPreferencesFromResource(R.xml.screen_pinning_settings);
202             root = getPreferenceScreen();
203 
204             mUseScreenLock = (SwitchPreference) root.findPreference(KEY_USE_SCREEN_LOCK);
205             mUseScreenLock.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
206                 @Override
207                 public boolean onPreferenceChange(Preference preference, Object newValue) {
208                     return setScreenLockUsed((boolean) newValue);
209                 }
210             });
211             mUseScreenLock.setChecked(isScreenLockUsed());
212             mUseScreenLock.setTitle(getCurrentSecurityTitle());
213         }
214     }
215 
216     /**
217      * For search
218      */
219     public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
220         new BaseSearchIndexProvider() {
221 
222             @Override
223             public List<SearchIndexableResource> getXmlResourcesToIndex(Context context,
224                     boolean enabled) {
225                 final SearchIndexableResource sir = new SearchIndexableResource(context);
226                 sir.xmlResId = R.xml.screen_pinning_settings;
227                 return Arrays.asList(sir);
228             }
229         };
230 }
231