Grant permission on slice uris based on whitelist
Bug: 112587202 Test: robotests Change-Id: I4e12a73f0acd848153f32c2569358dd55bed3f92
This commit is contained in:
@@ -106,6 +106,9 @@
|
|||||||
-->
|
-->
|
||||||
</string-array>
|
</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 -->
|
<!-- Whether or not App & Notification screen should display recently used apps -->
|
||||||
<bool name="config_display_recent_apps">true</bool>
|
<bool name="config_display_recent_apps">true</bool>
|
||||||
|
|
||||||
|
@@ -20,6 +20,7 @@ import static android.Manifest.permission.READ_SEARCH_INDEXABLES;
|
|||||||
|
|
||||||
import android.app.slice.SliceManager;
|
import android.app.slice.SliceManager;
|
||||||
import android.content.ContentResolver;
|
import android.content.ContentResolver;
|
||||||
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
@@ -36,6 +37,7 @@ import androidx.annotation.VisibleForTesting;
|
|||||||
import androidx.slice.Slice;
|
import androidx.slice.Slice;
|
||||||
import androidx.slice.SliceProvider;
|
import androidx.slice.SliceProvider;
|
||||||
|
|
||||||
|
import com.android.settings.R;
|
||||||
import com.android.settings.bluetooth.BluetoothSliceBuilder;
|
import com.android.settings.bluetooth.BluetoothSliceBuilder;
|
||||||
import com.android.settings.core.BasePreferenceController;
|
import com.android.settings.core.BasePreferenceController;
|
||||||
import com.android.settings.flashlight.FlashlightSliceBuilder;
|
import com.android.settings.flashlight.FlashlightSliceBuilder;
|
||||||
@@ -113,6 +115,8 @@ public class SettingsSliceProvider extends SliceProvider {
|
|||||||
public static final String EXTRA_SLICE_PLATFORM_DEFINED =
|
public static final String EXTRA_SLICE_PLATFORM_DEFINED =
|
||||||
"com.android.settings.slice.extra.platform";
|
"com.android.settings.slice.extra.platform";
|
||||||
|
|
||||||
|
private static final KeyValueListParser KEY_VALUE_LIST_PARSER = new KeyValueListParser(',');
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
CustomSliceManager mCustomSliceManager;
|
CustomSliceManager mCustomSliceManager;
|
||||||
|
|
||||||
@@ -125,13 +129,10 @@ public class SettingsSliceProvider extends SliceProvider {
|
|||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
Map<Uri, SliceData> mSliceDataCache;
|
Map<Uri, SliceData> mSliceDataCache;
|
||||||
|
|
||||||
private final KeyValueListParser mParser;
|
|
||||||
|
|
||||||
final Set<Uri> mRegisteredUris = new ArraySet<>();
|
final Set<Uri> mRegisteredUris = new ArraySet<>();
|
||||||
|
|
||||||
public SettingsSliceProvider() {
|
public SettingsSliceProvider() {
|
||||||
super(READ_SEARCH_INDEXABLES);
|
super(READ_SEARCH_INDEXABLES);
|
||||||
mParser = new KeyValueListParser(',');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -151,6 +152,7 @@ public class SettingsSliceProvider extends SliceProvider {
|
|||||||
SliceDeepLinkSpringBoard.parse(
|
SliceDeepLinkSpringBoard.parse(
|
||||||
intent.getData(), getContext().getPackageName()));
|
intent.getData(), getContext().getPackageName()));
|
||||||
} catch (URISyntaxException e) {
|
} catch (URISyntaxException e) {
|
||||||
|
Log.e(TAG, "Uri syntax error, can't map intent to uri.", e);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -319,9 +321,33 @@ public class SettingsSliceProvider extends SliceProvider {
|
|||||||
final List<String> keys = mSlicesDatabaseAccessor.getSliceKeys(isPlatformUri);
|
final List<String> keys = mSlicesDatabaseAccessor.getSliceKeys(isPlatformUri);
|
||||||
descendants.addAll(buildUrisFromKeys(keys, authority));
|
descendants.addAll(buildUrisFromKeys(keys, authority));
|
||||||
descendants.addAll(getSpecialCaseUris(isPlatformUri));
|
descendants.addAll(getSpecialCaseUris(isPlatformUri));
|
||||||
|
grantWhitelistedPackagePermissions(getContext(), descendants);
|
||||||
return 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) {
|
private List<Uri> buildUrisFromKeys(List<String> keys, String authority) {
|
||||||
final List<Uri> descendants = new ArrayList<>();
|
final List<Uri> descendants = new ArrayList<>();
|
||||||
|
|
||||||
@@ -428,7 +454,7 @@ public class SettingsSliceProvider extends SliceProvider {
|
|||||||
final Set<String> set = new ArraySet<>();
|
final Set<String> set = new ArraySet<>();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
mParser.setString(value);
|
KEY_VALUE_LIST_PARSER.setString(value);
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
Log.e(TAG, "Bad Settings Slices Whitelist flags", e);
|
Log.e(TAG, "Bad Settings Slices Whitelist flags", e);
|
||||||
return set;
|
return set;
|
||||||
|
@@ -67,4 +67,10 @@
|
|||||||
<string-array name="config_settings_slices_accessibility_components" translatable="false">
|
<string-array name="config_settings_slices_accessibility_components" translatable="false">
|
||||||
<item>fake_package/fake_service</item>
|
<item>fake_package/fake_service</item>
|
||||||
</string-array>
|
</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>
|
</resources>
|
||||||
|
@@ -21,9 +21,12 @@ 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.ArgumentMatchers.any;
|
||||||
|
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;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.never;
|
||||||
import static org.mockito.Mockito.spy;
|
import static org.mockito.Mockito.spy;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
@@ -64,6 +67,7 @@ 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 java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@@ -477,6 +481,28 @@ public class SettingsSliceProviderTest {
|
|||||||
mProvider.onSlicePinned(uri);
|
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) {
|
private void insertSpecialCase(String key) {
|
||||||
insertSpecialCase(key, true);
|
insertSpecialCase(key, true);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user