diff options
| author | TreeHugger Robot <treehugger-gerrit@google.com> | 2018-01-21 13:14:37 +0000 |
|---|---|---|
| committer | Android (Google) Code Review <android-gerrit@google.com> | 2018-01-21 13:14:37 +0000 |
| commit | 6ebcfe310919af87b87b534e149a22523aba0e2f (patch) | |
| tree | 584bfbb9e616158818bf2e5eb9586b938fe3a0d8 /core/java/android | |
| parent | 6e3be007786a8b0cc46b50f96438f2860f7f868b (diff) | |
| parent | 1214c878a839d99b1b29c8c31fc93af2ba949338 (diff) | |
Merge "Revert "Slices permission model""
Diffstat (limited to 'core/java/android')
| -rw-r--r-- | core/java/android/app/slice/ISliceManager.aidl | 2 | ||||
| -rw-r--r-- | core/java/android/app/slice/Slice.java | 7 | ||||
| -rw-r--r-- | core/java/android/app/slice/SliceManager.java | 65 | ||||
| -rw-r--r-- | core/java/android/app/slice/SliceProvider.java | 145 |
4 files changed, 27 insertions, 192 deletions
diff --git a/core/java/android/app/slice/ISliceManager.aidl b/core/java/android/app/slice/ISliceManager.aidl index 4461b16fe15c..5f0e542f4b12 100644 --- a/core/java/android/app/slice/ISliceManager.aidl +++ b/core/java/android/app/slice/ISliceManager.aidl @@ -29,6 +29,4 @@ interface ISliceManager { void unpinSlice(String pkg, in Uri uri); boolean hasSliceAccess(String pkg); SliceSpec[] getPinnedSpecs(in Uri uri, String pkg); - int checkSlicePermission(in Uri uri, String pkg, int pid, int uid); - void grantPermissionFromUser(in Uri uri, String pkg, String callingPkg, boolean allSlices); } diff --git a/core/java/android/app/slice/Slice.java b/core/java/android/app/slice/Slice.java index 5bd3440d09f8..6093a4a02fbe 100644 --- a/core/java/android/app/slice/Slice.java +++ b/core/java/android/app/slice/Slice.java @@ -156,13 +156,6 @@ public final class Slice implements Parcelable { */ public static final String HINT_SEE_MORE = "see_more"; /** - * A hint to tell the system that this slice cares about the return value of - * {@link SliceProvider#getBindingPackage} and should not cache the result - * for multiple apps. - * @hide - */ - public static final String HINT_CALLER_NEEDED = "caller_needed"; - /** * Key to retrieve an extra added to an intent when a control is changed. */ public static final String EXTRA_TOGGLE_STATE = "android.app.slice.extra.TOGGLE_STATE"; diff --git a/core/java/android/app/slice/SliceManager.java b/core/java/android/app/slice/SliceManager.java index 09c420c3e66a..74864cb1a371 100644 --- a/core/java/android/app/slice/SliceManager.java +++ b/core/java/android/app/slice/SliceManager.java @@ -53,34 +53,12 @@ public class SliceManager { private static final String TAG = "SliceManager"; - /** - * @hide - */ - public static final String ACTION_REQUEST_SLICE_PERMISSION = - "android.intent.action.REQUEST_SLICE_PERMISSION"; - private final ISliceManager mService; private final Context mContext; private final ArrayMap<Pair<Uri, SliceCallback>, ISliceListener> mListenerLookup = new ArrayMap<>(); /** - * Permission denied. - * @hide - */ - public static final int PERMISSION_DENIED = -1; - /** - * Permission granted. - * @hide - */ - public static final int PERMISSION_GRANTED = 0; - /** - * Permission just granted by the user, and should be granted uri permission as well. - * @hide - */ - public static final int PERMISSION_USER_GRANTED = 1; - - /** * @hide */ public SliceManager(Context context, Handler handler) throws ServiceNotFoundException { @@ -306,7 +284,7 @@ public class SliceManager { extras.putParcelable(SliceProvider.EXTRA_BIND_URI, uri); extras.putParcelableArrayList(SliceProvider.EXTRA_SUPPORTED_SPECS, new ArrayList<>(supportedSpecs)); - final Bundle res = provider.call(mContext.getPackageName(), SliceProvider.METHOD_SLICE, + final Bundle res = provider.call(resolver.getPackageName(), SliceProvider.METHOD_SLICE, null, extras); Bundle.setDefusable(res, true); if (res == null) { @@ -364,7 +342,7 @@ public class SliceManager { extras.putParcelable(SliceProvider.EXTRA_INTENT, intent); extras.putParcelableArrayList(SliceProvider.EXTRA_SUPPORTED_SPECS, new ArrayList<>(supportedSpecs)); - final Bundle res = provider.call(mContext.getPackageName(), + final Bundle res = provider.call(resolver.getPackageName(), SliceProvider.METHOD_MAP_INTENT, null, extras); if (res == null) { return null; @@ -380,45 +358,6 @@ 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) { - try { - if (pkg == null) { - throw new SecurityException("No pkg specified"); - } - int result = mService.checkSlicePermission(uri, pkg, pid, uid); - if (result == PERMISSION_DENIED) { - throw new SecurityException("User " + uid + " does not have slice permission for " - + uri + "."); - } - if (result == PERMISSION_USER_GRANTED) { - // We just had a user grant of this permission and need to grant this to the app - // permanently. - mContext.grantUriPermission(pkg, uri.buildUpon().path("").build(), - Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION - | Intent.FLAG_GRANT_WRITE_URI_PERMISSION - | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); - } - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * Called by SystemUI to grant a slice permission after a dialog is shown. - * @hide - */ - public void grantPermissionFromUser(Uri uri, String pkg, boolean allSlices) { - try { - mService.grantPermissionFromUser(uri, pkg, mContext.getPackageName(), allSlices); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** * Class that listens to changes in {@link Slice}s. */ public interface SliceCallback { diff --git a/core/java/android/app/slice/SliceProvider.java b/core/java/android/app/slice/SliceProvider.java index 8ffacf5280c1..aa41f14d8cb5 100644 --- a/core/java/android/app/slice/SliceProvider.java +++ b/core/java/android/app/slice/SliceProvider.java @@ -15,19 +15,13 @@ */ package android.app.slice; +import android.Manifest.permission; import android.annotation.NonNull; -import android.annotation.Nullable; -import android.app.PendingIntent; -import android.content.ComponentName; import android.content.ContentProvider; import android.content.ContentResolver; import android.content.ContentValues; -import android.content.Context; import android.content.Intent; import android.content.IntentFilter; -import android.content.pm.PackageManager; -import android.content.pm.PackageManager.NameNotFoundException; -import android.content.pm.ProviderInfo; import android.database.ContentObserver; import android.database.Cursor; import android.net.Uri; @@ -135,41 +129,9 @@ public abstract class SliceProvider extends ContentProvider { * @hide */ public static final String EXTRA_SLICE_DESCENDANTS = "slice_descendants"; - /** - * @hide - */ - public static final String EXTRA_PKG = "pkg"; - /** - * @hide - */ - public static final String EXTRA_PROVIDER_PKG = "provider_pkg"; - /** - * @hide - */ - public static final String EXTRA_OVERRIDE_PKG = "override_pkg"; private static final boolean DEBUG = false; - private String mBindingPkg; - private SliceManager mSliceManager; - - /** - * Return the package name of the caller that initiated the binding request - * currently happening. The returned package will have been - * verified to belong to the calling UID. Returns {@code null} if not - * currently performing an {@link #onBindSlice(Uri, List)}. - * @hide - */ - public final @Nullable String getBindingPackage() { - return mBindingPkg; - } - - @Override - public void attachInfo(Context context, ProviderInfo info) { - super.attachInfo(context, info); - mSliceManager = context.getSystemService(SliceManager.class); - } - /** * Implemented to create a slice. Will be called on the main thread. * <p> @@ -300,27 +262,28 @@ public abstract class SliceProvider extends ContentProvider { public Bundle call(String method, String arg, Bundle extras) { if (method.equals(METHOD_SLICE)) { Uri uri = extras.getParcelable(EXTRA_BIND_URI); + if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.myUid())) { + getContext().enforceUriPermission(uri, permission.BIND_SLICE, + permission.BIND_SLICE, Binder.getCallingPid(), Binder.getCallingUid(), + Intent.FLAG_GRANT_WRITE_URI_PERMISSION, + "Slice binding requires the permission BIND_SLICE"); + } List<SliceSpec> supportedSpecs = extras.getParcelableArrayList(EXTRA_SUPPORTED_SPECS); - String callingPackage = getCallingPackage(); - if (extras.containsKey(EXTRA_OVERRIDE_PKG)) { - if (Binder.getCallingUid() != Process.SYSTEM_UID) { - throw new SecurityException("Only the system can override calling pkg"); - } - callingPackage = extras.getString(EXTRA_OVERRIDE_PKG); - } - Slice s = handleBindSlice(uri, supportedSpecs, callingPackage); + Slice s = handleBindSlice(uri, supportedSpecs); Bundle b = new Bundle(); b.putParcelable(EXTRA_SLICE, s); return b; } else if (method.equals(METHOD_MAP_INTENT)) { + getContext().enforceCallingPermission(permission.BIND_SLICE, + "Slice binding requires the permission BIND_SLICE"); Intent intent = extras.getParcelable(EXTRA_INTENT); if (intent == null) return null; Uri uri = onMapIntentToUri(intent); List<SliceSpec> supportedSpecs = extras.getParcelableArrayList(EXTRA_SUPPORTED_SPECS); Bundle b = new Bundle(); if (uri != null) { - Slice s = handleBindSlice(uri, supportedSpecs, getCallingPackage()); + Slice s = handleBindSlice(uri, supportedSpecs); b.putParcelable(EXTRA_SLICE, s); } else { b.putParcelable(EXTRA_SLICE, null); @@ -328,14 +291,20 @@ public abstract class SliceProvider extends ContentProvider { return b; } else if (method.equals(METHOD_PIN)) { Uri uri = extras.getParcelable(EXTRA_BIND_URI); - if (Binder.getCallingUid() != Process.SYSTEM_UID) { - throw new SecurityException("Only the system can pin/unpin slices"); + if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.myUid())) { + getContext().enforceUriPermission(uri, permission.BIND_SLICE, + permission.BIND_SLICE, Binder.getCallingPid(), Binder.getCallingUid(), + Intent.FLAG_GRANT_WRITE_URI_PERMISSION, + "Slice binding requires the permission BIND_SLICE"); } handlePinSlice(uri); } else if (method.equals(METHOD_UNPIN)) { Uri uri = extras.getParcelable(EXTRA_BIND_URI); - if (Binder.getCallingUid() != Process.SYSTEM_UID) { - throw new SecurityException("Only the system can pin/unpin slices"); + if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.myUid())) { + getContext().enforceUriPermission(uri, permission.BIND_SLICE, + permission.BIND_SLICE, Binder.getCallingPid(), Binder.getCallingUid(), + Intent.FLAG_GRANT_WRITE_URI_PERMISSION, + "Slice binding requires the permission BIND_SLICE"); } handleUnpinSlice(uri); } else if (method.equals(METHOD_GET_DESCENDANTS)) { @@ -401,27 +370,14 @@ public abstract class SliceProvider extends ContentProvider { } } - private Slice handleBindSlice(Uri sliceUri, List<SliceSpec> supportedSpecs, - String callingPkg) { - // This can be removed once Slice#bindSlice is removed and everyone is using - // SliceManager#bindSlice. - String pkg = callingPkg != null ? callingPkg - : getContext().getPackageManager().getNameForUid(Binder.getCallingUid()); - if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.myUid())) { - try { - mSliceManager.enforceSlicePermission(sliceUri, pkg, - Binder.getCallingPid(), Binder.getCallingUid()); - } catch (SecurityException e) { - return createPermissionSlice(getContext(), sliceUri, pkg); - } - } + private Slice handleBindSlice(Uri sliceUri, List<SliceSpec> supportedSpecs) { if (Looper.myLooper() == Looper.getMainLooper()) { - return onBindSliceStrict(sliceUri, supportedSpecs, pkg); + return onBindSliceStrict(sliceUri, supportedSpecs); } else { CountDownLatch latch = new CountDownLatch(1); Slice[] output = new Slice[1]; Handler.getMain().post(() -> { - output[0] = onBindSliceStrict(sliceUri, supportedSpecs, pkg); + output[0] = onBindSliceStrict(sliceUri, supportedSpecs); latch.countDown(); }); try { @@ -433,66 +389,15 @@ public abstract class SliceProvider extends ContentProvider { } } - /** - * @hide - */ - public static Slice createPermissionSlice(Context context, Uri sliceUri, - String callingPackage) { - return new Slice.Builder(sliceUri) - .addAction(createPermissionIntent(context, sliceUri, callingPackage), - new Slice.Builder(sliceUri.buildUpon().appendPath("permission").build()) - .addText(getPermissionString(context, callingPackage), null) - .build()) - .addHints(Slice.HINT_LIST_ITEM) - .build(); - } - - /** - * @hide - */ - public static PendingIntent createPermissionIntent(Context context, Uri sliceUri, - String callingPackage) { - Intent intent = new Intent(SliceManager.ACTION_REQUEST_SLICE_PERMISSION); - intent.setComponent(new ComponentName("com.android.systemui", - "com.android.systemui.SlicePermissionActivity")); - intent.putExtra(EXTRA_BIND_URI, sliceUri); - intent.putExtra(EXTRA_PKG, callingPackage); - intent.putExtra(EXTRA_PROVIDER_PKG, context.getPackageName()); - // Unique pending intent. - intent.setData(sliceUri.buildUpon().appendQueryParameter("package", callingPackage) - .build()); - - return PendingIntent.getActivity(context, 0, intent, 0); - } - - /** - * @hide - */ - public static CharSequence getPermissionString(Context context, String callingPackage) { - PackageManager pm = context.getPackageManager(); - try { - return context.getString( - com.android.internal.R.string.slices_permission_request, - pm.getApplicationInfo(callingPackage, 0).loadLabel(pm), - context.getApplicationInfo().loadLabel(pm)); - } catch (NameNotFoundException e) { - // This shouldn't be possible since the caller is verified. - throw new RuntimeException("Unknown calling app", e); - } - } - - private Slice onBindSliceStrict(Uri sliceUri, List<SliceSpec> supportedSpecs, - String callingPackage) { + private Slice onBindSliceStrict(Uri sliceUri, List<SliceSpec> supportedSpecs) { ThreadPolicy oldPolicy = StrictMode.getThreadPolicy(); try { StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder() .detectAll() .penaltyDeath() .build()); - mBindingPkg = callingPackage; return onBindSlice(sliceUri, supportedSpecs); } finally { - mBindingPkg = null; StrictMode.setThreadPolicy(oldPolicy); } } |
