diff --git a/res/values/config.xml b/res/values/config.xml index f5105232035..b9a69f105e8 100755 --- a/res/values/config.xml +++ b/res/values/config.xml @@ -106,6 +106,9 @@ --> + + + true diff --git a/src/com/android/settings/slices/SettingsSliceProvider.java b/src/com/android/settings/slices/SettingsSliceProvider.java index f0439a893f2..e3594779356 100644 --- a/src/com/android/settings/slices/SettingsSliceProvider.java +++ b/src/com/android/settings/slices/SettingsSliceProvider.java @@ -20,6 +20,7 @@ import static android.Manifest.permission.READ_SEARCH_INDEXABLES; import android.app.slice.SliceManager; import android.content.ContentResolver; +import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.net.Uri; @@ -36,6 +37,7 @@ import androidx.annotation.VisibleForTesting; import androidx.slice.Slice; import androidx.slice.SliceProvider; +import com.android.settings.R; import com.android.settings.bluetooth.BluetoothSliceBuilder; import com.android.settings.core.BasePreferenceController; import com.android.settings.flashlight.FlashlightSliceBuilder; @@ -113,6 +115,8 @@ public class SettingsSliceProvider extends SliceProvider { public static final String EXTRA_SLICE_PLATFORM_DEFINED = "com.android.settings.slice.extra.platform"; + private static final KeyValueListParser KEY_VALUE_LIST_PARSER = new KeyValueListParser(','); + @VisibleForTesting CustomSliceManager mCustomSliceManager; @@ -125,13 +129,10 @@ public class SettingsSliceProvider extends SliceProvider { @VisibleForTesting Map mSliceDataCache; - private final KeyValueListParser mParser; - final Set mRegisteredUris = new ArraySet<>(); public SettingsSliceProvider() { super(READ_SEARCH_INDEXABLES); - mParser = new KeyValueListParser(','); } @Override @@ -151,6 +152,7 @@ public class SettingsSliceProvider extends SliceProvider { SliceDeepLinkSpringBoard.parse( intent.getData(), getContext().getPackageName())); } catch (URISyntaxException e) { + Log.e(TAG, "Uri syntax error, can't map intent to uri.", e); return null; } } @@ -319,9 +321,33 @@ public class SettingsSliceProvider extends SliceProvider { final List keys = mSlicesDatabaseAccessor.getSliceKeys(isPlatformUri); descendants.addAll(buildUrisFromKeys(keys, authority)); descendants.addAll(getSpecialCaseUris(isPlatformUri)); + grantWhitelistedPackagePermissions(getContext(), descendants); return descendants; } + @VisibleForTesting + static void grantWhitelistedPackagePermissions(Context context, List descendants) { + if (descendants == null) { + Log.d(TAG, "No descendants to grant permission with, skipping."); + } + final String[] whitelistPackages = + context.getResources().getStringArray(R.array.slice_whitelist_package_names); + if (whitelistPackages == null || whitelistPackages.length == 0) { + Log.d(TAG, "No packages to whitelist, skipping."); + return; + } else { + Log.d(TAG, String.format( + "Whitelisting %d uris to %d pkgs.", + descendants.size(), whitelistPackages.length)); + } + final SliceManager sliceManager = context.getSystemService(SliceManager.class); + for (Uri descendant : descendants) { + for (String toPackage : whitelistPackages) { + sliceManager.grantSlicePermission(toPackage, descendant); + } + } + } + private List buildUrisFromKeys(List keys, String authority) { final List descendants = new ArrayList<>(); @@ -428,7 +454,7 @@ public class SettingsSliceProvider extends SliceProvider { final Set set = new ArraySet<>(); try { - mParser.setString(value); + KEY_VALUE_LIST_PARSER.setString(value); } catch (IllegalArgumentException e) { Log.e(TAG, "Bad Settings Slices Whitelist flags", e); return set; diff --git a/tests/robotests/res/values-mcc999/config.xml b/tests/robotests/res/values-mcc999/config.xml index bbbdcc2e849..2488882f2b5 100644 --- a/tests/robotests/res/values-mcc999/config.xml +++ b/tests/robotests/res/values-mcc999/config.xml @@ -67,4 +67,10 @@ fake_package/fake_service + + + + com.android.settings.slice_whitelist_package + + diff --git a/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java b/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java index 1ee9230b50e..f7c6bba76e2 100644 --- a/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java +++ b/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java @@ -21,9 +21,12 @@ import static android.content.ContentResolver.SCHEME_CONTENT; import static com.google.common.truth.Truth.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -64,6 +67,7 @@ import org.robolectric.annotation.Implementation; import org.robolectric.annotation.Implements; import org.robolectric.annotation.Resetter; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; @@ -477,6 +481,28 @@ public class SettingsSliceProviderTest { mProvider.onSlicePinned(uri); } + @Test + public void grantWhitelistedPackagePermissions_noWhitelist_shouldNotGrant() { + final List uris = new ArrayList<>(); + uris.add(Uri.parse("content://settings/slice")); + + mProvider.grantWhitelistedPackagePermissions(mContext, uris); + + verify(mManager, never()).grantSlicePermission(anyString(), any(Uri.class)); + } + + @Test + @Config(qualifiers = "mcc999") + public void grantWhitelistedPackagePermissions_hasPackageWhitelist_shouldGrant() { + final List uris = new ArrayList<>(); + uris.add(Uri.parse("content://settings/slice")); + + mProvider.grantWhitelistedPackagePermissions(mContext, uris); + + verify(mManager) + .grantSlicePermission("com.android.settings.slice_whitelist_package", uris.get(0)); + } + private void insertSpecialCase(String key) { insertSpecialCase(key, true); }