diff --git a/res/xml/encryption_and_credential.xml b/res/xml/encryption_and_credential.xml
index be643b16ff4..715ea141158 100644
--- a/res/xml/encryption_and_credential.xml
+++ b/res/xml/encryption_and_credential.xml
@@ -24,25 +24,21 @@
android:order="100">
+ android:title="@string/credential_storage_type" />
+ android:summary="@string/credentials_install_summary">
+ android:summary="@string/credentials_reset_summary">
diff --git a/res/xml/security_settings_unencrypted.xml b/res/xml/security_settings_unencrypted.xml
index 7c51d259aae..27dbe968038 100644
--- a/res/xml/security_settings_unencrypted.xml
+++ b/res/xml/security_settings_unencrypted.xml
@@ -18,14 +18,14 @@
android:title="@string/crypt_keeper_settings_title">
-
+
diff --git a/src/com/android/settings/EncryptionAndCredential.java b/src/com/android/settings/EncryptionAndCredential.java
index 3cb2740ad73..4892f7ef389 100644
--- a/src/com/android/settings/EncryptionAndCredential.java
+++ b/src/com/android/settings/EncryptionAndCredential.java
@@ -20,7 +20,6 @@ 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;
@@ -34,7 +33,6 @@ 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;
@@ -106,7 +104,6 @@ public class EncryptionAndCredential extends SettingsPreferenceFragment implemen
}
}
-
// Credential storage
mKeyStore = KeyStore.getInstance(); // needs to be initialized for onResume()
@@ -182,83 +179,57 @@ public class EncryptionAndCredential extends SettingsPreferenceFragment implemen
@Override
public List getXmlResourcesToIndex(
Context context, boolean enabled) {
- final List index = new ArrayList();
+ 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;
- }
- }
+ // Add everything. We will suppress some of them in getNonIndexableKeys()
+ index.add(getSearchResource(context, R.xml.encryption_and_credential));
+ index.add(getSearchResource(context, R.xml.security_settings_encrypted));
+ index.add(getSearchResource(context, R.xml.security_settings_unencrypted));
return index;
}
+ @Override
+ protected boolean isPageSearchEnabled(Context context) {
+ final UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE);
+ return um.isAdminUser();
+ }
+
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 = super.getNonIndexableKeys(context);
-
- final UserManager um = UserManager.get(context);
+ if (!isPageSearchEnabled(context)) {
+ return keys;
+ }
+ final UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE);
if (um.hasUserRestriction(UserManager.DISALLOW_CONFIG_CREDENTIALS)) {
keys.add(KEY_CREDENTIALS_MANAGER);
+ keys.add(KEY_RESET_CREDENTIALS);
+ keys.add(KEY_CREDENTIALS_INSTALL);
+ keys.add(KEY_CREDENTIAL_STORAGE_TYPE);
+ keys.add(KEY_USER_CREDENTIALS);
+ }
+
+ final DevicePolicyManager dpm = (DevicePolicyManager)
+ context.getSystemService(Context.DEVICE_POLICY_SERVICE);
+ switch (dpm.getStorageEncryptionStatus()) {
+ case DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE:
+ // The device is currently encrypted. Disable security_settings_unencrypted
+ keys.addAll(getNonIndexableKeysFromXml(
+ context, R.xml.security_settings_unencrypted));
+ break;
+ default:
+ // This device supports encryption but isn't encrypted.
+ keys.addAll(getNonIndexableKeysFromXml(
+ context, R.xml.security_settings_encrypted));
+ break;
}
return keys;
diff --git a/src/com/android/settings/search/BaseSearchIndexProvider.java b/src/com/android/settings/search/BaseSearchIndexProvider.java
index 11b4db12154..239de15ff4c 100644
--- a/src/com/android/settings/search/BaseSearchIndexProvider.java
+++ b/src/com/android/settings/search/BaseSearchIndexProvider.java
@@ -16,10 +16,12 @@
package com.android.settings.search;
+import android.annotation.XmlRes;
import android.content.Context;
import android.content.res.XmlResourceParser;
import android.provider.SearchIndexableResource;
import android.support.annotation.CallSuper;
+import android.support.annotation.VisibleForTesting;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
@@ -94,18 +96,25 @@ public class BaseSearchIndexProvider implements Indexable.SearchIndexProvider {
}
final List nonIndexableKeys = new ArrayList<>();
for (SearchIndexableResource res : resources) {
- final XmlResourceParser parser = context.getResources().getXml(res.xmlResId);
- final AttributeSet attrs = Xml.asAttributeSet(parser);
- try {
- while (parser.next() != XmlPullParser.END_DOCUMENT) {
- final String key = XmlParserUtils.getDataKey(context, attrs);
- if (!TextUtils.isEmpty(key)) {
- nonIndexableKeys.add(key);
- }
+ nonIndexableKeys.addAll(getNonIndexableKeysFromXml(context, res.xmlResId));
+ }
+ return nonIndexableKeys;
+ }
+
+ @VisibleForTesting(otherwise = VisibleForTesting.PROTECTED)
+ public List getNonIndexableKeysFromXml(Context context, @XmlRes int xmlResId) {
+ final List nonIndexableKeys = new ArrayList<>();
+ final XmlResourceParser parser = context.getResources().getXml(xmlResId);
+ final AttributeSet attrs = Xml.asAttributeSet(parser);
+ try {
+ while (parser.next() != XmlPullParser.END_DOCUMENT) {
+ final String key = XmlParserUtils.getDataKey(context, attrs);
+ if (!TextUtils.isEmpty(key)) {
+ nonIndexableKeys.add(key);
}
- } catch (IOException | XmlPullParserException e) {
- Log.w(TAG, "Error parsing non-indexable from xml " + res.xmlResId);
}
+ } catch (IOException | XmlPullParserException e) {
+ Log.w(TAG, "Error parsing non-indexable from xml " + xmlResId);
}
return nonIndexableKeys;
}
diff --git a/src/com/android/settings/search/SearchIndexableResources.java b/src/com/android/settings/search/SearchIndexableResources.java
index 9b84bf1087e..31d39b5e367 100644
--- a/src/com/android/settings/search/SearchIndexableResources.java
+++ b/src/com/android/settings/search/SearchIndexableResources.java
@@ -171,8 +171,7 @@ 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(EncryptionAndCredential.class, NO_DATA_RES_ID, R.drawable.ic_settings_security);
addIndex(ScreenPinningSettings.class, NO_DATA_RES_ID, R.drawable.ic_settings_security);
addIndex(UserAndAccountDashboardFragment.class, NO_DATA_RES_ID,
R.drawable.ic_settings_accounts);
diff --git a/tests/robotests/src/com/android/settings/EncryptionAndCredentialTest.java b/tests/robotests/src/com/android/settings/EncryptionAndCredentialTest.java
index bc88b1aaa46..7a3875e8128 100644
--- a/tests/robotests/src/com/android/settings/EncryptionAndCredentialTest.java
+++ b/tests/robotests/src/com/android/settings/EncryptionAndCredentialTest.java
@@ -16,23 +16,110 @@
package com.android.settings;
+import static android.app.admin.DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE;
+import static android.app.admin.DevicePolicyManager.ENCRYPTION_STATUS_INACTIVE;
+import static com.android.settings.EncryptionAndCredential.SEARCH_INDEX_DATA_PROVIDER;
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.when;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.Context;
+import android.os.UserManager;
+import android.provider.SearchIndexableResource;
+
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
-import static com.google.common.truth.Truth.assertThat;
-
+import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
import org.robolectric.annotation.Config;
+import org.robolectric.shadows.ShadowApplication;
+
+import java.util.ArrayList;
+import java.util.List;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class EncryptionAndCredentialTest {
+ @Mock
+ private UserManager mUserManager;
+ @Mock
+ private DevicePolicyManager mDevicePolicyManager;
+
+ private ShadowApplication mApplication;
+ private Context mContext;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mApplication = ShadowApplication.getInstance();
+ mApplication.setSystemService(Context.DEVICE_POLICY_SERVICE, mDevicePolicyManager);
+ mApplication.setSystemService(Context.USER_SERVICE, mUserManager);
+ mContext = mApplication.getApplicationContext();
+ }
+
@Test
public void getMetricsCategory_shouldReturnEncryptionAndCredential() {
EncryptionAndCredential fragment = new EncryptionAndCredential();
assertThat(fragment.getMetricsCategory()).isEqualTo(MetricsEvent.ENCRYPTION_AND_CREDENTIAL);
}
+ // Search provider tests
+ @Test
+ public void getXmlResourcesToIndex_shouldReturnAllXmls() {
+ final List index =
+ SEARCH_INDEX_DATA_PROVIDER.getXmlResourcesToIndex(
+ mContext, true /* enabled */);
+
+ assertThat(index).hasSize(3);
+ }
+
+ @Test
+ public void getNonIndexableKeys_pageIsDisabled_shouldReturnAllKeysAsNonIndexable() {
+ when(mUserManager.isAdminUser()).thenReturn(false);
+
+ final List index =
+ SEARCH_INDEX_DATA_PROVIDER.getXmlResourcesToIndex(mContext, true /* enabled */);
+ final List expectedKeys = new ArrayList<>();
+ for (SearchIndexableResource res : index) {
+ expectedKeys.addAll(((BaseSearchIndexProvider) SEARCH_INDEX_DATA_PROVIDER)
+ .getNonIndexableKeysFromXml(mContext, res.xmlResId));
+ }
+ final List keys = SEARCH_INDEX_DATA_PROVIDER.getNonIndexableKeys(mContext);
+
+ assertThat(keys).containsExactlyElementsIn(expectedKeys);
+ }
+
+ @Test
+ public void getNonIndexableKeys_deviceEncrypted_shouldReturnUnencryptedKeys() {
+ when(mUserManager.isAdminUser()).thenReturn(true);
+ when(mDevicePolicyManager.getStorageEncryptionStatus()).thenReturn(
+ ENCRYPTION_STATUS_ACTIVE);
+
+ final List expectedKeys = new ArrayList<>();
+ expectedKeys.addAll(((BaseSearchIndexProvider) SEARCH_INDEX_DATA_PROVIDER)
+ .getNonIndexableKeysFromXml(mContext, R.xml.security_settings_unencrypted));
+ final List keys = SEARCH_INDEX_DATA_PROVIDER.getNonIndexableKeys(mContext);
+
+ assertThat(keys).containsExactlyElementsIn(expectedKeys);
+ }
+
+ @Test
+ public void getNonIndexableKeys_deviceNotEncrypted_shouldReturnEncryptedKeys() {
+ when(mUserManager.isAdminUser()).thenReturn(true);
+ when(mDevicePolicyManager.getStorageEncryptionStatus())
+ .thenReturn(ENCRYPTION_STATUS_INACTIVE);
+
+ final List expectedKeys = new ArrayList<>();
+ expectedKeys.addAll(((BaseSearchIndexProvider) SEARCH_INDEX_DATA_PROVIDER)
+ .getNonIndexableKeysFromXml(mContext, R.xml.security_settings_encrypted));
+ final List keys = SEARCH_INDEX_DATA_PROVIDER.getNonIndexableKeys(mContext);
+
+ assertThat(keys).containsExactlyElementsIn(expectedKeys);
+ }
}