Merge "[Permissions Hub Refactor] Expose AppOpsManager#OnOpNotedListener and AppOpsManager#start/stopWatchingNoted as System API"
This commit is contained in:
committed by
Android (Google) Code Review
commit
ee08e5f859
@@ -548,6 +548,8 @@ package android.app {
|
||||
method @Nullable public static String opToPermission(@NonNull String);
|
||||
method @RequiresPermission("android.permission.MANAGE_APP_OPS_MODES") public void setMode(@NonNull String, int, @Nullable String, int);
|
||||
method @RequiresPermission("android.permission.MANAGE_APP_OPS_MODES") public void setUidMode(@NonNull String, int, int);
|
||||
method @RequiresPermission(value="android.permission.WATCH_APPOPS", conditional=true) public void startWatchingNoted(@NonNull String[], @NonNull android.app.AppOpsManager.OnOpNotedListener);
|
||||
method public void stopWatchingNoted(@NonNull android.app.AppOpsManager.OnOpNotedListener);
|
||||
field public static final int HISTORY_FLAGS_ALL = 3; // 0x3
|
||||
field public static final int HISTORY_FLAG_AGGREGATE = 1; // 0x1
|
||||
field public static final int HISTORY_FLAG_DISCRETE = 2; // 0x2
|
||||
@@ -735,6 +737,10 @@ package android.app {
|
||||
field @NonNull public static final android.os.Parcelable.Creator<android.app.AppOpsManager.HistoricalUidOps> CREATOR;
|
||||
}
|
||||
|
||||
public static interface AppOpsManager.OnOpNotedListener {
|
||||
method public void onOpNoted(@NonNull String, int, @NonNull String, @Nullable String, int, int);
|
||||
}
|
||||
|
||||
public static final class AppOpsManager.OpEntry implements android.os.Parcelable {
|
||||
method public int describeContents();
|
||||
method @NonNull public java.util.Map<java.lang.String,android.app.AppOpsManager.AttributedOpEntry> getAttributedOpEntries();
|
||||
|
||||
@@ -6844,22 +6844,52 @@ public class AppOpsManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for notification of an op being noted.
|
||||
* Callback for notification of an app-op being noted.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
public interface OnOpNotedListener {
|
||||
/**
|
||||
* Called when an op was noted.
|
||||
* @param code The op code.
|
||||
* Called when an app-op is noted.
|
||||
*
|
||||
* @param op The operation that was noted.
|
||||
* @param uid The UID performing the operation.
|
||||
* @param packageName The package performing the operation.
|
||||
* @param attributionTag The attribution tag performing the operation.
|
||||
* @param flags The flags of this op
|
||||
* @param result The result of the note.
|
||||
*/
|
||||
void onOpNoted(int code, int uid, String packageName, String attributionTag,
|
||||
@OpFlags int flags, @Mode int result);
|
||||
void onOpNoted(@NonNull String op, int uid, @NonNull String packageName,
|
||||
@Nullable String attributionTag, @OpFlags int flags, @Mode int result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for notification of an app-op being noted to be used within platform code.
|
||||
*
|
||||
* This allows being notified using raw op codes instead of string op names.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public interface OnOpNotedInternalListener extends OnOpNotedListener {
|
||||
/**
|
||||
* Called when an app-op is noted.
|
||||
*
|
||||
* @param code The code of the operation that was noted.
|
||||
* @param uid The UID performing the operation.
|
||||
* @param packageName The package performing the operation.
|
||||
* @param attributionTag The attribution tag performing the operation.
|
||||
* @param flags The flags of this op
|
||||
* @param result The result of the note.
|
||||
*/
|
||||
void onOpNoted(int code, int uid, @NonNull String packageName,
|
||||
@Nullable String attributionTag, @OpFlags int flags, @Mode int result);
|
||||
|
||||
@Override
|
||||
default void onOpNoted(@NonNull String op, int uid, @NonNull String packageName,
|
||||
@Nullable String attributionTag, @OpFlags int flags, @Mode int result) {
|
||||
onOpNoted(strOpToOp(op), uid, packageName, attributionTag, flags, result);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -7654,13 +7684,42 @@ public class AppOpsManager {
|
||||
* @param ops The ops to watch.
|
||||
* @param callback Where to report changes.
|
||||
*
|
||||
* @see #startWatchingActive(int[], OnOpActiveChangedListener)
|
||||
* @see #startWatchingStarted(int[], OnOpStartedListener)
|
||||
* @see #stopWatchingNoted(OnOpNotedListener)
|
||||
* @see #noteOp(String, int, String, String, String)
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
@RequiresPermission(value=Manifest.permission.WATCH_APPOPS, conditional=true)
|
||||
public void startWatchingNoted(@NonNull String[] ops, @NonNull OnOpNotedListener callback) {
|
||||
final int[] intOps = new int[ops.length];
|
||||
for (int i = 0; i < ops.length; i++) {
|
||||
intOps[i] = strOpToOp(ops[i]);
|
||||
}
|
||||
startWatchingNoted(intOps, callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Start watching for noted app ops. An app op may be immediate or long running.
|
||||
* Immediate ops are noted while long running ones are started and stopped. This
|
||||
* method allows registering a listener to be notified when an app op is noted. If
|
||||
* an op is being noted by any package you will get a callback. To change the
|
||||
* watched ops for a registered callback you need to unregister and register it again.
|
||||
*
|
||||
* <p> If you don't hold the {@link android.Manifest.permission#WATCH_APPOPS} permission
|
||||
* you can watch changes only for your UID.
|
||||
*
|
||||
* This allows observing noted ops by their raw op codes instead of string op names.
|
||||
*
|
||||
* @param ops The ops to watch.
|
||||
* @param callback Where to report changes.
|
||||
*
|
||||
* @see #startWatchingActive(int[], OnOpActiveChangedListener)
|
||||
* @see #startWatchingStarted(int[], OnOpStartedListener)
|
||||
* @see #startWatchingNoted(String[], OnOpNotedListener)
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@RequiresPermission(value=Manifest.permission.WATCH_APPOPS, conditional=true)
|
||||
public void startWatchingNoted(@NonNull int[] ops, @NonNull OnOpNotedListener callback) {
|
||||
IAppOpsNotedCallback cb;
|
||||
@@ -7673,7 +7732,10 @@ public class AppOpsManager {
|
||||
@Override
|
||||
public void opNoted(int op, int uid, String packageName, String attributionTag,
|
||||
int flags, int mode) {
|
||||
callback.onOpNoted(op, uid, packageName, attributionTag, flags, mode);
|
||||
if (sAppOpInfos[op].name != null) {
|
||||
callback.onOpNoted(sAppOpInfos[op].name, uid, packageName, attributionTag,
|
||||
flags, mode);
|
||||
}
|
||||
}
|
||||
};
|
||||
mNotedWatchers.put(callback, cb);
|
||||
@@ -7689,11 +7751,12 @@ public class AppOpsManager {
|
||||
* Stop watching for noted app ops. An app op may be immediate or long running.
|
||||
* Unregistering a non-registered callback has no effect.
|
||||
*
|
||||
* @see #startWatchingNoted(int[], OnOpNotedListener)
|
||||
* @see #startWatchingNoted(String[], OnOpNotedListener)
|
||||
* @see #noteOp(String, int, String, String, String)
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
public void stopWatchingNoted(@NonNull OnOpNotedListener callback) {
|
||||
synchronized (mNotedWatchers) {
|
||||
final IAppOpsNotedCallback cb = mNotedWatchers.remove(callback);
|
||||
|
||||
@@ -64,7 +64,7 @@ import javax.inject.Inject;
|
||||
@SysUISingleton
|
||||
public class AppOpsControllerImpl extends BroadcastReceiver implements AppOpsController,
|
||||
AppOpsManager.OnOpActiveChangedListener,
|
||||
AppOpsManager.OnOpNotedListener, IndividualSensorPrivacyController.Callback,
|
||||
AppOpsManager.OnOpNotedInternalListener, IndividualSensorPrivacyController.Callback,
|
||||
Dumpable {
|
||||
|
||||
// This is the minimum time that we will keep AppOps that are noted on record. If multiple
|
||||
|
||||
@@ -2787,8 +2787,8 @@ public final class ActiveServices {
|
||||
}
|
||||
}
|
||||
|
||||
private final AppOpsManager.OnOpNotedListener mOpNotedCallback =
|
||||
new AppOpsManager.OnOpNotedListener() {
|
||||
private final AppOpsManager.OnOpNotedInternalListener mOpNotedCallback =
|
||||
new AppOpsManager.OnOpNotedInternalListener() {
|
||||
@Override
|
||||
public void onOpNoted(int op, int uid, String pkgName,
|
||||
String attributionTag, int flags, int result) {
|
||||
|
||||
@@ -223,7 +223,7 @@ public final class SensorPrivacyService extends SystemService {
|
||||
}
|
||||
|
||||
class SensorPrivacyServiceImpl extends ISensorPrivacyManager.Stub implements
|
||||
AppOpsManager.OnOpNotedListener, AppOpsManager.OnOpStartedListener,
|
||||
AppOpsManager.OnOpNotedInternalListener, AppOpsManager.OnOpStartedListener,
|
||||
IBinder.DeathRecipient, UserManagerInternal.UserRestrictionsListener {
|
||||
|
||||
private final SensorPrivacyHandler mHandler;
|
||||
|
||||
@@ -64,12 +64,12 @@ public class AppOpsNotedWatcherTest {
|
||||
// Verify that we got called for the ops being noted
|
||||
final InOrder inOrder = inOrder(listener);
|
||||
inOrder.verify(listener, timeout(NOTIFICATION_TIMEOUT_MILLIS)
|
||||
.times(1)).onOpNoted(eq(AppOpsManager.OP_FINE_LOCATION),
|
||||
.times(1)).onOpNoted(eq(AppOpsManager.OPSTR_FINE_LOCATION),
|
||||
eq(Process.myUid()), eq(getContext().getPackageName()),
|
||||
eq(getContext().getAttributionTag()), eq(AppOpsManager.OP_FLAG_SELF),
|
||||
eq(AppOpsManager.MODE_ALLOWED));
|
||||
inOrder.verify(listener, timeout(NOTIFICATION_TIMEOUT_MILLIS)
|
||||
.times(1)).onOpNoted(eq(AppOpsManager.OP_CAMERA),
|
||||
.times(1)).onOpNoted(eq(AppOpsManager.OPSTR_CAMERA),
|
||||
eq(Process.myUid()), eq(getContext().getPackageName()),
|
||||
eq(getContext().getAttributionTag()), eq(AppOpsManager.OP_FLAG_SELF),
|
||||
eq(AppOpsManager.MODE_ALLOWED));
|
||||
@@ -94,7 +94,7 @@ public class AppOpsNotedWatcherTest {
|
||||
|
||||
// Verify it's watched again
|
||||
verify(listener, timeout(NOTIFICATION_TIMEOUT_MILLIS)
|
||||
.times(2)).onOpNoted(eq(AppOpsManager.OP_FINE_LOCATION),
|
||||
.times(2)).onOpNoted(eq(AppOpsManager.OPSTR_FINE_LOCATION),
|
||||
eq(Process.myUid()), eq(getContext().getPackageName()),
|
||||
eq(getContext().getAttributionTag()), eq(AppOpsManager.OP_FLAG_SELF),
|
||||
eq(AppOpsManager.MODE_ALLOWED));
|
||||
|
||||
Reference in New Issue
Block a user