diff options
| author | Sooraj Sasindran <sasindran@google.com> | 2019-02-21 17:00:51 -0800 |
|---|---|---|
| committer | android-build-merger <android-build-merger@google.com> | 2019-02-21 17:00:51 -0800 |
| commit | 178684530b73c23807321f0563c8a77afd87bad9 (patch) | |
| tree | fdb415f3e5b7ba67d401c2d15344acbcd984b57f /core/java | |
| parent | 0287ddfde28d753504b66dd84586c8e24e96db60 (diff) | |
| parent | 9f0115bb6e20f18872303c8a68072d9268825913 (diff) | |
Merge "Allow UiAutomation to adopt the shell permission indentity"
am: 9f0115bb6e
Change-Id: I2f3d34f78446de60d51b84fcc81110585c9f2c81
Diffstat (limited to 'core/java')
| -rw-r--r-- | core/java/android/app/AppOpsManager.java | 2 | ||||
| -rw-r--r-- | core/java/android/app/AppOpsManagerInternal.java | 43 | ||||
| -rw-r--r-- | core/java/android/app/IActivityManager.aidl | 15 | ||||
| -rw-r--r-- | core/java/android/app/IUiAutomationConnection.aidl | 3 | ||||
| -rw-r--r-- | core/java/android/app/UiAutomation.java | 60 | ||||
| -rw-r--r-- | core/java/android/app/UiAutomationConnection.java | 35 | ||||
| -rw-r--r-- | core/java/android/content/pm/PackageManager.java | 2 | ||||
| -rw-r--r-- | core/java/android/content/pm/PackageManagerInternal.java | 43 | ||||
| -rw-r--r-- | core/java/com/android/internal/app/IAppOpsService.aidl | 2 |
9 files changed, 185 insertions, 20 deletions
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java index de84281328b2..398b4064d15a 100644 --- a/core/java/android/app/AppOpsManager.java +++ b/core/java/android/app/AppOpsManager.java @@ -2513,7 +2513,7 @@ public class AppOpsManager { */ public int noteProxyOpNoThrow(int op, String proxiedPackageName) { try { - return mService.noteProxyOperation(op, mContext.getOpPackageName(), + return mService.noteProxyOperation(op, Process.myUid(), mContext.getOpPackageName(), Binder.getCallingUid(), proxiedPackageName); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); diff --git a/core/java/android/app/AppOpsManagerInternal.java b/core/java/android/app/AppOpsManagerInternal.java index 24c5d234c120..f5d5e6e9a950 100644 --- a/core/java/android/app/AppOpsManagerInternal.java +++ b/core/java/android/app/AppOpsManagerInternal.java @@ -18,12 +18,55 @@ package android.app; import android.util.SparseIntArray; +import com.android.internal.util.function.QuadFunction; +import com.android.internal.util.function.TriFunction; + /** * App ops service local interface. * * @hide Only for use within the system server. */ public abstract class AppOpsManagerInternal { + /** Interface to override app ops checks via composition */ + public interface CheckOpsDelegate { + /** + * Allows overriding check operation behavior. + * + * @param code The op code to check. + * @param uid The UID for which to check. + * @param packageName The package for which to check. + * @param superImpl The super implementation. + * @return The app op check result. + */ + int checkOperation(int code, int uid, String packageName, + TriFunction<Integer, Integer, String, Integer> superImpl); + + /** + * Allows overriding check audio operation behavior. + * + * @param code The op code to check. + * @param usage The audio op usage. + * @param uid The UID for which to check. + * @param packageName The package for which to check. + * @param superImpl The super implementation. + * @return The app op check result. + */ + int checkAudioOperation(int code, int usage, int uid, String packageName, + QuadFunction<Integer, Integer, Integer, String, Integer> superImpl); + + /** + * Allows overriding note operation behavior. + * + * @param code The op code to note. + * @param uid The UID for which to note. + * @param packageName The package for which to note. + * @param superImpl The super implementation. + * @return The app op note result. + */ + int noteOperation(int code, int uid, String packageName, + TriFunction<Integer, Integer, String, Integer> superImpl); + } + /** * Set the currently configured device and profile owners. Specifies the package uid (value) * that has been configured for each user (key) that has one. These will be allowed privileged diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl index b192021f821b..52fd84113fdf 100644 --- a/core/java/android/app/IActivityManager.aidl +++ b/core/java/android/app/IActivityManager.aidl @@ -714,4 +714,19 @@ interface IActivityManager { /** @see android.app.ActivityManager#alwaysShowUnsupportedCompileSdkWarning */ void alwaysShowUnsupportedCompileSdkWarning(in ComponentName activity); + + /** + * Method for the shell UID to start deletating its permission identity to an + * active instrumenation. The shell can delegate permissions only to one active + * instrumentation at a time. An active instrumentation is one running and + * started from the shell. + */ + void startDelegateShellPermissionIdentity(int uid); + + /** + * Method for the shell UID to stop deletating its permission identity to an + * active instrumenation. An active instrumentation is one running and + * started from the shell. + */ + void stopDelegateShellPermissionIdentity(); } diff --git a/core/java/android/app/IUiAutomationConnection.aidl b/core/java/android/app/IUiAutomationConnection.aidl index d01938b123b1..ac4bf7d9c2c5 100644 --- a/core/java/android/app/IUiAutomationConnection.aidl +++ b/core/java/android/app/IUiAutomationConnection.aidl @@ -47,7 +47,8 @@ interface IUiAutomationConnection { in ParcelFileDescriptor source); void grantRuntimePermission(String packageName, String permission, int userId); void revokeRuntimePermission(String packageName, String permission, int userId); - + void adoptShellPermissionIdentity(int uid); + void dropShellPermissionIdentity(); // 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 c850c85b6e5b..c0903b65737c 100644 --- a/core/java/android/app/UiAutomation.java +++ b/core/java/android/app/UiAutomation.java @@ -35,6 +35,7 @@ import android.os.HandlerThread; import android.os.IBinder; import android.os.Looper; import android.os.ParcelFileDescriptor; +import android.os.Process; import android.os.RemoteException; import android.os.SystemClock; import android.os.UserHandle; @@ -52,6 +53,7 @@ import android.view.accessibility.AccessibilityWindowInfo; import android.view.accessibility.IAccessibilityInteractionConnection; import com.android.internal.util.function.pooled.PooledLambda; + import libcore.io.IoUtils; import java.io.IOException; @@ -352,6 +354,46 @@ public final class UiAutomation { } /** + * Adopt the permission identity of the shell UID. This allows you to call APIs protected + * permissions which normal apps cannot hold but are granted to the shell UID. If you + * already adopted the shell permission identity this method would be a no-op. + * Note that your permission state becomes that of the shell UID and it is not a + * combination of your and the shell UID permissions. + * + * @see #dropShellPermissionIdentity() + */ + public void adoptShellPermissionIdentity() { + synchronized (mLock) { + throwIfNotConnectedLocked(); + } + try { + // Calling out without a lock held. + mUiAutomationConnection.adoptShellPermissionIdentity(Process.myUid()); + } catch (RemoteException re) { + Log.e(LOG_TAG, "Error executing adopting shell permission identity!", re); + } + } + + /** + * Drop the shell permission identity adopted by a previous call to + * {@link #adoptShellPermissionIdentity()}. If you did not adopt the shell permission + * identity this method would be a no-op. + * + * @see #adoptShellPermissionIdentity() + */ + public void dropShellPermissionIdentity() { + synchronized (mLock) { + throwIfNotConnectedLocked(); + } + try { + // Calling out without a lock held. + mUiAutomationConnection.dropShellPermissionIdentity(); + } catch (RemoteException re) { + Log.e(LOG_TAG, "Error executing dropping shell permission identity!", re); + } + } + + /** * Performs a global action. Such an action can be performed at any moment * regardless of the current application or user location in that application. * For example going back, going home, opening recents, etc. @@ -1004,6 +1046,8 @@ public final class UiAutomation { * * @param command The command to execute. * @return A file descriptor to the standard output stream. + * + * @see #adoptShellPermissionIdentity() */ public ParcelFileDescriptor executeShellCommand(String command) { synchronized (mLock) { @@ -1086,22 +1130,6 @@ public final class UiAutomation { return result; } - private static float getDegreesForRotation(int value) { - switch (value) { - case Surface.ROTATION_90: { - return 360f - 90f; - } - case Surface.ROTATION_180: { - return 360f - 180f; - } - case Surface.ROTATION_270: { - return 360f - 270f; - } default: { - return 0; - } - } - } - private boolean isConnectedLocked() { return mConnectionId != CONNECTION_ID_UNDEFINED; } diff --git a/core/java/android/app/UiAutomationConnection.java b/core/java/android/app/UiAutomationConnection.java index e6347354b723..b406d9e30a53 100644 --- a/core/java/android/app/UiAutomationConnection.java +++ b/core/java/android/app/UiAutomationConnection.java @@ -31,6 +31,7 @@ import android.os.Process; import android.os.RemoteException; import android.os.ServiceManager; import android.os.UserHandle; +import android.util.Log; import android.view.IWindowManager; import android.view.InputEvent; import android.view.SurfaceControl; @@ -38,7 +39,6 @@ import android.view.WindowAnimationFrameStats; import android.view.WindowContentFrameStats; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.IAccessibilityManager; -import android.util.Log; import libcore.io.IoUtils; @@ -72,6 +72,9 @@ public final class UiAutomationConnection extends IUiAutomationConnection.Stub { private final IPackageManager mPackageManager = IPackageManager.Stub .asInterface(ServiceManager.getService("package")); + private final IActivityManager mActivityManager = IActivityManager.Stub + .asInterface(ServiceManager.getService("activity")); + private final Object mLock = new Object(); private final Binder mToken = new Binder(); @@ -275,6 +278,36 @@ public final class UiAutomationConnection extends IUiAutomationConnection.Stub { } } + @Override + public void adoptShellPermissionIdentity(int uid) throws RemoteException { + synchronized (mLock) { + throwIfCalledByNotTrustedUidLocked(); + throwIfShutdownLocked(); + throwIfNotConnectedLocked(); + } + final long identity = Binder.clearCallingIdentity(); + try { + mActivityManager.startDelegateShellPermissionIdentity(uid); + } finally { + Binder.restoreCallingIdentity(identity); + } + } + + @Override + public void dropShellPermissionIdentity() throws RemoteException { + synchronized (mLock) { + throwIfCalledByNotTrustedUidLocked(); + throwIfShutdownLocked(); + throwIfNotConnectedLocked(); + } + final long identity = Binder.clearCallingIdentity(); + try { + mActivityManager.stopDelegateShellPermissionIdentity(); + } finally { + Binder.restoreCallingIdentity(identity); + } + } + public class Repeater implements Runnable { // Continuously read readFrom and write back to writeTo until EOF is encountered private final InputStream readFrom; diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index 92c757ceaa29..72981a773277 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -3623,6 +3623,7 @@ public abstract class PackageManager { * * @hide */ + @TestApi @SystemApi @RequiresPermission(android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS) public abstract void grantRuntimePermission(@NonNull String packageName, @@ -3649,6 +3650,7 @@ public abstract class PackageManager { * * @hide */ + @TestApi @SystemApi @RequiresPermission(android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS) public abstract void revokeRuntimePermission(@NonNull String packageName, diff --git a/core/java/android/content/pm/PackageManagerInternal.java b/core/java/android/content/pm/PackageManagerInternal.java index 755232c6a6b6..7c9943b61ea4 100644 --- a/core/java/android/content/pm/PackageManagerInternal.java +++ b/core/java/android/content/pm/PackageManagerInternal.java @@ -29,9 +29,12 @@ import android.os.Bundle; import android.os.PersistableBundle; import android.util.SparseArray; +import com.android.internal.util.function.TriFunction; + import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.List; +import java.util.function.BiFunction; /** * Package manager local system service interface. @@ -64,6 +67,32 @@ public abstract class PackageManagerInternal { void onPackageRemoved(@NonNull String packageName); } + /** Interface to override permission checks via composition */ + public interface CheckPermissionDelegate { + /** + * Allows overriding check permission behavior. + * + * @param permName The permission to check. + * @param pkgName The package for which to check. + * @param userId The user for which to check. + * @param superImpl The super implementation. + * @return The check permission result. + */ + int checkPermission(String permName, String pkgName, int userId, + TriFunction<String, String, Integer, Integer> superImpl); + + /** + * Allows overriding check UID permission behavior. + * + * @param permName The permission to check. + * @param uid The UID for which to check. + * @param superImpl The super implementation. + * @return The check permission result. + */ + int checkUidPermission(String permName, int uid, + BiFunction<String, Integer, Integer> superImpl); + } + /** * Provider for package names. */ @@ -633,4 +662,18 @@ public abstract class PackageManagerInternal { * Ask the package manager to compile layouts in the given package. */ public abstract boolean compileLayouts(String packageName); + + /** + * Get the delegate to influence permission checking. + * + * @return The delegate instance or null to clear. + */ + public abstract @Nullable CheckPermissionDelegate getCheckPermissionDelegate(); + + /** + * Set a delegate to influence permission checking. + * + * @param delegate A delegate instance or null to clear. + */ + public abstract void setCheckPermissionDelegate(@Nullable CheckPermissionDelegate delegate); } diff --git a/core/java/com/android/internal/app/IAppOpsService.aidl b/core/java/com/android/internal/app/IAppOpsService.aidl index 0ed972477123..768dddd35a6d 100644 --- a/core/java/com/android/internal/app/IAppOpsService.aidl +++ b/core/java/com/android/internal/app/IAppOpsService.aidl @@ -33,7 +33,7 @@ interface IAppOpsService { void stopWatchingMode(IAppOpsCallback callback); IBinder getToken(IBinder clientToken); int permissionToOpCode(String permission); - int noteProxyOperation(int code, String proxyPackageName, + int noteProxyOperation(int code, int proxyUid, String proxyPackageName, int callingUid, String callingPackageName); // Remaining methods are only used in Java. |
