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