Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit dbe69464 authored by Karishma Vakil's avatar Karishma Vakil
Browse files

[Permissions Hub Refactor] Add executor parameter to `startWatchingNoted` API...

[Permissions Hub Refactor] Add executor parameter to `startWatchingNoted` API along with an overload to run on the main thread.

* Also wrap all op strings into a @StringDef.

Bug: 265118296
Test: atest CtsAppOpsTestCases:AppOpsTest
Change-Id: I61e73b5e0c03f2f5d768caeb35832d10bde9ed7d
parent 52a61a8b
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -587,6 +587,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 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 java.util.concurrent.Executor, @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
+251 −27
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.StringDef;
import android.annotation.SuppressLint;
import android.annotation.SystemApi;
import android.annotation.SystemService;
@@ -1464,6 +1465,149 @@ public class AppOpsManager {
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
    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. */
    public static final String OPSTR_COARSE_LOCATION = "android:coarse_location";
    /** 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.
     * 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.
     * Start watching for noted app ops.
     *
     * <p> If you don't hold the {@link android.Manifest.permission#WATCH_APPOPS} permission
     * you can watch changes only for your UID.
     * <p> Similar to {@link #startWatchingNoted(String[], Executor, OnOpNotedListener)}, but
     * without an executor parameter.
     *
     * @param ops The ops to watch.
     * @param callback Where to report changes.
     * <p> Note that the listener will be called on the main thread using
     * {@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 #noteOp(String, int, String, String, String)
     *
@@ -7755,40 +7900,111 @@ public class AppOpsManager {
     */
    @SystemApi
    @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];
        for (int i = 0; i < ops.length; 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.
     * 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.
     * Start watching for noted app ops.
     *
     * <p> If you don't hold the {@link android.Manifest.permission#WATCH_APPOPS} permission
     * you can watch changes only for your UID.
     * <p> An app op may be immediate or long-running. Immediate ops are noted while long-running
     * 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.
     * @param callback Where to report changes.
     * <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 #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 #startWatchingStarted(int[], OnOpStartedListener)
     * @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
     */
    @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;
        synchronized (mNotedWatchers) {
            cb = mNotedWatchers.get(callback);
            cb = mNotedWatchers.get(listener);
            if (cb != null) {
                return;
            }
@@ -7796,13 +8012,21 @@ public class AppOpsManager {
                @Override
                public void opNoted(int op, int uid, String packageName, String attributionTag,
                        int flags, int mode) {
                    final long identity = Binder.clearCallingIdentity();
                    try {
                        executor.execute(() -> {
                            if (sAppOpInfos[op].name != null) {
                        callback.onOpNoted(sAppOpInfos[op].name, uid, packageName, attributionTag,
                                listener.onOpNoted(sAppOpInfos[op].name, uid, packageName,
                                        attributionTag,
                                        flags, mode);
                            }
                        });
                    } finally {
                        Binder.restoreCallingIdentity(identity);
                    }
                }
            };
            mNotedWatchers.put(callback, cb);
            mNotedWatchers.put(listener, cb);
        }
        try {
            mService.startWatchingNoted(ops, cb);