Declare "searchable" attribute for preferences.
Now we can easily mark a preference nonIndexable in xml instead of adding key into searchIndexProvider. Bug: 112608186 Test: robotests Change-Id: I0ff16d44bb7b6ad148d3d35f09ca0da0163f73f4
This commit is contained in:
@@ -69,6 +69,8 @@
|
|||||||
<declare-styleable name="Preference">
|
<declare-styleable name="Preference">
|
||||||
<!-- Synonyms for search results -->
|
<!-- Synonyms for search results -->
|
||||||
<attr name="keywords" format="string" />
|
<attr name="keywords" format="string" />
|
||||||
|
<!-- Whether or not the preference is searchable, by default it's true. -->
|
||||||
|
<attr name="searchable" format="boolean" />
|
||||||
<!-- Classname of a PreferenceController corresponding to the preference -->
|
<!-- Classname of a PreferenceController corresponding to the preference -->
|
||||||
<attr name="controller" format="string" />
|
<attr name="controller" format="string" />
|
||||||
<!-- {@code true} when the controller declared represents a slice from {@link android.app.SettingsSliceContract} -->
|
<!-- {@code true} when the controller declared represents a slice from {@link android.app.SettingsSliceContract} -->
|
||||||
|
@@ -71,6 +71,7 @@
|
|||||||
android:key="special_access"
|
android:key="special_access"
|
||||||
android:fragment="com.android.settings.applications.specialaccess.SpecialAccessSettings"
|
android:fragment="com.android.settings.applications.specialaccess.SpecialAccessSettings"
|
||||||
android:title="@string/special_access"
|
android:title="@string/special_access"
|
||||||
android:order="20" />
|
android:order="20"
|
||||||
|
settings:searchable="false"/>
|
||||||
|
|
||||||
</PreferenceScreen>
|
</PreferenceScreen>
|
||||||
|
@@ -25,7 +25,7 @@
|
|||||||
android:key="assist_and_voice_input"
|
android:key="assist_and_voice_input"
|
||||||
android:title="@string/assist_and_voice_input_title"
|
android:title="@string/assist_and_voice_input_title"
|
||||||
android:fragment="com.android.settings.applications.assist.ManageAssist"
|
android:fragment="com.android.settings.applications.assist.ManageAssist"
|
||||||
settings:keywords="@string/keywords_assist_input"/>
|
settings:searchable="false"/>
|
||||||
|
|
||||||
<com.android.settings.widget.AppPreference
|
<com.android.settings.widget.AppPreference
|
||||||
android:key="default_browser"
|
android:key="default_browser"
|
||||||
@@ -86,7 +86,8 @@
|
|||||||
<com.android.settings.widget.AppPreference
|
<com.android.settings.widget.AppPreference
|
||||||
android:key="work_default_browser"
|
android:key="work_default_browser"
|
||||||
android:title="@string/default_browser_title"
|
android:title="@string/default_browser_title"
|
||||||
android:fragment="com.android.settings.applications.defaultapps.DefaultBrowserPicker">
|
android:fragment="com.android.settings.applications.defaultapps.DefaultBrowserPicker"
|
||||||
|
settings:searchable="false">
|
||||||
<extra android:name="for_work" android:value="true" />
|
<extra android:name="for_work" android:value="true" />
|
||||||
</com.android.settings.widget.AppPreference>
|
</com.android.settings.widget.AppPreference>
|
||||||
|
|
||||||
@@ -94,7 +95,7 @@
|
|||||||
android:key="work_default_phone_app"
|
android:key="work_default_phone_app"
|
||||||
android:title="@string/default_phone_title"
|
android:title="@string/default_phone_title"
|
||||||
android:fragment="com.android.settings.applications.defaultapps.DefaultPhonePicker"
|
android:fragment="com.android.settings.applications.defaultapps.DefaultPhonePicker"
|
||||||
settings:keywords="@string/keywords_default_phone_app">
|
settings:searchable="false">
|
||||||
<extra android:name="for_work" android:value="true" />
|
<extra android:name="for_work" android:value="true" />
|
||||||
</com.android.settings.widget.AppPreference>
|
</com.android.settings.widget.AppPreference>
|
||||||
|
|
||||||
|
@@ -32,7 +32,7 @@
|
|||||||
|
|
||||||
|
|
||||||
<com.android.settings.widget.WorkOnlyCategory
|
<com.android.settings.widget.WorkOnlyCategory
|
||||||
android:key="work_app_defaults"
|
android:key="autofill_work_app_defaults"
|
||||||
android:title="@string/default_for_work">
|
android:title="@string/default_for_work">
|
||||||
|
|
||||||
<com.android.settings.widget.GearPreference
|
<com.android.settings.widget.GearPreference
|
||||||
|
@@ -183,7 +183,8 @@
|
|||||||
<Preference
|
<Preference
|
||||||
android:key="feature_flags_dashboard"
|
android:key="feature_flags_dashboard"
|
||||||
android:title="@string/feature_flags_dashboard_title"
|
android:title="@string/feature_flags_dashboard_title"
|
||||||
android:fragment="com.android.settings.development.featureflags.FeatureFlagsDashboard" />
|
android:fragment="com.android.settings.development.featureflags.FeatureFlagsDashboard"
|
||||||
|
settings:searchable="false" />
|
||||||
|
|
||||||
<SwitchPreference
|
<SwitchPreference
|
||||||
android:key="enable_gpu_debug_layers"
|
android:key="enable_gpu_debug_layers"
|
||||||
|
@@ -19,7 +19,8 @@
|
|||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:settings="http://schemas.android.com/apk/res-auto"
|
xmlns:settings="http://schemas.android.com/apk/res-auto"
|
||||||
android:key="manage_assist_screen"
|
android:key="manage_assist_screen"
|
||||||
android:title="@string/assist_and_voice_input_title">
|
android:title="@string/assist_and_voice_input_title"
|
||||||
|
settings:keywords="@string/keywords_assist_input">
|
||||||
|
|
||||||
<com.android.settings.widget.GearPreference
|
<com.android.settings.widget.GearPreference
|
||||||
android:key="default_assist"
|
android:key="default_assist"
|
||||||
|
@@ -97,13 +97,5 @@ public class AppAndNotificationDashboardFragment extends DashboardFragment {
|
|||||||
Context context) {
|
Context context) {
|
||||||
return buildPreferenceControllers(context, null, null /* host */);
|
return buildPreferenceControllers(context, null, null /* host */);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<String> getNonIndexableKeys(Context context) {
|
|
||||||
List<String> keys = super.getNonIndexableKeys(context);
|
|
||||||
keys.add((new SpecialAppAccessPreferenceController(context))
|
|
||||||
.getPreferenceKey());
|
|
||||||
return keys;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@@ -101,16 +101,6 @@ public class DefaultAppSettings extends DashboardFragment {
|
|||||||
return Arrays.asList(sir);
|
return Arrays.asList(sir);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<String> getNonIndexableKeys(Context context) {
|
|
||||||
List<String> keys = super.getNonIndexableKeys(context);
|
|
||||||
keys.add(KEY_ASSIST_VOICE_INPUT);
|
|
||||||
// TODO (b/38230148) Remove these keys when we can differentiate work results
|
|
||||||
keys.add(DefaultWorkPhonePreferenceController.KEY);
|
|
||||||
keys.add(DefaultWorkBrowserPreferenceController.KEY);
|
|
||||||
return keys;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<AbstractPreferenceController> createPreferenceControllers(
|
public List<AbstractPreferenceController> createPreferenceControllers(
|
||||||
Context context) {
|
Context context) {
|
||||||
|
@@ -40,7 +40,7 @@ public class BackupSettingsActivityPreferenceController extends BasePreferenceCo
|
|||||||
@Override
|
@Override
|
||||||
public int getAvailabilityStatus() {
|
public int getAvailabilityStatus() {
|
||||||
return mUm.isAdminUser()
|
return mUm.isAdminUser()
|
||||||
? AVAILABLE
|
? AVAILABLE_UNSEARCHABLE
|
||||||
: UNSUPPORTED_ON_DEVICE;
|
: UNSUPPORTED_ON_DEVICE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -274,6 +274,10 @@ public abstract class BasePreferenceController extends AbstractPreferenceControl
|
|||||||
Log.w(TAG, "Skipping updateNonIndexableKeys due to empty key " + toString());
|
Log.w(TAG, "Skipping updateNonIndexableKeys due to empty key " + toString());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (keys.contains(key)) {
|
||||||
|
Log.w(TAG, "Skipping updateNonIndexableKeys, key already in list. " + toString());
|
||||||
|
return;
|
||||||
|
}
|
||||||
keys.add(key);
|
keys.add(key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -42,7 +42,12 @@ public interface PreferenceControllerMixin {
|
|||||||
final String key = ((AbstractPreferenceController) this).getPreferenceKey();
|
final String key = ((AbstractPreferenceController) this).getPreferenceKey();
|
||||||
if (TextUtils.isEmpty(key)) {
|
if (TextUtils.isEmpty(key)) {
|
||||||
Log.w(TAG,
|
Log.w(TAG,
|
||||||
"Skipping updateNonIndexableKeys due to empty key " + this.toString());
|
"Skipping updateNonIndexableKeys due to empty key " + toString());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (keys.contains(key)) {
|
||||||
|
Log.w(TAG, "Skipping updateNonIndexableKeys, key already in list. "
|
||||||
|
+ toString());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
keys.add(key);
|
keys.add(key);
|
||||||
|
@@ -29,6 +29,9 @@ import android.util.Log;
|
|||||||
import android.util.TypedValue;
|
import android.util.TypedValue;
|
||||||
import android.util.Xml;
|
import android.util.Xml;
|
||||||
|
|
||||||
|
import androidx.annotation.IntDef;
|
||||||
|
import androidx.annotation.VisibleForTesting;
|
||||||
|
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
|
|
||||||
import org.xmlpull.v1.XmlPullParser;
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
@@ -41,9 +44,6 @@ import java.util.ArrayList;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import androidx.annotation.IntDef;
|
|
||||||
import androidx.annotation.VisibleForTesting;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility class to parse elements of XML preferences
|
* Utility class to parse elements of XML preferences
|
||||||
*/
|
*/
|
||||||
@@ -53,7 +53,8 @@ public class PreferenceXmlParserUtils {
|
|||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
static final String PREF_SCREEN_TAG = "PreferenceScreen";
|
static final String PREF_SCREEN_TAG = "PreferenceScreen";
|
||||||
private static final List<String> SUPPORTED_PREF_TYPES = Arrays.asList(
|
private static final List<String> SUPPORTED_PREF_TYPES = Arrays.asList(
|
||||||
"Preference", "PreferenceCategory", "PreferenceScreen");
|
"Preference", "PreferenceCategory", "PreferenceScreen",
|
||||||
|
"com.android.settings.widget.WorkOnlyCategory");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flag definition to indicate which metadata should be extracted when
|
* Flag definition to indicate which metadata should be extracted when
|
||||||
@@ -67,7 +68,8 @@ public class PreferenceXmlParserUtils {
|
|||||||
MetadataFlag.FLAG_NEED_PREF_CONTROLLER,
|
MetadataFlag.FLAG_NEED_PREF_CONTROLLER,
|
||||||
MetadataFlag.FLAG_NEED_PREF_TITLE,
|
MetadataFlag.FLAG_NEED_PREF_TITLE,
|
||||||
MetadataFlag.FLAG_NEED_PREF_SUMMARY,
|
MetadataFlag.FLAG_NEED_PREF_SUMMARY,
|
||||||
MetadataFlag.FLAG_NEED_PREF_ICON})
|
MetadataFlag.FLAG_NEED_PREF_ICON,
|
||||||
|
MetadataFlag.FLAG_NEED_SEARCHABLE})
|
||||||
@Retention(RetentionPolicy.SOURCE)
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
public @interface MetadataFlag {
|
public @interface MetadataFlag {
|
||||||
int FLAG_INCLUDE_PREF_SCREEN = 1;
|
int FLAG_INCLUDE_PREF_SCREEN = 1;
|
||||||
@@ -79,6 +81,7 @@ public class PreferenceXmlParserUtils {
|
|||||||
int FLAG_NEED_PREF_ICON = 1 << 6;
|
int FLAG_NEED_PREF_ICON = 1 << 6;
|
||||||
int FLAG_NEED_PLATFORM_SLICE_FLAG = 1 << 7;
|
int FLAG_NEED_PLATFORM_SLICE_FLAG = 1 << 7;
|
||||||
int FLAG_NEED_KEYWORDS = 1 << 8;
|
int FLAG_NEED_KEYWORDS = 1 << 8;
|
||||||
|
int FLAG_NEED_SEARCHABLE = 1 << 9;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final String METADATA_PREF_TYPE = "type";
|
public static final String METADATA_PREF_TYPE = "type";
|
||||||
@@ -89,6 +92,7 @@ public class PreferenceXmlParserUtils {
|
|||||||
public static final String METADATA_ICON = "icon";
|
public static final String METADATA_ICON = "icon";
|
||||||
public static final String METADATA_PLATFORM_SLICE_FLAG = "platform_slice";
|
public static final String METADATA_PLATFORM_SLICE_FLAG = "platform_slice";
|
||||||
public static final String METADATA_KEYWORDS = "keywords";
|
public static final String METADATA_KEYWORDS = "keywords";
|
||||||
|
public static final String METADATA_SEARCHABLE = "searchable";
|
||||||
|
|
||||||
private static final String ENTRIES_SEPARATOR = "|";
|
private static final String ENTRIES_SEPARATOR = "|";
|
||||||
|
|
||||||
@@ -154,18 +158,6 @@ public class PreferenceXmlParserUtils {
|
|||||||
R.styleable.Preference_controller);
|
R.styleable.Preference_controller);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Call {@link #extractMetadata(Context, int, int)} with {@link #METADATA_ICON} instead.
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public static int getDataIcon(Context context, AttributeSet attrs) {
|
|
||||||
final TypedArray ta = context.obtainStyledAttributes(attrs,
|
|
||||||
com.android.internal.R.styleable.Preference);
|
|
||||||
final int dataIcon = ta.getResourceId(com.android.internal.R.styleable.Icon_icon, 0);
|
|
||||||
ta.recycle();
|
|
||||||
return dataIcon;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extracts metadata from preference xml and put them into a {@link Bundle}.
|
* Extracts metadata from preference xml and put them into a {@link Bundle}.
|
||||||
*
|
*
|
||||||
@@ -232,6 +224,10 @@ public class PreferenceXmlParserUtils {
|
|||||||
if (hasFlag(flags, MetadataFlag.FLAG_NEED_KEYWORDS)) {
|
if (hasFlag(flags, MetadataFlag.FLAG_NEED_KEYWORDS)) {
|
||||||
preferenceMetadata.putString(METADATA_KEYWORDS, getKeywords(preferenceAttributes));
|
preferenceMetadata.putString(METADATA_KEYWORDS, getKeywords(preferenceAttributes));
|
||||||
}
|
}
|
||||||
|
if (hasFlag(flags, MetadataFlag.FLAG_NEED_SEARCHABLE)) {
|
||||||
|
preferenceMetadata.putBoolean(METADATA_SEARCHABLE,
|
||||||
|
isSearchable(preferenceAttributes));
|
||||||
|
}
|
||||||
metadata.add(preferenceMetadata);
|
metadata.add(preferenceMetadata);
|
||||||
|
|
||||||
preferenceAttributes.recycle();
|
preferenceAttributes.recycle();
|
||||||
@@ -312,6 +308,10 @@ public class PreferenceXmlParserUtils {
|
|||||||
return styledAttributes.getBoolean(R.styleable.Preference_platform_slice, false /* def */);
|
return styledAttributes.getBoolean(R.styleable.Preference_platform_slice, false /* def */);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean isSearchable(TypedArray styledAttributes) {
|
||||||
|
return styledAttributes.getBoolean(R.styleable.Preference_searchable, true /* default */);
|
||||||
|
}
|
||||||
|
|
||||||
private static String getKeywords(TypedArray styleAttributes) {
|
private static String getKeywords(TypedArray styleAttributes) {
|
||||||
return styleAttributes.getString(R.styleable.Preference_keywords);
|
return styleAttributes.getString(R.styleable.Preference_keywords);
|
||||||
}
|
}
|
||||||
|
@@ -21,6 +21,7 @@ import android.content.Context;
|
|||||||
import android.database.ContentObserver;
|
import android.database.ContentObserver;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
|
import android.os.Looper;
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
|
|
||||||
@@ -30,7 +31,7 @@ final class AutofillDeveloperSettingsObserver extends ContentObserver {
|
|||||||
private final ContentResolver mResolver;
|
private final ContentResolver mResolver;
|
||||||
|
|
||||||
public AutofillDeveloperSettingsObserver(Context context, Runnable changeCallback) {
|
public AutofillDeveloperSettingsObserver(Context context, Runnable changeCallback) {
|
||||||
super(new Handler());
|
super(new Handler(Looper.getMainLooper()));
|
||||||
|
|
||||||
mResolver = context.getContentResolver();
|
mResolver = context.getContentResolver();
|
||||||
mChangeCallback = changeCallback;
|
mChangeCallback = changeCallback;
|
||||||
|
@@ -47,6 +47,9 @@ public class SwipeUpPreferenceController extends GesturePreferenceController {
|
|||||||
|
|
||||||
final ComponentName recentsComponentName = ComponentName.unflattenFromString(
|
final ComponentName recentsComponentName = ComponentName.unflattenFromString(
|
||||||
context.getString(R.string.config_recentsComponentName));
|
context.getString(R.string.config_recentsComponentName));
|
||||||
|
if (recentsComponentName == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
final Intent quickStepIntent = new Intent(ACTION_QUICKSTEP)
|
final Intent quickStepIntent = new Intent(ACTION_QUICKSTEP)
|
||||||
.setPackage(recentsComponentName.getPackageName());
|
.setPackage(recentsComponentName.getPackageName());
|
||||||
if (context.getPackageManager().resolveService(quickStepIntent,
|
if (context.getPackageManager().resolveService(quickStepIntent,
|
||||||
|
@@ -108,7 +108,7 @@ public class LanguageAndInputSettings extends DashboardFragment {
|
|||||||
|
|
||||||
// Pointer and Tts
|
// Pointer and Tts
|
||||||
final TtsPreferenceController ttsPreferenceController =
|
final TtsPreferenceController ttsPreferenceController =
|
||||||
new TtsPreferenceController(context, new TtsEngines(context));
|
new TtsPreferenceController(context, KEY_TEXT_TO_SPEECH);
|
||||||
controllers.add(ttsPreferenceController);
|
controllers.add(ttsPreferenceController);
|
||||||
final PointerSpeedController pointerController = new PointerSpeedController(context);
|
final PointerSpeedController pointerController = new PointerSpeedController(context);
|
||||||
controllers.add(pointerController);
|
controllers.add(pointerController);
|
||||||
@@ -180,7 +180,6 @@ public class LanguageAndInputSettings extends DashboardFragment {
|
|||||||
public List<String> getNonIndexableKeys(Context context) {
|
public List<String> getNonIndexableKeys(Context context) {
|
||||||
List<String> keys = super.getNonIndexableKeys(context);
|
List<String> keys = super.getNonIndexableKeys(context);
|
||||||
// Duplicates in summary and details pages.
|
// Duplicates in summary and details pages.
|
||||||
keys.add(KEY_TEXT_TO_SPEECH);
|
|
||||||
keys.add(KEY_PHYSICAL_KEYBOARD);
|
keys.add(KEY_PHYSICAL_KEYBOARD);
|
||||||
return keys;
|
return keys;
|
||||||
}
|
}
|
||||||
|
@@ -19,31 +19,26 @@ package com.android.settings.language;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.speech.tts.TtsEngines;
|
import android.speech.tts.TtsEngines;
|
||||||
|
|
||||||
|
import androidx.annotation.VisibleForTesting;
|
||||||
|
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
import com.android.settings.core.PreferenceControllerMixin;
|
import com.android.settings.core.BasePreferenceController;
|
||||||
import com.android.settingslib.core.AbstractPreferenceController;
|
|
||||||
|
|
||||||
public class TtsPreferenceController extends AbstractPreferenceController
|
public class TtsPreferenceController extends BasePreferenceController {
|
||||||
implements PreferenceControllerMixin {
|
|
||||||
|
|
||||||
private static final String KEY_VOICE_CATEGORY = "voice_category";
|
@VisibleForTesting
|
||||||
private static final String KEY_TTS_SETTINGS = "tts_settings_summary";
|
TtsEngines mTtsEngines;
|
||||||
|
|
||||||
private final TtsEngines mTtsEngines;
|
public TtsPreferenceController(Context context, String key) {
|
||||||
|
super(context, key);
|
||||||
public TtsPreferenceController(Context context, TtsEngines ttsEngines) {
|
mTtsEngines = new TtsEngines(context);
|
||||||
super(context);
|
|
||||||
mTtsEngines = ttsEngines;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isAvailable() {
|
public int getAvailabilityStatus() {
|
||||||
return !mTtsEngines.getEngines().isEmpty() &&
|
return !mTtsEngines.getEngines().isEmpty() &&
|
||||||
mContext.getResources().getBoolean(R.bool.config_show_tts_settings_summary);
|
mContext.getResources().getBoolean(R.bool.config_show_tts_settings_summary)
|
||||||
}
|
? AVAILABLE_UNSEARCHABLE
|
||||||
|
: CONDITIONALLY_UNAVAILABLE;
|
||||||
@Override
|
|
||||||
public String getPreferenceKey() {
|
|
||||||
return KEY_TTS_SETTINGS;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -16,14 +16,21 @@
|
|||||||
|
|
||||||
package com.android.settings.search;
|
package com.android.settings.search;
|
||||||
|
|
||||||
|
import static com.android.settings.core.PreferenceXmlParserUtils.METADATA_KEY;
|
||||||
|
import static com.android.settings.core.PreferenceXmlParserUtils.METADATA_SEARCHABLE;
|
||||||
|
import static com.android.settings.core.PreferenceXmlParserUtils.MetadataFlag
|
||||||
|
.FLAG_INCLUDE_PREF_SCREEN;
|
||||||
|
import static com.android.settings.core.PreferenceXmlParserUtils.MetadataFlag.FLAG_NEED_KEY;
|
||||||
|
import static com.android.settings.core.PreferenceXmlParserUtils.MetadataFlag.FLAG_NEED_SEARCHABLE;
|
||||||
|
|
||||||
import android.annotation.XmlRes;
|
import android.annotation.XmlRes;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.res.XmlResourceParser;
|
import android.os.Bundle;
|
||||||
import android.provider.SearchIndexableResource;
|
import android.provider.SearchIndexableResource;
|
||||||
import android.text.TextUtils;
|
|
||||||
import android.util.AttributeSet;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.Xml;
|
|
||||||
|
import androidx.annotation.CallSuper;
|
||||||
|
import androidx.annotation.VisibleForTesting;
|
||||||
|
|
||||||
import com.android.settings.core.BasePreferenceController;
|
import com.android.settings.core.BasePreferenceController;
|
||||||
import com.android.settings.core.PreferenceControllerListHelper;
|
import com.android.settings.core.PreferenceControllerListHelper;
|
||||||
@@ -31,16 +38,12 @@ import com.android.settings.core.PreferenceControllerMixin;
|
|||||||
import com.android.settings.core.PreferenceXmlParserUtils;
|
import com.android.settings.core.PreferenceXmlParserUtils;
|
||||||
import com.android.settingslib.core.AbstractPreferenceController;
|
import com.android.settingslib.core.AbstractPreferenceController;
|
||||||
|
|
||||||
import org.xmlpull.v1.XmlPullParser;
|
|
||||||
import org.xmlpull.v1.XmlPullParserException;
|
import org.xmlpull.v1.XmlPullParserException;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import androidx.annotation.CallSuper;
|
|
||||||
import androidx.annotation.VisibleForTesting;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A basic SearchIndexProvider that returns no data to index.
|
* A basic SearchIndexProvider that returns no data to index.
|
||||||
*/
|
*/
|
||||||
@@ -66,11 +69,12 @@ public class BaseSearchIndexProvider implements Indexable.SearchIndexProvider {
|
|||||||
public List<String> getNonIndexableKeys(Context context) {
|
public List<String> getNonIndexableKeys(Context context) {
|
||||||
if (!isPageSearchEnabled(context)) {
|
if (!isPageSearchEnabled(context)) {
|
||||||
// Entire page should be suppressed, mark all keys from this page as non-indexable.
|
// Entire page should be suppressed, mark all keys from this page as non-indexable.
|
||||||
return getNonIndexableKeysFromXml(context);
|
return getNonIndexableKeysFromXml(context, true /* suppressAllPage */);
|
||||||
}
|
}
|
||||||
|
final List<String> nonIndexableKeys = new ArrayList<>();
|
||||||
|
nonIndexableKeys.addAll(getNonIndexableKeysFromXml(context, false /* suppressAllPage */));
|
||||||
final List<AbstractPreferenceController> controllers = getPreferenceControllers(context);
|
final List<AbstractPreferenceController> controllers = getPreferenceControllers(context);
|
||||||
if (controllers != null && !controllers.isEmpty()) {
|
if (controllers != null && !controllers.isEmpty()) {
|
||||||
final List<String> nonIndexableKeys = new ArrayList<>();
|
|
||||||
for (AbstractPreferenceController controller : controllers) {
|
for (AbstractPreferenceController controller : controllers) {
|
||||||
if (controller instanceof PreferenceControllerMixin) {
|
if (controller instanceof PreferenceControllerMixin) {
|
||||||
((PreferenceControllerMixin) controller)
|
((PreferenceControllerMixin) controller)
|
||||||
@@ -85,10 +89,8 @@ public class BaseSearchIndexProvider implements Indexable.SearchIndexProvider {
|
|||||||
nonIndexableKeys.add(controller.getPreferenceKey());
|
nonIndexableKeys.add(controller.getPreferenceKey());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nonIndexableKeys;
|
|
||||||
} else {
|
|
||||||
return new ArrayList<>();
|
|
||||||
}
|
}
|
||||||
|
return nonIndexableKeys;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -131,7 +133,11 @@ public class BaseSearchIndexProvider implements Indexable.SearchIndexProvider {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<String> getNonIndexableKeysFromXml(Context context) {
|
/**
|
||||||
|
* Get all non-indexable keys from xml. If {@param suppressAllPage} is set, all keys are
|
||||||
|
* considered non-indexable. Otherwise, only keys with searchable="false" are included.
|
||||||
|
*/
|
||||||
|
private List<String> getNonIndexableKeysFromXml(Context context, boolean suppressAllPage) {
|
||||||
final List<SearchIndexableResource> resources = getXmlResourcesToIndex(
|
final List<SearchIndexableResource> resources = getXmlResourcesToIndex(
|
||||||
context, true /* not used*/);
|
context, true /* not used*/);
|
||||||
if (resources == null || resources.isEmpty()) {
|
if (resources == null || resources.isEmpty()) {
|
||||||
@@ -139,27 +145,32 @@ public class BaseSearchIndexProvider implements Indexable.SearchIndexProvider {
|
|||||||
}
|
}
|
||||||
final List<String> nonIndexableKeys = new ArrayList<>();
|
final List<String> nonIndexableKeys = new ArrayList<>();
|
||||||
for (SearchIndexableResource res : resources) {
|
for (SearchIndexableResource res : resources) {
|
||||||
nonIndexableKeys.addAll(getNonIndexableKeysFromXml(context, res.xmlResId));
|
nonIndexableKeys.addAll(
|
||||||
|
getNonIndexableKeysFromXml(context, res.xmlResId, suppressAllPage));
|
||||||
}
|
}
|
||||||
return nonIndexableKeys;
|
return nonIndexableKeys;
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting(otherwise = VisibleForTesting.PROTECTED)
|
@VisibleForTesting(otherwise = VisibleForTesting.PROTECTED)
|
||||||
public List<String> getNonIndexableKeysFromXml(Context context, @XmlRes int xmlResId) {
|
public List<String> getNonIndexableKeysFromXml(Context context, @XmlRes int xmlResId,
|
||||||
final List<String> nonIndexableKeys = new ArrayList<>();
|
boolean suppressAllPage) {
|
||||||
final XmlResourceParser parser = context.getResources().getXml(xmlResId);
|
return getKeysFromXml(context, xmlResId, suppressAllPage);
|
||||||
final AttributeSet attrs = Xml.asAttributeSet(parser);
|
}
|
||||||
|
|
||||||
|
private List<String> getKeysFromXml(Context context, @XmlRes int xmlResId,
|
||||||
|
boolean suppressAllPage) {
|
||||||
|
final List<String> keys = new ArrayList<>();
|
||||||
try {
|
try {
|
||||||
while (parser.next() != XmlPullParser.END_DOCUMENT) {
|
final List<Bundle> metadata = PreferenceXmlParserUtils.extractMetadata(context,
|
||||||
final String key = PreferenceXmlParserUtils.getDataKey(context, attrs);
|
xmlResId, FLAG_NEED_KEY | FLAG_INCLUDE_PREF_SCREEN | FLAG_NEED_SEARCHABLE);
|
||||||
if (!TextUtils.isEmpty(key)) {
|
for (Bundle bundle : metadata) {
|
||||||
nonIndexableKeys.add(key);
|
if (suppressAllPage || !bundle.getBoolean(METADATA_SEARCHABLE, true)) {
|
||||||
|
keys.add(bundle.getString(METADATA_KEY));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (IOException | XmlPullParserException e) {
|
} catch (IOException | XmlPullParserException e) {
|
||||||
Log.w(TAG, "Error parsing non-indexable from xml " + xmlResId);
|
Log.w(TAG, "Error parsing non-indexable from xml " + xmlResId);
|
||||||
}
|
}
|
||||||
return nonIndexableKeys;
|
return keys;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -101,8 +101,6 @@ public class SystemDashboardFragment extends DashboardFragment {
|
|||||||
@Override
|
@Override
|
||||||
public List<String> getNonIndexableKeys(Context context) {
|
public List<String> getNonIndexableKeys(Context context) {
|
||||||
List<String> keys = super.getNonIndexableKeys(context);
|
List<String> keys = super.getNonIndexableKeys(context);
|
||||||
keys.add((new BackupSettingsActivityPreferenceController(
|
|
||||||
context).getPreferenceKey()));
|
|
||||||
keys.add(KEY_RESET);
|
keys.add(KEY_RESET);
|
||||||
return keys;
|
return keys;
|
||||||
}
|
}
|
||||||
|
@@ -49,6 +49,13 @@ import android.view.MenuItem;
|
|||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.SimpleAdapter;
|
import android.widget.SimpleAdapter;
|
||||||
|
|
||||||
|
import androidx.annotation.VisibleForTesting;
|
||||||
|
import androidx.annotation.WorkerThread;
|
||||||
|
import androidx.appcompat.app.AlertDialog;
|
||||||
|
import androidx.preference.Preference;
|
||||||
|
import androidx.preference.PreferenceGroup;
|
||||||
|
import androidx.preference.PreferenceScreen;
|
||||||
|
|
||||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||||
import com.android.internal.util.UserIcons;
|
import com.android.internal.util.UserIcons;
|
||||||
import com.android.internal.widget.LockPatternUtils;
|
import com.android.internal.widget.LockPatternUtils;
|
||||||
@@ -76,13 +83,6 @@ import java.util.Collections;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import androidx.annotation.VisibleForTesting;
|
|
||||||
import androidx.annotation.WorkerThread;
|
|
||||||
import androidx.appcompat.app.AlertDialog;
|
|
||||||
import androidx.preference.Preference;
|
|
||||||
import androidx.preference.PreferenceGroup;
|
|
||||||
import androidx.preference.PreferenceScreen;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Screen that manages the list of users on the device.
|
* Screen that manages the list of users on the device.
|
||||||
* Guest user is an always visible entry, even if the guest is not currently
|
* Guest user is an always visible entry, even if the guest is not currently
|
||||||
@@ -635,8 +635,8 @@ public class UserSettings extends SettingsPreferenceFragment
|
|||||||
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||||
SimpleAdapter adapter = new SimpleAdapter(builder.getContext(),
|
SimpleAdapter adapter = new SimpleAdapter(builder.getContext(),
|
||||||
data, R.layout.two_line_list_item,
|
data, R.layout.two_line_list_item,
|
||||||
new String[] {KEY_TITLE, KEY_SUMMARY},
|
new String[]{KEY_TITLE, KEY_SUMMARY},
|
||||||
new int[] {R.id.title, R.id.summary});
|
new int[]{R.id.title, R.id.summary});
|
||||||
builder.setTitle(R.string.user_add_user_type_title);
|
builder.setTitle(R.string.user_add_user_type_title);
|
||||||
builder.setAdapter(adapter,
|
builder.setAdapter(adapter,
|
||||||
new DialogInterface.OnClickListener() {
|
new DialogInterface.OnClickListener() {
|
||||||
@@ -1238,8 +1238,10 @@ public class UserSettings extends SettingsPreferenceFragment
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> getNonIndexableKeysFromXml(Context context, int xmlResId) {
|
public List<String> getNonIndexableKeysFromXml(Context context, int xmlResId,
|
||||||
final List<String> niks = super.getNonIndexableKeysFromXml(context, xmlResId);
|
boolean suppressAllPage) {
|
||||||
|
final List<String> niks = super.getNonIndexableKeysFromXml(context, xmlResId,
|
||||||
|
suppressAllPage);
|
||||||
new AddUserWhenLockedPreferenceController(context, KEY_ADD_USER_WHEN_LOCKED)
|
new AddUserWhenLockedPreferenceController(context, KEY_ADD_USER_WHEN_LOCKED)
|
||||||
.updateNonIndexableKeys(niks);
|
.updateNonIndexableKeys(niks);
|
||||||
new AutoSyncDataPreferenceController(context, null /* parent */)
|
new AutoSyncDataPreferenceController(context, null /* parent */)
|
||||||
|
@@ -59,5 +59,6 @@
|
|||||||
android:title="pref_title_5"
|
android:title="pref_title_5"
|
||||||
android:summaryOn="summary_on"
|
android:summaryOn="summary_on"
|
||||||
android:summaryOff="summary_off"
|
android:summaryOff="summary_off"
|
||||||
|
settings:searchable="false"
|
||||||
settings:keywords="keywords1, keywords2, keywords3" />
|
settings:keywords="keywords1, keywords2, keywords3" />
|
||||||
</PreferenceScreen>
|
</PreferenceScreen>
|
@@ -17,6 +17,7 @@
|
|||||||
package com.android.settings.applications;
|
package com.android.settings.applications;
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.spy;
|
import static org.mockito.Mockito.spy;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
@@ -26,7 +27,6 @@ import android.os.UserManager;
|
|||||||
|
|
||||||
import com.android.settings.notification.EmergencyBroadcastPreferenceController;
|
import com.android.settings.notification.EmergencyBroadcastPreferenceController;
|
||||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||||
import com.android.settings.testutils.XmlTestUtils;
|
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
@@ -42,19 +42,16 @@ public class AppAndNotificationDashboardFragmentTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Config(shadows = {ShadowEmergencyBroadcastPreferenceController.class})
|
@Config(shadows = {ShadowEmergencyBroadcastPreferenceController.class})
|
||||||
public void testNonIndexableKeys_existInXmlLayout() {
|
public void getNonIndexableKeys_shouldIncludeSpecialAppAccess() {
|
||||||
final Context context = spy(RuntimeEnvironment.application);
|
final Context context = spy(RuntimeEnvironment.application);
|
||||||
UserManager manager = mock(UserManager.class);
|
UserManager manager = mock(UserManager.class);
|
||||||
when(manager.isAdminUser()).thenReturn(true);
|
when(manager.isAdminUser()).thenReturn(true);
|
||||||
when(context.getSystemService(Context.USER_SERVICE)).thenReturn(manager);
|
when(context.getSystemService(Context.USER_SERVICE)).thenReturn(manager);
|
||||||
final List<String> niks = AppAndNotificationDashboardFragment.SEARCH_INDEX_DATA_PROVIDER
|
final List<String> niks = AppAndNotificationDashboardFragment.SEARCH_INDEX_DATA_PROVIDER
|
||||||
.getNonIndexableKeys(context);
|
.getNonIndexableKeys(context);
|
||||||
AppAndNotificationDashboardFragment fragment = new AppAndNotificationDashboardFragment();
|
|
||||||
final int xmlId = fragment.getPreferenceScreenResId();
|
|
||||||
|
|
||||||
final List<String> keys = XmlTestUtils.getKeysFromPreferenceXml(context, xmlId);
|
assertThat(niks).contains(
|
||||||
|
new SpecialAppAccessPreferenceController(context).getPreferenceKey());
|
||||||
assertThat(keys).containsAllIn(niks);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Implements(EmergencyBroadcastPreferenceController.class)
|
@Implements(EmergencyBroadcastPreferenceController.class)
|
||||||
|
@@ -165,7 +165,7 @@ public class DefaultAppSettingsTest {
|
|||||||
final List<String> niks = DefaultAppSettings.SEARCH_INDEX_DATA_PROVIDER
|
final List<String> niks = DefaultAppSettings.SEARCH_INDEX_DATA_PROVIDER
|
||||||
.getNonIndexableKeys(context);
|
.getNonIndexableKeys(context);
|
||||||
|
|
||||||
final int xmlId = (new DefaultAppSettings()).getPreferenceScreenResId();
|
final int xmlId = new DefaultAppSettings().getPreferenceScreenResId();
|
||||||
|
|
||||||
final List<String> keys = XmlTestUtils.getKeysFromPreferenceXml(context, xmlId);
|
final List<String> keys = XmlTestUtils.getKeysFromPreferenceXml(context, xmlId);
|
||||||
|
|
||||||
|
@@ -16,7 +16,10 @@
|
|||||||
|
|
||||||
package com.android.settings.core;
|
package com.android.settings.core;
|
||||||
|
|
||||||
|
import static com.android.settings.core.PreferenceXmlParserUtils.METADATA_KEY;
|
||||||
import static com.android.settings.core.PreferenceXmlParserUtils.METADATA_KEYWORDS;
|
import static com.android.settings.core.PreferenceXmlParserUtils.METADATA_KEYWORDS;
|
||||||
|
import static com.android.settings.core.PreferenceXmlParserUtils.METADATA_SEARCHABLE;
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
@@ -247,8 +250,7 @@ public class PreferenceXmlParserUtilsTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Config(qualifiers = "mcc999")
|
@Config(qualifiers = "mcc999")
|
||||||
public void extractMetadata_requestIncludesKeywords_shouldContainKeywords()
|
public void extractMetadata_requestIncludesKeywords_shouldContainKeywords() throws Exception {
|
||||||
throws IOException, XmlPullParserException {
|
|
||||||
final String expectedKeywords = "a, b, c";
|
final String expectedKeywords = "a, b, c";
|
||||||
final List<Bundle> metadata = PreferenceXmlParserUtils.extractMetadata(mContext,
|
final List<Bundle> metadata = PreferenceXmlParserUtils.extractMetadata(mContext,
|
||||||
R.xml.location_settings,
|
R.xml.location_settings,
|
||||||
@@ -260,6 +262,32 @@ public class PreferenceXmlParserUtilsTest {
|
|||||||
assertThat(keywords).isEqualTo(expectedKeywords);
|
assertThat(keywords).isEqualTo(expectedKeywords);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void extractMetadata_requestSearchable_shouldDefaultToTrue() throws Exception {
|
||||||
|
final List<Bundle> metadata = PreferenceXmlParserUtils.extractMetadata(mContext,
|
||||||
|
R.xml.display_settings, MetadataFlag.FLAG_NEED_SEARCHABLE);
|
||||||
|
for (Bundle bundle : metadata) {
|
||||||
|
assertThat(bundle.getBoolean(METADATA_SEARCHABLE)).isTrue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Config(qualifiers = "mcc999")
|
||||||
|
public void extractMetadata_requestSearchable_shouldReturnAttributeValue() throws Exception {
|
||||||
|
final List<Bundle> metadata = PreferenceXmlParserUtils.extractMetadata(mContext,
|
||||||
|
R.xml.display_settings,
|
||||||
|
MetadataFlag.FLAG_NEED_KEY | MetadataFlag.FLAG_NEED_SEARCHABLE);
|
||||||
|
boolean foundKey = false;
|
||||||
|
for (Bundle bundle : metadata) {
|
||||||
|
if (TextUtils.equals(bundle.getString(METADATA_KEY), "pref_key_5")) {
|
||||||
|
assertThat(bundle.getBoolean(METADATA_SEARCHABLE)).isFalse();
|
||||||
|
foundKey = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assertThat(foundKey).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param resId the ID for the XML preference
|
* @param resId the ID for the XML preference
|
||||||
* @return an XML resource parser that points to the start tag
|
* @return an XML resource parser that points to the start tag
|
||||||
|
@@ -17,6 +17,7 @@
|
|||||||
package com.android.settings.language;
|
package com.android.settings.language;
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.spy;
|
import static org.mockito.Mockito.spy;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
@@ -25,6 +26,9 @@ import android.content.Context;
|
|||||||
import android.speech.tts.TextToSpeech;
|
import android.speech.tts.TextToSpeech;
|
||||||
import android.speech.tts.TtsEngines;
|
import android.speech.tts.TtsEngines;
|
||||||
|
|
||||||
|
import androidx.preference.Preference;
|
||||||
|
import androidx.preference.PreferenceScreen;
|
||||||
|
|
||||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
@@ -38,9 +42,6 @@ import org.robolectric.annotation.Config;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import androidx.preference.Preference;
|
|
||||||
import androidx.preference.PreferenceScreen;
|
|
||||||
|
|
||||||
@RunWith(SettingsRobolectricTestRunner.class)
|
@RunWith(SettingsRobolectricTestRunner.class)
|
||||||
public class TtsPreferenceControllerTest {
|
public class TtsPreferenceControllerTest {
|
||||||
|
|
||||||
@@ -58,7 +59,8 @@ public class TtsPreferenceControllerTest {
|
|||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
mContext = spy(RuntimeEnvironment.application);
|
mContext = spy(RuntimeEnvironment.application);
|
||||||
|
|
||||||
mController = new TtsPreferenceController(mContext, mTtsEngines);
|
mController = new TtsPreferenceController(mContext, "test_key");
|
||||||
|
mController.mTtsEngines = mTtsEngines;
|
||||||
mPreference = new Preference(RuntimeEnvironment.application);
|
mPreference = new Preference(RuntimeEnvironment.application);
|
||||||
mPreference.setKey(mController.getPreferenceKey());
|
mPreference.setKey(mController.getPreferenceKey());
|
||||||
when(mScreen.findPreference(mPreference.getKey())).thenReturn(mPreference);
|
when(mScreen.findPreference(mPreference.getKey())).thenReturn(mPreference);
|
||||||
|
@@ -169,4 +169,24 @@ public class BaseSearchIndexProviderTest {
|
|||||||
|
|
||||||
assertThat(nonIndexableKeys).contains("status_header");
|
assertThat(nonIndexableKeys).contains("status_header");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Config(qualifiers = "mcc999")
|
||||||
|
public void getNonIndexableKeys_hasSearchableAttributeInXml_shouldSuppressUnsearchable() {
|
||||||
|
final BaseSearchIndexProvider provider = new BaseSearchIndexProvider() {
|
||||||
|
@Override
|
||||||
|
public List<SearchIndexableResource> getXmlResourcesToIndex(Context context,
|
||||||
|
boolean enabled) {
|
||||||
|
final SearchIndexableResource sir = new SearchIndexableResource(context);
|
||||||
|
sir.xmlResId = R.xml.display_settings;
|
||||||
|
return Collections.singletonList(sir);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
final List<String> nonIndexableKeys =
|
||||||
|
provider.getNonIndexableKeys(RuntimeEnvironment.application);
|
||||||
|
|
||||||
|
assertThat(nonIndexableKeys).contains("pref_key_5");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
package com.android.settings.search;
|
package com.android.settings.search;
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.spy;
|
import static org.mockito.Mockito.spy;
|
||||||
|
|
||||||
@@ -21,6 +22,9 @@ import org.junit.runner.RunWith;
|
|||||||
import org.robolectric.RuntimeEnvironment;
|
import org.robolectric.RuntimeEnvironment;
|
||||||
import org.robolectric.annotation.Config;
|
import org.robolectric.annotation.Config;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@RunWith(SettingsRobolectricTestRunner.class)
|
@RunWith(SettingsRobolectricTestRunner.class)
|
||||||
public class SettingsSearchIndexablesProviderTest {
|
public class SettingsSearchIndexablesProviderTest {
|
||||||
|
|
||||||
@@ -96,16 +100,19 @@ public class SettingsSearchIndexablesProviderTest {
|
|||||||
@Test
|
@Test
|
||||||
@Config(qualifiers = "mcc999")
|
@Config(qualifiers = "mcc999")
|
||||||
public void testNonIndexablesColumnFetched() {
|
public void testNonIndexablesColumnFetched() {
|
||||||
Uri rawUri = Uri.parse("content://" + BASE_AUTHORITY + "/" +
|
final Uri rawUri = Uri.parse("content://" + BASE_AUTHORITY + "/" +
|
||||||
SearchIndexablesContract.NON_INDEXABLES_KEYS_PATH);
|
SearchIndexablesContract.NON_INDEXABLES_KEYS_PATH);
|
||||||
|
|
||||||
final Cursor cursor = mProvider.query(rawUri,
|
final List<String> keys = new ArrayList<>();
|
||||||
SearchIndexablesContract.NON_INDEXABLES_KEYS_COLUMNS, null, null, null);
|
|
||||||
|
|
||||||
cursor.moveToFirst();
|
try (Cursor cursor = mProvider.query(rawUri,
|
||||||
assertThat(cursor.getCount()).isEqualTo(2);
|
SearchIndexablesContract.NON_INDEXABLES_KEYS_COLUMNS, null, null, null)) {
|
||||||
assertThat(cursor.getString(0)).isEqualTo("pref_key_1");
|
while (cursor.moveToNext()) {
|
||||||
cursor.moveToNext();
|
keys.add(cursor.getString(0));
|
||||||
assertThat(cursor.getString(0)).isEqualTo("pref_key_3");
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assertThat(keys).hasSize(3);
|
||||||
|
assertThat(keys).containsAllOf("pref_key_1", "pref_key_3", "pref_key_5");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -73,7 +73,7 @@ public class EncryptionAndCredentialTest {
|
|||||||
final List<String> expectedKeys = new ArrayList<>();
|
final List<String> expectedKeys = new ArrayList<>();
|
||||||
for (SearchIndexableResource res : index) {
|
for (SearchIndexableResource res : index) {
|
||||||
expectedKeys.addAll(((BaseSearchIndexProvider) SEARCH_INDEX_DATA_PROVIDER)
|
expectedKeys.addAll(((BaseSearchIndexProvider) SEARCH_INDEX_DATA_PROVIDER)
|
||||||
.getNonIndexableKeysFromXml(mContext, res.xmlResId));
|
.getNonIndexableKeysFromXml(mContext, res.xmlResId, true /* suppressAll */));
|
||||||
}
|
}
|
||||||
final List<String> keys = SEARCH_INDEX_DATA_PROVIDER.getNonIndexableKeys(mContext);
|
final List<String> keys = SEARCH_INDEX_DATA_PROVIDER.getNonIndexableKeys(mContext);
|
||||||
|
|
||||||
|
@@ -1,15 +1,16 @@
|
|||||||
package com.android.settings.testutils;
|
package com.android.settings.testutils;
|
||||||
|
|
||||||
|
import static com.android.settings.core.PreferenceXmlParserUtils.METADATA_KEY;
|
||||||
|
import static com.android.settings.core.PreferenceXmlParserUtils.MetadataFlag
|
||||||
|
.FLAG_INCLUDE_PREF_SCREEN;
|
||||||
|
import static com.android.settings.core.PreferenceXmlParserUtils.MetadataFlag.FLAG_NEED_KEY;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.res.Resources;
|
import android.os.Bundle;
|
||||||
import android.content.res.XmlResourceParser;
|
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.AttributeSet;
|
|
||||||
import android.util.Xml;
|
|
||||||
|
|
||||||
import com.android.settings.core.PreferenceXmlParserUtils;
|
import com.android.settings.core.PreferenceXmlParserUtils;
|
||||||
|
|
||||||
import org.xmlpull.v1.XmlPullParser;
|
|
||||||
import org.xmlpull.v1.XmlPullParserException;
|
import org.xmlpull.v1.XmlPullParserException;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -25,30 +26,21 @@ public class XmlTestUtils {
|
|||||||
* on the screen.
|
* on the screen.
|
||||||
*
|
*
|
||||||
* @param context of the preference screen.
|
* @param context of the preference screen.
|
||||||
* @param xmlId of the Preference Xml to be parsed.
|
* @param xmlId of the Preference Xml to be parsed.
|
||||||
* @return List of all keys in the preference Xml
|
* @return List of all keys in the preference Xml
|
||||||
*/
|
*/
|
||||||
public static List<String> getKeysFromPreferenceXml(Context context, int xmlId) {
|
public static List<String> getKeysFromPreferenceXml(Context context, int xmlId) {
|
||||||
final XmlResourceParser parser = context.getResources().getXml(xmlId);
|
|
||||||
final AttributeSet attrs = Xml.asAttributeSet(parser);
|
|
||||||
final List<String> keys = new ArrayList<>();
|
final List<String> keys = new ArrayList<>();
|
||||||
String key;
|
|
||||||
try {
|
try {
|
||||||
while (parser.next() != XmlPullParser.END_DOCUMENT) {
|
List<Bundle> metadata = PreferenceXmlParserUtils.extractMetadata(context, xmlId,
|
||||||
try {
|
FLAG_NEED_KEY | FLAG_INCLUDE_PREF_SCREEN);
|
||||||
key = PreferenceXmlParserUtils.getDataKey(context, attrs);
|
for (Bundle bundle : metadata) {
|
||||||
if (!TextUtils.isEmpty(key)) {
|
final String key = bundle.getString(METADATA_KEY);
|
||||||
keys.add(key);
|
if (!TextUtils.isEmpty(key)) {
|
||||||
}
|
keys.add(key);
|
||||||
} catch (NullPointerException e) {
|
|
||||||
continue;
|
|
||||||
} catch (Resources.NotFoundException e) {
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (java.io.IOException e) {
|
} catch (java.io.IOException | XmlPullParserException e) {
|
||||||
return null;
|
|
||||||
} catch (XmlPullParserException e) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user