From 65a4f251c7e14307f46911e376db49c8c7a1a8bb Mon Sep 17 00:00:00 2001 From: Dianne Hackborn Date: Tue, 8 May 2018 17:30:48 -0700 Subject: Further flesh out app ops foreground state. Fix some bugs, add the ability to monitor state changes, improve dumpsys output to help debugging, add a new check API that allows the caller to get the real state. Bug: 78480444 Test: atest FrameworksServicesTests:AppOpsServiceTest Test: atest CtsPermissionTestCases:AppOpsTest Change-Id: I3d41be9968c1d95a1456f4052da958ea64aa068d --- core/java/android/app/AppOpsManager.java | 58 ++++++++++++++++++++++++++++++-- 1 file changed, 56 insertions(+), 2 deletions(-) (limited to 'core/java/android/app/AppOpsManager.java') diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java index 07048f98d26d..21a3c0721371 100644 --- a/core/java/android/app/AppOpsManager.java +++ b/core/java/android/app/AppOpsManager.java @@ -118,6 +118,13 @@ public class AppOpsManager { */ public static final int MODE_FOREGROUND = 4; + /** + * Flag for {@link #startWatchingMode(String, String, int, OnOpChangedListener)}: + * Also get reports if the foreground state of an op's uid changes. This only works + * when watching a particular op, not when watching a package. + * @hide + */ + public static final int WATCH_FOREGROUND_CHANGES = 1 << 0; /** * @hide @@ -1898,6 +1905,21 @@ public class AppOpsManager { startWatchingMode(strOpToOp(op), packageName, callback); } + /** + * Monitor for changes to the operating mode for the given op in the given app package. + * You can watch op changes only for your UID. + * + * @param op The operation to monitor, one of OPSTR_*. + * @param packageName The name of the application to monitor. + * @param flags Option flags: any combination of {@link #WATCH_FOREGROUND_CHANGES} or 0. + * @param callback Where to report changes. + * @hide + */ + public void startWatchingMode(String op, String packageName, int flags, + final OnOpChangedListener callback) { + startWatchingMode(strOpToOp(op), packageName, flags, callback); + } + /** * Monitor for changes to the operating mode for the given op in the given app package. * @@ -1911,6 +1933,24 @@ public class AppOpsManager { */ @RequiresPermission(value=android.Manifest.permission.WATCH_APPOPS, conditional=true) public void startWatchingMode(int op, String packageName, final OnOpChangedListener callback) { + startWatchingMode(op, packageName, 0, callback); + } + + /** + * Monitor for changes to the operating mode for the given op in the given app package. + * + *

If you don't hold the {@link android.Manifest.permission#WATCH_APPOPS} permission + * you can watch changes only for your UID. + * + * @param op The operation to monitor, one of OP_*. + * @param packageName The name of the application to monitor. + * @param flags Option flags: any combination of {@link #WATCH_FOREGROUND_CHANGES} or 0. + * @param callback Where to report changes. + * @hide + */ + @RequiresPermission(value=android.Manifest.permission.WATCH_APPOPS, conditional=true) + public void startWatchingMode(int op, String packageName, int flags, + final OnOpChangedListener callback) { synchronized (mModeWatchers) { IAppOpsCallback cb = mModeWatchers.get(callback); if (cb == null) { @@ -1927,7 +1967,7 @@ public class AppOpsManager { mModeWatchers.put(callback, cb); } try { - mService.startWatchingMode(op, packageName, cb); + mService.startWatchingModeWithFlags(op, packageName, flags, cb); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -2079,6 +2119,19 @@ public class AppOpsManager { return checkOpNoThrow(strOpToOp(op), uid, packageName); } + /** + * Like {@link #checkOp} but returns the raw mode associated with the op. + * Does not throw a security exception, does not translate {@link #MODE_FOREGROUND}. + * @hide + */ + public int unsafeCheckOpRaw(String op, int uid, String packageName) { + try { + return mService.checkOperation(strOpToOp(op), uid, packageName); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + /** * Make note of an application performing an operation. Note that you must pass * in both the uid and name of the application to be checked; this function will verify @@ -2217,7 +2270,8 @@ public class AppOpsManager { */ public int checkOpNoThrow(int op, int uid, String packageName) { try { - return mService.checkOperation(op, uid, packageName); + int mode = mService.checkOperation(op, uid, packageName); + return mode == AppOpsManager.MODE_FOREGROUND ? AppOpsManager.MODE_ALLOWED : mode; } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } -- cgit v1.2.3