Home | History | Annotate | Download | only in settings
      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
     59     public int getMetricsCategory() {
     60         return MetricsEvent.SCREEN_PINNING;
     61     }
     62 
     63     @Override
     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
     78     protected int getHelpResource() {
     79         return R.string.help_url_screen_pinning;
     80     }
     81 
     82     @Override
     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
     93     public void onDestroyView() {
     94         super.onDestroyView();
     95 
     96         mSwitchBar.removeOnSwitchChangeListener(this);
     97         mSwitchBar.hide();
     98     }
     99 
    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 
    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 
    114     private boolean isScreenLockUsed() {
    115         int def = getCurrentSecurityTitle() != R.string.screen_pinning_unlock_none ? 1 : 0;
    116         return Settings.Secure.getInt(getContentResolver(),
    117                 Settings.Secure.LOCK_TO_APP_EXIT_LOCKED, def) != 0;
    118     }
    119 
    120     private boolean setScreenLockUsed(boolean isEnabled) {
    121         if (isEnabled) {
    122             LockPatternUtils lockPatternUtils = new LockPatternUtils(getActivity());
    123             int passwordQuality = lockPatternUtils
    124                     .getKeyguardStoredPasswordQuality(UserHandle.myUserId());
    125             if (passwordQuality == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {
    126                 Intent chooseLockIntent = new Intent(DevicePolicyManager.ACTION_SET_NEW_PASSWORD);
    127                 chooseLockIntent.putExtra(
    128                         ChooseLockGeneric.ChooseLockGenericFragment.MINIMUM_QUALITY_KEY,
    129                         DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
    130                 startActivityForResult(chooseLockIntent, CHANGE_LOCK_METHOD_REQUEST);
    131                 return false;
    132             }
    133         }
    134         setScreenLockUsedSetting(isEnabled);
    135         return true;
    136     }
    137 
    138     private void setScreenLockUsedSetting(boolean isEnabled) {
    139         Settings.Secure.putInt(getContentResolver(), Settings.Secure.LOCK_TO_APP_EXIT_LOCKED,
    140                 isEnabled ? 1 : 0);
    141     }
    142 
    143     @Override
    144     public void onActivityResult(int requestCode, int resultCode, Intent data) {
    145         super.onActivityResult(requestCode, resultCode, data);
    146         if (requestCode == CHANGE_LOCK_METHOD_REQUEST) {
    147             LockPatternUtils lockPatternUtils = new LockPatternUtils(getActivity());
    148             boolean validPassQuality = lockPatternUtils.getKeyguardStoredPasswordQuality(
    149                     UserHandle.myUserId())
    150                     != DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
    151             setScreenLockUsed(validPassQuality);
    152             // Make sure the screen updates.
    153             mUseScreenLock.setChecked(validPassQuality);
    154         }
    155     }
    156 
    157     private int getCurrentSecurityTitle() {
    158         int quality = mLockPatternUtils.getKeyguardStoredPasswordQuality(
    159                 UserHandle.myUserId());
    160         switch (quality) {
    161             case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
    162             case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX:
    163                 return R.string.screen_pinning_unlock_pin;
    164             case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC:
    165             case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC:
    166             case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX:
    167             case DevicePolicyManager.PASSWORD_QUALITY_MANAGED:
    168                 return R.string.screen_pinning_unlock_password;
    169             case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
    170                 if (mLockPatternUtils.isLockPatternEnabled(UserHandle.myUserId())) {
    171                     return R.string.screen_pinning_unlock_pattern;
    172                 }
    173         }
    174         return R.string.screen_pinning_unlock_none;
    175     }
    176 
    177     /**
    178      * Listens to the state change of the lock-to-app master switch.
    179      */
    180     @Override
    181     public void onSwitchChanged(Switch switchView, boolean isChecked) {
    182         setLockToAppEnabled(isChecked);
    183         updateDisplay();
    184     }
    185 
    186     public void updateDisplay() {
    187         PreferenceScreen root = getPreferenceScreen();
    188         if (root != null) {
    189             root.removeAll();
    190         }
    191         if (isLockToAppEnabled(getActivity())) {
    192             addPreferencesFromResource(R.xml.screen_pinning_settings);
    193             root = getPreferenceScreen();
    194 
    195             mUseScreenLock = (SwitchPreference) root.findPreference(KEY_USE_SCREEN_LOCK);
    196             mUseScreenLock.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
    197                 @Override
    198                 public boolean onPreferenceChange(Preference preference, Object newValue) {
    199                     return setScreenLockUsed((boolean) newValue);
    200                 }
    201             });
    202             mUseScreenLock.setChecked(isScreenLockUsed());
    203             mUseScreenLock.setTitle(getCurrentSecurityTitle());
    204         }
    205     }
    206 
    207     /**
    208      * For search
    209      */
    210     public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
    211         new BaseSearchIndexProvider() {
    212             @Override
    213             public List<SearchIndexableRaw> getRawDataToIndex(Context context, boolean enabled) {
    214                 final List<SearchIndexableRaw> result = new ArrayList<SearchIndexableRaw>();
    215 
    216                 final Resources res = context.getResources();
    217 
    218                 // Add fragment title
    219                 SearchIndexableRaw data = new SearchIndexableRaw(context);
    220                 data.title = res.getString(R.string.screen_pinning_title);
    221                 data.screenTitle = res.getString(R.string.screen_pinning_title);
    222                 result.add(data);
    223 
    224                 if (isLockToAppEnabled(context)) {
    225                     // Screen lock option
    226                     data = new SearchIndexableRaw(context);
    227                     data.title = res.getString(R.string.screen_pinning_unlock_none);
    228                     data.screenTitle = res.getString(R.string.screen_pinning_title);
    229                     result.add(data);
    230                 } else {
    231                     // Screen pinning description.
    232                     data = new SearchIndexableRaw(context);
    233                     data.title = res.getString(R.string.screen_pinning_description);
    234                     data.screenTitle = res.getString(R.string.screen_pinning_title);
    235                     result.add(data);
    236                 }
    237 
    238                 return result;
    239             }
    240         };
    241 }
    242