diff options
author | Svet Ganov <svetoslavganov@google.com> | 2015-08-11 08:59:12 -0700 |
---|---|---|
committer | Svet Ganov <svetoslavganov@google.com> | 2015-08-12 21:57:59 -0700 |
commit | 52153f4c0540a991b5b7214f4f14b5a891479a3c (patch) | |
tree | 934aee2bfdd5307c01434c2ab18e15cb8b66dbd1 | |
parent | ff9912d594bc5cdc10a4a224b9a2296bac50851b (diff) | |
download | frameworks_base-52153f4c0540a991b5b7214f4f14b5a891479a3c.zip frameworks_base-52153f4c0540a991b5b7214f4f14b5a891479a3c.tar.gz frameworks_base-52153f4c0540a991b5b7214f4f14b5a891479a3c.tar.bz2 |
Add GTS test to ensure valid default permission grants - framework
The platform grants runtime permissions by default to apps on the
system image that provide core device use cases which a user expects
to work out-of-the-box. We are now adding a test to ensure that
OEMs cannot pregrant premissions on non approved components.
bug:23043018
Change-Id: Id76717cce0ee59678956bd0be347d3c045fe4c51
8 files changed, 123 insertions, 5 deletions
diff --git a/core/java/android/app/IUiAutomationConnection.aidl b/core/java/android/app/IUiAutomationConnection.aidl index 474154b..2caec369 100644 --- a/core/java/android/app/IUiAutomationConnection.aidl +++ b/core/java/android/app/IUiAutomationConnection.aidl @@ -43,6 +43,8 @@ interface IUiAutomationConnection { void clearWindowAnimationFrameStats(); WindowAnimationFrameStats getWindowAnimationFrameStats(); void executeShellCommand(String command, in ParcelFileDescriptor fd); + void grantRuntimePermission(String packageName, String permission, int userId); + void revokeRuntimePermission(String packageName, String permission, int userId); // Called from the system process. oneway void shutdown(); diff --git a/core/java/android/app/UiAutomation.java b/core/java/android/app/UiAutomation.java index a8494fb..efed2e0 100644 --- a/core/java/android/app/UiAutomation.java +++ b/core/java/android/app/UiAutomation.java @@ -30,6 +30,7 @@ import android.os.Looper; import android.os.ParcelFileDescriptor; import android.os.RemoteException; import android.os.SystemClock; +import android.os.UserHandle; import android.util.Log; import android.view.Display; import android.view.InputEvent; @@ -846,6 +847,62 @@ public final class UiAutomation { } /** + * Grants a runtime permission to a package for a user. + * @param packageName The package to which to grant. + * @param permission The permission to grant. + * @return Whether granting succeeded. + * + * @hide + */ + public boolean grantRuntimePermission(String packageName, String permission, + UserHandle userHandle) { + synchronized (mLock) { + throwIfNotConnectedLocked(); + } + try { + if (DEBUG) { + Log.i(LOG_TAG, "Granting runtime permission"); + } + // Calling out without a lock held. + mUiAutomationConnection.grantRuntimePermission(packageName, + permission, userHandle.getIdentifier()); + // TODO: The package manager API should return boolean. + return true; + } catch (RemoteException re) { + Log.e(LOG_TAG, "Error granting runtime permission", re); + } + return false; + } + + /** + * Revokes a runtime permission from a package for a user. + * @param packageName The package from which to revoke. + * @param permission The permission to revoke. + * @return Whether revoking succeeded. + * + * @hide + */ + public boolean revokeRuntimePermission(String packageName, String permission, + UserHandle userHandle) { + synchronized (mLock) { + throwIfNotConnectedLocked(); + } + try { + if (DEBUG) { + Log.i(LOG_TAG, "Revoking runtime permission"); + } + // Calling out without a lock held. + mUiAutomationConnection.revokeRuntimePermission(packageName, + permission, userHandle.getIdentifier()); + // TODO: The package manager API should return boolean. + return true; + } catch (RemoteException re) { + Log.e(LOG_TAG, "Error revoking runtime permission", re); + } + return false; + } + + /** * Executes a shell command. This method returs a file descriptor that points * to the standard output stream. The command execution is similar to running * "adb shell <command>" from a host connected to the device. diff --git a/core/java/android/app/UiAutomationConnection.java b/core/java/android/app/UiAutomationConnection.java index 39cd3bc..13e27e2 100644 --- a/core/java/android/app/UiAutomationConnection.java +++ b/core/java/android/app/UiAutomationConnection.java @@ -19,6 +19,7 @@ package android.app; import android.accessibilityservice.AccessibilityServiceInfo; import android.accessibilityservice.IAccessibilityServiceClient; import android.content.Context; +import android.content.pm.IPackageManager; import android.graphics.Bitmap; import android.hardware.input.InputManager; import android.os.Binder; @@ -60,6 +61,9 @@ public final class UiAutomationConnection extends IUiAutomationConnection.Stub { private final IAccessibilityManager mAccessibilityManager = IAccessibilityManager.Stub .asInterface(ServiceManager.getService(Service.ACCESSIBILITY_SERVICE)); + private final IPackageManager mPackageManager = IPackageManager.Stub + .asInterface(ServiceManager.getService("package")); + private final Object mLock = new Object(); private final Binder mToken = new Binder(); @@ -227,6 +231,38 @@ public final class UiAutomationConnection extends IUiAutomationConnection.Stub { } @Override + public void grantRuntimePermission(String packageName, String permission, int userId) + throws RemoteException { + synchronized (mLock) { + throwIfCalledByNotTrustedUidLocked(); + throwIfShutdownLocked(); + throwIfNotConnectedLocked(); + } + final long identity = Binder.clearCallingIdentity(); + try { + mPackageManager.grantRuntimePermission(packageName, permission, userId); + } finally { + Binder.restoreCallingIdentity(identity); + } + } + + @Override + public void revokeRuntimePermission(String packageName, String permission, int userId) + throws RemoteException { + synchronized (mLock) { + throwIfCalledByNotTrustedUidLocked(); + throwIfShutdownLocked(); + throwIfNotConnectedLocked(); + } + final long identity = Binder.clearCallingIdentity(); + try { + mPackageManager.revokeRuntimePermission(packageName, permission, userId); + } finally { + Binder.restoreCallingIdentity(identity); + } + } + + @Override public void executeShellCommand(final String command, final ParcelFileDescriptor sink) throws RemoteException { synchronized (mLock) { diff --git a/core/java/com/android/internal/util/ArrayUtils.java b/core/java/com/android/internal/util/ArrayUtils.java index 9d0636a..f190d8c 100644 --- a/core/java/com/android/internal/util/ArrayUtils.java +++ b/core/java/com/android/internal/util/ArrayUtils.java @@ -294,6 +294,29 @@ public class ArrayUtils { } /** + * Removes value from given array if present, providing set-like behavior. + */ + public static @Nullable String[] removeString(@Nullable String[] cur, String val) { + if (cur == null) { + return null; + } + final int N = cur.length; + for (int i = 0; i < N; i++) { + if (Objects.equals(cur[i], val)) { + String[] ret = new String[N - 1]; + if (i > 0) { + System.arraycopy(cur, 0, ret, 0, i); + } + if (i < (N - 1)) { + System.arraycopy(cur, i + 1, ret, i, N - i - 1); + } + return ret; + } + } + return cur; + } + + /** * Adds value to given array if not already present, providing set-like * behavior. */ diff --git a/services/core/java/com/android/server/content/ContentService.java b/services/core/java/com/android/server/content/ContentService.java index c13401f..b766894 100644 --- a/services/core/java/com/android/server/content/ContentService.java +++ b/services/core/java/com/android/server/content/ContentService.java @@ -157,7 +157,7 @@ public final class ContentService extends IContentService.Stub { mFactoryTest = factoryTest; // Let the package manager query for the sync adapters for a given authority - // as we grant default permissions to sync adapters for specifix authorities. + // as we grant default permissions to sync adapters for specific authorities. PackageManagerInternal packageManagerInternal = LocalServices.getService( PackageManagerInternal.class); packageManagerInternal.setSyncAdapterPackagesprovider( diff --git a/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java index 71a2d59..d2a70df 100644 --- a/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java +++ b/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java @@ -296,7 +296,7 @@ final class DefaultPermissionGrantPolicy { PackageParser.Package storagePackage = getDefaultProviderAuthorityPackageLPr( "com.android.externalstorage.documents", userId); if (storagePackage != null) { - grantRuntimePermissionsLPw(storagePackage, STORAGE_PERMISSIONS, userId); + grantRuntimePermissionsLPw(storagePackage, STORAGE_PERMISSIONS, true, userId); } // CertInstaller @@ -360,7 +360,7 @@ final class DefaultPermissionGrantPolicy { PackageParser.Package cbrPackage = getDefaultSystemHandlerActivityPackageLPr(cbrIntent, userId); if (cbrPackage != null && doesPackageSupportRuntimePermissions(cbrPackage)) { - grantRuntimePermissionsLPw(cbrPackage, SMS_PERMISSIONS, false, userId); + grantRuntimePermissionsLPw(cbrPackage, SMS_PERMISSIONS, userId); } // Calendar diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java index 00d0fe1..7dc04de 100644 --- a/services/core/java/com/android/server/pm/Settings.java +++ b/services/core/java/com/android/server/pm/Settings.java @@ -4151,7 +4151,7 @@ final class Settings { pw.print(", COSTS_MONEY"); } if ((perm.info.flags&PermissionInfo.FLAG_HIDDEN) != 0) { - pw.print(", COSTS_HIDDEN"); + pw.print(", HIDDEN"); } if ((perm.info.flags&PermissionInfo.FLAG_INSTALLED) != 0) { pw.print(", INSTALLED"); diff --git a/telecomm/java/android/telecom/DefaultDialerManager.java b/telecomm/java/android/telecom/DefaultDialerManager.java index 3d49308..5852b8e 100644 --- a/telecomm/java/android/telecom/DefaultDialerManager.java +++ b/telecomm/java/android/telecom/DefaultDialerManager.java @@ -97,7 +97,7 @@ public class DefaultDialerManager { * @hide * */ public static String getDefaultDialerApplication(Context context) { - return getDefaultDialerApplication(context, ActivityManager.getCurrentUser()); + return getDefaultDialerApplication(context, context.getUserId()); } /** |