Merge "Remove PreferenceXmlParserUtils deprecated methods" into main

This commit is contained in:
Chaohui Wang
2023-08-07 03:13:42 +00:00
committed by Android (Google) Code Review
5 changed files with 16 additions and 332 deletions

View File

@@ -17,7 +17,6 @@
package com.android.settings.core;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.XmlRes;
import android.content.Context;
import android.content.res.TypedArray;
@@ -26,11 +25,9 @@ import android.os.Bundle;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.util.Xml;
import androidx.annotation.IntDef;
import androidx.annotation.VisibleForTesting;
import com.android.settings.R;
@@ -50,8 +47,7 @@ import java.util.List;
public class PreferenceXmlParserUtils {
private static final String TAG = "PreferenceXmlParserUtil";
@VisibleForTesting
static final String PREF_SCREEN_TAG = "PreferenceScreen";
public static final String PREF_SCREEN_TAG = "PreferenceScreen";
private static final List<String> SUPPORTED_PREF_TYPES = Arrays.asList(
"Preference", "PreferenceCategory", "PreferenceScreen",
"com.android.settings.widget.WorkOnlyCategory");
@@ -71,7 +67,9 @@ public class PreferenceXmlParserUtils {
MetadataFlag.FLAG_NEED_PREF_TITLE,
MetadataFlag.FLAG_NEED_PREF_SUMMARY,
MetadataFlag.FLAG_NEED_PREF_ICON,
MetadataFlag.FLAG_NEED_KEYWORDS,
MetadataFlag.FLAG_NEED_SEARCHABLE,
MetadataFlag.FLAG_NEED_PREF_APPEND,
MetadataFlag.FLAG_UNAVAILABLE_SLICE_SUBTITLE,
MetadataFlag.FLAG_FOR_WORK,
MetadataFlag.FLAG_NEED_HIGHLIGHTABLE_MENU_KEY,
@@ -109,70 +107,6 @@ public class PreferenceXmlParserUtils {
public static final String METADATA_HIGHLIGHTABLE_MENU_KEY = "highlightable_menu_key";
public static final String METADATA_USER_RESTRICTION = "userRestriction";
private static final String ENTRIES_SEPARATOR = "|";
/**
* Call {@link #extractMetadata(Context, int, int)} with {@link #METADATA_KEY} instead.
*/
@Deprecated
public static String getDataKey(Context context, AttributeSet attrs) {
return getStringData(context, attrs,
com.android.internal.R.styleable.Preference,
com.android.internal.R.styleable.Preference_key);
}
/**
* Call {@link #extractMetadata(Context, int, int)} with {@link #METADATA_TITLE} instead.
*/
@Deprecated
public static String getDataTitle(Context context, AttributeSet attrs) {
return getStringData(context, attrs,
com.android.internal.R.styleable.Preference,
com.android.internal.R.styleable.Preference_title);
}
/**
* Call {@link #extractMetadata(Context, int, int)} with {@link #METADATA_SUMMARY} instead.
*/
@Deprecated
public static String getDataSummary(Context context, AttributeSet attrs) {
return getStringData(context, attrs,
com.android.internal.R.styleable.Preference,
com.android.internal.R.styleable.Preference_summary);
}
public static String getDataSummaryOn(Context context, AttributeSet attrs) {
return getStringData(context, attrs,
com.android.internal.R.styleable.CheckBoxPreference,
com.android.internal.R.styleable.CheckBoxPreference_summaryOn);
}
public static String getDataSummaryOff(Context context, AttributeSet attrs) {
return getStringData(context, attrs,
com.android.internal.R.styleable.CheckBoxPreference,
com.android.internal.R.styleable.CheckBoxPreference_summaryOff);
}
public static String getDataEntries(Context context, AttributeSet attrs) {
return getDataEntries(context, attrs,
com.android.internal.R.styleable.ListPreference,
com.android.internal.R.styleable.ListPreference_entries);
}
public static String getDataKeywords(Context context, AttributeSet attrs) {
return getStringData(context, attrs, R.styleable.Preference,
R.styleable.Preference_keywords);
}
/**
* Call {@link #extractMetadata(Context, int, int)} with {@link #METADATA_CONTROLLER} instead.
*/
@Deprecated
public static String getController(Context context, AttributeSet attrs) {
return getStringData(context, attrs, R.styleable.Preference,
R.styleable.Preference_controller);
}
/**
* Extracts metadata from preference xml and put them into a {@link Bundle}.
*
@@ -276,45 +210,10 @@ public class PreferenceXmlParserUtils {
return metadata;
}
/**
* Call {@link #extractMetadata(Context, int, int)} with a {@link MetadataFlag} instead.
*/
@Deprecated
@Nullable
private static String getStringData(Context context, AttributeSet set, int[] attrs, int resId) {
final TypedArray ta = context.obtainStyledAttributes(set, attrs);
String data = ta.getString(resId);
ta.recycle();
return data;
}
private static boolean hasFlag(int flags, @MetadataFlag int flag) {
return (flags & flag) != 0;
}
private static String getDataEntries(Context context, AttributeSet set, int[] attrs,
int resId) {
final TypedArray sa = context.obtainStyledAttributes(set, attrs);
final TypedValue tv = sa.peekValue(resId);
sa.recycle();
String[] data = null;
if (tv != null && tv.type == TypedValue.TYPE_REFERENCE) {
if (tv.resourceId != 0) {
data = context.getResources().getStringArray(tv.resourceId);
}
}
final int count = (data == null) ? 0 : data.length;
if (count == 0) {
return null;
}
final StringBuilder result = new StringBuilder();
for (int n = 0; n < count; n++) {
result.append(data[n]);
result.append(ENTRIES_SEPARATOR);
}
return result.toString();
}
private static String getKey(TypedArray styledAttributes) {
return styledAttributes.getString(com.android.internal.R.styleable.Preference_key);
}

View File

@@ -19,10 +19,12 @@ package com.android.settings.slices;
import static com.android.settings.core.PreferenceXmlParserUtils.METADATA_CONTROLLER;
import static com.android.settings.core.PreferenceXmlParserUtils.METADATA_ICON;
import static com.android.settings.core.PreferenceXmlParserUtils.METADATA_KEY;
import static com.android.settings.core.PreferenceXmlParserUtils.METADATA_PREF_TYPE;
import static com.android.settings.core.PreferenceXmlParserUtils.METADATA_SUMMARY;
import static com.android.settings.core.PreferenceXmlParserUtils.METADATA_TITLE;
import static com.android.settings.core.PreferenceXmlParserUtils.METADATA_UNAVAILABLE_SLICE_SUBTITLE;
import static com.android.settings.core.PreferenceXmlParserUtils.METADATA_USER_RESTRICTION;
import static com.android.settings.core.PreferenceXmlParserUtils.PREF_SCREEN_TAG;
import android.accessibilityservice.AccessibilityServiceInfo;
import android.app.settings.SettingsEnums;
@@ -33,17 +35,15 @@ import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.content.res.Resources;
import android.content.res.XmlResourceParser;
import android.net.Uri;
import android.os.Bundle;
import android.provider.SearchIndexableResource;
import android.provider.SettingsSlicesContract;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.util.Xml;
import android.view.accessibility.AccessibilityManager;
import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
import com.android.settings.R;
@@ -59,7 +59,6 @@ import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
import com.android.settingslib.search.Indexable.SearchIndexProvider;
import com.android.settingslib.search.SearchIndexableData;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
@@ -80,8 +79,6 @@ class SliceDataConverter {
private static final String TAG = "SliceDataConverter";
private static final String NODE_NAME_PREFERENCE_SCREEN = "PreferenceScreen";
private final MetricsFeatureProvider mMetricsFeatureProvider;
private Context mContext;
@@ -155,36 +152,18 @@ class SliceDataConverter {
}
private List<SliceData> getSliceDataFromXML(int xmlResId, String fragmentName) {
XmlResourceParser parser = null;
final List<SliceData> xmlSliceData = new ArrayList<>();
String controllerClassName = "";
@NonNull String screenTitle = "";
try {
parser = mContext.getResources().getXml(xmlResId);
int type;
while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
&& type != XmlPullParser.START_TAG) {
// Parse next until start tag is found
}
String nodeName = parser.getName();
if (!NODE_NAME_PREFERENCE_SCREEN.equals(nodeName)) {
throw new RuntimeException(
"XML document must start with <PreferenceScreen> tag; found"
+ nodeName + " at " + parser.getPositionDescription());
}
final AttributeSet attrs = Xml.asAttributeSet(parser);
final String screenTitle = PreferenceXmlParserUtils.getDataTitle(mContext, attrs);
// TODO (b/67996923) Investigate if we need headers for Slices, since they never
// correspond to an actual setting.
final List<Bundle> metadata = PreferenceXmlParserUtils.extractMetadata(mContext,
xmlResId,
MetadataFlag.FLAG_NEED_KEY
MetadataFlag.FLAG_INCLUDE_PREF_SCREEN
| MetadataFlag.FLAG_NEED_KEY
| MetadataFlag.FLAG_NEED_PREF_CONTROLLER
| MetadataFlag.FLAG_NEED_PREF_TYPE
| MetadataFlag.FLAG_NEED_PREF_TITLE
@@ -194,6 +173,13 @@ class SliceDataConverter {
| MetadataFlag.FLAG_NEED_USER_RESTRICTION);
for (Bundle bundle : metadata) {
final String title = bundle.getString(METADATA_TITLE);
if (PREF_SCREEN_TAG.equals(bundle.getString(METADATA_PREF_TYPE))) {
if (title != null) {
screenTitle = title;
}
continue;
}
// TODO (b/67996923) Non-controller Slices should become intent-only slices.
// Note that without a controller, dynamic summaries are impossible.
controllerClassName = bundle.getString(METADATA_CONTROLLER);
@@ -211,7 +197,6 @@ class SliceDataConverter {
|| controller instanceof RingerModeAffectedVolumePreferenceController)) {
continue;
}
final String title = bundle.getString(METADATA_TITLE);
final String summary = bundle.getString(METADATA_SUMMARY);
final int iconResId = bundle.getInt(METADATA_ICON);
@@ -261,8 +246,6 @@ class SliceDataConverter {
SettingsEnums.PAGE_UNKNOWN,
fragmentName + "_" + controllerClassName,
1);
} finally {
if (parser != null) parser.close();
}
return xmlSliceData;
}

View File

@@ -1,35 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
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.
-->
<!--
WARNING: This resource file is used to test Settings Search indexing.
If you change something in here, please run the settings robotests and
make sure they still pass.
-->
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res-auto"
android:title="bears_bears_bears"
settings:keywords="keywords">
<Preference
android:key="pref_key_1"
android:title="bears_bears_bears"
settings:controller="mind_flayer"/>
</PreferenceScreen>

View File

@@ -27,11 +27,8 @@ import static com.android.settings.core.PreferenceXmlParserUtils.METADATA_UNAVAI
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import android.content.res.XmlResourceParser;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Xml;
import com.android.settings.R;
import com.android.settings.core.PreferenceXmlParserUtils.MetadataFlag;
@@ -42,12 +39,10 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
import java.util.List;
import java.util.Objects;
/**
* These tests use a series of preferences that have specific attributes which are sometimes
@@ -67,115 +62,6 @@ public class PreferenceXmlParserUtilsTest {
mContext = getApplicationContext();
}
@Test
public void testDataTitleValid_ReturnsPreferenceTitle() {
XmlResourceParser parser = getChildByType(R.xml.display_settings,
"com.android.settings.display.darkmode.DarkModePreference");
final AttributeSet attrs = Xml.asAttributeSet(parser);
String title = PreferenceXmlParserUtils.getDataTitle(mContext, attrs);
String expTitle = mContext.getString(R.string.dark_ui_mode);
assertThat(title).isEqualTo(expTitle);
}
@Test
public void testDataKeywordsValid_ReturnsPreferenceKeywords() {
XmlResourceParser parser = getChildByType(R.xml.display_settings,
"com.android.settings.display.darkmode.DarkModePreference");
final AttributeSet attrs = Xml.asAttributeSet(parser);
String keywords = PreferenceXmlParserUtils.getDataKeywords(mContext, attrs);
String expKeywords = mContext.getString(R.string.keywords_dark_ui_mode);
assertThat(keywords).isEqualTo(expKeywords);
}
@Test
public void testDataKeyValid_ReturnsPreferenceKey() {
XmlResourceParser parser = getChildByType(R.xml.display_settings,
"com.android.settings.display.darkmode.DarkModePreference");
final AttributeSet attrs = Xml.asAttributeSet(parser);
String key = PreferenceXmlParserUtils.getDataKey(mContext, attrs);
String expKey = "dark_ui_mode";
assertThat(key).isEqualTo(expKey);
}
@Test
public void testDataSummaryValid_ReturnsPreferenceSummary() {
XmlResourceParser parser = getChildByType(R.xml.sound_settings,
"com.android.settings.DefaultRingtonePreference");
final AttributeSet attrs = Xml.asAttributeSet(parser);
String summary = PreferenceXmlParserUtils.getDataSummary(mContext, attrs);
String expSummary = mContext.getString(R.string.summary_placeholder);
assertThat(summary).isEqualTo(expSummary);
}
@Test
@Config(qualifiers = "mcc999")
public void testDataSummaryOnOffValid_ReturnsPreferenceSummaryOnOff() {
XmlResourceParser parser = getChildByType(R.xml.display_settings, "CheckBoxPreference");
final AttributeSet attrs = Xml.asAttributeSet(parser);
assertThat(PreferenceXmlParserUtils.getDataSummaryOn(mContext, attrs))
.isEqualTo("summary_on");
assertThat(PreferenceXmlParserUtils.getDataSummaryOff(mContext, attrs))
.isEqualTo("summary_off");
}
@Test
@Config(qualifiers = "mcc999")
public void testDataEntriesValid_ReturnsPreferenceEntries() {
XmlResourceParser parser = getChildByType(R.xml.display_settings, "ListPreference");
final AttributeSet attrs = Xml.asAttributeSet(parser);
String entries = PreferenceXmlParserUtils.getDataEntries(mContext, attrs);
String[] expEntries = mContext.getResources()
.getStringArray(R.array.mvno_type_entries);
for (String expEntry : expEntries) {
assertThat(entries).contains(expEntry);
}
}
// Null checks
@Test
@Config(qualifiers = "mcc999")
public void testDataKeyInvalid_ReturnsNull() {
XmlResourceParser parser = getParentPrimedParser(R.xml.display_settings);
final AttributeSet attrs = Xml.asAttributeSet(parser);
String key = PreferenceXmlParserUtils.getDataKey(mContext, attrs);
assertThat(key).isNull();
}
@Test
@Config(qualifiers = "mcc999")
public void testControllerAttribute_returnsValidData() {
XmlResourceParser parser = getChildByType(R.xml.about_legal, "Preference");
final AttributeSet attrs = Xml.asAttributeSet(parser);
String controller = PreferenceXmlParserUtils.getController(mContext, attrs);
assertThat(controller).isEqualTo("mind_flayer");
}
@Test
public void testDataSummaryInvalid_ReturnsNull() {
XmlResourceParser parser = getParentPrimedParser(R.xml.display_settings);
final AttributeSet attrs = Xml.asAttributeSet(parser);
String summary = PreferenceXmlParserUtils.getDataSummary(mContext, attrs);
assertThat(summary).isNull();
}
@Test
public void testDataSummaryOffInvalid_ReturnsNull() {
XmlResourceParser parser = getParentPrimedParser(R.xml.display_settings);
final AttributeSet attrs = Xml.asAttributeSet(parser);
String summaryOff = PreferenceXmlParserUtils.getDataSummaryOff(mContext, attrs);
assertThat(summaryOff).isNull();
}
@Test
public void testDataEntriesInvalid_ReturnsNull() {
XmlResourceParser parser = getParentPrimedParser(R.xml.display_settings);
final AttributeSet attrs = Xml.asAttributeSet(parser);
String entries = PreferenceXmlParserUtils.getDataEntries(mContext, attrs);
assertThat(entries).isNull();
}
@Test
public void extractHomepageMetadata_shouldContainKeyAndHighlightableMenuKey()
throws IOException, XmlPullParserException {
@@ -380,46 +266,4 @@ public class PreferenceXmlParserUtilsTest {
assertThat(bundleWithKey2Found).isTrue();
}
/**
* @param resId the ID for the XML preference
* @return an XML resource parser that points to the start tag
*/
private XmlResourceParser getParentPrimedParser(int resId) {
XmlResourceParser parser = null;
try {
parser = mContext.getResources().getXml(resId);
int type;
while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
&& type != XmlPullParser.START_TAG) {
}
} catch (Exception e) {
}
return parser;
}
private XmlResourceParser getChildByType(int resId, String xmlType) {
XmlResourceParser parser = null;
try {
parser = mContext.getResources().getXml(resId);
int type;
while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
&& type != XmlPullParser.START_TAG) {
}
while (true) {
if (Objects.equals(parser.getName(), xmlType)) {
break;
}
final int nextEvent = parser.next();
if (nextEvent == XmlPullParser.END_DOCUMENT) {
break;
}
}
} catch (Exception e) {
}
return parser;
}
}

View File

@@ -5,7 +5,6 @@ import static com.google.common.truth.Truth.assertWithMessage;
import android.content.Context;
import android.content.res.XmlResourceParser;
import android.provider.SearchIndexableResource;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Xml;
@@ -156,12 +155,6 @@ public class XmlControllerAttributeTest {
if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
continue;
}
controllerClassName = PreferenceXmlParserUtils.getController(mContext, attrs);
// If controller is not indexed, then it is not compatible with
if (!TextUtils.isEmpty(controllerClassName)) {
xmlControllers.add(controllerClassName);
}
}
return xmlControllers;