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

Commit 720add59 authored by Svetoslav Ganov's avatar Svetoslav Ganov Committed by Android (Google) Code Review
Browse files

Merge "Prepare AttributionSource to expose to native" into sc-dev

parents dc3608af 4bf102ae
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -326,6 +326,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