Fix search indexing for encryption_and_credential page
- Rewrite search index provider to include all possible keys through getXmlResourcesToIndex() - Add isPageSearchEnabled() to disable all keys if user is not admin - Add getNonIndexableKeys to suppress unrelated keys based on current device state Change-Id: I2c6943483789bf4c9f3931d344cf279fec0edaee Fix: 37650170 Test: robotests
This commit is contained in:
@@ -24,25 +24,21 @@
|
||||
android:order="100">
|
||||
|
||||
<com.android.settingslib.RestrictedPreference android:key="credential_storage_type"
|
||||
android:title="@string/credential_storage_type"
|
||||
android:persistent="false" />
|
||||
android:title="@string/credential_storage_type" />
|
||||
|
||||
<Preference android:key="trusted_credentials"
|
||||
android:title="@string/trusted_credentials"
|
||||
android:summary="@string/trusted_credentials_summary"
|
||||
android:persistent="false"
|
||||
android:fragment="com.android.settings.TrustedCredentialsSettings"/>
|
||||
|
||||
<com.android.settingslib.RestrictedPreference android:key="user_credentials"
|
||||
android:title="@string/user_credentials"
|
||||
android:summary="@string/user_credentials_summary"
|
||||
android:persistent="false"
|
||||
android:fragment="com.android.settings.UserCredentialsSettings"/>
|
||||
|
||||
<com.android.settingslib.RestrictedPreference android:key="credentials_install"
|
||||
android:title="@string/credentials_install"
|
||||
android:summary="@string/credentials_install_summary"
|
||||
android:persistent="false">
|
||||
android:summary="@string/credentials_install_summary">
|
||||
|
||||
<intent android:action="android.credentials.INSTALL"
|
||||
android:targetPackage="com.android.certinstaller"
|
||||
@@ -52,8 +48,7 @@
|
||||
|
||||
<com.android.settingslib.RestrictedPreference android:key="credentials_reset"
|
||||
android:title="@string/credentials_reset"
|
||||
android:summary="@string/credentials_reset_summary"
|
||||
android:persistent="false">
|
||||
android:summary="@string/credentials_reset_summary">
|
||||
|
||||
<intent android:action="com.android.credentials.RESET"
|
||||
android:targetPackage="com.android.settings"
|
||||
|
@@ -18,12 +18,10 @@
|
||||
android:title="@string/security_settings_title">
|
||||
|
||||
<PreferenceCategory
|
||||
android:key="security_category"
|
||||
android:key="security_category_for_encrypted_device"
|
||||
android:title="@string/crypt_keeper_settings_title">
|
||||
|
||||
<Preference
|
||||
android:enabled="false"
|
||||
android:shouldDisableView="false"
|
||||
android:key="crypt_keeper_encrypt_title"
|
||||
android:title="@string/crypt_keeper_encrypt_title"
|
||||
android:summary="@string/crypt_keeper_encrypted_summary"/>
|
||||
|
@@ -18,7 +18,7 @@
|
||||
android:title="@string/crypt_keeper_settings_title">
|
||||
|
||||
<PreferenceCategory
|
||||
android:key="security_category"
|
||||
android:key="security_category_for_unencrypted_device"
|
||||
android:title="@string/crypt_keeper_settings_title">
|
||||
|
||||
<Preference
|
||||
|
@@ -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<SearchIndexableResource> getXmlResourcesToIndex(
|
||||
Context context, boolean enabled) {
|
||||
final List<SearchIndexableResource> index = new ArrayList<SearchIndexableResource>();
|
||||
final List<SearchIndexableResource> 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.
|
||||
// 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));
|
||||
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;
|
||||
}
|
||||
|
||||
@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<SearchIndexableRaw> getRawDataToIndex(Context context, boolean enabled) {
|
||||
final List<SearchIndexableRaw> result = new ArrayList<SearchIndexableRaw>();
|
||||
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<String> getNonIndexableKeys(Context context) {
|
||||
final List<String> 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;
|
||||
|
@@ -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,7 +96,15 @@ public class BaseSearchIndexProvider implements Indexable.SearchIndexProvider {
|
||||
}
|
||||
final List<String> nonIndexableKeys = new ArrayList<>();
|
||||
for (SearchIndexableResource res : resources) {
|
||||
final XmlResourceParser parser = context.getResources().getXml(res.xmlResId);
|
||||
nonIndexableKeys.addAll(getNonIndexableKeysFromXml(context, res.xmlResId));
|
||||
}
|
||||
return nonIndexableKeys;
|
||||
}
|
||||
|
||||
@VisibleForTesting(otherwise = VisibleForTesting.PROTECTED)
|
||||
public List<String> getNonIndexableKeysFromXml(Context context, @XmlRes int xmlResId) {
|
||||
final List<String> nonIndexableKeys = new ArrayList<>();
|
||||
final XmlResourceParser parser = context.getResources().getXml(xmlResId);
|
||||
final AttributeSet attrs = Xml.asAttributeSet(parser);
|
||||
try {
|
||||
while (parser.next() != XmlPullParser.END_DOCUMENT) {
|
||||
@@ -104,8 +114,7 @@ public class BaseSearchIndexProvider implements Indexable.SearchIndexProvider {
|
||||
}
|
||||
}
|
||||
} catch (IOException | XmlPullParserException e) {
|
||||
Log.w(TAG, "Error parsing non-indexable from xml " + res.xmlResId);
|
||||
}
|
||||
Log.w(TAG, "Error parsing non-indexable from xml " + xmlResId);
|
||||
}
|
||||
return nonIndexableKeys;
|
||||
}
|
||||
|
@@ -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);
|
||||
|
@@ -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<SearchIndexableResource> 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<SearchIndexableResource> index =
|
||||
SEARCH_INDEX_DATA_PROVIDER.getXmlResourcesToIndex(mContext, true /* enabled */);
|
||||
final List<String> expectedKeys = new ArrayList<>();
|
||||
for (SearchIndexableResource res : index) {
|
||||
expectedKeys.addAll(((BaseSearchIndexProvider) SEARCH_INDEX_DATA_PROVIDER)
|
||||
.getNonIndexableKeysFromXml(mContext, res.xmlResId));
|
||||
}
|
||||
final List<String> 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<String> expectedKeys = new ArrayList<>();
|
||||
expectedKeys.addAll(((BaseSearchIndexProvider) SEARCH_INDEX_DATA_PROVIDER)
|
||||
.getNonIndexableKeysFromXml(mContext, R.xml.security_settings_unencrypted));
|
||||
final List<String> 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<String> expectedKeys = new ArrayList<>();
|
||||
expectedKeys.addAll(((BaseSearchIndexProvider) SEARCH_INDEX_DATA_PROVIDER)
|
||||
.getNonIndexableKeysFromXml(mContext, R.xml.security_settings_encrypted));
|
||||
final List<String> keys = SEARCH_INDEX_DATA_PROVIDER.getNonIndexableKeys(mContext);
|
||||
|
||||
assertThat(keys).containsExactlyElementsIn(expectedKeys);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user