Merge "[Permissions Hub Refactor] Expose AppOpsManager#OnOpNotedListener and AppOpsManager#start/stopWatchingNoted as System API"

This commit is contained in:
Karishma Vakil
2022-12-12 20:57:56 +00:00
committed by Android (Google) Code Review
6 changed files with 85 additions and 16 deletions

View File

@@ -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();

View File

@@ -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);

View File

@@ -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

View File

@@ -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) {

View File

@@ -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;

View File

@@ -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));