Merge "Index SliceType and Official Platform flag" into pi-dev am: f663d78436

am: 467b47be5f

Change-Id: I34e60b72206616d4c569869ac8416972aa30c5ce
This commit is contained in:
Matthew Fritze
2018-03-21 04:33:12 +00:00
committed by android-build-merger
11 changed files with 167 additions and 29 deletions

View File

@@ -37,7 +37,8 @@
android:fragment="com.android.settings.fuelgauge.batterysaver.BatterySaverSettings" android:fragment="com.android.settings.fuelgauge.batterysaver.BatterySaverSettings"
android:key="battery_saver_summary" android:key="battery_saver_summary"
android:title="@string/battery_saver" android:title="@string/battery_saver"
settings:controller="com.android.settings.fuelgauge.BatterySaverController"/> settings:controller="com.android.settings.fuelgauge.BatterySaverController"
settings:platform_slice="true"/>
<Preference <Preference
android:fragment="com.android.settings.fuelgauge.SmartBatterySettings" android:fragment="com.android.settings.fuelgauge.SmartBatterySettings"

View File

@@ -26,6 +26,7 @@ import android.graphics.drawable.Icon;
import android.net.Uri; import android.net.Uri;
import android.provider.SettingsSlicesContract; import android.provider.SettingsSlicesContract;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Pair;
import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting;
import com.android.settings.R; import com.android.settings.R;
@@ -91,6 +92,38 @@ public class SliceBuilderUtils {
return controller.getSliceType(); return controller.getSliceType();
} }
/**
* 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 * Looks at the {@link SliceData#preferenceController} from {@param sliceData} and attempts to
* build an {@link AbstractPreferenceController}. * build an {@link AbstractPreferenceController}.

View File

@@ -24,6 +24,7 @@ import android.net.Uri;
import android.content.Context; import android.content.Context;
import android.os.Binder; import android.os.Binder;
import android.util.Pair;
import com.android.settings.overlay.FeatureFactory; import com.android.settings.overlay.FeatureFactory;
import com.android.settings.slices.SlicesDatabaseHelper.IndexColumns; import com.android.settings.slices.SlicesDatabaseHelper.IndexColumns;
@@ -35,7 +36,7 @@ import androidx.slice.Slice;
*/ */
public class SlicesDatabaseAccessor { public class SlicesDatabaseAccessor {
public static final String[] SELECT_COLUMNS = { public static final String[] SELECT_COLUMNS_ALL = {
IndexColumns.KEY, IndexColumns.KEY,
IndexColumns.TITLE, IndexColumns.TITLE,
IndexColumns.SUMMARY, IndexColumns.SUMMARY,
@@ -43,8 +44,13 @@ public class SlicesDatabaseAccessor {
IndexColumns.ICON_RESOURCE, IndexColumns.ICON_RESOURCE,
IndexColumns.FRAGMENT, IndexColumns.FRAGMENT,
IndexColumns.CONTROLLER, IndexColumns.CONTROLLER,
IndexColumns.PLATFORM_SLICE,
IndexColumns.SLICE_TYPE,
}; };
// Cursor value for boolean true
private final int TRUE = 1;
Context mContext; Context mContext;
public SlicesDatabaseAccessor(Context context) { public SlicesDatabaseAccessor(Context context) {
@@ -58,9 +64,9 @@ public class SlicesDatabaseAccessor {
* Used when building a {@link Slice}. * Used when building a {@link Slice}.
*/ */
public SliceData getSliceDataFromUri(Uri uri) { public SliceData getSliceDataFromUri(Uri uri) {
String key = uri.getLastPathSegment(); Pair<Boolean, String> pathData = SliceBuilderUtils.getPathData(uri);
Cursor cursor = getIndexedSliceData(key); Cursor cursor = getIndexedSliceData(pathData.second /* key */);
return buildSliceData(cursor, uri); return buildSliceData(cursor, uri, pathData.first /* isIntentOnly */);
} }
/** /**
@@ -70,18 +76,18 @@ public class SlicesDatabaseAccessor {
*/ */
public SliceData getSliceDataFromKey(String key) { public SliceData getSliceDataFromKey(String key) {
Cursor cursor = getIndexedSliceData(key); Cursor cursor = getIndexedSliceData(key);
return buildSliceData(cursor, null /* uri */); return buildSliceData(cursor, null /* uri */, false /* isInlineOnly */);
} }
private Cursor getIndexedSliceData(String path) { private Cursor getIndexedSliceData(String path) {
verifyIndexing(); verifyIndexing();
final String whereClause = buildWhereClause(); final String whereClause = buildKeyMatchWhereClause();
final SlicesDatabaseHelper helper = SlicesDatabaseHelper.getInstance(mContext); final SlicesDatabaseHelper helper = SlicesDatabaseHelper.getInstance(mContext);
final SQLiteDatabase database = helper.getReadableDatabase(); final SQLiteDatabase database = helper.getReadableDatabase();
final String[] selection = new String[]{path}; 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 */); selection, null /* groupBy */, null /* having */, null /* orderBy */);
int numResults = resultCursor.getCount(); int numResults = resultCursor.getCount();
@@ -99,13 +105,13 @@ public class SlicesDatabaseAccessor {
return resultCursor; return resultCursor;
} }
private String buildWhereClause() { private String buildKeyMatchWhereClause() {
return new StringBuilder(IndexColumns.KEY) return new StringBuilder(IndexColumns.KEY)
.append(" = ?") .append(" = ?")
.toString(); .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 key = cursor.getString(cursor.getColumnIndex(IndexColumns.KEY));
final String title = cursor.getString(cursor.getColumnIndex(IndexColumns.TITLE)); final String title = cursor.getString(cursor.getColumnIndex(IndexColumns.TITLE));
final String summary = cursor.getString(cursor.getColumnIndex(IndexColumns.SUMMARY)); final String summary = cursor.getString(cursor.getColumnIndex(IndexColumns.SUMMARY));
@@ -116,6 +122,14 @@ public class SlicesDatabaseAccessor {
cursor.getColumnIndex(IndexColumns.FRAGMENT)); cursor.getColumnIndex(IndexColumns.FRAGMENT));
final String controllerClassName = cursor.getString( final String controllerClassName = cursor.getString(
cursor.getColumnIndex(IndexColumns.CONTROLLER)); 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() return new SliceData.Builder()
.setKey(key) .setKey(key)
@@ -126,6 +140,8 @@ public class SlicesDatabaseAccessor {
.setFragmentName(fragmentClassName) .setFragmentName(fragmentClassName)
.setPreferenceControllerClassName(controllerClassName) .setPreferenceControllerClassName(controllerClassName)
.setUri(uri) .setUri(uri)
.setPlatformDefined(isPlatformDefined)
.setSliceType(sliceType)
.build(); .build();
} }

View File

@@ -78,6 +78,16 @@ public class SlicesDatabaseHelper extends SQLiteOpenHelper {
* {@link com.android.settings.core.BasePreferenceController}. * {@link com.android.settings.core.BasePreferenceController}.
*/ */
String CONTROLLER = "controller"; 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 = private static final String CREATE_SLICES_TABLE =
@@ -96,6 +106,10 @@ public class SlicesDatabaseHelper extends SQLiteOpenHelper {
IndexColumns.FRAGMENT + IndexColumns.FRAGMENT +
", " + ", " +
IndexColumns.CONTROLLER + IndexColumns.CONTROLLER +
", " +
IndexColumns.PLATFORM_SLICE +
", " +
IndexColumns.SLICE_TYPE+
");"; ");";
private final Context mContext; private final Context mContext;

View File

@@ -108,6 +108,8 @@ class SlicesIndexer implements Runnable {
values.put(IndexColumns.ICON_RESOURCE, dataRow.getIconResource()); values.put(IndexColumns.ICON_RESOURCE, dataRow.getIconResource());
values.put(IndexColumns.FRAGMENT, dataRow.getFragmentClassName()); values.put(IndexColumns.FRAGMENT, dataRow.getFragmentClassName());
values.put(IndexColumns.CONTROLLER, dataRow.getPreferenceController()); 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 */, database.replaceOrThrow(Tables.TABLE_SLICES_INDEX, null /* nullColumnHack */,
values); values);

View File

@@ -48,7 +48,7 @@ import java.util.List;
* with another preference with a matchin replacement attribute. * with another preference with a matchin replacement attribute.
*/ */
@RunWith(SettingsRobolectricTestRunner.class) @RunWith(SettingsRobolectricTestRunner.class)
public class PreferenceXmlParserUtilTest { public class PreferenceXmlParserUtilsTest {
private Context mContext; private Context mContext;

View File

@@ -82,7 +82,7 @@ public class SettingsSliceProviderTest {
@Test @Test
public void testInitialSliceReturned_emptySlice() { public void testInitialSliceReturned_emptySlice() {
insertSpecialCase(INTENT_PATH); insertSpecialCase(KEY);
Uri uri = SliceBuilderUtils.getUri(INTENT_PATH, false); Uri uri = SliceBuilderUtils.getUri(INTENT_PATH, false);
Slice slice = mProvider.onBindSlice(uri); Slice slice = mProvider.onBindSlice(uri);
@@ -93,7 +93,7 @@ public class SettingsSliceProviderTest {
@Test @Test
public void testLoadSlice_returnsSliceFromAccessor() { public void testLoadSlice_returnsSliceFromAccessor() {
insertSpecialCase(KEY); insertSpecialCase(KEY);
Uri uri = SliceBuilderUtils.getUri(KEY, false); Uri uri = SliceBuilderUtils.getUri(INTENT_PATH, false);
mProvider.loadSlice(uri); mProvider.loadSlice(uri);
SliceData data = mProvider.mSliceDataCache.get(uri); SliceData data = mProvider.mSliceDataCache.get(uri);

View File

@@ -24,6 +24,7 @@ import android.content.ContentResolver;
import android.content.Context; import android.content.Context;
import android.net.Uri; import android.net.Uri;
import android.provider.SettingsSlicesContract; import android.provider.SettingsSlicesContract;
import android.util.Pair;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.core.BasePreferenceController; import com.android.settings.core.BasePreferenceController;
@@ -188,6 +189,59 @@ public class SliceBuilderUtilsTest {
assertThat(summary).isEqualTo(data.getScreenTitle()); 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() { private SliceData getDummyData() {
return getDummyData(PREF_CONTROLLER, SUMMARY); return getDummyData(PREF_CONTROLLER, SUMMARY);
} }

View File

@@ -89,8 +89,9 @@ public class SlicesDatabaseAccessorTest {
@Test @Test
public void testGetSliceFromUri_validUri_validSliceReturned() { public void testGetSliceFromUri_validUri_validSliceReturned() {
String key = "key"; String key = "key";
String path = "intent/" + key;
insertSpecialCase(key); insertSpecialCase(key);
Uri uri = SliceBuilderUtils.getUri(key, false); Uri uri = SliceBuilderUtils.getUri(path, false);
SliceData data = mAccessor.getSliceDataFromUri(uri); SliceData data = mAccessor.getSliceDataFromUri(uri);
@@ -106,8 +107,7 @@ public class SlicesDatabaseAccessorTest {
@Test(expected = IllegalStateException.class) @Test(expected = IllegalStateException.class)
public void testGetSliceFromUri_invalidUri_errorThrown() { public void testGetSliceFromUri_invalidUri_errorThrown() {
Uri uri = SliceBuilderUtils.getUri("durr", false); Uri uri = SliceBuilderUtils.getUri("intent/durr", false);
mAccessor.getSliceDataFromUri(uri); mAccessor.getSliceDataFromUri(uri);
} }

View File

@@ -68,7 +68,9 @@ public class SlicesDatabaseHelperTest {
IndexColumns.SCREENTITLE, IndexColumns.SCREENTITLE,
IndexColumns.ICON_RESOURCE, IndexColumns.ICON_RESOURCE,
IndexColumns.FRAGMENT, IndexColumns.FRAGMENT,
IndexColumns.CONTROLLER IndexColumns.CONTROLLER,
IndexColumns.PLATFORM_SLICE,
IndexColumns.SLICE_TYPE,
}; };
assertThat(columnNames).isEqualTo(expectedNames); assertThat(columnNames).isEqualTo(expectedNames);

View File

@@ -50,6 +50,8 @@ public class SlicesIndexerTest {
private final int ICON = 1234; // I declare a thumb war private final int ICON = 1234; // I declare a thumb war
private final Uri URI = Uri.parse("content://com.android.settings.slices/test"); private final Uri URI = Uri.parse("content://com.android.settings.slices/test");
private final String PREF_CONTROLLER = "com.android.settings.slices.tester"; 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; private Context mContext;
@@ -109,10 +111,22 @@ public class SlicesIndexerTest {
cursor.moveToFirst(); cursor.moveToFirst();
for (int i = 0; i < sliceData.size(); i++) { for (int i = 0; i < sliceData.size(); i++) {
assertThat(cursor.getString(cursor.getColumnIndex(IndexColumns.KEY))) assertThat(cursor.getString(cursor.getColumnIndex(IndexColumns.KEY))).isEqualTo(
.isEqualTo(KEYS[i]); KEYS[i]);
assertThat(cursor.getString(cursor.getColumnIndex(IndexColumns.TITLE))) assertThat(cursor.getString(cursor.getColumnIndex(IndexColumns.TITLE))).isEqualTo(
.isEqualTo(TITLES[i]); 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(); cursor.moveToNext();
} }
} }
@@ -126,15 +140,17 @@ public class SlicesIndexerTest {
} }
private List<SliceData> getDummyIndexableData() { private List<SliceData> getDummyIndexableData() {
final List<SliceData> sliceData = new ArrayList<>();
final SliceData.Builder builder = new SliceData.Builder() final SliceData.Builder builder = new SliceData.Builder()
.setSummary(SUMMARY) .setSummary(SUMMARY)
.setScreenTitle(SCREEN_TITLE) .setScreenTitle(SCREEN_TITLE)
.setFragmentName(FRAGMENT_NAME) .setFragmentName(FRAGMENT_NAME)
.setIcon(ICON) .setIcon(ICON)
.setUri(URI) .setUri(URI)
.setPreferenceControllerClassName(PREF_CONTROLLER); .setPreferenceControllerClassName(PREF_CONTROLLER)
.setPlatformDefined(PLATFORM_DEFINED)
.setSliceType(SLICE_TYPE);
final List<SliceData> sliceData = new ArrayList<>();
for (int i = 0; i < KEYS.length; i++) { for (int i = 0; i < KEYS.length; i++) {
builder.setKey(KEYS[i]).setTitle(TITLES[i]); builder.setKey(KEYS[i]).setTitle(TITLES[i]);
sliceData.add(builder.build()); sliceData.add(builder.build());