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

Commit e2942cb6 authored by Nate Myren's avatar Nate Myren Committed by Automerger Merge Worker
Browse files

Merge "Revert sync app op chain changes" into sc-dev am: 50ff5ac8

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

Change-Id: I63c16fa22d36295b9992740ea95ae69342f22307
parents 15f31990 50ff5ac8
Loading
Loading
Loading
Loading
+103 −100
Original line number Diff line number Diff line
@@ -2849,14 +2849,14 @@ 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
     * ops that were noted blaming any app (the caller, the caller of the caller, etc).
     * 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.
     *
     * @see #getNotedOpCollectionMode
     * @see #collectNotedOpSync
     */
    private static final ThreadLocal<ArrayMap<String, ArrayMap<String, long[]>>>
            sAppOpsNotedInThisBinderTransaction = new ThreadLocal<>();
    private static final ThreadLocal<ArrayMap<String, long[]>> sAppOpsNotedInThisBinderTransaction =
            new ThreadLocal<>();

    /** Whether noting for an appop should be collected */
    private static final @ShouldCollectNoteOp byte[] sAppOpsToNote = new byte[_NUM_OP];
@@ -9051,6 +9051,66 @@ public class AppOpsManager {
        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.
     *
@@ -9091,47 +9151,26 @@ public class AppOpsManager {
     */
    @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}
        ArrayMap<String, ArrayMap<String, long[]>> appOpsNoted =
                sAppOpsNotedInThisBinderTransaction.get();
        int op = sOpStrToOp.get(syncOp.getOp());
        ArrayMap<String, long[]> appOpsNoted = sAppOpsNotedInThisBinderTransaction.get();
        if (appOpsNoted == null) {
            appOpsNoted = new ArrayMap<>(1);
            sAppOpsNotedInThisBinderTransaction.set(appOpsNoted);
        }

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

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

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

@@ -9185,7 +9224,9 @@ public class AppOpsManager {
            }
        }

        if (isListeningForOpNotedInBinderTransaction()) {
        Integer binderUid = sBinderThreadCallingUid.get();

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

        p.writeInt(Parcel.EX_HAS_NOTED_APPOPS_REPLY_HEADER);

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

        for (int i = 0; i < packageCount; i++) {
        for (int i = 0; i < numAttributionWithNotesAppOps; i++) {
            p.writeString(notedAppOps.keyAt(i));

            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]);
            }
            p.writeLong(notedAppOps.valueAt(i)[0]);
            p.writeLong(notedAppOps.valueAt(i)[1]);
        }
    }

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

        final String myPackageName = ActivityThread.currentPackageName();
        int numAttributionsWithNotedAppOps = p.readInt();

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

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

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

                    final BitSet notedAppOps = BitSet.valueOf(rawNotedAppOps);
                synchronized (sLock) {
                    for (int code = notedAppOps.nextSetBit(0); code != -1;
                            code = notedAppOps.nextSetBit(code + 1)) {
                        if (Objects.equals(myPackageName, packageName)) {
                        if (sOnOpNotedCallback != null) {
                                sOnOpNotedCallback.onNoted(new SyncNotedAppOp(code,
                                        attributionTag, packageName));
                            sOnOpNotedCallback.onNoted(new SyncNotedAppOp(code, attributionTag));
                        } 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)) {
                        if (Objects.equals(myPackageName, packageName)) {
                            sMessageCollector.onNoted(new SyncNotedAppOp(code,
                                    attributionTag, packageName));
                        }
                    }
                    sMessageCollector.onNoted(new SyncNotedAppOp(code, attributionTag));
                }
            }
        }
@@ -9398,15 +9409,7 @@ public class AppOpsManager {
     * @hide
     */
    public static boolean isListeningForOpNoted() {
        return sOnOpNotedCallback != null || isListeningForOpNotedInBinderTransaction()
                || isCollectingStackTraces();
    }

    /**
     * @return whether we are in a binder transaction and collecting appops.
     */
    private static boolean isListeningForOpNotedInBinderTransaction() {
        return sBinderThreadCallingUid.get() != null;
        return sOnOpNotedCallback != null || isCollectingStackTraces();
    }

    /**
+2 −1
Original line number Diff line number Diff line
@@ -21,7 +21,6 @@ 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;
@@ -29,6 +28,8 @@ import com.android.internal.util.DataClass;
/**
 * Description of an app-op that was noted for the current process.
 *
 * Note: package name is currently unused in the system.
 *
 * <p>This is either delivered after a
 * {@link AppOpsManager.OnOpNotedCallback#onNoted(SyncNotedAppOp) two way binder call} or
 * when the app
+5 −0
Original line number Diff line number Diff line
@@ -560,6 +560,9 @@ public final class BinderProxy implements IBinder {
            }
        }

        final AppOpsManager.PausedNotedAppOpsCollection prevCollection =
                AppOpsManager.pauseNotedAppOpsCollection();

        if ((flags & FLAG_ONEWAY) == 0 && AppOpsManager.isListeningForOpNoted()) {
            flags |= FLAG_COLLECT_NOTED_APP_OPS;
        }
@@ -567,6 +570,8 @@ public final class BinderProxy implements IBinder {
        try {
            return transactNative(code, data, reply, flags);
        } finally {
            AppOpsManager.resumeNotedAppOpsCollection(prevCollection);

            if (transactListener != null) {
                transactListener.onTransactEnded(session);
            }
+1 −1
Original line number Diff line number Diff line
@@ -3438,7 +3438,7 @@ public class AppOpsService extends IAppOpsService.Stub {
                        + " package " + packageName + "flags: " +
                        AppOpsManager.flagsToString(flags));
                return new SyncNotedAppOp(AppOpsManager.MODE_ERRORED, code, attributionTag,
                        packageName + " flags: " + AppOpsManager.flagsToString(flags));
                        packageName);
            }
            final Op op = getOpLocked(ops, code, uid, true);
            final AttributedOp attributedOp = op.getOrCreateAttribution(op, attributionTag);