From 81610543a9d26cf52a4b8aad0bbdde4aa010e197 Mon Sep 17 00:00:00 2001 From: Doris Ling Date: Wed, 15 Feb 2017 17:49:18 -0800 Subject: [PATCH] Update Security & screen lock preference - change password category title to Privacy and move Location into it. - remove Advanced security preference category - remove SIM card preference category and move the SIM card lock preferece down. - move Encryption and Credential settings to a separate screen. Bug: 34976707 Test: make RunSettingsRoboTests Change-Id: Iebaba4a8aad135fa88f163de0b60b488fd9510d0 --- AndroidManifest.xml | 13 - res/values/strings.xml | 4 +- res/xml/encryption_and_credential.xml | 65 +++++ res/xml/security_settings_misc.xml | 114 +++----- .../settings/EncryptionAndCredential.java | 268 ++++++++++++++++++ .../android/settings/SecuritySettings.java | 121 +------- .../core/gateway/SettingsGateway.java | 2 - .../LocationPreferenceController.java | 83 ++++++ .../settings/location/LocationSettings.java | 27 +- .../search/SearchIndexableResources.java | 3 + .../LocationPreferenceControllerTest.java | 132 +++++++++ 11 files changed, 604 insertions(+), 228 deletions(-) create mode 100644 res/xml/encryption_and_credential.xml create mode 100644 src/com/android/settings/EncryptionAndCredential.java create mode 100644 src/com/android/settings/location/LocationPreferenceController.java create mode 100644 tests/robotests/src/com/android/settings/location/LocationPreferenceControllerTest.java diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 05010775e7f..d14085b602b 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -3153,19 +3153,6 @@ android:value="com.android.settings.category.ia.homepage"/> - - - - - - - - - diff --git a/res/values/strings.xml b/res/values/strings.xml index 852e81d94f1..bd2f64c9c21 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -744,13 +744,15 @@ Accounts Security & screen lock + + Encryption & credentials Set My Location, screen unlock, SIM card lock, credential storage lock Set My Location, screen unlock, credential storage lock - Passwords + Privacy Disabled by administrator diff --git a/res/xml/encryption_and_credential.xml b/res/xml/encryption_and_credential.xml new file mode 100644 index 00000000000..a84c2a11fc9 --- /dev/null +++ b/res/xml/encryption_and_credential.xml @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/xml/security_settings_misc.xml b/res/xml/security_settings_misc.xml index aefbbd81a82..544769d7ad5 100644 --- a/res/xml/security_settings_misc.xml +++ b/res/xml/security_settings_misc.xml @@ -15,28 +15,17 @@ --> - - - - - - - - - - + + + + @@ -54,74 +43,39 @@ - + - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - + + + diff --git a/src/com/android/settings/EncryptionAndCredential.java b/src/com/android/settings/EncryptionAndCredential.java new file mode 100644 index 00000000000..35c8c0c1c7e --- /dev/null +++ b/src/com/android/settings/EncryptionAndCredential.java @@ -0,0 +1,268 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings; + +import android.app.Activity; +import android.app.admin.DevicePolicyManager; +import android.content.Context; +import android.content.Intent; +import android.content.res.Resources; +import android.os.Bundle; +import android.os.UserHandle; +import android.os.UserManager; +import android.provider.SearchIndexableResource; +import android.security.KeyStore; +import android.support.v7.preference.PreferenceGroup; +import android.support.v7.preference.PreferenceScreen; + +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; +import com.android.internal.widget.LockPatternUtils; +import com.android.settings.dashboard.DashboardFragment; +import com.android.settings.search.BaseSearchIndexProvider; +import com.android.settings.search.Indexable; +import com.android.settings.search.SearchIndexableRaw; +import com.android.settingslib.RestrictedLockUtils; +import com.android.settingslib.RestrictedPreference; + +import java.util.ArrayList; +import java.util.List; + +/** + * Encryption and Credential settings. + * TODO: Extends this from {@link DashboardFragment} instead + */ +public class EncryptionAndCredential extends SettingsPreferenceFragment implements Indexable { + + private static final String TAG = "EncryptionAndCredential"; + + // Misc Settings + private static final String KEY_CREDENTIAL_STORAGE_TYPE = "credential_storage_type"; + private static final String KEY_USER_CREDENTIALS = "user_credentials"; + private static final String KEY_RESET_CREDENTIALS = "credentials_reset"; + private static final String KEY_CREDENTIALS_INSTALL = "credentials_install"; + private static final String KEY_CREDENTIALS_MANAGER = "credentials_management"; + + private static final int MY_USER_ID = UserHandle.myUserId(); + + private UserManager mUm; + + private KeyStore mKeyStore; + private RestrictedPreference mResetCredentials; + + private boolean mIsAdmin; + + @Override + public int getMetricsCategory() { + return MetricsEvent.SECURITY; + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + final Activity activity = getActivity(); + + mUm = UserManager.get(activity); + } + + /** + * Important! + * + * Don't forget to update the SecuritySearchIndexProvider if you are doing any change in the + * logic or adding/removing preferences here. + */ + private PreferenceScreen createPreferenceHierarchy() { + PreferenceScreen root = getPreferenceScreen(); + if (root != null) { + root.removeAll(); + } + addPreferencesFromResource(R.xml.encryption_and_credential); + root = getPreferenceScreen(); + + // Add options for device encryption + mIsAdmin = mUm.isAdminUser(); + + if (mIsAdmin) { + if (LockPatternUtils.isDeviceEncryptionEnabled()) { + // The device is currently encrypted. + addPreferencesFromResource(R.xml.security_settings_encrypted); + } else { + // This device supports encryption but isn't encrypted. + addPreferencesFromResource(R.xml.security_settings_unencrypted); + } + } + + + // Credential storage + mKeyStore = KeyStore.getInstance(); // needs to be initialized for onResume() + + if (!RestrictedLockUtils.hasBaseUserRestriction(getActivity(), + UserManager.DISALLOW_CONFIG_CREDENTIALS, MY_USER_ID)) { + RestrictedPreference userCredentials = (RestrictedPreference) root.findPreference( + KEY_USER_CREDENTIALS); + userCredentials.checkRestrictionAndSetDisabled( + UserManager.DISALLOW_CONFIG_CREDENTIALS); + RestrictedPreference credentialStorageType = (RestrictedPreference) root.findPreference( + KEY_CREDENTIAL_STORAGE_TYPE); + credentialStorageType.checkRestrictionAndSetDisabled( + UserManager.DISALLOW_CONFIG_CREDENTIALS); + RestrictedPreference installCredentials = (RestrictedPreference) root.findPreference( + KEY_CREDENTIALS_INSTALL); + installCredentials.checkRestrictionAndSetDisabled( + UserManager.DISALLOW_CONFIG_CREDENTIALS); + mResetCredentials = (RestrictedPreference) root.findPreference(KEY_RESET_CREDENTIALS); + mResetCredentials.checkRestrictionAndSetDisabled( + UserManager.DISALLOW_CONFIG_CREDENTIALS); + + final int storageSummaryRes = + mKeyStore.isHardwareBacked() ? R.string.credential_storage_type_hardware + : R.string.credential_storage_type_software; + credentialStorageType.setSummary(storageSummaryRes); + } else { + PreferenceGroup credentialsManager = (PreferenceGroup) + root.findPreference(KEY_CREDENTIALS_MANAGER); + credentialsManager.removePreference(root.findPreference(KEY_RESET_CREDENTIALS)); + credentialsManager.removePreference(root.findPreference(KEY_CREDENTIALS_INSTALL)); + credentialsManager.removePreference(root.findPreference(KEY_CREDENTIAL_STORAGE_TYPE)); + credentialsManager.removePreference(root.findPreference(KEY_USER_CREDENTIALS)); + } + + return root; + } + + @Override + public void onResume() { + super.onResume(); + + // Make sure we reload the preference hierarchy since some of these settings + // depend on others... + createPreferenceHierarchy(); + + if (mResetCredentials != null && !mResetCredentials.isDisabledByAdmin()) { + mResetCredentials.setEnabled(!mKeyStore.isEmpty()); + } + } + + /** + * see confirmPatternThenDisableAndClear + */ + @Override + public void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + createPreferenceHierarchy(); + } + + @Override + protected int getHelpResource() { + return R.string.help_url_security; + } + + /** + * For Search. Please keep it in sync when updating "createPreferenceHierarchy()" + */ + public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = + new SecuritySearchIndexProvider(); + + private static class SecuritySearchIndexProvider extends BaseSearchIndexProvider { + + @Override + public List getXmlResourcesToIndex( + Context context, boolean enabled) { + final List index = new ArrayList(); + + final DevicePolicyManager dpm = (DevicePolicyManager) + context.getSystemService(Context.DEVICE_POLICY_SERVICE); + final UserManager um = UserManager.get(context); + + if (um.isAdminUser()) { + switch (dpm.getStorageEncryptionStatus()) { + case DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE: + // The device is currently encrypted. + index.add(getSearchResource(context, R.xml.security_settings_encrypted)); + break; + case DevicePolicyManager.ENCRYPTION_STATUS_INACTIVE: + // This device supports encryption but isn't encrypted. + index.add(getSearchResource(context, R.xml.security_settings_unencrypted)); + break; + } + } + + return index; + } + + private SearchIndexableResource getSearchResource(Context context, int xmlResId) { + final SearchIndexableResource sir = new SearchIndexableResource(context); + sir.xmlResId = xmlResId; + return sir; + } + + @Override + public List getRawDataToIndex(Context context, boolean enabled) { + final List result = new ArrayList(); + final Resources res = context.getResources(); + + final String screenTitle = res.getString( + R.string.encryption_and_credential_settings_title); + + SearchIndexableRaw data = new SearchIndexableRaw(context); + data.title = screenTitle; + data.screenTitle = screenTitle; + result.add(data); + + final UserManager um = UserManager.get(context); + if (!um.isAdminUser()) { + int resId = um.isLinkedUser() ? + R.string.profile_info_settings_title : R.string.user_info_settings_title; + + data = new SearchIndexableRaw(context); + data.title = res.getString(resId); + data.screenTitle = screenTitle; + result.add(data); + } + + // Credential storage + if (!um.hasUserRestriction(UserManager.DISALLOW_CONFIG_CREDENTIALS)) { + KeyStore keyStore = KeyStore.getInstance(); + + final int storageSummaryRes = keyStore.isHardwareBacked() ? + R.string.credential_storage_type_hardware : + R.string.credential_storage_type_software; + + data = new SearchIndexableRaw(context); + data.title = res.getString(storageSummaryRes); + data.screenTitle = screenTitle; + result.add(data); + } + + return result; + } + + @Override + public List getNonIndexableKeys(Context context) { + final List keys = new ArrayList(); + + final UserManager um = UserManager.get(context); + + if (um.hasUserRestriction(UserManager.DISALLOW_CONFIG_CREDENTIALS)) { + keys.add(KEY_CREDENTIALS_MANAGER); + } + + return keys; + } + } + +} diff --git a/src/com/android/settings/SecuritySettings.java b/src/com/android/settings/SecuritySettings.java index b66f2f52dfb..88f03703173 100644 --- a/src/com/android/settings/SecuritySettings.java +++ b/src/com/android/settings/SecuritySettings.java @@ -25,7 +25,6 @@ import android.app.admin.DevicePolicyManager; import android.content.ComponentName; import android.content.Context; import android.content.DialogInterface; -import android.content.IContentProvider; import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; @@ -37,7 +36,6 @@ import android.os.UserHandle; import android.os.UserManager; import android.provider.SearchIndexableResource; import android.provider.Settings; -import android.security.KeyStore; import android.service.trust.TrustAgentService; import android.support.annotation.VisibleForTesting; import android.support.v14.preference.SwitchPreference; @@ -61,6 +59,7 @@ import com.android.settings.core.instrumentation.InstrumentedDialogFragment; import com.android.settings.dashboard.DashboardFeatureProvider; import com.android.settings.dashboard.SummaryLoader; import com.android.settings.fingerprint.FingerprintSettings; +import com.android.settings.location.LocationPreferenceController; import com.android.settings.overlay.FeatureFactory; import com.android.settings.search.BaseSearchIndexProvider; import com.android.settings.search.Index; @@ -101,7 +100,6 @@ public class SecuritySettings extends SettingsPreferenceFragment private static final String KEY_VISIBLE_PATTERN_PROFILE = "visiblepattern_profile"; private static final String KEY_SECURITY_CATEGORY = "security_category"; private static final String KEY_DEVICE_ADMIN_CATEGORY = "device_admin_category"; - private static final String KEY_ADVANCED_SECURITY = "advanced_security"; private static final String KEY_MANAGE_TRUST_AGENTS = "manage_trust_agents"; private static final String KEY_UNIFICATION = "unification"; @@ -114,14 +112,8 @@ public class SecuritySettings extends SettingsPreferenceFragment private static final String TAG_UNIFICATION_DIALOG = "unification_dialog"; // Misc Settings - private static final String KEY_SIM_LOCK = "sim_lock"; + private static final String KEY_SIM_LOCK = "sim_lock_settings"; private static final String KEY_SHOW_PASSWORD = "show_password"; - private static final String KEY_CREDENTIAL_STORAGE_TYPE = "credential_storage_type"; - private static final String KEY_USER_CREDENTIALS = "user_credentials"; - private static final String KEY_RESET_CREDENTIALS = "credentials_reset"; - private static final String KEY_CREDENTIALS_INSTALL = "credentials_install"; - private static final String KEY_CREDENTIALS_MANAGER = "credentials_management"; - private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive"; private static final String KEY_TRUST_AGENT = "trust_agent"; private static final String KEY_SCREEN_PINNING = "screen_pinning_settings"; @@ -160,9 +152,6 @@ public class SecuritySettings extends SettingsPreferenceFragment private SwitchPreference mShowPassword; - private KeyStore mKeyStore; - private RestrictedPreference mResetCredentials; - private boolean mIsAdmin; private Intent mTrustAgentClickIntent; @@ -172,6 +161,8 @@ public class SecuritySettings extends SettingsPreferenceFragment private String mCurrentDevicePassword; private String mCurrentProfilePassword; + private LocationPreferenceController mLocationcontroller; + @Override public int getMetricsCategory() { return MetricsEvent.SECURITY; @@ -206,6 +197,8 @@ public class SecuritySettings extends SettingsPreferenceFragment && savedInstanceState.containsKey(TRUST_AGENT_CLICK_INTENT)) { mTrustAgentClickIntent = savedInstanceState.getParcelable(TRUST_AGENT_CLICK_INTENT); } + + mLocationcontroller = new LocationPreferenceController(activity); } private static int getResIdForLockUnlockScreen(Context context, @@ -304,19 +297,8 @@ public class SecuritySettings extends SettingsPreferenceFragment ((GearPreference) unlockSetOrChange).setOnGearClickListener(this); } - // Add options for device encryption mIsAdmin = mUm.isAdminUser(); - if (mIsAdmin) { - if (LockPatternUtils.isDeviceEncryptionEnabled()) { - // The device is currently encrypted. - addPreferencesFromResource(R.xml.security_settings_encrypted); - } else { - // This device supports encryption but isn't encrypted. - addPreferencesFromResource(R.xml.security_settings_unencrypted); - } - } - // Fingerprint and trust agents PreferenceGroup securityCategory = (PreferenceGroup) root.findPreference(KEY_SECURITY_CATEGORY); @@ -352,56 +334,19 @@ public class SecuritySettings extends SettingsPreferenceFragment // Show password mShowPassword = (SwitchPreference) root.findPreference(KEY_SHOW_PASSWORD); - mResetCredentials = (RestrictedPreference) root.findPreference(KEY_RESET_CREDENTIALS); // Credential storage final UserManager um = (UserManager) getActivity().getSystemService(Context.USER_SERVICE); - mKeyStore = KeyStore.getInstance(); // needs to be initialized for onResume() - - if (!RestrictedLockUtils.hasBaseUserRestriction(getActivity(), - UserManager.DISALLOW_CONFIG_CREDENTIALS, MY_USER_ID)) { - RestrictedPreference userCredentials = (RestrictedPreference) root.findPreference( - KEY_USER_CREDENTIALS); - userCredentials.checkRestrictionAndSetDisabled( - UserManager.DISALLOW_CONFIG_CREDENTIALS); - RestrictedPreference credentialStorageType = (RestrictedPreference) root.findPreference( - KEY_CREDENTIAL_STORAGE_TYPE); - credentialStorageType.checkRestrictionAndSetDisabled( - UserManager.DISALLOW_CONFIG_CREDENTIALS); - RestrictedPreference installCredentials = (RestrictedPreference) root.findPreference( - KEY_CREDENTIALS_INSTALL); - installCredentials.checkRestrictionAndSetDisabled( - UserManager.DISALLOW_CONFIG_CREDENTIALS); - mResetCredentials.checkRestrictionAndSetDisabled( - UserManager.DISALLOW_CONFIG_CREDENTIALS); - - final int storageSummaryRes = - mKeyStore.isHardwareBacked() ? R.string.credential_storage_type_hardware - : R.string.credential_storage_type_software; - credentialStorageType.setSummary(storageSummaryRes); - } else { - PreferenceGroup credentialsManager = (PreferenceGroup) - root.findPreference(KEY_CREDENTIALS_MANAGER); - credentialsManager.removePreference(root.findPreference(KEY_RESET_CREDENTIALS)); - credentialsManager.removePreference(root.findPreference(KEY_CREDENTIALS_INSTALL)); - credentialsManager.removePreference(root.findPreference(KEY_CREDENTIAL_STORAGE_TYPE)); - credentialsManager.removePreference(root.findPreference(KEY_USER_CREDENTIALS)); - } - // Application install PreferenceGroup deviceAdminCategory = (PreferenceGroup) root.findPreference(KEY_DEVICE_ADMIN_CATEGORY); // Advanced Security features - PreferenceGroup advancedCategory = - (PreferenceGroup)root.findPreference(KEY_ADVANCED_SECURITY); - if (advancedCategory != null) { - Preference manageAgents = advancedCategory.findPreference(KEY_MANAGE_TRUST_AGENTS); - if (manageAgents != null && !mLockPatternUtils.isSecure(MY_USER_ID)) { - manageAgents.setEnabled(false); - manageAgents.setSummary(R.string.disabled_because_no_backup_security); - } + Preference manageAgents = root.findPreference(KEY_MANAGE_TRUST_AGENTS); + if (manageAgents != null && !mLockPatternUtils.isSecure(MY_USER_ID)) { + manageAgents.setEnabled(false); + manageAgents.setSummary(R.string.disabled_because_no_backup_security); } // The above preferences come and go based on security state, so we need to update @@ -448,6 +393,8 @@ public class SecuritySettings extends SettingsPreferenceFragment final Preference pref = findPreference(SWITCH_PREFERENCE_KEYS[i]); if (pref != null) pref.setOnPreferenceChangeListener(this); } + + mLocationcontroller.displayPreference(root); return root; } @@ -610,9 +557,7 @@ public class SecuritySettings extends SettingsPreferenceFragment Settings.System.TEXT_SHOW_PASSWORD, 1) != 0); } - if (mResetCredentials != null && !mResetCredentials.isDisabledByAdmin()) { - mResetCredentials.setEnabled(!mKeyStore.isEmpty()); - } + mLocationcontroller.updateSummary(); } private void updateUnificationPreference() { @@ -836,19 +781,6 @@ public class SecuritySettings extends SettingsPreferenceFragment lockPatternUtils, managedPasswordProvider, profileUserId))); } - if (um.isAdminUser()) { - switch (dpm.getStorageEncryptionStatus()) { - case DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE: - // The device is currently encrypted. - index.add(getSearchResource(context, R.xml.security_settings_encrypted)); - break; - case DevicePolicyManager.ENCRYPTION_STATUS_INACTIVE: - // This device supports encryption but isn't encrypted. - index.add(getSearchResource(context, R.xml.security_settings_unencrypted)); - break; - } - } - final SearchIndexableResource sir = getSearchResource(context, SecuritySubSettings.getResIdForLockUnlockSubScreen(context, lockPatternUtils, managedPasswordProvider)); @@ -887,15 +819,6 @@ public class SecuritySettings extends SettingsPreferenceFragment result.add(data); final UserManager um = UserManager.get(context); - if (!um.isAdminUser()) { - int resId = um.isLinkedUser() ? - R.string.profile_info_settings_title : R.string.user_info_settings_title; - - data = new SearchIndexableRaw(context); - data.title = res.getString(resId); - data.screenTitle = screenTitle; - result.add(data); - } // Fingerprint final FingerprintManager fpm = Utils.getFingerprintManagerOrNull(context); @@ -927,20 +850,6 @@ public class SecuritySettings extends SettingsPreferenceFragment } } - // Credential storage - if (!um.hasUserRestriction(UserManager.DISALLOW_CONFIG_CREDENTIALS)) { - KeyStore keyStore = KeyStore.getInstance(); - - final int storageSummaryRes = keyStore.isHardwareBacked() ? - R.string.credential_storage_type_hardware : - R.string.credential_storage_type_software; - - data = new SearchIndexableRaw(context); - data.title = res.getString(storageSummaryRes); - data.screenTitle = screenTitle; - result.add(data); - } - // Advanced if (lockPatternUtils.isSecure(MY_USER_ID)) { final TrustAgentManager trustAgentManager = @@ -973,10 +882,6 @@ public class SecuritySettings extends SettingsPreferenceFragment keys.add(KEY_SIM_LOCK); } - if (um.hasUserRestriction(UserManager.DISALLOW_CONFIG_CREDENTIALS)) { - keys.add(KEY_CREDENTIALS_MANAGER); - } - // TrustAgent settings disappear when the user has no primary security. if (!lockPatternUtils.isSecure(MY_USER_ID)) { keys.add(KEY_TRUST_AGENT); diff --git a/src/com/android/settings/core/gateway/SettingsGateway.java b/src/com/android/settings/core/gateway/SettingsGateway.java index f3f0f87ed79..ab2ec09b974 100644 --- a/src/com/android/settings/core/gateway/SettingsGateway.java +++ b/src/com/android/settings/core/gateway/SettingsGateway.java @@ -296,8 +296,6 @@ public class SettingsGateway { "com.android.settings.PaymentSettingsDashboardAlias", // Home page > Network & Internet "com.android.settings.DataUsageDashboardAlias", - // Home page > Security - "com.android.settings.LocationDashboardAlias", // Home page > System Settings.LanguageAndInputSettingsActivity.class.getName(), "com.android.settings.DateTimeDashboardAlias", diff --git a/src/com/android/settings/location/LocationPreferenceController.java b/src/com/android/settings/location/LocationPreferenceController.java new file mode 100644 index 00000000000..766ee472bf1 --- /dev/null +++ b/src/com/android/settings/location/LocationPreferenceController.java @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.settings.location; + +import android.content.Context; +import android.provider.Settings.Secure; +import android.support.v7.preference.Preference; +import android.support.v7.preference.PreferenceScreen; +import com.android.settings.R; +import com.android.settings.core.PreferenceController; + +public class LocationPreferenceController extends PreferenceController { + + private static final String KEY_LOCATION = "location"; + private Preference mPreference; + + public LocationPreferenceController(Context context) { + super(context); + } + + @Override + public void displayPreference(PreferenceScreen screen) { + super.displayPreference(screen); + mPreference = screen.findPreference(KEY_LOCATION); + } + + @Override + public void updateState(Preference preference) { + preference.setSummary(getLocationSummary(mContext)); + } + + @Override + public String getPreferenceKey() { + return KEY_LOCATION; + } + + @Override + public boolean isAvailable() { + return true; + } + + public void updateSummary() { + updateState(mPreference); + } + + public static String getLocationSummary(Context context) { + int mode = Secure.getInt(context.getContentResolver(), + Secure.LOCATION_MODE, Secure.LOCATION_MODE_OFF); + if (mode != Secure.LOCATION_MODE_OFF) { + return context.getString(R.string.location_on_summary, + context.getString(getLocationString(mode))); + } + return context.getString(R.string.location_off_summary); + } + + public static int getLocationString(int mode) { + switch (mode) { + case Secure.LOCATION_MODE_OFF: + return R.string.location_mode_location_off_title; + case Secure.LOCATION_MODE_SENSORS_ONLY: + return R.string.location_mode_sensors_only_title; + case Secure.LOCATION_MODE_BATTERY_SAVING: + return R.string.location_mode_battery_saving_title; + case Secure.LOCATION_MODE_HIGH_ACCURACY: + return R.string.location_mode_high_accuracy_title; + } + return 0; + } + +} diff --git a/src/com/android/settings/location/LocationSettings.java b/src/com/android/settings/location/LocationSettings.java index 4177afbae3e..750def1ecc5 100644 --- a/src/com/android/settings/location/LocationSettings.java +++ b/src/com/android/settings/location/LocationSettings.java @@ -362,23 +362,9 @@ public class LocationSettings extends LocationSettingsBase return R.string.help_url_location_access; } - private static int getLocationString(int mode) { - switch (mode) { - case android.provider.Settings.Secure.LOCATION_MODE_OFF: - return R.string.location_mode_location_off_title; - case android.provider.Settings.Secure.LOCATION_MODE_SENSORS_ONLY: - return R.string.location_mode_sensors_only_title; - case android.provider.Settings.Secure.LOCATION_MODE_BATTERY_SAVING: - return R.string.location_mode_battery_saving_title; - case android.provider.Settings.Secure.LOCATION_MODE_HIGH_ACCURACY: - return R.string.location_mode_high_accuracy_title; - } - return 0; - } - @Override public void onModeChanged(int mode, boolean restricted) { - int modeDescription = getLocationString(mode); + int modeDescription = LocationPreferenceController.getLocationString(mode); if (modeDescription != 0) { mLocationMode.setSummary(modeDescription); } @@ -486,15 +472,8 @@ public class LocationSettings extends LocationSettingsBase @Override public void setListening(boolean listening) { if (listening) { - int mode = Settings.Secure.getInt(mContext.getContentResolver(), - Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF); - if (mode != Settings.Secure.LOCATION_MODE_OFF) { - mSummaryLoader.setSummary(this, mContext.getString(R.string.location_on_summary, - mContext.getString(getLocationString(mode)))); - } else { - mSummaryLoader.setSummary(this, - mContext.getString(R.string.location_off_summary)); - } + mSummaryLoader.setSummary( + this, LocationPreferenceController.getLocationSummary(mContext)); } } } diff --git a/src/com/android/settings/search/SearchIndexableResources.java b/src/com/android/settings/search/SearchIndexableResources.java index ada82009851..32a33992308 100644 --- a/src/com/android/settings/search/SearchIndexableResources.java +++ b/src/com/android/settings/search/SearchIndexableResources.java @@ -24,6 +24,7 @@ import com.android.settings.DateTimeSettings; import com.android.settings.DevelopmentSettings; import com.android.settings.DeviceInfoSettings; import com.android.settings.DisplaySettings; +import com.android.settings.EncryptionAndCredential; import com.android.settings.LegalSettings; import com.android.settings.PrivacySettings; import com.android.settings.R; @@ -146,6 +147,8 @@ public final class SearchIndexableResources { addIndex(LocationSettings.class, R.xml.location_settings, R.drawable.ic_settings_location); addIndex(ScanningSettings.class, R.xml.location_scanning, R.drawable.ic_settings_location); addIndex(SecuritySettings.class, NO_DATA_RES_ID, R.drawable.ic_settings_security); + addIndex(EncryptionAndCredential.class, R.xml.encryption_and_credential, + R.drawable.ic_settings_security); addIndex(ScreenPinningSettings.class, NO_DATA_RES_ID, R.drawable.ic_settings_security); addIndex(AccountSettings.class, NO_DATA_RES_ID, R.drawable.ic_settings_accounts); addIndex(UserAndAccountDashboardFragment.class, NO_DATA_RES_ID, diff --git a/tests/robotests/src/com/android/settings/location/LocationPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/location/LocationPreferenceControllerTest.java new file mode 100644 index 00000000000..2e001695dfb --- /dev/null +++ b/tests/robotests/src/com/android/settings/location/LocationPreferenceControllerTest.java @@ -0,0 +1,132 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.settings.location; + +import android.content.Context; +import android.provider.Settings.Secure; +import android.support.v7.preference.Preference; +import android.support.v7.preference.PreferenceScreen; + +import com.android.settings.R; +import com.android.settings.SettingsRobolectricTestRunner; +import com.android.settings.TestConfig; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Answers; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.annotation.Config; +import org.robolectric.shadows.ShadowApplication; + +import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@RunWith(SettingsRobolectricTestRunner.class) +@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) +public class LocationPreferenceControllerTest { + @Mock + private Preference mPreference; + @Mock + private PreferenceScreen mScreen; + + private LocationPreferenceController mController; + + @Mock(answer = Answers.RETURNS_DEEP_STUBS) + private Context mContext; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + mController = new LocationPreferenceController(mContext); + when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference); + } + + @Test + public void isAvailable_shouldReturnTrue() { + assertThat(mController.isAvailable()).isTrue(); + } + + @Test + public void updateState_shouldSetSummary() { + mController.updateState(mPreference); + + verify(mPreference).setSummary(anyString()); + } + + @Test + public void updateSummary_shouldSetSummary() { + mController.displayPreference(mScreen); + mController.updateSummary(); + + verify(mPreference).setSummary(anyString()); + } + + @Test + public void getLocationSummary_locationOff_shouldSetSummaryOff() { + Secure.putInt(mContext.getContentResolver(), + Secure.LOCATION_MODE, Secure.LOCATION_MODE_OFF); + + assertThat(mController.getLocationSummary(mContext)).isEqualTo( + mContext.getString(R.string.location_off_summary)); + } + + @Test + public void getLocationSummary_sensorsOnly_shouldSetSummarySensorsOnly() { + Secure.putInt(mContext.getContentResolver(), + Secure.LOCATION_MODE, Secure.LOCATION_MODE_SENSORS_ONLY); + + assertThat(mController.getLocationSummary(mContext)).isEqualTo( + mContext.getString(R.string.location_on_summary, + mContext.getString(R.string.location_mode_sensors_only_title))); + } + + @Test + public void getLocationSummary_highAccuracy_shouldSetSummarHighAccuracy() { + Secure.putInt(mContext.getContentResolver(), + Secure.LOCATION_MODE, Secure.LOCATION_MODE_HIGH_ACCURACY); + + assertThat(mController.getLocationSummary(mContext)).isEqualTo( + mContext.getString(R.string.location_on_summary, + mContext.getString(R.string.location_mode_high_accuracy_title))); + } + + @Test + public void getLocationSummary_batterySaving_shouldSetSummaryBatterySaving() { + Secure.putInt(mContext.getContentResolver(), + Secure.LOCATION_MODE, Secure.LOCATION_MODE_BATTERY_SAVING); + + assertThat(mController.getLocationSummary(mContext)).isEqualTo( + mContext.getString(R.string.location_on_summary, + mContext.getString(R.string.location_mode_battery_saving_title))); + } + + @Test + public void getLocationString_shouldCorrectString() { + assertThat(mController.getLocationString(Secure.LOCATION_MODE_OFF)).isEqualTo( + R.string.location_mode_location_off_title); + assertThat(mController.getLocationString(Secure.LOCATION_MODE_SENSORS_ONLY)).isEqualTo( + R.string.location_mode_sensors_only_title); + assertThat(mController.getLocationString(Secure.LOCATION_MODE_BATTERY_SAVING)).isEqualTo( + R.string.location_mode_battery_saving_title); + assertThat(mController.getLocationString(Secure.LOCATION_MODE_HIGH_ACCURACY)).isEqualTo( + R.string.location_mode_high_accuracy_title); + } + +}