Add the impl for the ability to query non-public Slices
Apps get Settings Slices through onGetSliceDescendants(), so adding some codes here to make us be capable returning non-public Slices. As these SliceData come from slice_index.db, where SliceDatabaseAccessor is the middleman for us to access those data, so adding a parameter in getSliceUris() to determine what data should be returned. Bug: 141088937 Test: robotests Change-Id: I411eb1ff194b7c8915b9e7309c684046dbde29fb
This commit is contained in:
@@ -425,4 +425,7 @@
|
|||||||
<string-array name="config_panel_keep_observe_uri" translatable="false">
|
<string-array name="config_panel_keep_observe_uri" translatable="false">
|
||||||
<item>content://com.android.settings.slices/intent/media_output_indicator</item>
|
<item>content://com.android.settings.slices/intent/media_output_indicator</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
|
||||||
|
<!-- Uri to query non-public Slice Uris. -->
|
||||||
|
<string name="config_non_public_slice_query_uri" translatable="false"></string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@@ -20,10 +20,13 @@ import static android.Manifest.permission.READ_SEARCH_INDEXABLES;
|
|||||||
|
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
import android.app.slice.SliceManager;
|
import android.app.slice.SliceManager;
|
||||||
|
import android.content.ContentResolver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
import android.os.Binder;
|
||||||
import android.os.StrictMode;
|
import android.os.StrictMode;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
import android.provider.SettingsSlicesContract;
|
import android.provider.SettingsSlicesContract;
|
||||||
@@ -265,16 +268,29 @@ public class SettingsSliceProvider extends SliceProvider {
|
|||||||
@Override
|
@Override
|
||||||
public Collection<Uri> onGetSliceDescendants(Uri uri) {
|
public Collection<Uri> onGetSliceDescendants(Uri uri) {
|
||||||
final List<Uri> descendants = new ArrayList<>();
|
final List<Uri> descendants = new ArrayList<>();
|
||||||
final Pair<Boolean, String> pathData = SliceBuilderUtils.getPathData(uri);
|
Uri finalUri = uri;
|
||||||
|
|
||||||
|
if (isPrivateSlicesNeeded(finalUri)) {
|
||||||
|
descendants.addAll(
|
||||||
|
mSlicesDatabaseAccessor.getSliceUris(finalUri.getAuthority(),
|
||||||
|
false /* isPublicSlice */));
|
||||||
|
Log.d(TAG, "provide " + descendants.size() + " non-public slices");
|
||||||
|
finalUri = new Uri.Builder()
|
||||||
|
.scheme(ContentResolver.SCHEME_CONTENT)
|
||||||
|
.authority(finalUri.getAuthority())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
final Pair<Boolean, String> pathData = SliceBuilderUtils.getPathData(finalUri);
|
||||||
|
|
||||||
if (pathData != null) {
|
if (pathData != null) {
|
||||||
// Uri has a full path and will not have any descendants.
|
// Uri has a full path and will not have any descendants.
|
||||||
descendants.add(uri);
|
descendants.add(finalUri);
|
||||||
return descendants;
|
return descendants;
|
||||||
}
|
}
|
||||||
|
|
||||||
final String authority = uri.getAuthority();
|
final String authority = finalUri.getAuthority();
|
||||||
final String path = uri.getPath();
|
final String path = finalUri.getPath();
|
||||||
final boolean isPathEmpty = path.isEmpty();
|
final boolean isPathEmpty = path.isEmpty();
|
||||||
|
|
||||||
// Path is anything but empty, "action", or "intent". Return empty list.
|
// Path is anything but empty, "action", or "intent". Return empty list.
|
||||||
@@ -286,7 +302,7 @@ public class SettingsSliceProvider extends SliceProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add all descendants from db with matching authority.
|
// Add all descendants from db with matching authority.
|
||||||
descendants.addAll(mSlicesDatabaseAccessor.getSliceUris(authority));
|
descendants.addAll(mSlicesDatabaseAccessor.getSliceUris(authority, true /*isPublicSlice*/));
|
||||||
|
|
||||||
if (isPathEmpty && TextUtils.isEmpty(authority)) {
|
if (isPathEmpty && TextUtils.isEmpty(authority)) {
|
||||||
// No path nor authority. Return all possible Uris by adding all special slice uri
|
// No path nor authority. Return all possible Uris by adding all special slice uri
|
||||||
@@ -404,6 +420,24 @@ public class SettingsSliceProvider extends SliceProvider {
|
|||||||
return set;
|
return set;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
boolean isPrivateSlicesNeeded(Uri uri) {
|
||||||
|
final String queryUri = getContext().getString(R.string.config_non_public_slice_query_uri);
|
||||||
|
|
||||||
|
if (!TextUtils.isEmpty(queryUri) && TextUtils.equals(uri.toString(), queryUri)) {
|
||||||
|
// check if the calling package is eligible for private slices
|
||||||
|
final int callingUid = Binder.getCallingUid();
|
||||||
|
final boolean hasPermission = getContext().checkPermission(
|
||||||
|
android.Manifest.permission.READ_SEARCH_INDEXABLES, Binder.getCallingPid(),
|
||||||
|
callingUid) == PackageManager.PERMISSION_GRANTED;
|
||||||
|
final String callingPackage = getContext().getPackageManager()
|
||||||
|
.getPackagesForUid(callingUid)[0];
|
||||||
|
return hasPermission && TextUtils.equals(callingPackage,
|
||||||
|
getContext().getString(R.string.config_settingsintelligence_package_name));
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private void startBackgroundWorker(Sliceable sliceable, Uri uri) {
|
private void startBackgroundWorker(Sliceable sliceable, Uri uri) {
|
||||||
final Class workerClass = sliceable.getBackgroundWorkerClass();
|
final Class workerClass = sliceable.getBackgroundWorkerClass();
|
||||||
if (workerClass == null) {
|
if (workerClass == null) {
|
||||||
|
@@ -88,16 +88,18 @@ public class SlicesDatabaseAccessor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return a list of Slice {@link Uri}s matching {@param authority}.
|
* @return a list of Slice {@link Uri}s based on their visibility {@param isPublicSlice } and
|
||||||
|
* {@param authority}.
|
||||||
*/
|
*/
|
||||||
public List<Uri> getSliceUris(String authority) {
|
public List<Uri> getSliceUris(String authority, boolean isPublicSlice) {
|
||||||
verifyIndexing();
|
verifyIndexing();
|
||||||
final List<Uri> uris = new ArrayList<>();
|
final List<Uri> uris = new ArrayList<>();
|
||||||
|
final String whereClause = IndexColumns.PUBLIC_SLICE + (isPublicSlice ? "=1" : "=0");
|
||||||
final SQLiteDatabase database = mHelper.getReadableDatabase();
|
final SQLiteDatabase database = mHelper.getReadableDatabase();
|
||||||
final String[] columns = new String[]{IndexColumns.SLICE_URI};
|
final String[] columns = new String[]{IndexColumns.SLICE_URI};
|
||||||
try (final Cursor resultCursor = database.query(TABLE_SLICES_INDEX, columns,
|
try (Cursor resultCursor = database.query(TABLE_SLICES_INDEX, columns,
|
||||||
null /* where */, null /* selection */, null /* groupBy */, null /* having */,
|
whereClause /* where */, null /* selection */, null /* groupBy */,
|
||||||
null /* orderBy */)) {
|
null /* having */, null /* orderBy */)) {
|
||||||
if (!resultCursor.moveToFirst()) {
|
if (!resultCursor.moveToFirst()) {
|
||||||
return uris;
|
return uris;
|
||||||
}
|
}
|
||||||
|
@@ -94,4 +94,7 @@
|
|||||||
<item>injected_tile_key</item>
|
<item>injected_tile_key</item>
|
||||||
<item>injected_tile_key2</item>
|
<item>injected_tile_key2</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
|
||||||
|
<!-- Uri to query non-public Slice Uris. -->
|
||||||
|
<string name="config_non_public_slice_query_uri" translatable="false">content://com.android.settings.slices/test</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@@ -18,10 +18,13 @@
|
|||||||
package com.android.settings.slices;
|
package com.android.settings.slices;
|
||||||
|
|
||||||
import static android.content.ContentResolver.SCHEME_CONTENT;
|
import static android.content.ContentResolver.SCHEME_CONTENT;
|
||||||
|
import static android.content.pm.PackageManager.PERMISSION_DENIED;
|
||||||
|
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.ArgumentMatchers.anyInt;
|
||||||
import static org.mockito.ArgumentMatchers.anyString;
|
import static org.mockito.ArgumentMatchers.anyString;
|
||||||
import static org.mockito.ArgumentMatchers.eq;
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
import static org.mockito.Mockito.doReturn;
|
import static org.mockito.Mockito.doReturn;
|
||||||
@@ -66,12 +69,15 @@ import org.mockito.MockitoAnnotations;
|
|||||||
import org.robolectric.Robolectric;
|
import org.robolectric.Robolectric;
|
||||||
import org.robolectric.RobolectricTestRunner;
|
import org.robolectric.RobolectricTestRunner;
|
||||||
import org.robolectric.RuntimeEnvironment;
|
import org.robolectric.RuntimeEnvironment;
|
||||||
|
import org.robolectric.Shadows;
|
||||||
import org.robolectric.annotation.Config;
|
import org.robolectric.annotation.Config;
|
||||||
import org.robolectric.annotation.Implementation;
|
import org.robolectric.annotation.Implementation;
|
||||||
import org.robolectric.annotation.Implements;
|
import org.robolectric.annotation.Implements;
|
||||||
import org.robolectric.annotation.Resetter;
|
import org.robolectric.annotation.Resetter;
|
||||||
import org.robolectric.shadow.api.Shadow;
|
import org.robolectric.shadow.api.Shadow;
|
||||||
import org.robolectric.shadows.ShadowAccessibilityManager;
|
import org.robolectric.shadows.ShadowAccessibilityManager;
|
||||||
|
import org.robolectric.shadows.ShadowBinder;
|
||||||
|
import org.robolectric.shadows.ShadowPackageManager;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@@ -110,6 +116,7 @@ public class SettingsSliceProviderTest {
|
|||||||
|
|
||||||
private Context mContext;
|
private Context mContext;
|
||||||
private SettingsSliceProvider mProvider;
|
private SettingsSliceProvider mProvider;
|
||||||
|
private ShadowPackageManager mPackageManager;
|
||||||
@Mock
|
@Mock
|
||||||
private SliceManager mManager;
|
private SliceManager mManager;
|
||||||
|
|
||||||
@@ -146,6 +153,8 @@ public class SettingsSliceProviderTest {
|
|||||||
doReturn(mManager).when(mContext).getSystemService(SliceManager.class);
|
doReturn(mManager).when(mContext).getSystemService(SliceManager.class);
|
||||||
when(mManager.getPinnedSlices()).thenReturn(Collections.emptyList());
|
when(mManager.getPinnedSlices()).thenReturn(Collections.emptyList());
|
||||||
|
|
||||||
|
mPackageManager = Shadows.shadowOf(mContext.getPackageManager());
|
||||||
|
|
||||||
SliceProvider.setSpecs(SliceLiveData.SUPPORTED_SPECS);
|
SliceProvider.setSpecs(SliceLiveData.SUPPORTED_SPECS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -284,7 +293,8 @@ public class SettingsSliceProviderTest {
|
|||||||
@Test
|
@Test
|
||||||
public void getDescendantUris_invalidPath_returnsEmpty() {
|
public void getDescendantUris_invalidPath_returnsEmpty() {
|
||||||
final String key = "platform_key";
|
final String key = "platform_key";
|
||||||
SliceTestUtils.insertSliceToDb(mContext, key, true /* isPlatformSlice */);
|
SliceTestUtils.insertSliceToDb(mContext, key, true /* isPlatformSlice */,
|
||||||
|
null /* customizedUnavailableSliceSubtitle */, true /* isPublicSlice */);
|
||||||
final Uri uri = new Uri.Builder()
|
final Uri uri = new Uri.Builder()
|
||||||
.scheme(SCHEME_CONTENT)
|
.scheme(SCHEME_CONTENT)
|
||||||
.authority(SettingsSlicesContract.AUTHORITY)
|
.authority(SettingsSlicesContract.AUTHORITY)
|
||||||
@@ -299,7 +309,8 @@ public class SettingsSliceProviderTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getDescendantUris_platformSlice_doesNotReturnOEMSlice() {
|
public void getDescendantUris_platformSlice_doesNotReturnOEMSlice() {
|
||||||
SliceTestUtils.insertSliceToDb(mContext, "oem_key", false /* isPlatformSlice */);
|
SliceTestUtils.insertSliceToDb(mContext, "oem_key", false /* isPlatformSlice */,
|
||||||
|
null /* customizedUnavailableSliceSubtitle */, true /* isPublicSlice */);
|
||||||
final Uri uri = new Uri.Builder()
|
final Uri uri = new Uri.Builder()
|
||||||
.scheme(SCHEME_CONTENT)
|
.scheme(SCHEME_CONTENT)
|
||||||
.authority(SettingsSlicesContract.AUTHORITY)
|
.authority(SettingsSlicesContract.AUTHORITY)
|
||||||
@@ -313,7 +324,8 @@ public class SettingsSliceProviderTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getDescendantUris_oemSlice_doesNotReturnPlatformSlice() {
|
public void getDescendantUris_oemSlice_doesNotReturnPlatformSlice() {
|
||||||
SliceTestUtils.insertSliceToDb(mContext, "platform_key", true /* isPlatformSlice */);
|
SliceTestUtils.insertSliceToDb(mContext, "platform_key", true /* isPlatformSlice */,
|
||||||
|
null /* customizedUnavailableSliceSubtitle */, true /* isPublicSlice */);
|
||||||
final Uri uri = new Uri.Builder()
|
final Uri uri = new Uri.Builder()
|
||||||
.scheme(SCHEME_CONTENT)
|
.scheme(SCHEME_CONTENT)
|
||||||
.authority(SettingsSliceProvider.SLICE_AUTHORITY)
|
.authority(SettingsSliceProvider.SLICE_AUTHORITY)
|
||||||
@@ -328,7 +340,8 @@ public class SettingsSliceProviderTest {
|
|||||||
@Test
|
@Test
|
||||||
public void getDescendantUris_oemSlice_returnsOEMUriDescendant() {
|
public void getDescendantUris_oemSlice_returnsOEMUriDescendant() {
|
||||||
final String key = "oem_key";
|
final String key = "oem_key";
|
||||||
SliceTestUtils.insertSliceToDb(mContext, key, false /* isPlatformSlice */);
|
SliceTestUtils.insertSliceToDb(mContext, key, false /* isPlatformSlice */,
|
||||||
|
null /* customizedUnavailableSliceSubtitle */, true /* isPublicSlice */);
|
||||||
final Uri uri = new Uri.Builder()
|
final Uri uri = new Uri.Builder()
|
||||||
.scheme(SCHEME_CONTENT)
|
.scheme(SCHEME_CONTENT)
|
||||||
.authority(SettingsSliceProvider.SLICE_AUTHORITY)
|
.authority(SettingsSliceProvider.SLICE_AUTHORITY)
|
||||||
@@ -351,7 +364,8 @@ public class SettingsSliceProviderTest {
|
|||||||
@Test
|
@Test
|
||||||
public void getDescendantUris_oemSliceNoPath_returnsOEMUriDescendant() {
|
public void getDescendantUris_oemSliceNoPath_returnsOEMUriDescendant() {
|
||||||
final String key = "oem_key";
|
final String key = "oem_key";
|
||||||
SliceTestUtils.insertSliceToDb(mContext, key, false /* isPlatformSlice */);
|
SliceTestUtils.insertSliceToDb(mContext, key, false /* isPlatformSlice */,
|
||||||
|
null /* customizedUnavailableSliceSubtitle */, true /* isPublicSlice */);
|
||||||
final Uri uri = new Uri.Builder()
|
final Uri uri = new Uri.Builder()
|
||||||
.scheme(SCHEME_CONTENT)
|
.scheme(SCHEME_CONTENT)
|
||||||
.authority(SettingsSliceProvider.SLICE_AUTHORITY)
|
.authority(SettingsSliceProvider.SLICE_AUTHORITY)
|
||||||
@@ -370,10 +384,32 @@ public class SettingsSliceProviderTest {
|
|||||||
assertThat(descendants).containsExactlyElementsIn(expectedUris);
|
assertThat(descendants).containsExactlyElementsIn(expectedUris);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getDescendantUris_oemSliceNoPath_notContainPrivateUri() {
|
||||||
|
final String key = "oem_key";
|
||||||
|
SliceTestUtils.insertSliceToDb(mContext, key, false /* isPlatformSlice */,
|
||||||
|
null /* customizedUnavailableSliceSubtitle */, false /* isPublicSlice */);
|
||||||
|
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).doesNotContain(expectedUri);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getDescendantUris_platformSlice_returnsPlatformUriDescendant() {
|
public void getDescendantUris_platformSlice_returnsPlatformUriDescendant() {
|
||||||
final String key = "platform_key";
|
final String key = "platform_key";
|
||||||
SliceTestUtils.insertSliceToDb(mContext, key, true /* isPlatformSlice */);
|
SliceTestUtils.insertSliceToDb(mContext, key, true /* isPlatformSlice */,
|
||||||
|
null /* customizedUnavailableSliceSubtitle */, true /* isPublicSlice */);
|
||||||
final Uri uri = new Uri.Builder()
|
final Uri uri = new Uri.Builder()
|
||||||
.scheme(SCHEME_CONTENT)
|
.scheme(SCHEME_CONTENT)
|
||||||
.authority(SettingsSlicesContract.AUTHORITY)
|
.authority(SettingsSlicesContract.AUTHORITY)
|
||||||
@@ -396,7 +432,8 @@ public class SettingsSliceProviderTest {
|
|||||||
@Test
|
@Test
|
||||||
public void getDescendantUris_platformSliceNoPath_returnsPlatformUriDescendant() {
|
public void getDescendantUris_platformSliceNoPath_returnsPlatformUriDescendant() {
|
||||||
final String key = "platform_key";
|
final String key = "platform_key";
|
||||||
SliceTestUtils.insertSliceToDb(mContext, key, true /* isPlatformSlice */);
|
SliceTestUtils.insertSliceToDb(mContext, key, true /* isPlatformSlice */,
|
||||||
|
null /* customizedUnavailableSliceSubtitle */, true /* isPublicSlice */);
|
||||||
final Uri uri = new Uri.Builder()
|
final Uri uri = new Uri.Builder()
|
||||||
.scheme(SCHEME_CONTENT)
|
.scheme(SCHEME_CONTENT)
|
||||||
.authority(SettingsSlicesContract.AUTHORITY)
|
.authority(SettingsSlicesContract.AUTHORITY)
|
||||||
@@ -419,8 +456,10 @@ public class SettingsSliceProviderTest {
|
|||||||
public void getDescendantUris_noAuthorityNorPath_returnsAllUris() {
|
public void getDescendantUris_noAuthorityNorPath_returnsAllUris() {
|
||||||
final String platformKey = "platform_key";
|
final String platformKey = "platform_key";
|
||||||
final String oemKey = "oemKey";
|
final String oemKey = "oemKey";
|
||||||
SliceTestUtils.insertSliceToDb(mContext, platformKey, true /* isPlatformSlice */);
|
SliceTestUtils.insertSliceToDb(mContext, platformKey, true /* isPlatformSlice */,
|
||||||
SliceTestUtils.insertSliceToDb(mContext, oemKey, false /* isPlatformSlice */);
|
null /* customizedUnavailableSliceSubtitle */, true /* isPublicSlice */);
|
||||||
|
SliceTestUtils.insertSliceToDb(mContext, oemKey, false /* isPlatformSlice */,
|
||||||
|
null /* customizedUnavailableSliceSubtitle */, true /* isPublicSlice */);
|
||||||
final Uri uri = new Uri.Builder()
|
final Uri uri = new Uri.Builder()
|
||||||
.scheme(SCHEME_CONTENT)
|
.scheme(SCHEME_CONTENT)
|
||||||
.build();
|
.build();
|
||||||
@@ -445,6 +484,48 @@ public class SettingsSliceProviderTest {
|
|||||||
assertThat(descendants).containsExactlyElementsIn(expectedUris);
|
assertThat(descendants).containsExactlyElementsIn(expectedUris);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Config(qualifiers = "mcc999")
|
||||||
|
public void getDescendantUris_privateSlicesNeeded_containsPrivateSliceUri() {
|
||||||
|
final String privateKey = "test_private";
|
||||||
|
final Uri specialUri = Uri.parse("content://com.android.settings.slices/test");
|
||||||
|
doReturn(true).when(mProvider).isPrivateSlicesNeeded(specialUri);
|
||||||
|
SliceTestUtils.insertSliceToDb(mContext, privateKey /* key */, false /* isPlatformSlice */,
|
||||||
|
null /* customizedUnavailableSliceSubtitle */, false /* isPublicSlice */);
|
||||||
|
final Collection<Uri> expectedUris = new HashSet<>();
|
||||||
|
expectedUris.addAll(SPECIAL_CASE_OEM_URIS);
|
||||||
|
expectedUris.add(new Uri.Builder()
|
||||||
|
.scheme(SCHEME_CONTENT)
|
||||||
|
.authority(SettingsSliceProvider.SLICE_AUTHORITY)
|
||||||
|
.appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
|
||||||
|
.appendPath(privateKey)
|
||||||
|
.build());
|
||||||
|
|
||||||
|
final Collection<Uri> descendants = mProvider.onGetSliceDescendants(specialUri);
|
||||||
|
|
||||||
|
assertThat(descendants).containsExactlyElementsIn(expectedUris);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Config(qualifiers = "mcc999")
|
||||||
|
public void getDescendantUris_privateSlicesNotNeeded_notContainPrivateSliceUri() {
|
||||||
|
final Uri specialUri = Uri.parse("content://com.android.settings.slices/test");
|
||||||
|
doReturn(false).when(mProvider).isPrivateSlicesNeeded(specialUri);
|
||||||
|
SliceTestUtils.insertSliceToDb(mContext,
|
||||||
|
"test_private" /* key */, false /* isPlatformSlice */,
|
||||||
|
null /* customizedUnavailableSliceSubtitle */, false /* isPublicSlice */);
|
||||||
|
final Uri expectedUri = new Uri.Builder()
|
||||||
|
.scheme(SCHEME_CONTENT)
|
||||||
|
.authority(SettingsSliceProvider.SLICE_AUTHORITY)
|
||||||
|
.appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
|
||||||
|
.appendPath("test_private")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
final Collection<Uri> descendants = mProvider.onGetSliceDescendants(specialUri);
|
||||||
|
|
||||||
|
assertThat(descendants).doesNotContain(expectedUri);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void onCreatePermissionRequest_returnsSettingIntent() {
|
public void onCreatePermissionRequest_returnsSettingIntent() {
|
||||||
final PendingIntent pendingIntent = mProvider.onCreatePermissionRequest(
|
final PendingIntent pendingIntent = mProvider.onCreatePermissionRequest(
|
||||||
@@ -531,6 +612,56 @@ public class SettingsSliceProviderTest {
|
|||||||
.grantSlicePermission("com.android.settings.slice_whitelist_package", uris.get(0));
|
.grantSlicePermission("com.android.settings.slice_whitelist_package", uris.get(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Config(qualifiers = "mcc999")
|
||||||
|
public void isPrivateSlicesNeeded_incorrectUri_returnFalse() {
|
||||||
|
final Uri uri = Uri.parse("content://com.android.settings.slices/test123");
|
||||||
|
|
||||||
|
assertThat(mProvider.isPrivateSlicesNeeded(uri)).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void isPrivateSlicesNeeded_noUri_returnFalse() {
|
||||||
|
final Uri uri = Uri.parse("content://com.android.settings.slices/test");
|
||||||
|
|
||||||
|
assertThat(mProvider.isPrivateSlicesNeeded(uri)).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Config(qualifiers = "mcc999")
|
||||||
|
public void isPrivateSlicesNeeded_correctUriWithPermissionAndIsSI_returnTrue() {
|
||||||
|
final Uri uri = Uri.parse("content://com.android.settings.slices/test");
|
||||||
|
ShadowBinder.setCallingUid(123);
|
||||||
|
doReturn(PERMISSION_GRANTED)
|
||||||
|
.when(mContext).checkPermission(anyString(), anyInt(), anyInt());
|
||||||
|
mPackageManager.setPackagesForUid(123, new String[]{"com.android.settings.intelligence"});
|
||||||
|
|
||||||
|
assertThat(mProvider.isPrivateSlicesNeeded(uri)).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Config(qualifiers = "mcc999")
|
||||||
|
public void isPrivateSlicesNeeded_correctUriWithPermissionNotSI_returnFalse() {
|
||||||
|
final Uri uri = Uri.parse("content://com.android.settings.slices/test");
|
||||||
|
ShadowBinder.setCallingUid(123);
|
||||||
|
doReturn(PERMISSION_GRANTED)
|
||||||
|
.when(mContext).checkPermission(anyString(), anyInt(), anyInt());
|
||||||
|
mPackageManager.setPackagesForUid(123, new String[]{"com.android.settings.test"});
|
||||||
|
|
||||||
|
assertThat(mProvider.isPrivateSlicesNeeded(uri)).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Config(qualifiers = "mcc999")
|
||||||
|
public void isPrivateSlicesNeeded_correctUriNoPermission_returnFalse() {
|
||||||
|
final Uri uri = Uri.parse("content://com.android.settings.slices/test");
|
||||||
|
ShadowBinder.setCallingUid(123);
|
||||||
|
doReturn(PERMISSION_DENIED).when(mContext).checkPermission(anyString(), anyInt(), anyInt());
|
||||||
|
mPackageManager.setPackagesForUid(123, new String[]{"com.android.settings.intelligence"});
|
||||||
|
|
||||||
|
assertThat(mProvider.isPrivateSlicesNeeded(uri)).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
private static SliceData getDummyData() {
|
private static SliceData getDummyData() {
|
||||||
return new SliceData.Builder()
|
return new SliceData.Builder()
|
||||||
.setKey(KEY)
|
.setKey(KEY)
|
||||||
|
@@ -47,6 +47,11 @@ class SliceTestUtils {
|
|||||||
|
|
||||||
public static void insertSliceToDb(Context context, String key, boolean isPlatformSlice,
|
public static void insertSliceToDb(Context context, String key, boolean isPlatformSlice,
|
||||||
String customizedUnavailableSliceSubtitle) {
|
String customizedUnavailableSliceSubtitle) {
|
||||||
|
insertSliceToDb(context, key, isPlatformSlice, customizedUnavailableSliceSubtitle, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void insertSliceToDb(Context context, String key, boolean isPlatformSlice,
|
||||||
|
String customizedUnavailableSliceSubtitle, boolean isPublicSlice) {
|
||||||
final SQLiteDatabase db = SlicesDatabaseHelper.getInstance(context).getWritableDatabase();
|
final SQLiteDatabase db = SlicesDatabaseHelper.getInstance(context).getWritableDatabase();
|
||||||
ContentValues values = new ContentValues();
|
ContentValues values = new ContentValues();
|
||||||
values.put(SlicesDatabaseHelper.IndexColumns.KEY, key);
|
values.put(SlicesDatabaseHelper.IndexColumns.KEY, key);
|
||||||
@@ -69,6 +74,7 @@ class SliceTestUtils {
|
|||||||
values.put(SlicesDatabaseHelper.IndexColumns.SLICE_TYPE, SliceData.SliceType.INTENT);
|
values.put(SlicesDatabaseHelper.IndexColumns.SLICE_TYPE, SliceData.SliceType.INTENT);
|
||||||
values.put(SlicesDatabaseHelper.IndexColumns.UNAVAILABLE_SLICE_SUBTITLE,
|
values.put(SlicesDatabaseHelper.IndexColumns.UNAVAILABLE_SLICE_SUBTITLE,
|
||||||
customizedUnavailableSliceSubtitle);
|
customizedUnavailableSliceSubtitle);
|
||||||
|
values.put(SlicesDatabaseHelper.IndexColumns.PUBLIC_SLICE, isPublicSlice);
|
||||||
|
|
||||||
db.replaceOrThrow(SlicesDatabaseHelper.Tables.TABLE_SLICES_INDEX, null, values);
|
db.replaceOrThrow(SlicesDatabaseHelper.Tables.TABLE_SLICES_INDEX, null, values);
|
||||||
db.close();
|
db.close();
|
||||||
|
@@ -17,6 +17,8 @@
|
|||||||
|
|
||||||
package com.android.settings.slices;
|
package com.android.settings.slices;
|
||||||
|
|
||||||
|
import static android.content.ContentResolver.SCHEME_CONTENT;
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
import static org.mockito.Mockito.spy;
|
import static org.mockito.Mockito.spy;
|
||||||
@@ -168,8 +170,10 @@ public class SlicesDatabaseAccessorTest {
|
|||||||
@Test
|
@Test
|
||||||
public void getDescendantUris_platformSlice_doesNotReturnOEMSlice() {
|
public void getDescendantUris_platformSlice_doesNotReturnOEMSlice() {
|
||||||
final String key = "oem_key";
|
final String key = "oem_key";
|
||||||
SliceTestUtils.insertSliceToDb(mContext, key, false /* isPlatformSlice */);
|
SliceTestUtils.insertSliceToDb(mContext, key, false /* isPlatformSlice */,
|
||||||
final List<Uri> keys = mAccessor.getSliceUris(SettingsSlicesContract.AUTHORITY);
|
null /* customizedUnavailableSliceSubtitle */, true /* isPublicSlice */);
|
||||||
|
final List<Uri> keys = mAccessor.getSliceUris(SettingsSlicesContract.AUTHORITY,
|
||||||
|
true /* isPublicSlice */);
|
||||||
|
|
||||||
assertThat(keys).isEmpty();
|
assertThat(keys).isEmpty();
|
||||||
}
|
}
|
||||||
@@ -177,8 +181,10 @@ public class SlicesDatabaseAccessorTest {
|
|||||||
@Test
|
@Test
|
||||||
public void getDescendantUris_oemSlice_doesNotReturnPlatformSlice() {
|
public void getDescendantUris_oemSlice_doesNotReturnPlatformSlice() {
|
||||||
final String key = "platform_key";
|
final String key = "platform_key";
|
||||||
SliceTestUtils.insertSliceToDb(mContext, key, true /* isPlatformSlice */);
|
SliceTestUtils.insertSliceToDb(mContext, key, true /* isPlatformSlice */,
|
||||||
final List<Uri> keys = mAccessor.getSliceUris(SettingsSliceProvider.SLICE_AUTHORITY);
|
null /* customizedUnavailableSliceSubtitle */, true /* isPublicSlice */);
|
||||||
|
final List<Uri> keys = mAccessor.getSliceUris(SettingsSliceProvider.SLICE_AUTHORITY,
|
||||||
|
true /* isPublicSlice */);
|
||||||
|
|
||||||
assertThat(keys).isEmpty();
|
assertThat(keys).isEmpty();
|
||||||
}
|
}
|
||||||
@@ -186,8 +192,10 @@ public class SlicesDatabaseAccessorTest {
|
|||||||
@Test
|
@Test
|
||||||
public void getDescendantUris_oemSlice_returnsOEMUriDescendant() {
|
public void getDescendantUris_oemSlice_returnsOEMUriDescendant() {
|
||||||
final String key = "oem_key";
|
final String key = "oem_key";
|
||||||
SliceTestUtils.insertSliceToDb(mContext, key, false /* isPlatformSlice */);
|
SliceTestUtils.insertSliceToDb(mContext, key, false /* isPlatformSlice */,
|
||||||
final List<Uri> keys = mAccessor.getSliceUris(SettingsSliceProvider.SLICE_AUTHORITY);
|
null /* customizedUnavailableSliceSubtitle */, true /* isPublicSlice */);
|
||||||
|
final List<Uri> keys = mAccessor.getSliceUris(SettingsSliceProvider.SLICE_AUTHORITY,
|
||||||
|
true /* isPublicSlice */);
|
||||||
|
|
||||||
assertThat(keys).containsExactly(
|
assertThat(keys).containsExactly(
|
||||||
Uri.parse("content://com.android.settings.slices/action/oem_key"));
|
Uri.parse("content://com.android.settings.slices/action/oem_key"));
|
||||||
@@ -196,13 +204,51 @@ public class SlicesDatabaseAccessorTest {
|
|||||||
@Test
|
@Test
|
||||||
public void getDescendantUris_platformSlice_returnsPlatformUriDescendant() {
|
public void getDescendantUris_platformSlice_returnsPlatformUriDescendant() {
|
||||||
final String key = "platform_key";
|
final String key = "platform_key";
|
||||||
SliceTestUtils.insertSliceToDb(mContext, key, true /* isPlatformSlice */);
|
SliceTestUtils.insertSliceToDb(mContext, key, true /* isPlatformSlice */,
|
||||||
final List<Uri> keys = mAccessor.getSliceUris(SettingsSlicesContract.AUTHORITY);
|
null /* customizedUnavailableSliceSubtitle */, true /* isPublicSlice */);
|
||||||
|
final List<Uri> keys = mAccessor.getSliceUris(SettingsSlicesContract.AUTHORITY,
|
||||||
|
true /* isPublicSlice */);
|
||||||
|
|
||||||
assertThat(keys).containsExactly(
|
assertThat(keys).containsExactly(
|
||||||
Uri.parse("content://android.settings.slices/action/platform_key"));
|
Uri.parse("content://android.settings.slices/action/platform_key"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getSliceUris_publicSlice_returnPublicUri() {
|
||||||
|
SliceTestUtils.insertSliceToDb(mContext, "test_public", false /* isPlatformSlice */,
|
||||||
|
null /* customizedUnavailableSliceSubtitle */, true /* isPublicSlice */);
|
||||||
|
SliceTestUtils.insertSliceToDb(mContext, "test_private", false /* isPlatformSlice */,
|
||||||
|
null /* customizedUnavailableSliceSubtitle */, false /* isPublicSlice */);
|
||||||
|
final Uri expectedUri = new Uri.Builder()
|
||||||
|
.scheme(SCHEME_CONTENT)
|
||||||
|
.authority(SettingsSliceProvider.SLICE_AUTHORITY)
|
||||||
|
.appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
|
||||||
|
.appendPath("test_public")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
final List<Uri> uri = mAccessor.getSliceUris(SettingsSliceProvider.SLICE_AUTHORITY, true);
|
||||||
|
|
||||||
|
assertThat(uri).containsExactly(expectedUri);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getSliceUris_nonPublicSlice_returnNonPublicUri() {
|
||||||
|
SliceTestUtils.insertSliceToDb(mContext, "test_public", false /* isPlatformSlice */,
|
||||||
|
null /* customizedUnavailableSliceSubtitle */, true /* isPublicSlice */);
|
||||||
|
SliceTestUtils.insertSliceToDb(mContext, "test_private", false /* isPlatformSlice */,
|
||||||
|
null /* customizedUnavailableSliceSubtitle */, false /* isPublicSlice */);
|
||||||
|
final Uri expectedUri = new Uri.Builder()
|
||||||
|
.scheme(SCHEME_CONTENT)
|
||||||
|
.authority(SettingsSliceProvider.SLICE_AUTHORITY)
|
||||||
|
.appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
|
||||||
|
.appendPath("test_private")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
final List<Uri> uri = mAccessor.getSliceUris(SettingsSliceProvider.SLICE_AUTHORITY, false);
|
||||||
|
|
||||||
|
assertThat(uri).containsExactly(expectedUri);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Config(qualifiers = "mcc999")
|
@Config(qualifiers = "mcc999")
|
||||||
public void getSliceKeys_indexesDatabase() {
|
public void getSliceKeys_indexesDatabase() {
|
||||||
@@ -220,7 +266,8 @@ public class SlicesDatabaseAccessorTest {
|
|||||||
FakeIndexProvider.SEARCH_INDEX_DATA_PROVIDER));
|
FakeIndexProvider.SEARCH_INDEX_DATA_PROVIDER));
|
||||||
|
|
||||||
final SlicesDatabaseAccessor accessor = new SlicesDatabaseAccessor(mContext);
|
final SlicesDatabaseAccessor accessor = new SlicesDatabaseAccessor(mContext);
|
||||||
final List<Uri> keys = accessor.getSliceUris(SettingsSliceProvider.SLICE_AUTHORITY);
|
final List<Uri> keys = accessor.getSliceUris(SettingsSliceProvider.SLICE_AUTHORITY,
|
||||||
|
true /* isPublicSlice */);
|
||||||
|
|
||||||
assertThat(keys).isNotEmpty();
|
assertThat(keys).isNotEmpty();
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user