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

Commit d67461e3 authored by Automerger Merge Worker's avatar Automerger Merge Worker
Browse files

Rename AppOpsCollector -> OnOpNotedCallback am: 5892a8f7

Change-Id: I42fd4209b26050206c7e5d1396ca65d69ea972b8
parents 829fa681 5892a8f7
Loading
Loading
Loading
Loading
+9 −10
Original line number Diff line number Diff line
@@ -4368,7 +4368,7 @@ package android.app {
    method @Deprecated public int noteProxyOpNoThrow(@NonNull String, @Nullable String, int);
    method public int noteProxyOpNoThrow(@NonNull String, @Nullable String, int, @Nullable String, @Nullable String);
    method @Nullable public static String permissionToOp(@NonNull String);
    method public void setNotedAppOpsCollector(@Nullable android.app.AppOpsManager.AppOpsCollector);
    method public void setOnOpNotedCallback(@Nullable java.util.concurrent.Executor, @Nullable android.app.AppOpsManager.OnOpNotedCallback);
    method @Deprecated public int startOp(@NonNull String, int, @NonNull String);
    method public int startOp(@NonNull String, int, @Nullable String, @Nullable String, @Nullable String);
    method @Deprecated public int startOpNoThrow(@NonNull String, int, @NonNull String);
@@ -4424,14 +4424,6 @@ package android.app {
    field public static final int WATCH_FOREGROUND_CHANGES = 1; // 0x1
  }
  public abstract static class AppOpsManager.AppOpsCollector {
    ctor public AppOpsManager.AppOpsCollector();
    method @NonNull public java.util.concurrent.Executor getAsyncNotedExecutor();
    method public abstract void onAsyncNoted(@NonNull android.app.AsyncNotedAppOp);
    method public abstract void onNoted(@NonNull android.app.SyncNotedAppOp);
    method public abstract void onSelfNoted(@NonNull android.app.SyncNotedAppOp);
  }
  public static interface AppOpsManager.OnOpActiveChangedListener {
    method public void onOpActiveChanged(@NonNull String, int, @NonNull String, boolean);
  }
@@ -4440,6 +4432,13 @@ package android.app {
    method public void onOpChanged(String, String);
  }
  public abstract static class AppOpsManager.OnOpNotedCallback {
    ctor public AppOpsManager.OnOpNotedCallback();
    method public abstract void onAsyncNoted(@NonNull android.app.AsyncNotedAppOp);
    method public abstract void onNoted(@NonNull android.app.SyncNotedAppOp);
    method public abstract void onSelfNoted(@NonNull android.app.SyncNotedAppOp);
  }
  public class Application extends android.content.ContextWrapper implements android.content.ComponentCallbacks2 {
    ctor public Application();
    method public static String getProcessName();
@@ -4591,7 +4590,7 @@ package android.app {
    method @NonNull public String getMessage();
    method @IntRange(from=0) public int getNotingUid();
    method @NonNull public String getOp();
    method @IntRange(from=0) public long getTime();
    method public long getTime();
    method public void writeToParcel(@NonNull android.os.Parcel, int);
    field @NonNull public static final android.os.Parcelable.Creator<android.app.AsyncNotedAppOp> CREATOR;
  }
+6 −0
Original line number Diff line number Diff line
@@ -11,6 +11,12 @@ package android.app {

  public class AppOpsManager {
    method @Deprecated @NonNull @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS) public java.util.List<android.app.AppOpsManager.PackageOps> getOpsForPackage(int, @NonNull String, @Nullable int[]);
    method @Deprecated public void setNotedAppOpsCollector(@Nullable android.app.AppOpsManager.AppOpsCollector);
  }

  @Deprecated public abstract static class AppOpsManager.AppOpsCollector extends android.app.AppOpsManager.OnOpNotedCallback {
    ctor public AppOpsManager.AppOpsCollector();
    method @NonNull public java.util.concurrent.Executor getAsyncNotedExecutor();
  }

  public class Notification implements android.os.Parcelable {
+104 −42
Original line number Diff line number Diff line
@@ -162,7 +162,7 @@ import java.util.function.Supplier;
 * might also make sense inside of a single app if the access is forwarded between two features of
 * the app.
 *
 * <p>An app can register an {@link AppOpsCollector} to get informed about what accesses the
 * <p>An app can register an {@link OnOpNotedCallback} to get informed about what accesses the
 * system is tracking for it. As each runtime permission has an associated app-op this API is
 * particularly useful for an app that want to find unexpected private data accesses.
 */
@@ -206,16 +206,16 @@ public class AppOpsManager {

    private static final Object sLock = new Object();

    /** Current {@link AppOpsCollector}. Change via {@link #setNotedAppOpsCollector} */
    /** Current {@link OnOpNotedCallback}. Change via {@link #setOnOpNotedCallback} */
    @GuardedBy("sLock")
    private static @Nullable AppOpsCollector sNotedAppOpsCollector;
    private static @Nullable OnOpNotedCallback sOnOpNotedCallback;

    /**
     * Additional collector that collect accesses and forwards a few of them them via
     * {@link IAppOpsService#reportRuntimeAppOpAccessMessageAndGetConfig}.
     */
    private static AppOpsCollector sMessageCollector =
            new AppOpsCollector() {
    private static OnOpNotedCallback sMessageCollector =
            new OnOpNotedCallback() {
                @Override
                public void onNoted(@NonNull SyncNotedAppOp op) {
                    reportStackTraceIfNeeded(op);
@@ -7800,8 +7800,8 @@ public class AppOpsManager {
     */
    private void collectNotedOpForSelf(int op, @Nullable String featureId) {
        synchronized (sLock) {
            if (sNotedAppOpsCollector != null) {
                sNotedAppOpsCollector.onSelfNoted(new SyncNotedAppOp(op, featureId));
            if (sOnOpNotedCallback != null) {
                sOnOpNotedCallback.onSelfNoted(new SyncNotedAppOp(op, featureId));
            }
        }
        sMessageCollector.onSelfNoted(new SyncNotedAppOp(op, featureId));
@@ -7950,8 +7950,8 @@ public class AppOpsManager {
                synchronized (sLock) {
                    for (int code = notedAppOps.nextSetBit(0); code != -1;
                            code = notedAppOps.nextSetBit(code + 1)) {
                        if (sNotedAppOpsCollector != null) {
                            sNotedAppOpsCollector.onNoted(new SyncNotedAppOp(code, featureId));
                        if (sOnOpNotedCallback != null) {
                            sOnOpNotedCallback.onNoted(new SyncNotedAppOp(code, featureId));
                        }
                    }
                }
@@ -7964,33 +7964,45 @@ public class AppOpsManager {
    }

    /**
     * Register a new {@link AppOpsCollector}.
     * Set a new {@link OnOpNotedCallback}.
     *
     * <p>There can only ever be one collector per process. If there currently is a collector
     * registered, it will be unregistered.
     * <p>There can only ever be one collector per process. If there currently is another callback
     * set, this will fail.
     *
     * <p><b>Only appops related to dangerous permissions are collected.</b>
     * @param asyncExecutor executor to execute {@link OnOpNotedCallback#onAsyncNoted} on, {@code
     * null} to unset
     * @param callback listener to set, {@code null} to unset
     *
     * @param collector The collector to set or {@code null} to unregister.
     * @throws IllegalStateException If another callback is already registered
     */
    public void setNotedAppOpsCollector(@Nullable AppOpsCollector collector) {
    public void setOnOpNotedCallback(@Nullable @CallbackExecutor Executor asyncExecutor,
            @Nullable OnOpNotedCallback callback) {
        Preconditions.checkState((callback == null) == (asyncExecutor == null));

        synchronized (sLock) {
            if (sNotedAppOpsCollector != null) {
            if (callback == null) {
                Preconditions.checkState(sOnOpNotedCallback != null,
                        "No callback is currently registered");

                try {
                    mService.stopWatchingAsyncNoted(mContext.getPackageName(),
                            sNotedAppOpsCollector.mAsyncCb);
                            sOnOpNotedCallback.mAsyncCb);
                } catch (RemoteException e) {
                    e.rethrowFromSystemServer();
                }
            }

            sNotedAppOpsCollector = collector;
                sOnOpNotedCallback = null;
            } else {
                Preconditions.checkState(sOnOpNotedCallback == null,
                        "Another callback is already registered");

                callback.mAsyncExecutor = asyncExecutor;
                sOnOpNotedCallback = callback;

            if (sNotedAppOpsCollector != null) {
                List<AsyncNotedAppOp> missedAsyncOps = null;
                try {
                    mService.startWatchingAsyncNoted(mContext.getPackageName(),
                            sNotedAppOpsCollector.mAsyncCb);
                            sOnOpNotedCallback.mAsyncCb);
                    missedAsyncOps = mService.extractAsyncOps(mContext.getPackageName());
                } catch (RemoteException e) {
                    e.rethrowFromSystemServer();
@@ -8000,10 +8012,9 @@ public class AppOpsManager {
                    int numMissedAsyncOps = missedAsyncOps.size();
                    for (int i = 0; i < numMissedAsyncOps; i++) {
                        final AsyncNotedAppOp asyncNotedAppOp = missedAsyncOps.get(i);
                        if (sNotedAppOpsCollector != null) {
                            sNotedAppOpsCollector.getAsyncNotedExecutor().execute(
                                    () -> sNotedAppOpsCollector.onAsyncNoted(
                                            asyncNotedAppOp));
                        if (sOnOpNotedCallback != null) {
                            sOnOpNotedCallback.getAsyncNotedExecutor().execute(
                                    () -> sOnOpNotedCallback.onAsyncNoted(asyncNotedAppOp));
                        }
                    }
                }
@@ -8011,27 +8022,50 @@ public class AppOpsManager {
        }
    }

    // TODO moltmann: Remove
    /**
     * Will be removed before R ships, leave it just to not break apps immediately.
     *
     * @removed
     *
     * @hide
     */
    @SystemApi
    @Deprecated
    public void setNotedAppOpsCollector(@Nullable AppOpsCollector collector) {
        synchronized (sLock) {
            if (collector != null) {
                if (isListeningForOpNoted()) {
                    setOnOpNotedCallback(null, null);
                }
                setOnOpNotedCallback(new HandlerExecutor(Handler.getMain()), collector);
            } else if (sOnOpNotedCallback != null) {
                setOnOpNotedCallback(null, null);
            }
        }
    }

    /**
     * @return {@code true} iff the process currently is currently collecting noted appops.
     *
     * @see #setNotedAppOpsCollector(AppOpsCollector)
     * @see #setOnOpNotedCallback
     *
     * @hide
     */
    public static boolean isCollectingNotedAppOps() {
        return sNotedAppOpsCollector != null;
    public static boolean isListeningForOpNoted() {
        return sOnOpNotedCallback != null;
    }

    /**
     * Callback an app can {@link #setNotedAppOpsCollector register} to monitor the app-ops the
     * Callback an app can {@link #setOnOpNotedCallback set} to monitor the app-ops the
     * system has tracked for it. I.e. each time any app calls {@link #noteOp} or {@link #startOp}
     * one of the callback methods of this object is called.
     * one of a method of this object is called.
     *
     * <p><b>There will be a callback for all app-ops related to runtime permissions, but not
     * <p><b>There will be a call for all app-ops related to runtime permissions, but not
     * necessarily for all other app-ops.
     *
     * <pre>
     * setNotedAppOpsCollector(new AppOpsCollector() {
     * setOnOpNotedCallback(getMainExecutor(), new OnOpNotedCallback() {
     *     ArraySet<Pair<String, String>> opsNotedForThisProcess = new ArraySet<>();
     *
     *     private synchronized void addAccess(String op, String accessLocation) {
@@ -8056,24 +8090,36 @@ public class AppOpsManager {
     * });
     * </pre>
     *
     * @see #setNotedAppOpsCollector
     * @see #setOnOpNotedCallback
     */
    public abstract static class AppOpsCollector {
    public abstract static class OnOpNotedCallback {
        private @NonNull Executor mAsyncExecutor;

        /** Callback registered with the system. This will receive the async notes ops */
        private final IAppOpsAsyncNotedCallback mAsyncCb = new IAppOpsAsyncNotedCallback.Stub() {
            @Override
            public void opNoted(AsyncNotedAppOp op) {
                Objects.requireNonNull(op);

                long token = Binder.clearCallingIdentity();
                try {
                    getAsyncNotedExecutor().execute(() -> onAsyncNoted(op));
                } finally {
                    Binder.restoreCallingIdentity(token);
                }
            }
        };

        // TODO moltmann: Remove
        /**
         * Will be removed before R ships.
         *
         * @return The executor for the system to use when calling {@link #onAsyncNoted}.
         *
         * @hide
         */
        public @NonNull Executor getAsyncNotedExecutor() {
            return new HandlerExecutor(Handler.getMain());
        protected @NonNull Executor getAsyncNotedExecutor() {
            return mAsyncExecutor;
        }

        /**
@@ -8083,7 +8129,7 @@ public class AppOpsManager {
         * <p>Called on the calling thread before the API returns. This allows the app to e.g.
         * collect stack traces to figure out where the access came from.
         *
         * @param op The op noted
         * @param op op noted
         */
        public abstract void onNoted(@NonNull SyncNotedAppOp op);

@@ -8093,7 +8139,7 @@ public class AppOpsManager {
         * <p>This is very similar to {@link #onNoted} only that the tracking was not caused by the
         * API provider in a separate process, but by one in the app's own process.
         *
         * @param op The op noted
         * @param op op noted
         */
        public abstract void onSelfNoted(@NonNull SyncNotedAppOp op);

@@ -8105,14 +8151,30 @@ public class AppOpsManager {
         * guaranteed. Due to how async calls work in Android this might even be delivered slightly
         * before the private data is delivered to the app.
         *
         * <p>If the app is not running or no {@link AppOpsCollector} is registered a small amount
         * of noted app-ops are buffered and then delivered as soon as a collector is registered.
         * <p>If the app is not running or no {@link OnOpNotedCallback} is registered a small amount
         * of noted app-ops are buffered and then delivered as soon as a listener is registered.
         *
         * @param asyncOp The op noted
         * @param asyncOp op noted
         */
        public abstract void onAsyncNoted(@NonNull AsyncNotedAppOp asyncOp);
    }

    // TODO moltmann: Remove
    /**
     * Will be removed before R ships, leave it just to not break apps immediately.
     *
     * @removed
     *
     * @hide
     */
    @SystemApi
    @Deprecated
    public abstract static class AppOpsCollector extends OnOpNotedCallback {
        public @NonNull Executor getAsyncNotedExecutor() {
            return new HandlerExecutor(Handler.getMain());
        }
    };

    /**
     * Generate a stack trace used for noted app-ops logging.
     *
+15 −15
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package android.app;

import android.annotation.CurrentTimeMillisLong;
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -27,10 +28,11 @@ import com.android.internal.util.Preconditions;

/**
 * When an {@link AppOpsManager#noteOp(String, int, String, String, String) app-op is noted} and the
 * app the app-op is noted for has a {@link AppOpsManager.AppOpsCollector} registered the note-event
 * needs to be delivered to the collector. Usually this is done via an {@link SyncNotedAppOp}, but
 * in some cases this is not possible. In this case an {@link AsyncNotedAppOp} is send to the system
 * server and then forwarded to the {@link AppOpsManager.AppOpsCollector} in the app.
 * app the app-op is noted for has a {@link AppOpsManager.OnOpNotedCallback} registered the
 * note-event needs to be delivered to the callback. Usually this is done via an
 * {@link SyncNotedAppOp}, but in some cases this is not possible. In this case an
 * {@link AsyncNotedAppOp} is send to the system server and then forwarded to the
 * {@link AppOpsManager.OnOpNotedCallback} in the app.
 */
@Immutable
@DataClass(genEqualsHashCode = true,
@@ -53,7 +55,7 @@ public final class AsyncNotedAppOp implements Parcelable {
    private final @NonNull String mMessage;

    /** Milliseconds since epoch when the op was noted */
    private final @IntRange(from = 0) long mTime;
    private final @CurrentTimeMillisLong long mTime;

    /**
     * @return Op that was noted.
@@ -70,7 +72,7 @@ public final class AsyncNotedAppOp implements Parcelable {



    // Code below generated by codegen v1.0.14.
    // Code below generated by codegen v1.0.15.
    //
    // DO NOT MODIFY!
    // CHECKSTYLE:OFF Generated code
@@ -104,7 +106,7 @@ public final class AsyncNotedAppOp implements Parcelable {
            @IntRange(from = 0) int notingUid,
            @Nullable String featureId,
            @NonNull String message,
            @IntRange(from = 0) long time) {
            @CurrentTimeMillisLong long time) {
        this.mOpCode = opCode;
        com.android.internal.util.AnnotationValidations.validate(
                IntRange.class, null, mOpCode,
@@ -119,8 +121,7 @@ public final class AsyncNotedAppOp implements Parcelable {
                NonNull.class, null, mMessage);
        this.mTime = time;
        com.android.internal.util.AnnotationValidations.validate(
                IntRange.class, null, mTime,
                "from", 0);
                CurrentTimeMillisLong.class, null, mTime);

        onConstructed();
    }
@@ -153,7 +154,7 @@ public final class AsyncNotedAppOp implements Parcelable {
     * Milliseconds since epoch when the op was noted
     */
    @DataClass.Generated.Member
    public @IntRange(from = 0) long getTime() {
    public @CurrentTimeMillisLong long getTime() {
        return mTime;
    }

@@ -240,8 +241,7 @@ public final class AsyncNotedAppOp implements Parcelable {
                NonNull.class, null, mMessage);
        this.mTime = time;
        com.android.internal.util.AnnotationValidations.validate(
                IntRange.class, null, mTime,
                "from", 0);
                CurrentTimeMillisLong.class, null, mTime);

        onConstructed();
    }
@@ -261,10 +261,10 @@ public final class AsyncNotedAppOp implements Parcelable {
    };

    @DataClass.Generated(
            time = 1583375913345L,
            codegenVersion = "1.0.14",
            time = 1583866178330L,
            codegenVersion = "1.0.15",
            sourceFile = "frameworks/base/core/java/android/app/AsyncNotedAppOp.java",
            inputSignatures = "private final @android.annotation.IntRange(from=0L) int mOpCode\nprivate final @android.annotation.IntRange(from=0L) int mNotingUid\nprivate final @android.annotation.Nullable java.lang.String mFeatureId\nprivate final @android.annotation.NonNull java.lang.String mMessage\nprivate final @android.annotation.IntRange(from=0L) long mTime\npublic @android.annotation.NonNull java.lang.String getOp()\nprivate  void onConstructed()\nclass AsyncNotedAppOp extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genEqualsHashCode=true, genAidl=true, genHiddenConstructor=true)")
            inputSignatures = "private final @android.annotation.IntRange(from=0L) int mOpCode\nprivate final @android.annotation.IntRange(from=0L) int mNotingUid\nprivate final @android.annotation.Nullable java.lang.String mFeatureId\nprivate final @android.annotation.NonNull java.lang.String mMessage\nprivate final @android.annotation.CurrentTimeMillisLong long mTime\npublic @android.annotation.NonNull java.lang.String getOp()\nprivate  void onConstructed()\nclass AsyncNotedAppOp extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genEqualsHashCode=true, genAidl=true, genHiddenConstructor=true)")
    @Deprecated
    private void __metadata() {}

+2 −2
Original line number Diff line number Diff line
@@ -28,9 +28,9 @@ import com.android.internal.util.DataClass;
 * Description of an app-op that was noted for the current process.
 *
 * <p>This is either delivered after a
 * {@link AppOpsManager.AppOpsCollector#onNoted(SyncNotedAppOp) two way binder call} or
 * {@link AppOpsManager.OnOpNotedCallback#onNoted(SyncNotedAppOp) two way binder call} or
 * when the app
 * {@link AppOpsManager.AppOpsCollector#onSelfNoted(SyncNotedAppOp) notes an app-op for
 * {@link AppOpsManager.OnOpNotedCallback#onSelfNoted(SyncNotedAppOp) notes an app-op for
 * itself}.
 */
@Immutable
Loading