Loading res/values/config.xml +3 −0 Original line number Diff line number Diff line Loading @@ -106,6 +106,9 @@ --> </string-array> <!-- List of packages that should be whitelisted for slice uri access. Do not translate --> <string-array name="slice_whitelist_package_names" translatable="false"/> <!-- Whether or not App & Notification screen should display recently used apps --> <bool name="config_display_recent_apps">true</bool> Loading src/com/android/settings/slices/SettingsSliceProvider.java +30 −4 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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; Loading @@ -125,13 +129,10 @@ public class SettingsSliceProvider extends SliceProvider { @VisibleForTesting Map<Uri, SliceData> mSliceDataCache; private final KeyValueListParser mParser; final Set<Uri> mRegisteredUris = new ArraySet<>(); public SettingsSliceProvider() { super(READ_SEARCH_INDEXABLES); mParser = new KeyValueListParser(','); } @Override Loading @@ -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; } } Loading Loading @@ -319,9 +321,33 @@ public class SettingsSliceProvider extends SliceProvider { final List<String> 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<Uri> 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<Uri> buildUrisFromKeys(List<String> keys, String authority) { final List<Uri> descendants = new ArrayList<>(); Loading Loading @@ -428,7 +454,7 @@ public class SettingsSliceProvider extends SliceProvider { final Set<String> 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; Loading tests/robotests/res/values-mcc999/config.xml +6 −0 Original line number Diff line number Diff line Loading @@ -67,4 +67,10 @@ <string-array name="config_settings_slices_accessibility_components" translatable="false"> <item>fake_package/fake_service</item> </string-array> <!-- List of packages that should be whitelisted for slice uri access. Do not translate --> <string-array name="slice_whitelist_package_names" translatable="false"> <item>com.android.settings.slice_whitelist_package</item> </string-array> </resources> tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java +26 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -477,6 +481,28 @@ public class SettingsSliceProviderTest { mProvider.onSlicePinned(uri); } @Test public void grantWhitelistedPackagePermissions_noWhitelist_shouldNotGrant() { final List<Uri> 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<Uri> 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); } Loading Loading
res/values/config.xml +3 −0 Original line number Diff line number Diff line Loading @@ -106,6 +106,9 @@ --> </string-array> <!-- List of packages that should be whitelisted for slice uri access. Do not translate --> <string-array name="slice_whitelist_package_names" translatable="false"/> <!-- Whether or not App & Notification screen should display recently used apps --> <bool name="config_display_recent_apps">true</bool> Loading
src/com/android/settings/slices/SettingsSliceProvider.java +30 −4 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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; Loading @@ -125,13 +129,10 @@ public class SettingsSliceProvider extends SliceProvider { @VisibleForTesting Map<Uri, SliceData> mSliceDataCache; private final KeyValueListParser mParser; final Set<Uri> mRegisteredUris = new ArraySet<>(); public SettingsSliceProvider() { super(READ_SEARCH_INDEXABLES); mParser = new KeyValueListParser(','); } @Override Loading @@ -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; } } Loading Loading @@ -319,9 +321,33 @@ public class SettingsSliceProvider extends SliceProvider { final List<String> 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<Uri> 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<Uri> buildUrisFromKeys(List<String> keys, String authority) { final List<Uri> descendants = new ArrayList<>(); Loading Loading @@ -428,7 +454,7 @@ public class SettingsSliceProvider extends SliceProvider { final Set<String> 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; Loading
tests/robotests/res/values-mcc999/config.xml +6 −0 Original line number Diff line number Diff line Loading @@ -67,4 +67,10 @@ <string-array name="config_settings_slices_accessibility_components" translatable="false"> <item>fake_package/fake_service</item> </string-array> <!-- List of packages that should be whitelisted for slice uri access. Do not translate --> <string-array name="slice_whitelist_package_names" translatable="false"> <item>com.android.settings.slice_whitelist_package</item> </string-array> </resources>
tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java +26 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -477,6 +481,28 @@ public class SettingsSliceProviderTest { mProvider.onSlicePinned(uri); } @Test public void grantWhitelistedPackagePermissions_noWhitelist_shouldNotGrant() { final List<Uri> 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<Uri> 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); } Loading