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

Commit 0be6fcd0 authored by Jeff Sharkey's avatar Jeff Sharkey Committed by Android (Google) Code Review
Browse files

Merge changes from topic "activez"

* changes:
  Public API to check and note media operations.
  Public API to watch for "active" operations.
parents 4448f164 5997cc85
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -4278,6 +4278,7 @@ package android.app {
    method @Deprecated public int checkOpNoThrow(@NonNull String, int, @NonNull String);
    method public void checkPackage(int, @NonNull String);
    method public void finishOp(@NonNull String, int, @NonNull String);
    method public boolean isOpActive(@NonNull String, int, @NonNull String);
    method public int noteOp(@NonNull String, int, @NonNull String);
    method public int noteOpNoThrow(@NonNull String, int, @NonNull String);
    method public int noteProxyOp(@NonNull String, @NonNull String);
@@ -4286,8 +4287,10 @@ package android.app {
    method public static String permissionToOp(String);
    method public int startOp(@NonNull String, int, @NonNull String);
    method public int startOpNoThrow(@NonNull String, int, @NonNull String);
    method public void startWatchingActive(@NonNull String[], @NonNull java.util.concurrent.Executor, @NonNull android.app.AppOpsManager.OnOpActiveChangedListener);
    method public void startWatchingMode(@NonNull String, @Nullable String, @NonNull android.app.AppOpsManager.OnOpChangedListener);
    method public void startWatchingMode(@NonNull String, @Nullable String, int, @NonNull android.app.AppOpsManager.OnOpChangedListener);
    method public void stopWatchingActive(@NonNull android.app.AppOpsManager.OnOpActiveChangedListener);
    method public void stopWatchingMode(@NonNull android.app.AppOpsManager.OnOpChangedListener);
    method public int unsafeCheckOp(@NonNull String, int, @NonNull String);
    method public int unsafeCheckOpNoThrow(@NonNull String, int, @NonNull String);
@@ -4335,6 +4338,10 @@ package android.app {
    field public static final int WATCH_FOREGROUND_CHANGES = 1; // 0x1
  }
  public static interface AppOpsManager.OnOpActiveChangedListener {
    method public void onOpActiveChanged(@NonNull String, int, @NonNull String, boolean);
  }
  public static interface AppOpsManager.OnOpChangedListener {
    method public void onOpChanged(String, String);
  }
+6 −0
Original line number Diff line number Diff line
@@ -353,6 +353,9 @@ package android.app {
    field public static final String OPSTR_PROJECT_MEDIA = "android:project_media";
    field public static final String OPSTR_READ_CLIPBOARD = "android:read_clipboard";
    field public static final String OPSTR_READ_ICC_SMS = "android:read_icc_sms";
    field public static final String OPSTR_READ_MEDIA_AUDIO = "android:read_media_audio";
    field public static final String OPSTR_READ_MEDIA_IMAGES = "android:read_media_images";
    field public static final String OPSTR_READ_MEDIA_VIDEO = "android:read_media_video";
    field public static final String OPSTR_RECEIVE_EMERGENCY_BROADCAST = "android:receive_emergency_broadcast";
    field public static final String OPSTR_REQUEST_DELETE_PACKAGES = "android:request_delete_packages";
    field public static final String OPSTR_REQUEST_INSTALL_PACKAGES = "android:request_install_packages";
@@ -368,6 +371,9 @@ package android.app {
    field public static final String OPSTR_WIFI_SCAN = "android:wifi_scan";
    field public static final String OPSTR_WRITE_CLIPBOARD = "android:write_clipboard";
    field public static final String OPSTR_WRITE_ICC_SMS = "android:write_icc_sms";
    field public static final String OPSTR_WRITE_MEDIA_AUDIO = "android:write_media_audio";
    field public static final String OPSTR_WRITE_MEDIA_IMAGES = "android:write_media_images";
    field public static final String OPSTR_WRITE_MEDIA_VIDEO = "android:write_media_video";
    field public static final String OPSTR_WRITE_SMS = "android:write_sms";
    field public static final String OPSTR_WRITE_WALLPAPER = "android:write_wallpaper";
    field public static final int OP_FLAGS_ALL = 31; // 0x1f
+6 −6
Original line number Diff line number Diff line
@@ -160,8 +160,6 @@ package android.app {
    method @RequiresPermission("android.permission.MANAGE_APP_OPS_MODES") public void setMode(int, int, String, int);
    method @RequiresPermission("android.permission.MANAGE_APP_OPS_MODES") public void setMode(String, int, String, int);
    method @RequiresPermission("android.permission.MANAGE_APP_OPS_MODES") public void setUidMode(String, int, int);
    method public void startWatchingActive(@NonNull int[], @NonNull android.app.AppOpsManager.OnOpActiveChangedListener);
    method public void stopWatchingActive(@NonNull android.app.AppOpsManager.OnOpActiveChangedListener);
    method public static int strOpToOp(@NonNull String);
    field public static final int HISTORICAL_MODE_DISABLED = 0; // 0x0
    field public static final int HISTORICAL_MODE_ENABLED_ACTIVE = 1; // 0x1
@@ -193,6 +191,9 @@ package android.app {
    field public static final String OPSTR_PROJECT_MEDIA = "android:project_media";
    field public static final String OPSTR_READ_CLIPBOARD = "android:read_clipboard";
    field public static final String OPSTR_READ_ICC_SMS = "android:read_icc_sms";
    field public static final String OPSTR_READ_MEDIA_AUDIO = "android:read_media_audio";
    field public static final String OPSTR_READ_MEDIA_IMAGES = "android:read_media_images";
    field public static final String OPSTR_READ_MEDIA_VIDEO = "android:read_media_video";
    field public static final String OPSTR_RECEIVE_EMERGENCY_BROADCAST = "android:receive_emergency_broadcast";
    field public static final String OPSTR_REQUEST_DELETE_PACKAGES = "android:request_delete_packages";
    field public static final String OPSTR_REQUEST_INSTALL_PACKAGES = "android:request_install_packages";
@@ -208,6 +209,9 @@ package android.app {
    field public static final String OPSTR_WIFI_SCAN = "android:wifi_scan";
    field public static final String OPSTR_WRITE_CLIPBOARD = "android:write_clipboard";
    field public static final String OPSTR_WRITE_ICC_SMS = "android:write_icc_sms";
    field public static final String OPSTR_WRITE_MEDIA_AUDIO = "android:write_media_audio";
    field public static final String OPSTR_WRITE_MEDIA_IMAGES = "android:write_media_images";
    field public static final String OPSTR_WRITE_MEDIA_VIDEO = "android:write_media_video";
    field public static final String OPSTR_WRITE_SMS = "android:write_sms";
    field public static final String OPSTR_WRITE_WALLPAPER = "android:write_wallpaper";
    field public static final int OP_COARSE_LOCATION = 0; // 0x0
@@ -293,10 +297,6 @@ package android.app {
    field @NonNull public static final android.os.Parcelable.Creator<android.app.AppOpsManager.HistoricalUidOps> CREATOR;
  }

  public static interface AppOpsManager.OnOpActiveChangedListener {
    method public void onOpActiveChanged(int, int, String, boolean);
  }

  public static final class AppOpsManager.OpEntry implements android.os.Parcelable {
    method public int describeContents();
    method public long getDuration();
+72 −25
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package android.app;

import android.Manifest;
import android.annotation.CallbackExecutor;
import android.annotation.IntDef;
import android.annotation.IntRange;
import android.annotation.NonNull;
@@ -29,6 +30,7 @@ import android.annotation.UnsupportedAppUsage;
import android.app.usage.UsageStatsManager;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ParceledListSlice;
import android.media.AudioAttributes.AttributeUsage;
import android.os.Binder;
@@ -1095,21 +1097,27 @@ public class AppOpsManager {
            "android:sms_financial_transactions";

    /** @hide Read media of audio type. */
    @SystemApi @TestApi
    public static final String OPSTR_READ_MEDIA_AUDIO = "android:read_media_audio";
    /** @hide Write media of audio type. */
    @SystemApi @TestApi
    public static final String OPSTR_WRITE_MEDIA_AUDIO = "android:write_media_audio";
    /** @hide Read media of video type. */
    @SystemApi @TestApi
    public static final String OPSTR_READ_MEDIA_VIDEO = "android:read_media_video";
    /** @hide Write media of video type. */
    @SystemApi @TestApi
    public static final String OPSTR_WRITE_MEDIA_VIDEO = "android:write_media_video";
    /** @hide Read media of image type. */
    @SystemApi @TestApi
    public static final String OPSTR_READ_MEDIA_IMAGES = "android:read_media_images";
    /** @hide Write media of image type. */
    @SystemApi @TestApi
    public static final String OPSTR_WRITE_MEDIA_IMAGES = "android:write_media_images";
    /** @hide Has a legacy (non-isolated) view of storage. */
    @TestApi
    @SystemApi
    @SystemApi @TestApi
    public static final String OPSTR_LEGACY_STORAGE = "android:legacy_storage";

    /** @hide Interact with accessibility. */
    @SystemApi
    public static final String OPSTR_ACCESS_ACCESSIBILITY = "android:access_accessibility";
@@ -4281,20 +4289,17 @@ public class AppOpsManager {

    /**
     * Callback for notification of changes to operation active state.
     *
     * @hide
     */
    @TestApi
    public interface OnOpActiveChangedListener {
        /**
         * Called when the active state of an app op changes.
         *
         * @param code The op code.
         * @param uid The UID performing the operation.
         * @param op The operation that changed.
         * @param packageName The package performing the operation.
         * @param active Whether the operation became active or inactive.
         */
        void onOpActiveChanged(int code, int uid, String packageName, boolean active);
        void onOpActiveChanged(@NonNull String op, int uid, @NonNull String packageName,
                boolean active);
    }

    /**
@@ -4324,6 +4329,16 @@ public class AppOpsManager {
        public void onOpChanged(int op, String packageName) { }
    }

    /**
     * Callback for notification of changes to operation state.
     * This allows you to see the raw op codes instead of strings.
     * @hide
     */
    public interface OnOpActiveChangedInternalListener extends OnOpActiveChangedListener {
        default void onOpActiveChanged(String op, int uid, String packageName, boolean active) { }
        default void onOpActiveChanged(int op, int uid, String packageName, boolean active) { }
    }

    AppOpsManager(Context context, IAppOpsService service) {
        mContext = context;
        mService = service;
@@ -4779,6 +4794,17 @@ public class AppOpsManager {
        }
    }

    /** {@hide} */
    @Deprecated
    public void startWatchingActive(@NonNull int[] ops,
            @NonNull OnOpActiveChangedListener callback) {
        final String[] strOps = new String[ops.length];
        for (int i = 0; i < ops.length; i++) {
            strOps[i] = opToPublicName(ops[i]);
        }
        startWatchingActive(strOps, mContext.getMainExecutor(), callback);
    }

    /**
     * Start watching for changes to the active state of app ops. An app op may be
     * long running and it has a clear start and stop delimiters. If an op is being
@@ -4786,26 +4812,25 @@ public class AppOpsManager {
     * 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> If you don't hold the {@code android.Manifest.permission#WATCH_APPOPS} permission
     * you can watch changes only for your UID.
     *
     * @param ops The ops to watch.
     * @param ops The operations to watch.
     * @param callback Where to report changes.
     *
     * @see #isOperationActive(int, int, String)
     * @see #stopWatchingActive(OnOpActiveChangedListener)
     * @see #isOperationActive
     * @see #stopWatchingActive
     * @see #startOp(int, int, String)
     * @see #finishOp(int, int, String)
     *
     * @hide
     */
    @TestApi
    // TODO: Uncomment below annotation once b/73559440 is fixed
    // @RequiresPermission(value=Manifest.permission.WATCH_APPOPS, conditional=true)
    public void startWatchingActive(@NonNull int[] ops,
    public void startWatchingActive(@NonNull String[] ops,
            @CallbackExecutor @NonNull Executor executor,
            @NonNull OnOpActiveChangedListener callback) {
        Preconditions.checkNotNull(ops, "ops cannot be null");
        Preconditions.checkNotNull(callback, "callback cannot be null");
        Objects.requireNonNull(ops);
        Objects.requireNonNull(executor);
        Objects.requireNonNull(callback);
        IAppOpsActiveCallback cb;
        synchronized (mActiveWatchers) {
            cb = mActiveWatchers.get(callback);
@@ -4815,13 +4840,25 @@ public class AppOpsManager {
            cb = new IAppOpsActiveCallback.Stub() {
                @Override
                public void opActiveChanged(int op, int uid, String packageName, boolean active) {
                    callback.onOpActiveChanged(op, uid, packageName, active);
                    executor.execute(() -> {
                        if (callback instanceof OnOpActiveChangedInternalListener) {
                            ((OnOpActiveChangedInternalListener) callback).onOpActiveChanged(op,
                                    uid, packageName, active);
                        }
                        if (sOpToString[op] != null) {
                            callback.onOpActiveChanged(sOpToString[op], uid, packageName, active);
                        }
                    });
                }
            };
            mActiveWatchers.put(callback, cb);
        }
        final int[] rawOps = new int[ops.length];
        for (int i = 0; i < ops.length; i++) {
            rawOps[i] = strOpToOp(ops[i]);
        }
        try {
            mService.startWatchingActive(ops, cb);
            mService.startWatchingActive(rawOps, cb);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
@@ -4832,14 +4869,11 @@ public class AppOpsManager {
     * long running and it has a clear start and stop delimiters. Unregistering a
     * non-registered callback has no effect.
     *
     * @see #isOperationActive#(int, int, String)
     * @see #startWatchingActive(int[], OnOpActiveChangedListener)
     * @see #isOperationActive
     * @see #startWatchingActive
     * @see #startOp(int, int, String)
     * @see #finishOp(int, int, String)
     *
     * @hide
     */
    @TestApi
    public void stopWatchingActive(@NonNull OnOpActiveChangedListener callback) {
        synchronized (mActiveWatchers) {
            final IAppOpsActiveCallback cb = mActiveWatchers.remove(callback);
@@ -5448,6 +5482,19 @@ public class AppOpsManager {
        finishOp(op, Process.myUid(), mContext.getOpPackageName());
    }

    /**
     * Checks whether the given op for a package is active.
     * <p>
     * If you don't hold the {@code android.Manifest.permission#WATCH_APPOPS}
     * permission you can query only for your UID.
     *
     * @see #finishOp(int)
     * @see #startOp(int)
     */
    public boolean isOpActive(@NonNull String op, int uid, @NonNull String packageName) {
        return isOperationActive(strOpToOp(op), uid, packageName);
    }

    /**
     * Checks whether the given op for a UID and package is active.
     *
+1 −1
Original line number Diff line number Diff line
@@ -50,7 +50,7 @@ import javax.inject.Singleton;
 */
@Singleton
public class AppOpsControllerImpl implements AppOpsController,
        AppOpsManager.OnOpActiveChangedListener,
        AppOpsManager.OnOpActiveChangedInternalListener,
        AppOpsManager.OnOpNotedListener, Dumpable {

    private static final long NOTED_OP_TIME_DELAY_MS = 5000;
Loading