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

Commit 8fb897ac authored by Svetoslav Ganov's avatar Svetoslav Ganov Committed by Automerger Merge Worker
Browse files

Merge "Prepare AttributionSource to expose to native" into sc-dev am: 720add59

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/14381260

Change-Id: I14f40269541872bf807f669283da9a6f3d722f97
parents 05ac36df 720add59
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -328,6 +328,7 @@ java_defaults {
        "tv_tuner_resource_manager_aidl_interface-java",
        "soundtrigger_middleware-aidl-java",
        "modules-utils-os",
        "framework-permission-aidl-java",
    ],
}

+5 −0
Original line number Diff line number Diff line
@@ -219,6 +219,7 @@ package android.app {
  public class AppOpsManager {
    method @RequiresPermission("android.permission.MANAGE_APPOPS") public void addHistoricalOps(@NonNull android.app.AppOpsManager.HistoricalOps);
    method @RequiresPermission("android.permission.MANAGE_APPOPS") public void clearHistory();
    method public static void collectNotedOpSync(@NonNull android.app.SyncNotedAppOp);
    method @RequiresPermission("android.permission.MANAGE_APPOPS") public void getHistoricalOpsFromDiskRaw(@NonNull android.app.AppOpsManager.HistoricalOpsRequest, @Nullable java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.app.AppOpsManager.HistoricalOps>);
    method public static int getNumOps();
    method public boolean isOperationActive(int, int, String);
@@ -360,6 +361,10 @@ package android.app {
    method @RequiresPermission(android.Manifest.permission.STATUS_BAR) public void setExpansionDisabledForSimNetworkLock(boolean);
  }

  public final class SyncNotedAppOp implements android.os.Parcelable {
    ctor public SyncNotedAppOp(int, @IntRange(from=0L) int, @Nullable String, @NonNull String);
  }

  public class TaskInfo {
    method public boolean containsLaunchCookie(@NonNull android.os.IBinder);
    method @NonNull public android.content.res.Configuration getConfiguration();
+120 −105
Original line number Diff line number Diff line
@@ -2783,14 +2783,24 @@ public class AppOpsManager {
    private static final ThreadLocal<Integer> sBinderThreadCallingUid = new ThreadLocal<>();

    /**
     * If a thread is currently executing a two-way binder transaction, this stores the op-codes of
     * the app-ops that were noted during this transaction.
     * Optimization: we need to propagate to IPCs whether the current thread is collecting
     * app ops but using only the thread local above is too slow as it requires a map lookup
     * on every IPC. We add this static var that is lockless and stores an OR-ed mask of the
     * thread id's currently collecting ops, thus reducing the map lookup to a simple bit
     * operation except the extremely unlikely case when threads with overlapping id bits
     * execute op collecting ops.
     */
    private static volatile long sThreadsListeningForOpNotedInBinderTransaction = 0L;

    /**
     * If a thread is currently executing a two-way binder transaction, this stores the
     * ops that were noted blaming any app (the caller, the caller of the caller, etc).
     *
     * @see #getNotedOpCollectionMode
     * @see #collectNotedOpSync
     */
    private static final ThreadLocal<ArrayMap<String, long[]>> sAppOpsNotedInThisBinderTransaction =
            new ThreadLocal<>();
    private static final ThreadLocal<ArrayMap<String, ArrayMap<String, long[]>>>
            sAppOpsNotedInThisBinderTransaction = new ThreadLocal<>();

    /** Whether noting for an appop should be collected */
    private static final @ShouldCollectNoteOp byte[] sAppOpsToNote = new byte[_NUM_OP];
@@ -8872,69 +8882,10 @@ public class AppOpsManager {
     * @hide
     */
    public static void startNotedAppOpsCollection(int callingUid) {
        sThreadsListeningForOpNotedInBinderTransaction |= Thread.currentThread().getId();
        sBinderThreadCallingUid.set(callingUid);
    }

    /**
     * State of a temporarily paused noted app-ops collection.
     *
     * @see #pauseNotedAppOpsCollection()
     *
     * @hide
     */
    public static class PausedNotedAppOpsCollection {
        final int mUid;
        final @Nullable ArrayMap<String, long[]> mCollectedNotedAppOps;

        PausedNotedAppOpsCollection(int uid, @Nullable ArrayMap<String,
                long[]> collectedNotedAppOps) {
            mUid = uid;
            mCollectedNotedAppOps = collectedNotedAppOps;
        }
    }

    /**
     * Temporarily suspend collection of noted app-ops when binder-thread calls into the other
     * process. During such a call there might be call-backs coming back on the same thread which
     * should not be accounted to the current collection.
     *
     * @return a state needed to resume the collection
     *
     * @hide
     */
    public static @Nullable PausedNotedAppOpsCollection pauseNotedAppOpsCollection() {
        Integer previousUid = sBinderThreadCallingUid.get();
        if (previousUid != null) {
            ArrayMap<String, long[]> previousCollectedNotedAppOps =
                    sAppOpsNotedInThisBinderTransaction.get();

            sBinderThreadCallingUid.remove();
            sAppOpsNotedInThisBinderTransaction.remove();

            return new PausedNotedAppOpsCollection(previousUid, previousCollectedNotedAppOps);
        }

        return null;
    }

    /**
     * Resume a collection paused via {@link #pauseNotedAppOpsCollection}.
     *
     * @param prevCollection The state of the previous collection
     *
     * @hide
     */
    public static void resumeNotedAppOpsCollection(
            @Nullable PausedNotedAppOpsCollection prevCollection) {
        if (prevCollection != null) {
            sBinderThreadCallingUid.set(prevCollection.mUid);

            if (prevCollection.mCollectedNotedAppOps != null) {
                sAppOpsNotedInThisBinderTransaction.set(prevCollection.mCollectedNotedAppOps);
            }
        }
    }

    /**
     * Finish collection of noted appops on this thread.
     *
@@ -8946,6 +8897,7 @@ public class AppOpsManager {
     */
    public static void finishNotedAppOpsCollection() {
        sBinderThreadCallingUid.remove();
        sThreadsListeningForOpNotedInBinderTransaction &= ~Thread.currentThread().getId();
        sAppOpsNotedInThisBinderTransaction.remove();
    }

@@ -8970,28 +8922,52 @@ public class AppOpsManager {
     * <p> Delivered to caller via {@link #prefixParcelWithAppOpsIfNeeded}
     *
     * @param syncOp the op and attribution tag to note for
     *
     * @hide
     */
    private void collectNotedOpSync(@NonNull SyncNotedAppOp syncOp) {
    @TestApi
    public static void collectNotedOpSync(@NonNull SyncNotedAppOp syncOp) {
        collectNotedOpSync(sOpStrToOp.get(syncOp.getOp()), syncOp.getAttributionTag(),
                syncOp.getPackageName());
    }

    /**
     * Collect a noted op when inside of a two-way binder call.
     *
     * <p> Delivered to caller via {@link #prefixParcelWithAppOpsIfNeeded}
     *
     * @param code the op code to note for
     * @param attributionTag the attribution tag to note for
     * @param packageName the package to note for
     */
    private static void collectNotedOpSync(int code, @Nullable String attributionTag,
            @NonNull String packageName) {
        // If this is inside of a two-way binder call:
        // We are inside of a two-way binder call. Delivered to caller via
        // {@link #prefixParcelWithAppOpsIfNeeded}
        int op = sOpStrToOp.get(syncOp.getOp());
        ArrayMap<String, long[]> appOpsNoted = sAppOpsNotedInThisBinderTransaction.get();
        ArrayMap<String, ArrayMap<String, long[]>> appOpsNoted =
                sAppOpsNotedInThisBinderTransaction.get();
        if (appOpsNoted == null) {
            appOpsNoted = new ArrayMap<>(1);
            sAppOpsNotedInThisBinderTransaction.set(appOpsNoted);
        }

        long[] appOpsNotedForAttribution = appOpsNoted.get(syncOp.getAttributionTag());
        ArrayMap<String, long[]> packageAppOpsNotedForAttribution = appOpsNoted.get(packageName);
        if (packageAppOpsNotedForAttribution == null) {
            packageAppOpsNotedForAttribution = new ArrayMap<>(1);
            appOpsNoted.put(packageName, packageAppOpsNotedForAttribution);
        }

        long[] appOpsNotedForAttribution = packageAppOpsNotedForAttribution.get(attributionTag);
        if (appOpsNotedForAttribution == null) {
            appOpsNotedForAttribution = new long[2];
            appOpsNoted.put(syncOp.getAttributionTag(), appOpsNotedForAttribution);
            packageAppOpsNotedForAttribution.put(attributionTag, appOpsNotedForAttribution);
        }

        if (op < 64) {
            appOpsNotedForAttribution[0] |= 1L << op;
        if (code < 64) {
            appOpsNotedForAttribution[0] |= 1L << code;
        } else {
            appOpsNotedForAttribution[1] |= 1L << (op - 64);
            appOpsNotedForAttribution[1] |= 1L << (code - 64);
        }
    }

@@ -9045,9 +9021,7 @@ public class AppOpsManager {
            }
        }

        Integer binderUid = sBinderThreadCallingUid.get();

        if (binderUid != null && binderUid == uid) {
        if (isListeningForOpNotedInBinderTransaction()) {
            return COLLECT_SYNC;
        } else {
            return COLLECT_ASYNC;
@@ -9064,21 +9038,31 @@ public class AppOpsManager {
     *
     * @hide
     */
    // TODO (b/186872903) Refactor how sync noted ops are propagaged.
    public static void prefixParcelWithAppOpsIfNeeded(@NonNull Parcel p) {
        ArrayMap<String, long[]> notedAppOps = sAppOpsNotedInThisBinderTransaction.get();
        final ArrayMap<String, ArrayMap<String, long[]>> notedAppOps =
                sAppOpsNotedInThisBinderTransaction.get();
        if (notedAppOps == null) {
            return;
        }

        p.writeInt(Parcel.EX_HAS_NOTED_APPOPS_REPLY_HEADER);

        int numAttributionWithNotesAppOps = notedAppOps.size();
        p.writeInt(numAttributionWithNotesAppOps);
        final int packageCount = notedAppOps.size();
        p.writeInt(packageCount);

        for (int i = 0; i < numAttributionWithNotesAppOps; i++) {
        for (int i = 0; i < packageCount; i++) {
            p.writeString(notedAppOps.keyAt(i));
            p.writeLong(notedAppOps.valueAt(i)[0]);
            p.writeLong(notedAppOps.valueAt(i)[1]);

            final ArrayMap<String, long[]> notedTagAppOps = notedAppOps.valueAt(i);
            final int tagCount = notedTagAppOps.size();
            p.writeInt(tagCount);

            for (int j = 0; j < tagCount; j++) {
                p.writeString(notedTagAppOps.keyAt(j));
                p.writeLong(notedTagAppOps.valueAt(j)[0]);
                p.writeLong(notedTagAppOps.valueAt(j)[1]);
            }
        }
    }

@@ -9093,36 +9077,57 @@ public class AppOpsManager {
     * @hide
     */
    public static void readAndLogNotedAppops(@NonNull Parcel p) {
        int numAttributionsWithNotedAppOps = p.readInt();
        final int packageCount = p.readInt();
        if (packageCount <= 0) {
            return;
        }

        final String myPackageName = ActivityThread.currentPackageName();
        if (myPackageName == null) {
            return;
        }

        synchronized (sLock) {
            for (int i = 0; i < packageCount; i++) {
                final String packageName = p.readString();

        for (int i = 0; i < numAttributionsWithNotedAppOps; i++) {
            String attributionTag = p.readString();
            long[] rawNotedAppOps = new long[2];
                final int tagCount = p.readInt();
                for (int j = 0; j < tagCount; j++) {
                    final String attributionTag = p.readString();
                    final long[] rawNotedAppOps = new long[2];
                    rawNotedAppOps[0] = p.readLong();
                    rawNotedAppOps[1] = p.readLong();

            if (rawNotedAppOps[0] != 0 || rawNotedAppOps[1] != 0) {
                BitSet notedAppOps = BitSet.valueOf(rawNotedAppOps);
                    if (rawNotedAppOps[0] == 0 && rawNotedAppOps[1] == 0) {
                        continue;
                    }

                synchronized (sLock) {
                    final BitSet notedAppOps = BitSet.valueOf(rawNotedAppOps);
                    for (int code = notedAppOps.nextSetBit(0); code != -1;
                            code = notedAppOps.nextSetBit(code + 1)) {
                        if (myPackageName.equals(packageName)) {
                            if (sOnOpNotedCallback != null) {
                            sOnOpNotedCallback.onNoted(new SyncNotedAppOp(code, attributionTag));
                                sOnOpNotedCallback.onNoted(new SyncNotedAppOp(code,
                                        attributionTag, packageName));
                            } else {
                                String message = getFormattedStackTrace();
                            sUnforwardedOps.add(
                                    new AsyncNotedAppOp(code, Process.myUid(), attributionTag,
                                            message, System.currentTimeMillis()));
                                sUnforwardedOps.add(new AsyncNotedAppOp(code, Process.myUid(),
                                        attributionTag, message, System.currentTimeMillis()));
                                if (sUnforwardedOps.size() > MAX_UNFORWARDED_OPS) {
                                    sUnforwardedOps.remove(0);
                                }
                            }
                        } else if (isListeningForOpNotedInBinderTransaction()) {
                            collectNotedOpSync(code, attributionTag, packageName);
                        }
                    }
                    for (int code = notedAppOps.nextSetBit(0); code != -1;
                            code = notedAppOps.nextSetBit(code + 1)) {
                    sMessageCollector.onNoted(new SyncNotedAppOp(code, attributionTag));
                        if (myPackageName.equals(packageName)) {
                            sMessageCollector.onNoted(new SyncNotedAppOp(code,
                                    attributionTag, packageName));
                        }
                    }
                }
            }
        }
@@ -9229,7 +9234,17 @@ public class AppOpsManager {
     * @hide
     */
    public static boolean isListeningForOpNoted() {
        return sOnOpNotedCallback != null || isCollectingStackTraces();
        return sOnOpNotedCallback != null || isListeningForOpNotedInBinderTransaction()
                || isCollectingStackTraces();
    }

    /**
     * @return whether we are in a binder transaction and collecting appops.
     */
    private static boolean isListeningForOpNotedInBinderTransaction() {
        return (sThreadsListeningForOpNotedInBinderTransaction
                        & Thread.currentThread().getId()) != 0
                && sBinderThreadCallingUid.get() != null;
    }

    /**
+49 −5
Original line number Diff line number Diff line
@@ -19,7 +19,9 @@ package android.app;
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.TestApi;
import android.os.Parcelable;
import android.os.Process;

import com.android.internal.annotations.Immutable;
import com.android.internal.util.DataClass;
@@ -48,13 +50,19 @@ public final class SyncNotedAppOp implements Parcelable {
    private final @IntRange(from = 0L, to = AppOpsManager._NUM_OP - 1) int mOpCode;
    /** attributionTag of synchronous appop noted */
    private final @Nullable String mAttributionTag;
    /**
     * The package this op applies to
     * @hide
     */
    private final @NonNull String mPackageName;

    /**
     * Native code relies on parcel ordering, do not change
     * @hide
     */
    @TestApi
    public SyncNotedAppOp(int opMode, @IntRange(from = 0L) int opCode,
            @Nullable String attributionTag) {
            @Nullable String attributionTag, @NonNull String packageName) {
        this.mOpCode = opCode;
        com.android.internal.util.AnnotationValidations.validate(
                IntRange.class, null, mOpCode,
@@ -62,6 +70,7 @@ public final class SyncNotedAppOp implements Parcelable {
                "to", AppOpsManager._NUM_OP - 1);
        this.mAttributionTag = attributionTag;
        this.mOpMode = opMode;
        this.mPackageName = packageName;
    }

    /**
@@ -73,7 +82,25 @@ public final class SyncNotedAppOp implements Parcelable {
     *   attributionTag of synchronous appop noted
     */
    public SyncNotedAppOp(@IntRange(from = 0L) int opCode, @Nullable String attributionTag) {
        this(AppOpsManager.MODE_IGNORED, opCode, attributionTag);
        this(AppOpsManager.MODE_IGNORED, opCode, attributionTag, ActivityThread
                .currentPackageName());
    }

    /**
     * Creates a new SyncNotedAppOp.
     *
     * @param opCode
     *   op code of synchronous appop noted
     * @param attributionTag
     *   attributionTag of synchronous appop noted
     * @param packageName
     *   The package this op applies to
     *
     * @hide
     */
    public SyncNotedAppOp(@IntRange(from = 0L) int opCode, @Nullable String attributionTag,
            @NonNull String packageName) {
        this(AppOpsManager.MODE_IGNORED, opCode, attributionTag, packageName);
    }

    /**
@@ -113,6 +140,16 @@ public final class SyncNotedAppOp implements Parcelable {
        return mAttributionTag;
    }

    /**
     * The package this op applies to
     *
     * @hide
     */
    @DataClass.Generated.Member
    public @NonNull String getPackageName() {
        return mPackageName;
    }

    @Override
    @DataClass.Generated.Member
    public boolean equals(@Nullable Object o) {
@@ -128,7 +165,8 @@ public final class SyncNotedAppOp implements Parcelable {
        return true
                && mOpMode == that.mOpMode
                && mOpCode == that.mOpCode
                && java.util.Objects.equals(mAttributionTag, that.mAttributionTag);
                && java.util.Objects.equals(mAttributionTag, that.mAttributionTag)
                && java.util.Objects.equals(mPackageName, that.mPackageName);
    }

    @Override
@@ -141,6 +179,7 @@ public final class SyncNotedAppOp implements Parcelable {
        _hash = 31 * _hash + mOpMode;
        _hash = 31 * _hash + mOpCode;
        _hash = 31 * _hash + java.util.Objects.hashCode(mAttributionTag);
        _hash = 31 * _hash + java.util.Objects.hashCode(mPackageName);
        return _hash;
    }

@@ -156,6 +195,7 @@ public final class SyncNotedAppOp implements Parcelable {
        dest.writeInt(mOpMode);
        dest.writeInt(mOpCode);
        if (mAttributionTag != null) dest.writeString(mAttributionTag);
        dest.writeString(mPackageName);
    }

    @Override
@@ -173,6 +213,7 @@ public final class SyncNotedAppOp implements Parcelable {
        int opMode = in.readInt();
        int opCode = in.readInt();
        String attributionTag = (flg & 0x4) == 0 ? null : in.readString();
        String packageName = in.readString();

        this.mOpMode = opMode;
        this.mOpCode = opCode;
@@ -181,6 +222,9 @@ public final class SyncNotedAppOp implements Parcelable {
                "from", 0L,
                "to", AppOpsManager._NUM_OP - 1);
        this.mAttributionTag = attributionTag;
        this.mPackageName = packageName;
        com.android.internal.util.AnnotationValidations.validate(
                NonNull.class, null, mPackageName);

        // onConstructed(); // You can define this method to get a callback
    }
@@ -200,10 +244,10 @@ public final class SyncNotedAppOp implements Parcelable {
    };

    @DataClass.Generated(
            time = 1617317997768L,
            time = 1619711733947L,
            codegenVersion = "1.0.23",
            sourceFile = "frameworks/base/core/java/android/app/SyncNotedAppOp.java",
            inputSignatures = "private final  int mOpMode\nprivate final @android.annotation.IntRange int mOpCode\nprivate final @android.annotation.Nullable java.lang.String mAttributionTag\npublic @android.annotation.NonNull java.lang.String getOp()\npublic  int getOpMode()\nclass SyncNotedAppOp extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genEqualsHashCode=true, genAidl=true, genConstructor=false)")
            inputSignatures = "private final  int mOpMode\nprivate final @android.annotation.IntRange int mOpCode\nprivate final @android.annotation.Nullable java.lang.String mAttributionTag\nprivate final @android.annotation.NonNull java.lang.String mPackageName\npublic @android.annotation.NonNull java.lang.String getOp()\npublic  int getOpMode()\nclass SyncNotedAppOp extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genEqualsHashCode=true, genAidl=true, genConstructor=false)")
    @Deprecated
    private void __metadata() {}

+120 −265

File changed.

Preview size limit exceeded, changes collapsed.

Loading