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