1/* 2 * Copyright (C) 2007 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 17package com.android.settings; 18 19import android.app.Activity; 20import android.app.admin.DevicePolicyManager; 21import android.content.Context; 22import android.content.Intent; 23import android.os.Bundle; 24import android.os.UserHandle; 25import android.os.UserManager; 26import android.provider.SearchIndexableResource; 27import android.security.KeyStore; 28import android.support.v7.preference.PreferenceGroup; 29import android.support.v7.preference.PreferenceScreen; 30 31import com.android.internal.logging.nano.MetricsProto.MetricsEvent; 32import com.android.internal.widget.LockPatternUtils; 33import com.android.settings.dashboard.DashboardFragment; 34import com.android.settings.search.BaseSearchIndexProvider; 35import com.android.settings.search.Indexable; 36import com.android.settingslib.RestrictedLockUtils; 37import com.android.settingslib.RestrictedPreference; 38 39import java.util.ArrayList; 40import java.util.List; 41 42/** 43 * Encryption and Credential settings. 44 * TODO: Extends this from {@link DashboardFragment} instead 45 */ 46public class EncryptionAndCredential extends SettingsPreferenceFragment implements Indexable { 47 48 private static final String TAG = "EncryptionAndCredential"; 49 50 // Misc Settings 51 private static final String KEY_CREDENTIAL_STORAGE_TYPE = "credential_storage_type"; 52 private static final String KEY_USER_CREDENTIALS = "user_credentials"; 53 private static final String KEY_RESET_CREDENTIALS = "credentials_reset"; 54 private static final String KEY_CREDENTIALS_INSTALL = "credentials_install"; 55 private static final String KEY_CREDENTIALS_MANAGER = "credentials_management"; 56 57 private static final int MY_USER_ID = UserHandle.myUserId(); 58 59 private UserManager mUm; 60 61 private KeyStore mKeyStore; 62 private RestrictedPreference mResetCredentials; 63 64 private boolean mIsAdmin; 65 66 @Override 67 public int getMetricsCategory() { 68 return MetricsEvent.ENCRYPTION_AND_CREDENTIAL; 69 } 70 71 @Override 72 public void onCreate(Bundle savedInstanceState) { 73 super.onCreate(savedInstanceState); 74 75 final Activity activity = getActivity(); 76 77 mUm = UserManager.get(activity); 78 } 79 80 /** 81 * Important! 82 * 83 * Don't forget to update the SecuritySearchIndexProvider if you are doing any change in the 84 * logic or adding/removing preferences here. 85 */ 86 private PreferenceScreen createPreferenceHierarchy() { 87 PreferenceScreen root = getPreferenceScreen(); 88 if (root != null) { 89 root.removeAll(); 90 } 91 addPreferencesFromResource(R.xml.encryption_and_credential); 92 root = getPreferenceScreen(); 93 94 // Add options for device encryption 95 mIsAdmin = mUm.isAdminUser(); 96 97 if (mIsAdmin) { 98 if (LockPatternUtils.isDeviceEncryptionEnabled()) { 99 // The device is currently encrypted. 100 addPreferencesFromResource(R.xml.security_settings_encrypted); 101 } else { 102 // This device supports encryption but isn't encrypted. 103 addPreferencesFromResource(R.xml.security_settings_unencrypted); 104 } 105 } 106 107 // Credential storage 108 mKeyStore = KeyStore.getInstance(); // needs to be initialized for onResume() 109 110 if (!RestrictedLockUtils.hasBaseUserRestriction(getActivity(), 111 UserManager.DISALLOW_CONFIG_CREDENTIALS, MY_USER_ID)) { 112 RestrictedPreference userCredentials = (RestrictedPreference) root.findPreference( 113 KEY_USER_CREDENTIALS); 114 userCredentials.checkRestrictionAndSetDisabled( 115 UserManager.DISALLOW_CONFIG_CREDENTIALS); 116 RestrictedPreference credentialStorageType = (RestrictedPreference) root.findPreference( 117 KEY_CREDENTIAL_STORAGE_TYPE); 118 credentialStorageType.checkRestrictionAndSetDisabled( 119 UserManager.DISALLOW_CONFIG_CREDENTIALS); 120 RestrictedPreference installCredentials = (RestrictedPreference) root.findPreference( 121 KEY_CREDENTIALS_INSTALL); 122 installCredentials.checkRestrictionAndSetDisabled( 123 UserManager.DISALLOW_CONFIG_CREDENTIALS); 124 mResetCredentials = (RestrictedPreference) root.findPreference(KEY_RESET_CREDENTIALS); 125 mResetCredentials.checkRestrictionAndSetDisabled( 126 UserManager.DISALLOW_CONFIG_CREDENTIALS); 127 128 final int storageSummaryRes = 129 mKeyStore.isHardwareBacked() ? R.string.credential_storage_type_hardware 130 : R.string.credential_storage_type_software; 131 credentialStorageType.setSummary(storageSummaryRes); 132 } else { 133 PreferenceGroup credentialsManager = (PreferenceGroup) 134 root.findPreference(KEY_CREDENTIALS_MANAGER); 135 credentialsManager.removePreference(root.findPreference(KEY_RESET_CREDENTIALS)); 136 credentialsManager.removePreference(root.findPreference(KEY_CREDENTIALS_INSTALL)); 137 credentialsManager.removePreference(root.findPreference(KEY_CREDENTIAL_STORAGE_TYPE)); 138 credentialsManager.removePreference(root.findPreference(KEY_USER_CREDENTIALS)); 139 } 140 141 return root; 142 } 143 144 @Override 145 public void onResume() { 146 super.onResume(); 147 148 // Make sure we reload the preference hierarchy since some of these settings 149 // depend on others... 150 createPreferenceHierarchy(); 151 152 if (mResetCredentials != null && !mResetCredentials.isDisabledByAdmin()) { 153 mResetCredentials.setEnabled(!mKeyStore.isEmpty()); 154 } 155 } 156 157 /** 158 * see confirmPatternThenDisableAndClear 159 */ 160 @Override 161 public void onActivityResult(int requestCode, int resultCode, Intent data) { 162 super.onActivityResult(requestCode, resultCode, data); 163 createPreferenceHierarchy(); 164 } 165 166 @Override 167 protected int getHelpResource() { 168 return R.string.help_url_encryption; 169 } 170 171 /** 172 * For Search. Please keep it in sync when updating "createPreferenceHierarchy()" 173 */ 174 public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = 175 new SecuritySearchIndexProvider(); 176 177 private static class SecuritySearchIndexProvider extends BaseSearchIndexProvider { 178 179 @Override 180 public List<SearchIndexableResource> getXmlResourcesToIndex( 181 Context context, boolean enabled) { 182 final List<SearchIndexableResource> index = new ArrayList<>(); 183 184 // Add everything. We will suppress some of them in getNonIndexableKeys() 185 index.add(getSearchResource(context, R.xml.encryption_and_credential)); 186 index.add(getSearchResource(context, R.xml.security_settings_encrypted)); 187 index.add(getSearchResource(context, R.xml.security_settings_unencrypted)); 188 189 return index; 190 } 191 192 @Override 193 protected boolean isPageSearchEnabled(Context context) { 194 final UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE); 195 return um.isAdminUser(); 196 } 197 198 private SearchIndexableResource getSearchResource(Context context, int xmlResId) { 199 final SearchIndexableResource sir = new SearchIndexableResource(context); 200 sir.xmlResId = xmlResId; 201 return sir; 202 } 203 204 @Override 205 public List<String> getNonIndexableKeys(Context context) { 206 final List<String> keys = super.getNonIndexableKeys(context); 207 if (!isPageSearchEnabled(context)) { 208 return keys; 209 } 210 final UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE); 211 212 if (um.hasUserRestriction(UserManager.DISALLOW_CONFIG_CREDENTIALS)) { 213 keys.add(KEY_CREDENTIALS_MANAGER); 214 keys.add(KEY_RESET_CREDENTIALS); 215 keys.add(KEY_CREDENTIALS_INSTALL); 216 keys.add(KEY_CREDENTIAL_STORAGE_TYPE); 217 keys.add(KEY_USER_CREDENTIALS); 218 } 219 220 final DevicePolicyManager dpm = (DevicePolicyManager) 221 context.getSystemService(Context.DEVICE_POLICY_SERVICE); 222 switch (dpm.getStorageEncryptionStatus()) { 223 case DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE: 224 // The device is currently encrypted. Disable security_settings_unencrypted 225 keys.addAll(getNonIndexableKeysFromXml( 226 context, R.xml.security_settings_unencrypted)); 227 break; 228 default: 229 // This device supports encryption but isn't encrypted. 230 keys.addAll(getNonIndexableKeysFromXml( 231 context, R.xml.security_settings_encrypted)); 232 break; 233 } 234 235 return keys; 236 } 237 } 238 239} 240