Merge "Add auto-grant permission slice API" into pi-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
4ced90cb12
@@ -7304,6 +7304,7 @@ package android.app.slice {
|
||||
}
|
||||
|
||||
public abstract class SliceProvider extends android.content.ContentProvider {
|
||||
ctor public SliceProvider(java.lang.String...);
|
||||
ctor public SliceProvider();
|
||||
method public final int delete(android.net.Uri, java.lang.String, java.lang.String[]);
|
||||
method public final java.lang.String getType(android.net.Uri);
|
||||
|
||||
@@ -25,7 +25,8 @@ interface ISliceManager {
|
||||
void unpinSlice(String pkg, in Uri uri, in IBinder token);
|
||||
boolean hasSliceAccess(String pkg);
|
||||
SliceSpec[] getPinnedSpecs(in Uri uri, String pkg);
|
||||
int checkSlicePermission(in Uri uri, String pkg, int pid, int uid);
|
||||
int checkSlicePermission(in Uri uri, String pkg, int pid, int uid,
|
||||
in String[] autoGrantPermissions);
|
||||
void grantPermissionFromUser(in Uri uri, String pkg, String callingPkg, boolean allSlices);
|
||||
Uri[] getPinnedSlices(String pkg);
|
||||
|
||||
|
||||
@@ -404,7 +404,8 @@ public class SliceManager {
|
||||
* Does the permission check to see if a caller has access to a specific slice.
|
||||
* @hide
|
||||
*/
|
||||
public void enforceSlicePermission(Uri uri, String pkg, int pid, int uid) {
|
||||
public void enforceSlicePermission(Uri uri, String pkg, int pid, int uid,
|
||||
String[] autoGrantPermissions) {
|
||||
try {
|
||||
if (UserHandle.isSameApp(uid, Process.myUid())) {
|
||||
return;
|
||||
@@ -412,7 +413,7 @@ public class SliceManager {
|
||||
if (pkg == null) {
|
||||
throw new SecurityException("No pkg specified");
|
||||
}
|
||||
int result = mService.checkSlicePermission(uri, pkg, pid, uid);
|
||||
int result = mService.checkSlicePermission(uri, pkg, pid, uid, autoGrantPermissions);
|
||||
if (result == PERMISSION_DENIED) {
|
||||
throw new SecurityException("User " + uid + " does not have slice permission for "
|
||||
+ uri + ".");
|
||||
@@ -424,6 +425,8 @@ public class SliceManager {
|
||||
Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
|
||||
| Intent.FLAG_GRANT_WRITE_URI_PERMISSION
|
||||
| Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
|
||||
// Notify a change has happened because we just granted a permission.
|
||||
mContext.getContentResolver().notifyChange(uri, null);
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
|
||||
@@ -149,10 +149,31 @@ public abstract class SliceProvider extends ContentProvider {
|
||||
private static final boolean DEBUG = false;
|
||||
|
||||
private static final long SLICE_BIND_ANR = 2000;
|
||||
private final String[] mAutoGrantPermissions;
|
||||
|
||||
private String mCallback;
|
||||
private SliceManager mSliceManager;
|
||||
|
||||
/**
|
||||
* A version of constructing a SliceProvider that allows autogranting slice permissions
|
||||
* to apps that hold specific platform permissions.
|
||||
* <p>
|
||||
* When an app tries to bind a slice from this provider that it does not have access to,
|
||||
* This provider will check if the caller holds permissions to any of the autoGrantPermissions
|
||||
* specified, if they do they will be granted persisted uri access to all slices of this
|
||||
* provider.
|
||||
*
|
||||
* @param autoGrantPermissions List of permissions that holders are auto-granted access
|
||||
* to slices.
|
||||
*/
|
||||
public SliceProvider(@NonNull String... autoGrantPermissions) {
|
||||
mAutoGrantPermissions = autoGrantPermissions;
|
||||
}
|
||||
|
||||
public SliceProvider() {
|
||||
mAutoGrantPermissions = new String[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void attachInfo(Context context, ProviderInfo info) {
|
||||
super.attachInfo(context, info);
|
||||
@@ -402,7 +423,7 @@ public abstract class SliceProvider extends ContentProvider {
|
||||
: getContext().getPackageManager().getNameForUid(callingUid);
|
||||
try {
|
||||
mSliceManager.enforceSlicePermission(sliceUri, pkg,
|
||||
callingPid, callingUid);
|
||||
callingPid, callingUid, mAutoGrantPermissions);
|
||||
} catch (SecurityException e) {
|
||||
return createPermissionSlice(getContext(), sliceUri, pkg);
|
||||
}
|
||||
|
||||
@@ -168,7 +168,8 @@ public class SliceManagerService extends ISliceManager.Stub {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pinSlice(String pkg, Uri uri, SliceSpec[] specs, IBinder token) throws RemoteException {
|
||||
public void pinSlice(String pkg, Uri uri, SliceSpec[] specs, IBinder token)
|
||||
throws RemoteException {
|
||||
verifyCaller(pkg);
|
||||
enforceAccess(pkg, uri);
|
||||
int user = Binder.getCallingUserHandle().getIdentifier();
|
||||
@@ -210,7 +211,8 @@ public class SliceManagerService extends ISliceManager.Stub {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int checkSlicePermission(Uri uri, String pkg, int pid, int uid) throws RemoteException {
|
||||
public int checkSlicePermission(Uri uri, String pkg, int pid, int uid,
|
||||
String[] autoGrantPermissions) throws RemoteException {
|
||||
if (mContext.checkUriPermission(uri, pid, uid, Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
|
||||
== PERMISSION_GRANTED) {
|
||||
return SliceManager.PERMISSION_GRANTED;
|
||||
@@ -218,6 +220,11 @@ public class SliceManagerService extends ISliceManager.Stub {
|
||||
if (hasFullSliceAccess(pkg, UserHandle.getUserId(uid))) {
|
||||
return SliceManager.PERMISSION_GRANTED;
|
||||
}
|
||||
for (String perm : autoGrantPermissions) {
|
||||
if (mContext.checkPermission(perm, pid, uid) == PERMISSION_GRANTED) {
|
||||
return SliceManager.PERMISSION_USER_GRANTED;
|
||||
}
|
||||
}
|
||||
synchronized (mLock) {
|
||||
if (mUserGrants.contains(new SliceGrant(uri, pkg, UserHandle.getUserId(uid)))) {
|
||||
return SliceManager.PERMISSION_USER_GRANTED;
|
||||
|
||||
@@ -15,8 +15,10 @@
|
||||
package com.android.server.slice;
|
||||
|
||||
import static android.content.ContentProvider.maybeAddUserId;
|
||||
import static android.content.pm.PackageManager.PERMISSION_DENIED;
|
||||
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
@@ -35,9 +37,11 @@ import android.content.pm.PackageManagerInternal;
|
||||
import android.net.Uri;
|
||||
import android.os.Binder;
|
||||
import android.os.IBinder;
|
||||
import android.os.Process;
|
||||
import android.os.RemoteException;
|
||||
import android.support.test.filters.SmallTest;
|
||||
import android.testing.AndroidTestingRunner;
|
||||
import android.testing.TestableContext;
|
||||
import android.testing.TestableLooper;
|
||||
import android.testing.TestableLooper.RunWithLooper;
|
||||
|
||||
@@ -63,6 +67,7 @@ public class SliceManagerServiceTest extends UiServiceTestCase {
|
||||
private SliceManagerService mService;
|
||||
private PinnedSliceState mCreatedSliceState;
|
||||
private IBinder mToken = new Binder();
|
||||
private TestableContext mContextSpy;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
@@ -72,7 +77,8 @@ public class SliceManagerServiceTest extends UiServiceTestCase {
|
||||
mContext.addMockSystemService(AppOpsManager.class, mock(AppOpsManager.class));
|
||||
mContext.getTestablePermissions().setPermission(TEST_URI, PERMISSION_GRANTED);
|
||||
|
||||
mService = spy(new SliceManagerService(mContext, TestableLooper.get(this).getLooper()));
|
||||
mContextSpy = spy(mContext);
|
||||
mService = spy(new SliceManagerService(mContextSpy, TestableLooper.get(this).getLooper()));
|
||||
mCreatedSliceState = mock(PinnedSliceState.class);
|
||||
doReturn(mCreatedSliceState).when(mService).createPinnedSlice(eq(TEST_URI), anyString());
|
||||
}
|
||||
@@ -103,4 +109,23 @@ public class SliceManagerServiceTest extends UiServiceTestCase {
|
||||
verify(mCreatedSliceState, never()).destroy();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckAutoGrantPermissions() throws RemoteException {
|
||||
String[] testPerms = new String[] {
|
||||
"perm1",
|
||||
"perm2",
|
||||
};
|
||||
when(mContextSpy.checkUriPermission(any(), anyInt(), anyInt(), anyInt()))
|
||||
.thenReturn(PERMISSION_DENIED);
|
||||
when(mContextSpy.checkPermission("perm1", Process.myPid(), Process.myUid()))
|
||||
.thenReturn(PERMISSION_DENIED);
|
||||
when(mContextSpy.checkPermission("perm2", Process.myPid(), Process.myUid()))
|
||||
.thenReturn(PERMISSION_GRANTED);
|
||||
mService.checkSlicePermission(TEST_URI, mContext.getPackageName(), Process.myPid(),
|
||||
Process.myUid(), testPerms);
|
||||
|
||||
verify(mContextSpy).checkPermission(eq("perm1"), eq(Process.myPid()), eq(Process.myUid()));
|
||||
verify(mContextSpy).checkPermission(eq("perm2"), eq(Process.myPid()), eq(Process.myUid()));
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user