Loading src/com/android/settings/slices/SettingsSliceProvider.java +86 −0 Original line number Diff line number Diff line Loading @@ -18,19 +18,26 @@ package com.android.settings.slices; import android.app.PendingIntent; import android.app.slice.SliceManager; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.graphics.drawable.Icon; import android.net.Uri; import android.net.wifi.WifiManager; import android.provider.SettingsSlicesContract; import android.support.annotation.VisibleForTesting; import android.support.v4.graphics.drawable.IconCompat; import android.text.TextUtils; import android.util.Log; import android.util.Pair; import com.android.settings.R; import com.android.settingslib.utils.ThreadUtils; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; import java.util.WeakHashMap; Loading Loading @@ -144,6 +151,85 @@ public class SettingsSliceProvider extends SliceProvider { return SliceBuilderUtils.buildSlice(getContext(), cachedSliceData); } /** * Get a list of all valid Uris based on the keys indexed in the Slices database. * <p> * This will return a list of {@link Uri uris} depending on {@param uri}, following: * 1. Authority & Full Path -> Only {@param uri}. It is only a prefix for itself. * 2. Authority & No path -> A list of authority/action/$KEY$, where * {@code $KEY$} is a list of all Slice-enabled keys for the authority. * 3. Authority & action path -> A list of authority/action/$KEY$, where * {@code $KEY$} is a list of all Slice-enabled keys for the authority. * 4. Empty authority & path -> A list of Uris with all keys for both supported authorities. * 5. Else -> Empty list. * <p> * Note that the authority will stay consistent with {@param uri}, and the list of valid Slice * keys depends on if the authority is {@link SettingsSlicesContract#AUTHORITY} or * {@link #SLICE_AUTHORITY}. * * @param uri The uri to look for descendants under. * @returns all valid Settings uris for which {@param uri} is a prefix. */ @Override public Collection<Uri> onGetSliceDescendants(Uri uri) { final List<Uri> descendants = new ArrayList<>(); final Pair<Boolean, String> pathData = SliceBuilderUtils.getPathData(uri); if (pathData != null) { // Uri has a full path and will not have any descendants. descendants.add(uri); return descendants; } final String authority = uri.getAuthority(); final String pathPrefix = uri.getPath(); final boolean isPathEmpty = pathPrefix.isEmpty(); // No path nor authority. Return all possible Uris. if (isPathEmpty && TextUtils.isEmpty(authority)) { final List<String> platformKeys = mSlicesDatabaseAccessor.getSliceKeys( true /* isPlatformSlice */); final List<String> oemKeys = mSlicesDatabaseAccessor.getSliceKeys( false /* isPlatformSlice */); final List<Uri> allUris = buildUrisFromKeys(platformKeys, SettingsSlicesContract.AUTHORITY); allUris.addAll(buildUrisFromKeys(oemKeys, SettingsSliceProvider.SLICE_AUTHORITY)); return allUris; } // Path is anything but empty, "action", or "intent". Return empty list. if (!isPathEmpty && !TextUtils.equals(pathPrefix, "/" + SettingsSlicesContract.PATH_SETTING_ACTION) && !TextUtils.equals(pathPrefix, "/" + SettingsSlicesContract.PATH_SETTING_INTENT)) { // Invalid path prefix, there are no valid Uri descendants. return descendants; } // Can assume authority belongs to the provider. Return all Uris for the authority. final boolean isPlatformUri = TextUtils.equals(authority, SettingsSlicesContract.AUTHORITY); final List<String> keys = mSlicesDatabaseAccessor.getSliceKeys(isPlatformUri); return buildUrisFromKeys(keys, authority); } private List<Uri> buildUrisFromKeys(List<String> keys, String authority) { final List<Uri> descendants = new ArrayList<>(); final Uri.Builder builder = new Uri.Builder() .scheme(ContentResolver.SCHEME_CONTENT) .authority(authority) .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION); final String newUriPathPrefix = SettingsSlicesContract.PATH_SETTING_ACTION + "/"; for (String key : keys) { builder.path(newUriPathPrefix + key); descendants.add(builder.build()); } return descendants; } @VisibleForTesting void loadSlice(Uri uri) { long startBuildTime = System.currentTimeMillis(); Loading src/com/android/settings/slices/SliceBuilderUtils.java +1 −1 Original line number Diff line number Diff line Loading @@ -130,7 +130,7 @@ public class SliceBuilderUtils { // Example: "/action/wifi" -> [{}, "action", "wifi"] // "/action/longer/path" -> [{}, "action", "longer/path"] if (split.length != 3) { throw new IllegalArgumentException("Uri (" + uri + ") has incomplete path: " + path); return null; } final boolean isInline = TextUtils.equals(SettingsSlicesContract.PATH_SETTING_ACTION, Loading src/com/android/settings/slices/SlicesDatabaseAccessor.java +39 −6 Original line number Diff line number Diff line Loading @@ -29,6 +29,9 @@ import android.util.Pair; import com.android.settings.overlay.FeatureFactory; import com.android.settings.slices.SlicesDatabaseHelper.IndexColumns; import java.util.ArrayList; import java.util.List; import androidx.slice.Slice; /** Loading @@ -51,10 +54,12 @@ public class SlicesDatabaseAccessor { // Cursor value for boolean true private final int TRUE = 1; Context mContext; private final Context mContext; private final SlicesDatabaseHelper mHelper; public SlicesDatabaseAccessor(Context context) { mContext = context; mHelper = SlicesDatabaseHelper.getInstance(mContext); } /** Loading @@ -79,16 +84,44 @@ public class SlicesDatabaseAccessor { return buildSliceData(cursor, null /* uri */, false /* isInlineOnly */); } /** * @return a list of keys in the Slices database matching on {@param isPlatformSlice}. */ public List<String> getSliceKeys(boolean isPlatformSlice) { final String whereClause; if (isPlatformSlice) { whereClause = IndexColumns.PLATFORM_SLICE + " = 1"; } else { whereClause = IndexColumns.PLATFORM_SLICE + " = 0"; } final SQLiteDatabase database = mHelper.getReadableDatabase(); final String[] columns = new String[]{IndexColumns.KEY}; final List<String> keys = new ArrayList<>(); try (final Cursor resultCursor = database.query(TABLE_SLICES_INDEX, columns, whereClause, null /* selection */, null /* groupBy */, null /* having */, null /* orderBy */)) { if (!resultCursor.moveToFirst()) { return keys; } do { keys.add(resultCursor.getString(0 /* key index */)); } while (resultCursor.moveToNext()); } return keys; } private Cursor getIndexedSliceData(String path) { verifyIndexing(); final String whereClause = buildKeyMatchWhereClause(); final SlicesDatabaseHelper helper = SlicesDatabaseHelper.getInstance(mContext); final SQLiteDatabase database = helper.getReadableDatabase(); final SQLiteDatabase database = mHelper.getReadableDatabase(); final String[] selection = new String[]{path}; Cursor resultCursor = database.query(TABLE_SLICES_INDEX, SELECT_COLUMNS_ALL, whereClause, selection, null /* groupBy */, null /* having */, null /* orderBy */); final Cursor resultCursor = database.query(TABLE_SLICES_INDEX, SELECT_COLUMNS_ALL, whereClause, selection, null /* groupBy */, null /* having */, null /* orderBy */); int numResults = resultCursor.getCount(); Loading tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java +188 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,8 @@ package com.android.settings.slices; import static android.content.ContentResolver.SCHEME_CONTENT; import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.spy; Loading @@ -41,6 +43,7 @@ import org.robolectric.RuntimeEnvironment; import androidx.slice.Slice; import java.util.Collection; import java.util.HashMap; /** Loading Loading @@ -114,7 +117,190 @@ public class SettingsSliceProviderTest { assertThat(cachedData).isNull(); } @Test public void getDescendantUris_fullActionUri_returnsSelf() { final Uri uri = SliceBuilderUtils.getUri( SettingsSlicesContract.PATH_SETTING_ACTION + "/key", true); final Collection<Uri> descendants = mProvider.onGetSliceDescendants(uri); assertThat(descendants).containsExactly(uri); } @Test public void getDescendantUris_fullIntentUri_returnsSelf() { final Uri uri = SliceBuilderUtils.getUri( SettingsSlicesContract.PATH_SETTING_ACTION + "/key", true); final Collection<Uri> descendants = mProvider.onGetSliceDescendants(uri); assertThat(descendants).containsExactly(uri); } @Test public void getDescendantUris_wrongPath_returnsEmpty() { final Uri uri = SliceBuilderUtils.getUri("invalid_path", true); final Collection<Uri> descendants = mProvider.onGetSliceDescendants(uri); assertThat(descendants).isEmpty(); } @Test public void getDescendantUris_invalidPath_returnsEmpty() { final String key = "platform_key"; insertSpecialCase(key, true /* isPlatformSlice */); final Uri uri = new Uri.Builder() .scheme(SCHEME_CONTENT) .authority(SettingsSlicesContract.AUTHORITY) .appendPath("invalid") .build(); final Collection<Uri> descendants = mProvider.onGetSliceDescendants(uri); assertThat(descendants).isEmpty(); } @Test public void getDescendantUris_platformSlice_doesNotReturnOEMSlice() { insertSpecialCase("oem_key", false /* isPlatformSlice */); final Uri uri = new Uri.Builder() .scheme(SCHEME_CONTENT) .authority(SettingsSlicesContract.AUTHORITY) .build(); final Collection<Uri> descendants = mProvider.onGetSliceDescendants(uri); assertThat(descendants).isEmpty(); } @Test public void getDescendantUris_oemSlice_doesNotReturnPlatformSlice() { insertSpecialCase("platform_key", true /* isPlatformSlice */); final Uri uri = new Uri.Builder() .scheme(SCHEME_CONTENT) .authority(SettingsSliceProvider.SLICE_AUTHORITY) .build(); final Collection<Uri> descendants = mProvider.onGetSliceDescendants(uri); assertThat(descendants).isEmpty(); } @Test public void getDescendantUris_oemSlice_returnsOEMUriDescendant() { final String key = "oem_key"; insertSpecialCase(key, false /* isPlatformSlice */); final Uri uri = new Uri.Builder() .scheme(SCHEME_CONTENT) .authority(SettingsSliceProvider.SLICE_AUTHORITY) .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION) .build(); final Uri expectedUri = new Uri.Builder() .scheme(SCHEME_CONTENT) .authority(SettingsSliceProvider.SLICE_AUTHORITY) .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION) .appendPath(key) .build(); final Collection<Uri> descendants = mProvider.onGetSliceDescendants(uri); assertThat(descendants).containsExactly(expectedUri); } @Test public void getDescendantUris_oemSliceNoPath_returnsOEMUriDescendant() { final String key = "oem_key"; insertSpecialCase(key, false /* isPlatformSlice */); final Uri uri = new Uri.Builder() .scheme(SCHEME_CONTENT) .authority(SettingsSliceProvider.SLICE_AUTHORITY) .build(); final Uri expectedUri = new Uri.Builder() .scheme(SCHEME_CONTENT) .authority(SettingsSliceProvider.SLICE_AUTHORITY) .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION) .appendPath(key) .build(); final Collection<Uri> descendants = mProvider.onGetSliceDescendants(uri); assertThat(descendants).containsExactly(expectedUri); } @Test public void getDescendantUris_platformSlice_returnsPlatformUriDescendant() { final String key = "platform_key"; insertSpecialCase(key, true /* isPlatformSlice */); final Uri uri = new Uri.Builder() .scheme(SCHEME_CONTENT) .authority(SettingsSlicesContract.AUTHORITY) .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION) .build(); final Uri expectedUri = new Uri.Builder() .scheme(SCHEME_CONTENT) .authority(SettingsSlicesContract.AUTHORITY) .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION) .appendPath(key) .build(); final Collection<Uri> descendants = mProvider.onGetSliceDescendants(uri); assertThat(descendants).containsExactly(expectedUri); } @Test public void getDescendantUris_platformSliceNoPath_returnsPlatformUriDescendant() { final String key = "platform_key"; insertSpecialCase(key, true /* isPlatformSlice */); final Uri uri = new Uri.Builder() .scheme(SCHEME_CONTENT) .authority(SettingsSlicesContract.AUTHORITY) .build(); final Uri expectedUri = new Uri.Builder() .scheme(SCHEME_CONTENT) .authority(SettingsSlicesContract.AUTHORITY) .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION) .appendPath(key) .build(); final Collection<Uri> descendants = mProvider.onGetSliceDescendants(uri); assertThat(descendants).containsExactly(expectedUri); } @Test public void getDescendantUris_noAuthorityNorPath_returnsAllUris() { final String platformKey = "platform_key"; final String oemKey = "oemKey"; insertSpecialCase(platformKey, true /* isPlatformSlice */); insertSpecialCase(oemKey, false /* isPlatformSlice */); final Uri uri = new Uri.Builder() .scheme(SCHEME_CONTENT) .build(); final Uri expectedPlatformUri = new Uri.Builder() .scheme(SCHEME_CONTENT) .authority(SettingsSlicesContract.AUTHORITY) .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION) .appendPath(platformKey) .build(); final Uri expectedOemUri = new Uri.Builder() .scheme(SCHEME_CONTENT) .authority(SettingsSliceProvider.SLICE_AUTHORITY) .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION) .appendPath(oemKey) .build(); final Collection<Uri> descendants = mProvider.onGetSliceDescendants(uri); assertThat(descendants).containsExactly(expectedPlatformUri, expectedOemUri); } private void insertSpecialCase(String key) { insertSpecialCase(key, true); } private void insertSpecialCase(String key, boolean isPlatformSlice) { ContentValues values = new ContentValues(); values.put(SlicesDatabaseHelper.IndexColumns.KEY, key); values.put(SlicesDatabaseHelper.IndexColumns.TITLE, TITLE); Loading @@ -123,6 +309,8 @@ public class SettingsSliceProviderTest { values.put(SlicesDatabaseHelper.IndexColumns.ICON_RESOURCE, 1234); values.put(SlicesDatabaseHelper.IndexColumns.FRAGMENT, "test"); values.put(SlicesDatabaseHelper.IndexColumns.CONTROLLER, "test"); values.put(SlicesDatabaseHelper.IndexColumns.PLATFORM_SLICE, isPlatformSlice); values.put(SlicesDatabaseHelper.IndexColumns.SLICE_TYPE, SliceData.SliceType.INTENT); mDb.replaceOrThrow(SlicesDatabaseHelper.Tables.TABLE_SLICES_INDEX, null, values); } Loading tests/robotests/src/com/android/settings/slices/SliceBuilderUtilsTest.java +4 −2 Original line number Diff line number Diff line Loading @@ -295,14 +295,16 @@ public class SliceBuilderUtilsTest { assertThat(pathPair.second).isEqualTo(KEY); } @Test(expected = IllegalArgumentException.class) @Test public void getPathData_noKey_returnsNull() { final Uri uri = new Uri.Builder() .authority(SettingsSliceProvider.SLICE_AUTHORITY) .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION) .build(); SliceBuilderUtils.getPathData(uri); final Pair<Boolean, String> pathPair = SliceBuilderUtils.getPathData(uri); assertThat(pathPair).isNull(); } @Test Loading Loading
src/com/android/settings/slices/SettingsSliceProvider.java +86 −0 Original line number Diff line number Diff line Loading @@ -18,19 +18,26 @@ package com.android.settings.slices; import android.app.PendingIntent; import android.app.slice.SliceManager; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.graphics.drawable.Icon; import android.net.Uri; import android.net.wifi.WifiManager; import android.provider.SettingsSlicesContract; import android.support.annotation.VisibleForTesting; import android.support.v4.graphics.drawable.IconCompat; import android.text.TextUtils; import android.util.Log; import android.util.Pair; import com.android.settings.R; import com.android.settingslib.utils.ThreadUtils; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; import java.util.WeakHashMap; Loading Loading @@ -144,6 +151,85 @@ public class SettingsSliceProvider extends SliceProvider { return SliceBuilderUtils.buildSlice(getContext(), cachedSliceData); } /** * Get a list of all valid Uris based on the keys indexed in the Slices database. * <p> * This will return a list of {@link Uri uris} depending on {@param uri}, following: * 1. Authority & Full Path -> Only {@param uri}. It is only a prefix for itself. * 2. Authority & No path -> A list of authority/action/$KEY$, where * {@code $KEY$} is a list of all Slice-enabled keys for the authority. * 3. Authority & action path -> A list of authority/action/$KEY$, where * {@code $KEY$} is a list of all Slice-enabled keys for the authority. * 4. Empty authority & path -> A list of Uris with all keys for both supported authorities. * 5. Else -> Empty list. * <p> * Note that the authority will stay consistent with {@param uri}, and the list of valid Slice * keys depends on if the authority is {@link SettingsSlicesContract#AUTHORITY} or * {@link #SLICE_AUTHORITY}. * * @param uri The uri to look for descendants under. * @returns all valid Settings uris for which {@param uri} is a prefix. */ @Override public Collection<Uri> onGetSliceDescendants(Uri uri) { final List<Uri> descendants = new ArrayList<>(); final Pair<Boolean, String> pathData = SliceBuilderUtils.getPathData(uri); if (pathData != null) { // Uri has a full path and will not have any descendants. descendants.add(uri); return descendants; } final String authority = uri.getAuthority(); final String pathPrefix = uri.getPath(); final boolean isPathEmpty = pathPrefix.isEmpty(); // No path nor authority. Return all possible Uris. if (isPathEmpty && TextUtils.isEmpty(authority)) { final List<String> platformKeys = mSlicesDatabaseAccessor.getSliceKeys( true /* isPlatformSlice */); final List<String> oemKeys = mSlicesDatabaseAccessor.getSliceKeys( false /* isPlatformSlice */); final List<Uri> allUris = buildUrisFromKeys(platformKeys, SettingsSlicesContract.AUTHORITY); allUris.addAll(buildUrisFromKeys(oemKeys, SettingsSliceProvider.SLICE_AUTHORITY)); return allUris; } // Path is anything but empty, "action", or "intent". Return empty list. if (!isPathEmpty && !TextUtils.equals(pathPrefix, "/" + SettingsSlicesContract.PATH_SETTING_ACTION) && !TextUtils.equals(pathPrefix, "/" + SettingsSlicesContract.PATH_SETTING_INTENT)) { // Invalid path prefix, there are no valid Uri descendants. return descendants; } // Can assume authority belongs to the provider. Return all Uris for the authority. final boolean isPlatformUri = TextUtils.equals(authority, SettingsSlicesContract.AUTHORITY); final List<String> keys = mSlicesDatabaseAccessor.getSliceKeys(isPlatformUri); return buildUrisFromKeys(keys, authority); } private List<Uri> buildUrisFromKeys(List<String> keys, String authority) { final List<Uri> descendants = new ArrayList<>(); final Uri.Builder builder = new Uri.Builder() .scheme(ContentResolver.SCHEME_CONTENT) .authority(authority) .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION); final String newUriPathPrefix = SettingsSlicesContract.PATH_SETTING_ACTION + "/"; for (String key : keys) { builder.path(newUriPathPrefix + key); descendants.add(builder.build()); } return descendants; } @VisibleForTesting void loadSlice(Uri uri) { long startBuildTime = System.currentTimeMillis(); Loading
src/com/android/settings/slices/SliceBuilderUtils.java +1 −1 Original line number Diff line number Diff line Loading @@ -130,7 +130,7 @@ public class SliceBuilderUtils { // Example: "/action/wifi" -> [{}, "action", "wifi"] // "/action/longer/path" -> [{}, "action", "longer/path"] if (split.length != 3) { throw new IllegalArgumentException("Uri (" + uri + ") has incomplete path: " + path); return null; } final boolean isInline = TextUtils.equals(SettingsSlicesContract.PATH_SETTING_ACTION, Loading
src/com/android/settings/slices/SlicesDatabaseAccessor.java +39 −6 Original line number Diff line number Diff line Loading @@ -29,6 +29,9 @@ import android.util.Pair; import com.android.settings.overlay.FeatureFactory; import com.android.settings.slices.SlicesDatabaseHelper.IndexColumns; import java.util.ArrayList; import java.util.List; import androidx.slice.Slice; /** Loading @@ -51,10 +54,12 @@ public class SlicesDatabaseAccessor { // Cursor value for boolean true private final int TRUE = 1; Context mContext; private final Context mContext; private final SlicesDatabaseHelper mHelper; public SlicesDatabaseAccessor(Context context) { mContext = context; mHelper = SlicesDatabaseHelper.getInstance(mContext); } /** Loading @@ -79,16 +84,44 @@ public class SlicesDatabaseAccessor { return buildSliceData(cursor, null /* uri */, false /* isInlineOnly */); } /** * @return a list of keys in the Slices database matching on {@param isPlatformSlice}. */ public List<String> getSliceKeys(boolean isPlatformSlice) { final String whereClause; if (isPlatformSlice) { whereClause = IndexColumns.PLATFORM_SLICE + " = 1"; } else { whereClause = IndexColumns.PLATFORM_SLICE + " = 0"; } final SQLiteDatabase database = mHelper.getReadableDatabase(); final String[] columns = new String[]{IndexColumns.KEY}; final List<String> keys = new ArrayList<>(); try (final Cursor resultCursor = database.query(TABLE_SLICES_INDEX, columns, whereClause, null /* selection */, null /* groupBy */, null /* having */, null /* orderBy */)) { if (!resultCursor.moveToFirst()) { return keys; } do { keys.add(resultCursor.getString(0 /* key index */)); } while (resultCursor.moveToNext()); } return keys; } private Cursor getIndexedSliceData(String path) { verifyIndexing(); final String whereClause = buildKeyMatchWhereClause(); final SlicesDatabaseHelper helper = SlicesDatabaseHelper.getInstance(mContext); final SQLiteDatabase database = helper.getReadableDatabase(); final SQLiteDatabase database = mHelper.getReadableDatabase(); final String[] selection = new String[]{path}; Cursor resultCursor = database.query(TABLE_SLICES_INDEX, SELECT_COLUMNS_ALL, whereClause, selection, null /* groupBy */, null /* having */, null /* orderBy */); final Cursor resultCursor = database.query(TABLE_SLICES_INDEX, SELECT_COLUMNS_ALL, whereClause, selection, null /* groupBy */, null /* having */, null /* orderBy */); int numResults = resultCursor.getCount(); Loading
tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java +188 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,8 @@ package com.android.settings.slices; import static android.content.ContentResolver.SCHEME_CONTENT; import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.spy; Loading @@ -41,6 +43,7 @@ import org.robolectric.RuntimeEnvironment; import androidx.slice.Slice; import java.util.Collection; import java.util.HashMap; /** Loading Loading @@ -114,7 +117,190 @@ public class SettingsSliceProviderTest { assertThat(cachedData).isNull(); } @Test public void getDescendantUris_fullActionUri_returnsSelf() { final Uri uri = SliceBuilderUtils.getUri( SettingsSlicesContract.PATH_SETTING_ACTION + "/key", true); final Collection<Uri> descendants = mProvider.onGetSliceDescendants(uri); assertThat(descendants).containsExactly(uri); } @Test public void getDescendantUris_fullIntentUri_returnsSelf() { final Uri uri = SliceBuilderUtils.getUri( SettingsSlicesContract.PATH_SETTING_ACTION + "/key", true); final Collection<Uri> descendants = mProvider.onGetSliceDescendants(uri); assertThat(descendants).containsExactly(uri); } @Test public void getDescendantUris_wrongPath_returnsEmpty() { final Uri uri = SliceBuilderUtils.getUri("invalid_path", true); final Collection<Uri> descendants = mProvider.onGetSliceDescendants(uri); assertThat(descendants).isEmpty(); } @Test public void getDescendantUris_invalidPath_returnsEmpty() { final String key = "platform_key"; insertSpecialCase(key, true /* isPlatformSlice */); final Uri uri = new Uri.Builder() .scheme(SCHEME_CONTENT) .authority(SettingsSlicesContract.AUTHORITY) .appendPath("invalid") .build(); final Collection<Uri> descendants = mProvider.onGetSliceDescendants(uri); assertThat(descendants).isEmpty(); } @Test public void getDescendantUris_platformSlice_doesNotReturnOEMSlice() { insertSpecialCase("oem_key", false /* isPlatformSlice */); final Uri uri = new Uri.Builder() .scheme(SCHEME_CONTENT) .authority(SettingsSlicesContract.AUTHORITY) .build(); final Collection<Uri> descendants = mProvider.onGetSliceDescendants(uri); assertThat(descendants).isEmpty(); } @Test public void getDescendantUris_oemSlice_doesNotReturnPlatformSlice() { insertSpecialCase("platform_key", true /* isPlatformSlice */); final Uri uri = new Uri.Builder() .scheme(SCHEME_CONTENT) .authority(SettingsSliceProvider.SLICE_AUTHORITY) .build(); final Collection<Uri> descendants = mProvider.onGetSliceDescendants(uri); assertThat(descendants).isEmpty(); } @Test public void getDescendantUris_oemSlice_returnsOEMUriDescendant() { final String key = "oem_key"; insertSpecialCase(key, false /* isPlatformSlice */); final Uri uri = new Uri.Builder() .scheme(SCHEME_CONTENT) .authority(SettingsSliceProvider.SLICE_AUTHORITY) .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION) .build(); final Uri expectedUri = new Uri.Builder() .scheme(SCHEME_CONTENT) .authority(SettingsSliceProvider.SLICE_AUTHORITY) .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION) .appendPath(key) .build(); final Collection<Uri> descendants = mProvider.onGetSliceDescendants(uri); assertThat(descendants).containsExactly(expectedUri); } @Test public void getDescendantUris_oemSliceNoPath_returnsOEMUriDescendant() { final String key = "oem_key"; insertSpecialCase(key, false /* isPlatformSlice */); final Uri uri = new Uri.Builder() .scheme(SCHEME_CONTENT) .authority(SettingsSliceProvider.SLICE_AUTHORITY) .build(); final Uri expectedUri = new Uri.Builder() .scheme(SCHEME_CONTENT) .authority(SettingsSliceProvider.SLICE_AUTHORITY) .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION) .appendPath(key) .build(); final Collection<Uri> descendants = mProvider.onGetSliceDescendants(uri); assertThat(descendants).containsExactly(expectedUri); } @Test public void getDescendantUris_platformSlice_returnsPlatformUriDescendant() { final String key = "platform_key"; insertSpecialCase(key, true /* isPlatformSlice */); final Uri uri = new Uri.Builder() .scheme(SCHEME_CONTENT) .authority(SettingsSlicesContract.AUTHORITY) .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION) .build(); final Uri expectedUri = new Uri.Builder() .scheme(SCHEME_CONTENT) .authority(SettingsSlicesContract.AUTHORITY) .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION) .appendPath(key) .build(); final Collection<Uri> descendants = mProvider.onGetSliceDescendants(uri); assertThat(descendants).containsExactly(expectedUri); } @Test public void getDescendantUris_platformSliceNoPath_returnsPlatformUriDescendant() { final String key = "platform_key"; insertSpecialCase(key, true /* isPlatformSlice */); final Uri uri = new Uri.Builder() .scheme(SCHEME_CONTENT) .authority(SettingsSlicesContract.AUTHORITY) .build(); final Uri expectedUri = new Uri.Builder() .scheme(SCHEME_CONTENT) .authority(SettingsSlicesContract.AUTHORITY) .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION) .appendPath(key) .build(); final Collection<Uri> descendants = mProvider.onGetSliceDescendants(uri); assertThat(descendants).containsExactly(expectedUri); } @Test public void getDescendantUris_noAuthorityNorPath_returnsAllUris() { final String platformKey = "platform_key"; final String oemKey = "oemKey"; insertSpecialCase(platformKey, true /* isPlatformSlice */); insertSpecialCase(oemKey, false /* isPlatformSlice */); final Uri uri = new Uri.Builder() .scheme(SCHEME_CONTENT) .build(); final Uri expectedPlatformUri = new Uri.Builder() .scheme(SCHEME_CONTENT) .authority(SettingsSlicesContract.AUTHORITY) .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION) .appendPath(platformKey) .build(); final Uri expectedOemUri = new Uri.Builder() .scheme(SCHEME_CONTENT) .authority(SettingsSliceProvider.SLICE_AUTHORITY) .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION) .appendPath(oemKey) .build(); final Collection<Uri> descendants = mProvider.onGetSliceDescendants(uri); assertThat(descendants).containsExactly(expectedPlatformUri, expectedOemUri); } private void insertSpecialCase(String key) { insertSpecialCase(key, true); } private void insertSpecialCase(String key, boolean isPlatformSlice) { ContentValues values = new ContentValues(); values.put(SlicesDatabaseHelper.IndexColumns.KEY, key); values.put(SlicesDatabaseHelper.IndexColumns.TITLE, TITLE); Loading @@ -123,6 +309,8 @@ public class SettingsSliceProviderTest { values.put(SlicesDatabaseHelper.IndexColumns.ICON_RESOURCE, 1234); values.put(SlicesDatabaseHelper.IndexColumns.FRAGMENT, "test"); values.put(SlicesDatabaseHelper.IndexColumns.CONTROLLER, "test"); values.put(SlicesDatabaseHelper.IndexColumns.PLATFORM_SLICE, isPlatformSlice); values.put(SlicesDatabaseHelper.IndexColumns.SLICE_TYPE, SliceData.SliceType.INTENT); mDb.replaceOrThrow(SlicesDatabaseHelper.Tables.TABLE_SLICES_INDEX, null, values); } Loading
tests/robotests/src/com/android/settings/slices/SliceBuilderUtilsTest.java +4 −2 Original line number Diff line number Diff line Loading @@ -295,14 +295,16 @@ public class SliceBuilderUtilsTest { assertThat(pathPair.second).isEqualTo(KEY); } @Test(expected = IllegalArgumentException.class) @Test public void getPathData_noKey_returnsNull() { final Uri uri = new Uri.Builder() .authority(SettingsSliceProvider.SLICE_AUTHORITY) .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION) .build(); SliceBuilderUtils.getPathData(uri); final Pair<Boolean, String> pathPair = SliceBuilderUtils.getPathData(uri); assertThat(pathPair).isNull(); } @Test Loading