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

Commit 50ff5ac8 authored by Nate Myren's avatar Nate Myren Committed by Android (Google) Code Review
Browse files

Merge "Revert sync app op chain changes" into sc-dev

parents 2458c8f8 86c33765
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);