Index SliceType and Official Platform flag
Extend slices_index.db to include SliceType and platform flag.
This will be used when we generate a list of all available slices
for different authorities & separated intent/action paths.
Bug: 62807132
Test: robotests
Change-Id: I1cce49d077c02ab79153db9bfdfc894dbab5e16a
diff --git a/res/xml/power_usage_summary.xml b/res/xml/power_usage_summary.xml
index ac96151..391ef2c 100644
--- a/res/xml/power_usage_summary.xml
+++ b/res/xml/power_usage_summary.xml
@@ -37,7 +37,8 @@
android:fragment="com.android.settings.fuelgauge.batterysaver.BatterySaverSettings"
android:key="battery_saver_summary"
android:title="@string/battery_saver"
- settings:controller="com.android.settings.fuelgauge.BatterySaverController"/>
+ settings:controller="com.android.settings.fuelgauge.BatterySaverController"
+ settings:platform_slice="true"/>
<Preference
android:fragment="com.android.settings.fuelgauge.SmartBatterySettings"
diff --git a/src/com/android/settings/slices/SliceBuilderUtils.java b/src/com/android/settings/slices/SliceBuilderUtils.java
index a1f27d1..49972a8 100644
--- a/src/com/android/settings/slices/SliceBuilderUtils.java
+++ b/src/com/android/settings/slices/SliceBuilderUtils.java
@@ -26,6 +26,7 @@
import android.net.Uri;
import android.provider.SettingsSlicesContract;
import android.text.TextUtils;
+import android.util.Pair;
import com.android.internal.annotations.VisibleForTesting;
import com.android.settings.R;
@@ -92,6 +93,38 @@
}
/**
+ * Splits the Settings Slice Uri path into its two expected components:
+ * - intent/action
+ * - key
+ * <p>
+ * Examples of valid paths are:
+ * - intent/wifi
+ * - intent/bluetooth
+ * - action/wifi
+ * - action/accessibility/servicename
+ *
+ * @param uri of the Slice. Follows pattern outlined in {@link SettingsSliceProvider}.
+ * @return Pair whose first element {@code true} if the path is prepended with "action", and
+ * second is a key.
+ */
+ public static Pair<Boolean, String> getPathData(Uri uri) {
+ final String path = uri.getPath();
+ final String[] split = path.split("/", 3);
+
+ // Split should be: [{}, SLICE_TYPE, KEY].
+ // Example: "/action/wifi" -> [{}, "action", "wifi"]
+ // "/action/longer/path" -> [{}, "action", "longer/path"]
+ if (split.length != 3) {
+ throw new IllegalArgumentException("Uri (" + uri + ") has incomplete path: " + path);
+ }
+
+ final boolean isInline = TextUtils.equals(SettingsSlicesContract.PATH_SETTING_ACTION,
+ split[1]);
+
+ return new Pair<>(isInline, split[2]);
+ }
+
+ /**
* Looks at the {@link SliceData#preferenceController} from {@param sliceData} and attempts to
* build an {@link AbstractPreferenceController}.
*/
diff --git a/src/com/android/settings/slices/SlicesDatabaseAccessor.java b/src/com/android/settings/slices/SlicesDatabaseAccessor.java
index acd296b..82b3506 100644
--- a/src/com/android/settings/slices/SlicesDatabaseAccessor.java
+++ b/src/com/android/settings/slices/SlicesDatabaseAccessor.java
@@ -24,6 +24,7 @@
import android.content.Context;
import android.os.Binder;
+import android.util.Pair;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.slices.SlicesDatabaseHelper.IndexColumns;
@@ -35,7 +36,7 @@
*/
public class SlicesDatabaseAccessor {
- public static final String[] SELECT_COLUMNS = {
+ public static final String[] SELECT_COLUMNS_ALL = {
IndexColumns.KEY,
IndexColumns.TITLE,
IndexColumns.SUMMARY,
@@ -43,8 +44,13 @@
IndexColumns.ICON_RESOURCE,
IndexColumns.FRAGMENT,
IndexColumns.CONTROLLER,
+ IndexColumns.PLATFORM_SLICE,
+ IndexColumns.SLICE_TYPE,
};
+ // Cursor value for boolean true
+ private final int TRUE = 1;
+
Context mContext;
public SlicesDatabaseAccessor(Context context) {
@@ -58,9 +64,9 @@
* Used when building a {@link Slice}.
*/
public SliceData getSliceDataFromUri(Uri uri) {
- String key = uri.getLastPathSegment();
- Cursor cursor = getIndexedSliceData(key);
- return buildSliceData(cursor, uri);
+ Pair<Boolean, String> pathData = SliceBuilderUtils.getPathData(uri);
+ Cursor cursor = getIndexedSliceData(pathData.second /* key */);
+ return buildSliceData(cursor, uri, pathData.first /* isIntentOnly */);
}
/**
@@ -70,18 +76,18 @@
*/
public SliceData getSliceDataFromKey(String key) {
Cursor cursor = getIndexedSliceData(key);
- return buildSliceData(cursor, null /* uri */);
+ return buildSliceData(cursor, null /* uri */, false /* isInlineOnly */);
}
private Cursor getIndexedSliceData(String path) {
verifyIndexing();
- final String whereClause = buildWhereClause();
+ final String whereClause = buildKeyMatchWhereClause();
final SlicesDatabaseHelper helper = SlicesDatabaseHelper.getInstance(mContext);
final SQLiteDatabase database = helper.getReadableDatabase();
final String[] selection = new String[]{path};
- Cursor resultCursor = database.query(TABLE_SLICES_INDEX, SELECT_COLUMNS, whereClause,
+ Cursor resultCursor = database.query(TABLE_SLICES_INDEX, SELECT_COLUMNS_ALL, whereClause,
selection, null /* groupBy */, null /* having */, null /* orderBy */);
int numResults = resultCursor.getCount();
@@ -99,13 +105,13 @@
return resultCursor;
}
- private String buildWhereClause() {
+ private String buildKeyMatchWhereClause() {
return new StringBuilder(IndexColumns.KEY)
.append(" = ?")
.toString();
}
- private SliceData buildSliceData(Cursor cursor, Uri uri) {
+ private SliceData buildSliceData(Cursor cursor, Uri uri, boolean isInlineOnly) {
final String key = cursor.getString(cursor.getColumnIndex(IndexColumns.KEY));
final String title = cursor.getString(cursor.getColumnIndex(IndexColumns.TITLE));
final String summary = cursor.getString(cursor.getColumnIndex(IndexColumns.SUMMARY));
@@ -116,6 +122,14 @@
cursor.getColumnIndex(IndexColumns.FRAGMENT));
final String controllerClassName = cursor.getString(
cursor.getColumnIndex(IndexColumns.CONTROLLER));
+ final boolean isPlatformDefined = cursor.getInt(
+ cursor.getColumnIndex(IndexColumns.PLATFORM_SLICE)) == TRUE;
+ int sliceType = cursor.getInt(
+ cursor.getColumnIndex(IndexColumns.SLICE_TYPE));
+
+ if (!isInlineOnly) {
+ sliceType = SliceData.SliceType.INTENT;
+ }
return new SliceData.Builder()
.setKey(key)
@@ -126,6 +140,8 @@
.setFragmentName(fragmentClassName)
.setPreferenceControllerClassName(controllerClassName)
.setUri(uri)
+ .setPlatformDefined(isPlatformDefined)
+ .setSliceType(sliceType)
.build();
}
diff --git a/src/com/android/settings/slices/SlicesDatabaseHelper.java b/src/com/android/settings/slices/SlicesDatabaseHelper.java
index 627c62e..4334665 100644
--- a/src/com/android/settings/slices/SlicesDatabaseHelper.java
+++ b/src/com/android/settings/slices/SlicesDatabaseHelper.java
@@ -78,6 +78,16 @@
* {@link com.android.settings.core.BasePreferenceController}.
*/
String CONTROLLER = "controller";
+
+ /**
+ * Boolean flag, {@code true} when the Slice is officially platform-supported.
+ */
+ String PLATFORM_SLICE = "platform_slice";
+
+ /**
+ * {@link SliceData.SliceType} representing the inline type of the result.
+ */
+ String SLICE_TYPE = "slice_type";
}
private static final String CREATE_SLICES_TABLE =
@@ -96,6 +106,10 @@
IndexColumns.FRAGMENT +
", " +
IndexColumns.CONTROLLER +
+ ", " +
+ IndexColumns.PLATFORM_SLICE +
+ ", " +
+ IndexColumns.SLICE_TYPE+
");";
private final Context mContext;
diff --git a/src/com/android/settings/slices/SlicesIndexer.java b/src/com/android/settings/slices/SlicesIndexer.java
index a92388a..d7de7bc 100644
--- a/src/com/android/settings/slices/SlicesIndexer.java
+++ b/src/com/android/settings/slices/SlicesIndexer.java
@@ -108,6 +108,8 @@
values.put(IndexColumns.ICON_RESOURCE, dataRow.getIconResource());
values.put(IndexColumns.FRAGMENT, dataRow.getFragmentClassName());
values.put(IndexColumns.CONTROLLER, dataRow.getPreferenceController());
+ values.put(IndexColumns.PLATFORM_SLICE, dataRow.isPlatformDefined());
+ values.put(IndexColumns.SLICE_TYPE, dataRow.getSliceType());
database.replaceOrThrow(Tables.TABLE_SLICES_INDEX, null /* nullColumnHack */,
values);
diff --git a/tests/robotests/src/com/android/settings/core/PreferenceXmlParserUtilTest.java b/tests/robotests/src/com/android/settings/core/PreferenceXmlParserUtilsTest.java
similarity index 99%
rename from tests/robotests/src/com/android/settings/core/PreferenceXmlParserUtilTest.java
rename to tests/robotests/src/com/android/settings/core/PreferenceXmlParserUtilsTest.java
index 458bc02..c96cebd 100644
--- a/tests/robotests/src/com/android/settings/core/PreferenceXmlParserUtilTest.java
+++ b/tests/robotests/src/com/android/settings/core/PreferenceXmlParserUtilsTest.java
@@ -48,7 +48,7 @@
* with another preference with a matchin replacement attribute.
*/
@RunWith(SettingsRobolectricTestRunner.class)
-public class PreferenceXmlParserUtilTest {
+public class PreferenceXmlParserUtilsTest {
private Context mContext;
diff --git a/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java b/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java
index 8ddd48a..d54d16f 100644
--- a/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java
+++ b/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java
@@ -82,7 +82,7 @@
@Test
public void testInitialSliceReturned_emptySlice() {
- insertSpecialCase(INTENT_PATH);
+ insertSpecialCase(KEY);
Uri uri = SliceBuilderUtils.getUri(INTENT_PATH, false);
Slice slice = mProvider.onBindSlice(uri);
@@ -93,7 +93,7 @@
@Test
public void testLoadSlice_returnsSliceFromAccessor() {
insertSpecialCase(KEY);
- Uri uri = SliceBuilderUtils.getUri(KEY, false);
+ Uri uri = SliceBuilderUtils.getUri(INTENT_PATH, false);
mProvider.loadSlice(uri);
SliceData data = mProvider.mSliceDataCache.get(uri);
diff --git a/tests/robotests/src/com/android/settings/slices/SliceBuilderUtilsTest.java b/tests/robotests/src/com/android/settings/slices/SliceBuilderUtilsTest.java
index 39b381d..869ba48 100644
--- a/tests/robotests/src/com/android/settings/slices/SliceBuilderUtilsTest.java
+++ b/tests/robotests/src/com/android/settings/slices/SliceBuilderUtilsTest.java
@@ -24,6 +24,7 @@
import android.content.Context;
import android.net.Uri;
import android.provider.SettingsSlicesContract;
+import android.util.Pair;
import com.android.settings.R;
import com.android.settings.core.BasePreferenceController;
@@ -188,6 +189,59 @@
assertThat(summary).isEqualTo(data.getScreenTitle());
}
+ @Test
+ public void getPathData_splitsIntentUri() {
+ Uri uri = new Uri.Builder()
+ .authority(SettingsSliceProvider.SLICE_AUTHORITY)
+ .appendPath(SettingsSlicesContract.PATH_SETTING_INTENT)
+ .appendPath(KEY)
+ .build();
+
+ Pair<Boolean, String> pathPair = SliceBuilderUtils.getPathData(uri);
+
+ assertThat(pathPair.first).isFalse();
+ assertThat(pathPair.second).isEqualTo(KEY);
+ }
+
+ @Test
+ public void getPathData_splitsActionUri() {
+ Uri uri = new Uri.Builder()
+ .authority(SettingsSliceProvider.SLICE_AUTHORITY)
+ .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
+ .appendPath(KEY)
+ .build();
+
+ Pair<Boolean, String> pathPair = SliceBuilderUtils.getPathData(uri);
+
+ assertThat(pathPair.first).isTrue();
+ assertThat(pathPair.second).isEqualTo(KEY);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void getPathData_noKey_returnsNull() {
+ Uri uri = new Uri.Builder()
+ .authority(SettingsSliceProvider.SLICE_AUTHORITY)
+ .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
+ .build();
+
+ SliceBuilderUtils.getPathData(uri);
+ }
+
+ @Test
+ public void getPathData_extraArg_returnsNull() {
+ Uri uri = new Uri.Builder()
+ .authority(SettingsSliceProvider.SLICE_AUTHORITY)
+ .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
+ .appendPath(KEY)
+ .appendPath(KEY)
+ .build();
+
+ Pair<Boolean, String> pathPair = SliceBuilderUtils.getPathData(uri);
+
+ assertThat(pathPair.first).isTrue();
+ assertThat(pathPair.second).isEqualTo(KEY + "/" + KEY);
+ }
+
private SliceData getDummyData() {
return getDummyData(PREF_CONTROLLER, SUMMARY);
}
diff --git a/tests/robotests/src/com/android/settings/slices/SlicesDatabaseAccessorTest.java b/tests/robotests/src/com/android/settings/slices/SlicesDatabaseAccessorTest.java
index 331058c..77c9891 100644
--- a/tests/robotests/src/com/android/settings/slices/SlicesDatabaseAccessorTest.java
+++ b/tests/robotests/src/com/android/settings/slices/SlicesDatabaseAccessorTest.java
@@ -89,8 +89,9 @@
@Test
public void testGetSliceFromUri_validUri_validSliceReturned() {
String key = "key";
+ String path = "intent/" + key;
insertSpecialCase(key);
- Uri uri = SliceBuilderUtils.getUri(key, false);
+ Uri uri = SliceBuilderUtils.getUri(path, false);
SliceData data = mAccessor.getSliceDataFromUri(uri);
@@ -106,8 +107,7 @@
@Test(expected = IllegalStateException.class)
public void testGetSliceFromUri_invalidUri_errorThrown() {
- Uri uri = SliceBuilderUtils.getUri("durr", false);
-
+ Uri uri = SliceBuilderUtils.getUri("intent/durr", false);
mAccessor.getSliceDataFromUri(uri);
}
diff --git a/tests/robotests/src/com/android/settings/slices/SlicesDatabaseHelperTest.java b/tests/robotests/src/com/android/settings/slices/SlicesDatabaseHelperTest.java
index 7d1b401..98ab2a1 100644
--- a/tests/robotests/src/com/android/settings/slices/SlicesDatabaseHelperTest.java
+++ b/tests/robotests/src/com/android/settings/slices/SlicesDatabaseHelperTest.java
@@ -68,7 +68,9 @@
IndexColumns.SCREENTITLE,
IndexColumns.ICON_RESOURCE,
IndexColumns.FRAGMENT,
- IndexColumns.CONTROLLER
+ IndexColumns.CONTROLLER,
+ IndexColumns.PLATFORM_SLICE,
+ IndexColumns.SLICE_TYPE,
};
assertThat(columnNames).isEqualTo(expectedNames);
diff --git a/tests/robotests/src/com/android/settings/slices/SlicesIndexerTest.java b/tests/robotests/src/com/android/settings/slices/SlicesIndexerTest.java
index ca198cb..2af9c79 100644
--- a/tests/robotests/src/com/android/settings/slices/SlicesIndexerTest.java
+++ b/tests/robotests/src/com/android/settings/slices/SlicesIndexerTest.java
@@ -50,6 +50,8 @@
private final int ICON = 1234; // I declare a thumb war
private final Uri URI = Uri.parse("content://com.android.settings.slices/test");
private final String PREF_CONTROLLER = "com.android.settings.slices.tester";
+ private final boolean PLATFORM_DEFINED = true;
+ private final int SLICE_TYPE = SliceData.SliceType.SLIDER;
private Context mContext;
@@ -109,10 +111,22 @@
cursor.moveToFirst();
for (int i = 0; i < sliceData.size(); i++) {
- assertThat(cursor.getString(cursor.getColumnIndex(IndexColumns.KEY)))
- .isEqualTo(KEYS[i]);
- assertThat(cursor.getString(cursor.getColumnIndex(IndexColumns.TITLE)))
- .isEqualTo(TITLES[i]);
+ assertThat(cursor.getString(cursor.getColumnIndex(IndexColumns.KEY))).isEqualTo(
+ KEYS[i]);
+ assertThat(cursor.getString(cursor.getColumnIndex(IndexColumns.TITLE))).isEqualTo(
+ TITLES[i]);
+ assertThat(cursor.getString(cursor.getColumnIndex(IndexColumns.FRAGMENT))).isEqualTo(
+ FRAGMENT_NAME);
+ assertThat(cursor.getString(cursor.getColumnIndex(IndexColumns.SCREENTITLE))).isEqualTo(
+ SCREEN_TITLE);
+ assertThat(cursor.getInt(cursor.getColumnIndex(IndexColumns.ICON_RESOURCE))).isEqualTo(
+ ICON);
+ assertThat(cursor.getString(cursor.getColumnIndex(IndexColumns.CONTROLLER))).isEqualTo(
+ PREF_CONTROLLER);
+ assertThat(cursor.getInt(cursor.getColumnIndex(IndexColumns.PLATFORM_SLICE))).isEqualTo(
+ 1 /* true */);
+ assertThat(cursor.getInt(cursor.getColumnIndex(IndexColumns.SLICE_TYPE))).isEqualTo(
+ SLICE_TYPE);
cursor.moveToNext();
}
}
@@ -126,15 +140,17 @@
}
private List<SliceData> getDummyIndexableData() {
- final SliceData.Builder builder = new SliceData.Builder()
- .setSummary(SUMMARY)
- .setScreenTitle(SCREEN_TITLE)
- .setFragmentName(FRAGMENT_NAME)
- .setIcon(ICON)
- .setUri(URI)
- .setPreferenceControllerClassName(PREF_CONTROLLER);
-
final List<SliceData> sliceData = new ArrayList<>();
+ final SliceData.Builder builder = new SliceData.Builder()
+ .setSummary(SUMMARY)
+ .setScreenTitle(SCREEN_TITLE)
+ .setFragmentName(FRAGMENT_NAME)
+ .setIcon(ICON)
+ .setUri(URI)
+ .setPreferenceControllerClassName(PREF_CONTROLLER)
+ .setPlatformDefined(PLATFORM_DEFINED)
+ .setSliceType(SLICE_TYPE);
+
for (int i = 0; i < KEYS.length; i++) {
builder.setKey(KEYS[i]).setTitle(TITLES[i]);
sliceData.add(builder.build());