Merge "[Permissions Hub Refactor] Add executor parameter to startWatchingNoted API along with an overload to run on the main thread." into udc-dev

This commit is contained in:
Karishma Vakil
2023-02-26 01:58:14 +00:00
committed by Android (Google) Code Review
2 changed files with 252 additions and 27 deletions

View File

@@ -588,6 +588,7 @@ package android.app {
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 setMode(@NonNull String, int, @Nullable String, int);
method @RequiresPermission("android.permission.MANAGE_APP_OPS_MODES") public void setUidMode(@NonNull String, int, 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 @RequiresPermission(value="android.permission.WATCH_APPOPS", conditional=true) public void startWatchingNoted(@NonNull String[], @NonNull android.app.AppOpsManager.OnOpNotedListener);
method @RequiresPermission(value="android.permission.WATCH_APPOPS", conditional=true) public void startWatchingNoted(@NonNull String[], @NonNull java.util.concurrent.Executor, @NonNull android.app.AppOpsManager.OnOpNotedListener);
method public void stopWatchingNoted(@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_FLAGS_ALL = 3; // 0x3
field public static final int HISTORY_FLAG_AGGREGATE = 1; // 0x1 field public static final int HISTORY_FLAG_AGGREGATE = 1; // 0x1

View File

@@ -25,6 +25,7 @@ import android.annotation.IntRange;
import android.annotation.NonNull; import android.annotation.NonNull;
import android.annotation.Nullable; import android.annotation.Nullable;
import android.annotation.RequiresPermission; import android.annotation.RequiresPermission;
import android.annotation.StringDef;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.annotation.SystemApi; import android.annotation.SystemApi;
import android.annotation.SystemService; import android.annotation.SystemService;
@@ -1464,6 +1465,149 @@ public class AppOpsManager {
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public static final int _NUM_OP = 134; public static final int _NUM_OP = 134;
/**
* All app ops represented as strings.
*
* @hide
*/
@Retention(RetentionPolicy.SOURCE)
@StringDef(prefix = { "OPSTR_" }, value = {
OPSTR_COARSE_LOCATION,
OPSTR_FINE_LOCATION,
OPSTR_MONITOR_LOCATION,
OPSTR_MONITOR_HIGH_POWER_LOCATION,
OPSTR_GET_USAGE_STATS,
OPSTR_ACTIVATE_VPN,
OPSTR_READ_CONTACTS,
OPSTR_WRITE_CONTACTS,
OPSTR_READ_CALL_LOG,
OPSTR_WRITE_CALL_LOG,
OPSTR_READ_CALENDAR,
OPSTR_WRITE_CALENDAR,
OPSTR_CALL_PHONE,
OPSTR_READ_SMS,
OPSTR_RECEIVE_SMS,
OPSTR_RECEIVE_MMS,
OPSTR_RECEIVE_WAP_PUSH,
OPSTR_SEND_SMS,
OPSTR_CAMERA,
OPSTR_RECORD_AUDIO,
OPSTR_READ_PHONE_STATE,
OPSTR_ADD_VOICEMAIL,
OPSTR_USE_SIP,
OPSTR_PROCESS_OUTGOING_CALLS,
OPSTR_USE_FINGERPRINT,
OPSTR_BODY_SENSORS,
OPSTR_READ_CELL_BROADCASTS,
OPSTR_MOCK_LOCATION,
OPSTR_READ_EXTERNAL_STORAGE,
OPSTR_WRITE_EXTERNAL_STORAGE,
OPSTR_SYSTEM_ALERT_WINDOW,
OPSTR_WRITE_SETTINGS,
OPSTR_GET_ACCOUNTS,
OPSTR_READ_PHONE_NUMBERS,
OPSTR_PICTURE_IN_PICTURE,
OPSTR_INSTANT_APP_START_FOREGROUND,
OPSTR_ANSWER_PHONE_CALLS,
OPSTR_ACCEPT_HANDOVER,
OPSTR_GPS,
OPSTR_VIBRATE,
OPSTR_WIFI_SCAN,
OPSTR_POST_NOTIFICATION,
OPSTR_NEIGHBORING_CELLS,
OPSTR_WRITE_SMS,
OPSTR_RECEIVE_EMERGENCY_BROADCAST,
OPSTR_READ_ICC_SMS,
OPSTR_WRITE_ICC_SMS,
OPSTR_ACCESS_NOTIFICATIONS,
OPSTR_PLAY_AUDIO,
OPSTR_READ_CLIPBOARD,
OPSTR_WRITE_CLIPBOARD,
OPSTR_TAKE_MEDIA_BUTTONS,
OPSTR_TAKE_AUDIO_FOCUS,
OPSTR_AUDIO_MASTER_VOLUME,
OPSTR_AUDIO_VOICE_VOLUME,
OPSTR_AUDIO_RING_VOLUME,
OPSTR_AUDIO_MEDIA_VOLUME,
OPSTR_AUDIO_ALARM_VOLUME,
OPSTR_AUDIO_NOTIFICATION_VOLUME,
OPSTR_AUDIO_BLUETOOTH_VOLUME,
OPSTR_WAKE_LOCK,
OPSTR_MUTE_MICROPHONE,
OPSTR_TOAST_WINDOW,
OPSTR_PROJECT_MEDIA,
OPSTR_WRITE_WALLPAPER,
OPSTR_ASSIST_STRUCTURE,
OPSTR_ASSIST_SCREENSHOT,
OPSTR_TURN_SCREEN_ON,
OPSTR_RUN_IN_BACKGROUND,
OPSTR_AUDIO_ACCESSIBILITY_VOLUME,
OPSTR_REQUEST_INSTALL_PACKAGES,
OPSTR_RUN_ANY_IN_BACKGROUND,
OPSTR_CHANGE_WIFI_STATE,
OPSTR_REQUEST_DELETE_PACKAGES,
OPSTR_BIND_ACCESSIBILITY_SERVICE,
OPSTR_MANAGE_IPSEC_TUNNELS,
OPSTR_START_FOREGROUND,
OPSTR_BLUETOOTH_SCAN,
OPSTR_BLUETOOTH_CONNECT,
OPSTR_BLUETOOTH_ADVERTISE,
OPSTR_USE_BIOMETRIC,
OPSTR_ACTIVITY_RECOGNITION,
OPSTR_SMS_FINANCIAL_TRANSACTIONS,
OPSTR_READ_MEDIA_AUDIO,
OPSTR_WRITE_MEDIA_AUDIO,
OPSTR_READ_MEDIA_VIDEO,
OPSTR_WRITE_MEDIA_VIDEO,
OPSTR_READ_MEDIA_IMAGES,
OPSTR_WRITE_MEDIA_IMAGES,
OPSTR_LEGACY_STORAGE,
OPSTR_ACCESS_MEDIA_LOCATION,
OPSTR_ACCESS_ACCESSIBILITY,
OPSTR_READ_DEVICE_IDENTIFIERS,
OPSTR_QUERY_ALL_PACKAGES,
OPSTR_MANAGE_EXTERNAL_STORAGE,
OPSTR_AUTO_REVOKE_PERMISSIONS_IF_UNUSED,
OPSTR_AUTO_REVOKE_MANAGED_BY_INSTALLER,
OPSTR_INTERACT_ACROSS_PROFILES,
OPSTR_ACTIVATE_PLATFORM_VPN,
OPSTR_LOADER_USAGE_STATS,
OPSTR_MANAGE_ONGOING_CALLS,
OPSTR_NO_ISOLATED_STORAGE,
OPSTR_PHONE_CALL_MICROPHONE,
OPSTR_PHONE_CALL_CAMERA,
OPSTR_RECORD_AUDIO_HOTWORD,
OPSTR_MANAGE_CREDENTIALS,
OPSTR_USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER,
OPSTR_RECORD_AUDIO_OUTPUT,
OPSTR_SCHEDULE_EXACT_ALARM,
OPSTR_FINE_LOCATION_SOURCE,
OPSTR_COARSE_LOCATION_SOURCE,
OPSTR_MANAGE_MEDIA,
OPSTR_UWB_RANGING,
OPSTR_NEARBY_WIFI_DEVICES,
OPSTR_ACTIVITY_RECOGNITION_SOURCE,
OPSTR_RECORD_INCOMING_PHONE_AUDIO,
OPSTR_ESTABLISH_VPN_SERVICE,
OPSTR_ESTABLISH_VPN_MANAGER,
OPSTR_ACCESS_RESTRICTED_SETTINGS,
OPSTR_RECEIVE_AMBIENT_TRIGGER_AUDIO,
OPSTR_READ_MEDIA_VISUAL_USER_SELECTED,
OPSTR_READ_WRITE_HEALTH_DATA,
OPSTR_RECEIVE_EXPLICIT_USER_INTERACTION_AUDIO,
OPSTR_RUN_USER_INITIATED_JOBS,
OPSTR_SYSTEM_EXEMPT_FROM_SUSPENSION,
OPSTR_SYSTEM_EXEMPT_FROM_DISMISSIBLE_NOTIFICATIONS,
OPSTR_FOREGROUND_SERVICE_SPECIAL_USE,
OPSTR_SYSTEM_EXEMPT_FROM_POWER_RESTRICTIONS,
OPSTR_SYSTEM_EXEMPT_FROM_HIBERNATION,
OPSTR_SYSTEM_EXEMPT_FROM_ACTIVITY_BG_START_RESTRICTION,
OPSTR_CAPTURE_CONSENTLESS_BUGREPORT_ON_USERDEBUG_BUILD,
OPSTR_BODY_SENSORS_WRIST_TEMPERATURE,
OPSTR_USE_FULL_SCREEN_INTENT,
})
public @interface AppOpString {}
/** Access to coarse location information. */ /** Access to coarse location information. */
public static final String OPSTR_COARSE_LOCATION = "android:coarse_location"; public static final String OPSTR_COARSE_LOCATION = "android:coarse_location";
/** Access to fine location information. */ /** Access to fine location information. */
@@ -7736,18 +7880,19 @@ public class AppOpsManager {
} }
/** /**
* Start watching for noted app ops. An app op may be immediate or long running. * Start watching for noted app ops.
* 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 * <p> Similar to {@link #startWatchingNoted(String[], Executor, OnOpNotedListener)}, but
* you can watch changes only for your UID. * without an executor parameter.
* *
* @param ops The ops to watch. * <p> Note that the listener will be called on the main thread using
* @param callback Where to report changes. * {@link Context.getMainThread()}. To specify the execution thread, use
* {@link #startWatchingNoted(String[], Executor, OnOpNotedListener)}.
* *
* @param ops the ops to watch
* @param listener listener to notify when an app op is noted
*
* @see #startWatchingNoted(String[], Executor, OnOpNotedListener)
* @see #stopWatchingNoted(OnOpNotedListener) * @see #stopWatchingNoted(OnOpNotedListener)
* @see #noteOp(String, int, String, String, String) * @see #noteOp(String, int, String, String, String)
* *
@@ -7755,40 +7900,111 @@ public class AppOpsManager {
*/ */
@SystemApi @SystemApi
@RequiresPermission(value=Manifest.permission.WATCH_APPOPS, conditional=true) @RequiresPermission(value=Manifest.permission.WATCH_APPOPS, conditional=true)
public void startWatchingNoted(@NonNull String[] ops, @NonNull OnOpNotedListener callback) { public void startWatchingNoted(@NonNull @AppOpString String[] ops,
@NonNull OnOpNotedListener listener) {
final int[] intOps = new int[ops.length]; final int[] intOps = new int[ops.length];
for (int i = 0; i < ops.length; i++) { for (int i = 0; i < ops.length; i++) {
intOps[i] = strOpToOp(ops[i]); intOps[i] = strOpToOp(ops[i]);
} }
startWatchingNoted(intOps, callback); startWatchingNoted(intOps, listener);
} }
/** /**
* Start watching for noted app ops. An app op may be immediate or long running. * Start watching for noted app ops.
* 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 * <p> An app op may be immediate or long-running. Immediate ops are noted while long-running
* you can watch changes only for your UID. * ones are started and stopped.
* *
* This allows observing noted ops by their raw op codes instead of string op names. * <p> This method allows registering a listener to be notified when an app op is noted. To
* change the watched ops for a registered callback you need to unregister and register it
* again.
* *
* @param ops The ops to watch. * <p> If you don't hold the {@link android.Manifest.permission#WATCH_APPOPS} permission you can
* @param callback Where to report changes. * watch changes only for your UID.
*
* @param ops the ops to watch
* @param executor the executor on which the listener will be notified
* @param listener listener to notify when an app op is noted
*
* @see #startWatchingNoted(String[], OnOpNotedListener)
* @see #stopWatchingNoted(OnOpNotedListener)
* @see #noteOp(String, int, String, String, String)
*
* @hide
*/
@SystemApi
@RequiresPermission(value=Manifest.permission.WATCH_APPOPS, conditional=true)
public void startWatchingNoted(@NonNull @AppOpString String[] ops,
@CallbackExecutor @NonNull Executor executor, @NonNull OnOpNotedListener listener) {
final int[] intOps = new int[ops.length];
for (int i = 0; i < ops.length; i++) {
intOps[i] = strOpToOp(ops[i]);
}
startWatchingNoted(intOps, executor, listener);
}
/**
* Start watching for noted app ops.
*
* <p> Similar to {@link #startWatchingNoted(int[], Executor, OnOpNotedListener)}, but without
* an executor parameter.
*
* <p> This method is also similar to {@link #startWatchingNoted(String[], OnOpNotedListener)},
* but allows observing noted ops by their raw op codes instead of string op names.
*
* <p> Note that the listener will be called on the main thread using
* {@link Context.getMainThread()}. To specify the execution thread, use
* {@link {@link #startWatchingNoted(String[], Executor, OnOpNotedListener)}.
*
* @param ops the ops to watch
* @param listener listener to notify when an app op is noted
* *
* @see #startWatchingActive(int[], OnOpActiveChangedListener) * @see #startWatchingActive(int[], OnOpActiveChangedListener)
* @see #startWatchingStarted(int[], OnOpStartedListener) * @see #startWatchingStarted(int[], OnOpStartedListener)
* @see #startWatchingNoted(String[], OnOpNotedListener) * @see #startWatchingNoted(String[], OnOpNotedListener)
* @see #startWatchingNoted(int[], Executor, OnOpNotedListener)
*
* @hide
*/
@RequiresPermission(value=Manifest.permission.WATCH_APPOPS, conditional=true)
public void startWatchingNoted(@NonNull int[] ops, @NonNull OnOpNotedListener listener) {
startWatchingNoted(ops, mContext.getMainExecutor(), listener);
}
/**
* Start watching for noted app ops.
*
* <p> This method is similar to
* {@link #startWatchingNoted(String[], Executor, OnOpNotedListener)}, but allows observing
* noted ops by their raw op codes instead of string op names.
*
* <p> An app op may be immediate or long-running. Immediate ops are noted while long-running
* ones are started and stopped.
*
* <p> This method allows registering a listener to be notified when an app op is noted. 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.
*
* @param ops the ops to watch
* @param executor the executor on which the listener will be notified
* @param listener listener to notify when an app op is noted
*
* @see #startWatchingActive(int[], OnOpActiveChangedListener)
* @see #startWatchingStarted(int[], OnOpStartedListener)
* @see #startWatchingNoted(int[], Executor, OnOpNotedListener)
* @see #startWatchingNoted(String[], OnOpNotedListener)
* *
* @hide * @hide
*/ */
@RequiresPermission(value=Manifest.permission.WATCH_APPOPS, conditional=true) @RequiresPermission(value=Manifest.permission.WATCH_APPOPS, conditional=true)
public void startWatchingNoted(@NonNull int[] ops, @NonNull OnOpNotedListener callback) { public void startWatchingNoted(@NonNull int[] ops,
@CallbackExecutor @NonNull Executor executor, @NonNull OnOpNotedListener listener) {
IAppOpsNotedCallback cb; IAppOpsNotedCallback cb;
synchronized (mNotedWatchers) { synchronized (mNotedWatchers) {
cb = mNotedWatchers.get(callback); cb = mNotedWatchers.get(listener);
if (cb != null) { if (cb != null) {
return; return;
} }
@@ -7796,13 +8012,21 @@ public class AppOpsManager {
@Override @Override
public void opNoted(int op, int uid, String packageName, String attributionTag, public void opNoted(int op, int uid, String packageName, String attributionTag,
int flags, int mode) { int flags, int mode) {
final long identity = Binder.clearCallingIdentity();
try {
executor.execute(() -> {
if (sAppOpInfos[op].name != null) { if (sAppOpInfos[op].name != null) {
callback.onOpNoted(sAppOpInfos[op].name, uid, packageName, attributionTag, listener.onOpNoted(sAppOpInfos[op].name, uid, packageName,
attributionTag,
flags, mode); flags, mode);
} }
});
} finally {
Binder.restoreCallingIdentity(identity);
}
} }
}; };
mNotedWatchers.put(callback, cb); mNotedWatchers.put(listener, cb);
} }
try { try {
mService.startWatchingNoted(ops, cb); mService.startWatchingNoted(ops, cb);