Loading core/java/android/app/AppOpsManager.aidl +0 −1 Original line number Diff line number Diff line Loading @@ -19,7 +19,6 @@ package android.app; parcelable AppOpsManager.PackageOps; parcelable AppOpsManager.NoteOpEventProxyInfo; parcelable AppOpsManager.NoteOpEvent; parcelable AppOpsManager.NotedOp; parcelable AppOpsManager.OpFeatureEntry; parcelable AppOpsManager.OpEntry; Loading core/java/android/app/AppOpsManager.java +8 −217 Original line number Diff line number Diff line Loading @@ -262,24 +262,6 @@ public class AppOpsManager { private static final Object sLock = new Object(); // A map that records noted times for each op. private final ArrayMap<NotedOp, Integer> mPendingNotedOps = new ArrayMap<>(); private final HandlerThread mHandlerThread; private final Handler mHandler; private static final int NOTE_OP_BATCHING_DELAY_MILLIS = 1000; private boolean isNoteOpBatchingSupported() { // If noteOp is called from system server no IPC is made, hence we don't need batching. if (Process.myUid() == Process.SYSTEM_UID) { return false; } return Flags.noteOpBatchingEnabled(); } private final Object mBatchedNoteOpLock = new Object(); @GuardedBy("mBatchedNoteOpLock") private boolean mIsBatchedNoteOpCallScheduled = false; /** Current {@link OnOpNotedCallback}. Change via {@link #setOnOpNotedCallback} */ @GuardedBy("sLock") private static @Nullable OnOpNotedCallback sOnOpNotedCallback; Loading Loading @@ -7483,135 +7465,6 @@ public class AppOpsManager { }; } /** * A NotedOp is an app op grouped in noteOp API and sent to the system server in a batch * * @hide */ public static final class NotedOp implements Parcelable { private final @IntRange(from = 0, to = _NUM_OP - 1) int mOp; private final @IntRange(from = 0) int mUid; private final @Nullable String mPackageName; private final @Nullable String mAttributionTag; private final int mVirtualDeviceId; private final @Nullable String mMessage; private final boolean mShouldCollectAsyncNotedOp; private final boolean mShouldCollectMessage; public NotedOp(int op, int uid, @Nullable String packageName, @Nullable String attributionTag, int virtualDeviceId, @Nullable String message, boolean shouldCollectAsyncNotedOp, boolean shouldCollectMessage) { mOp = op; mUid = uid; mPackageName = packageName; mAttributionTag = attributionTag; mVirtualDeviceId = virtualDeviceId; mMessage = message; mShouldCollectAsyncNotedOp = shouldCollectAsyncNotedOp; mShouldCollectMessage = shouldCollectMessage; } NotedOp(Parcel source) { mOp = source.readInt(); mUid = source.readInt(); mPackageName = source.readString(); mAttributionTag = source.readString(); mVirtualDeviceId = source.readInt(); mMessage = source.readString(); mShouldCollectAsyncNotedOp = source.readBoolean(); mShouldCollectMessage = source.readBoolean(); } public int getOp() { return mOp; } public int getUid() { return mUid; } public @Nullable String getPackageName() { return mPackageName; } public @Nullable String getAttributionTag() { return mAttributionTag; } public int getVirtualDeviceId() { return mVirtualDeviceId; } public @Nullable String getMessage() { return mMessage; } public boolean getShouldCollectAsyncNotedOp() { return mShouldCollectAsyncNotedOp; } public boolean getShouldCollectMessage() { return mShouldCollectMessage; } @Override public int describeContents() { return 0; } @Override public void writeToParcel(@NonNull Parcel dest, int flags) { dest.writeInt(mOp); dest.writeInt(mUid); dest.writeString(mPackageName); dest.writeString(mAttributionTag); dest.writeInt(mVirtualDeviceId); dest.writeString(mMessage); dest.writeBoolean(mShouldCollectAsyncNotedOp); dest.writeBoolean(mShouldCollectMessage); } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; NotedOp that = (NotedOp) o; return mOp == that.mOp && mUid == that.mUid && Objects.equals(mPackageName, that.mPackageName) && Objects.equals(mAttributionTag, that.mAttributionTag) && mVirtualDeviceId == that.mVirtualDeviceId && Objects.equals(mMessage, that.mMessage) && Objects.equals(mShouldCollectAsyncNotedOp, that.mShouldCollectAsyncNotedOp) && Objects.equals(mShouldCollectMessage, that.mShouldCollectMessage); } @Override public int hashCode() { return Objects.hash(mOp, mUid, mPackageName, mAttributionTag, mVirtualDeviceId, mMessage, mShouldCollectAsyncNotedOp, mShouldCollectMessage); } @Override public String toString() { return "NotedOp{" + "mOp=" + mOp + ", mUid=" + mUid + ", mPackageName=" + mPackageName + ", mAttributionTag=" + mAttributionTag + ", mVirtualDeviceId=" + mVirtualDeviceId + ", mMessage=" + mMessage + ", mShouldCollectAsyncNotedOp=" + mShouldCollectAsyncNotedOp + ", mShouldCollectMessage=" + mShouldCollectMessage + "}"; } public static final @NonNull Creator<NotedOp> CREATOR = new Creator<>() { @Override public NotedOp createFromParcel(Parcel source) { return new NotedOp(source); } @Override public NotedOp[] newArray(int size) { return new NotedOp[size]; } }; } /** * Computes the sum of the counts for the given flags in between the begin and * end UID states. Loading Loading @@ -8126,9 +7979,6 @@ public class AppOpsManager { AppOpsManager(Context context, IAppOpsService service) { mContext = context; mService = service; mHandlerThread = new HandlerThread("AppOpsManager"); mHandlerThread.start(); mHandler = mHandlerThread.getThreadHandler(); if (mContext != null) { final PackageManager pm = mContext.getPackageManager(); Loading Loading @@ -9465,64 +9315,7 @@ public class AppOpsManager { } } SyncNotedAppOp syncOp = null; boolean skipBinderCall = false; if (isNoteOpBatchingSupported()) { int mode = sAppOpModeCache.query( new AppOpModeQuery(op, uid, packageName, virtualDeviceId, attributionTag, "noteOpNoThrow")); // For FOREGROUND mode, we still need to make a binder call to the system service // to translate it to ALLOWED or IGNORED. So no batching is needed. if (mode != MODE_FOREGROUND) { synchronized (mBatchedNoteOpLock) { NotedOp notedOp = new NotedOp(op, uid, packageName, attributionTag, virtualDeviceId, message, collectionMode == COLLECT_ASYNC, shouldCollectMessage); // Batch same noteOp calls and send them with their counters to the system // service asynchronously. The time window for batching is specified in // NOTE_OP_BATCHING_DELAY_MILLIS. Always allow the first noteOp call to go // through binder API. Accumulate subsequent same noteOp calls during the // time window in mPendingNotedOps. if (!mPendingNotedOps.containsKey(notedOp)) { mPendingNotedOps.put(notedOp, 0); } else { skipBinderCall = true; mPendingNotedOps.merge(notedOp, 1, Integer::sum); } if (!mIsBatchedNoteOpCallScheduled) { mHandler.postDelayed(() -> { ArrayMap<NotedOp, Integer> pendingNotedOpsCopy; synchronized(mBatchedNoteOpLock) { mIsBatchedNoteOpCallScheduled = false; pendingNotedOpsCopy = new ArrayMap<NotedOp, Integer>(mPendingNotedOps); mPendingNotedOps.clear(); } for (int i = pendingNotedOpsCopy.size() - 1; i >= 0; i--) { if (pendingNotedOpsCopy.valueAt(i) == 0) { pendingNotedOpsCopy.removeAt(i); } } if (!pendingNotedOpsCopy.isEmpty()) { try { mService.noteOperationsInBatch(pendingNotedOpsCopy); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } }, NOTE_OP_BATCHING_DELAY_MILLIS); mIsBatchedNoteOpCallScheduled = true; } } syncOp = new SyncNotedAppOp(mode, op, attributionTag, packageName); } } if (!skipBinderCall) { SyncNotedAppOp syncOp; if (virtualDeviceId == Context.DEVICE_ID_DEFAULT) { syncOp = mService.noteOperation(op, uid, packageName, attributionTag, collectionMode == COLLECT_ASYNC, message, shouldCollectMessage); Loading @@ -9531,8 +9324,6 @@ public class AppOpsManager { virtualDeviceId, collectionMode == COLLECT_ASYNC, message, shouldCollectMessage); } } if (syncOp.getOpMode() == MODE_ALLOWED) { if (collectionMode == COLLECT_SELF) { collectNotedOpForSelf(syncOp); Loading core/java/android/app/AppOpsManagerInternal.java +4 −4 Original line number Diff line number Diff line Loading @@ -29,7 +29,7 @@ import com.android.internal.app.IAppOpsCallback; import com.android.internal.util.function.DodecFunction; import com.android.internal.util.function.HexConsumer; import com.android.internal.util.function.HexFunction; import com.android.internal.util.function.NonaFunction; import com.android.internal.util.function.OctFunction; import com.android.internal.util.function.QuadFunction; import com.android.internal.util.function.UndecFunction; Loading Loading @@ -86,9 +86,9 @@ public abstract class AppOpsManagerInternal { */ SyncNotedAppOp noteOperation(int code, int uid, @Nullable String packageName, @Nullable String featureId, int virtualDeviceId, boolean shouldCollectAsyncNotedOp, @Nullable String message, boolean shouldCollectMessage, int notedCount, @NonNull NonaFunction<Integer, Integer, String, String, Integer, Boolean, String, Boolean, Integer, SyncNotedAppOp> superImpl); @Nullable String message, boolean shouldCollectMessage, @NonNull OctFunction<Integer, Integer, String, String, Integer, Boolean, String, Boolean, SyncNotedAppOp> superImpl); /** * Allows overriding note proxy operation behavior. Loading core/java/com/android/internal/app/IAppOpsService.aidl +0 −1 Original line number Diff line number Diff line Loading @@ -163,5 +163,4 @@ interface IAppOpsService { void finishOperationForDevice(IBinder clientId, int code, int uid, String packageName, @nullable String attributionTag, int virtualDeviceId); List<AppOpsManager.PackageOps> getPackagesForOpsForDevice(in int[] ops, String persistentDeviceId); oneway void noteOperationsInBatch(in Map batchedNoteOps); } services/core/java/com/android/server/appop/AppOpsService.java +39 −62 Original line number Diff line number Diff line Loading @@ -3191,7 +3191,7 @@ public class AppOpsService extends IAppOpsService.Stub { resolveProxyPackageName, proxyAttributionTag, proxyVirtualDeviceId, Process.INVALID_UID, null, null, Context.DEVICE_ID_DEFAULT, proxyFlags, !isProxyTrusted, "proxy " + message, shouldCollectMessage, 1); "proxy " + message, shouldCollectMessage); if (proxyReturn.getOpMode() != AppOpsManager.MODE_ALLOWED) { return new SyncNotedAppOp(proxyReturn.getOpMode(), code, proxiedAttributionTag, proxiedPackageName); Loading @@ -3210,20 +3210,7 @@ public class AppOpsService extends IAppOpsService.Stub { return noteOperationUnchecked(code, proxiedUid, resolveProxiedPackageName, proxiedAttributionTag, proxiedVirtualDeviceId, proxyUid, resolveProxyPackageName, proxyAttributionTag, proxyVirtualDeviceId, proxiedFlags, shouldCollectAsyncNotedOp, message, shouldCollectMessage, 1); } @Override public void noteOperationsInBatch(Map batchedNoteOps) { for (var entry : ((Map<AppOpsManager.NotedOp, Integer>) batchedNoteOps).entrySet()) { AppOpsManager.NotedOp notedOp = entry.getKey(); int notedCount = entry.getValue(); mCheckOpsDelegateDispatcher.noteOperation( notedOp.getOp(), notedOp.getUid(), notedOp.getPackageName(), notedOp.getAttributionTag(), notedOp.getVirtualDeviceId(), notedOp.getShouldCollectAsyncNotedOp(), notedOp.getMessage(), notedOp.getShouldCollectMessage(), notedCount); } message, shouldCollectMessage); } @Override Loading @@ -3241,7 +3228,7 @@ public class AppOpsService extends IAppOpsService.Stub { } return mCheckOpsDelegateDispatcher.noteOperation(code, uid, packageName, attributionTag, Context.DEVICE_ID_DEFAULT, shouldCollectAsyncNotedOp, message, shouldCollectMessage, 1); shouldCollectMessage); } @Override Loading @@ -3250,12 +3237,13 @@ public class AppOpsService extends IAppOpsService.Stub { String message, boolean shouldCollectMessage) { return mCheckOpsDelegateDispatcher.noteOperation(code, uid, packageName, attributionTag, virtualDeviceId, shouldCollectAsyncNotedOp, message, shouldCollectMessage, 1); shouldCollectMessage); } private SyncNotedAppOp noteOperationImpl(int code, int uid, @Nullable String packageName, @Nullable String attributionTag, int virtualDeviceId, boolean shouldCollectAsyncNotedOp, @Nullable String message, boolean shouldCollectMessage, int notedCount) { @Nullable String attributionTag, int virtualDeviceId, boolean shouldCollectAsyncNotedOp, @Nullable String message, boolean shouldCollectMessage) { String resolvedPackageName; if (!shouldUseNewCheckOp()) { verifyIncomingUid(uid); Loading Loading @@ -3290,14 +3278,14 @@ public class AppOpsService extends IAppOpsService.Stub { return noteOperationUnchecked(code, uid, resolvedPackageName, attributionTag, virtualDeviceId, Process.INVALID_UID, null, null, Context.DEVICE_ID_DEFAULT, AppOpsManager.OP_FLAG_SELF, shouldCollectAsyncNotedOp, message, shouldCollectMessage, notedCount); message, shouldCollectMessage); } private SyncNotedAppOp noteOperationUnchecked(int code, int uid, @NonNull String packageName, @Nullable String attributionTag, int virtualDeviceId, int proxyUid, String proxyPackageName, @Nullable String proxyAttributionTag, int proxyVirtualDeviceId, @OpFlags int flags, boolean shouldCollectAsyncNotedOp, @Nullable String message, boolean shouldCollectMessage, int notedCount) { boolean shouldCollectMessage) { PackageVerificationResult pvr; try { pvr = verifyAndGetBypass(uid, packageName, attributionTag, proxyPackageName); Loading Loading @@ -3400,11 +3388,11 @@ public class AppOpsService extends IAppOpsService.Stub { virtualDeviceId, flags, AppOpsManager.MODE_ALLOWED); attributedOp.accessed(proxyUid, proxyPackageName, proxyAttributionTag, getPersistentId(proxyVirtualDeviceId), uidState.getState(), flags, notedCount); getPersistentId(proxyVirtualDeviceId), uidState.getState(), flags); if (shouldCollectAsyncNotedOp) { collectAsyncNotedOp(uid, packageName, code, attributionTag, flags, message, shouldCollectMessage, notedCount); shouldCollectMessage); } return new SyncNotedAppOp(AppOpsManager.MODE_ALLOWED, code, attributionTag, Loading Loading @@ -3563,7 +3551,7 @@ public class AppOpsService extends IAppOpsService.Stub { */ private void collectAsyncNotedOp(int uid, @NonNull String packageName, int opCode, @Nullable String attributionTag, @OpFlags int flags, @NonNull String message, boolean shouldCollectMessage, int notedCount) { boolean shouldCollectMessage) { Objects.requireNonNull(message); int callingUid = Binder.getCallingUid(); Loading @@ -3571,42 +3559,34 @@ public class AppOpsService extends IAppOpsService.Stub { final long token = Binder.clearCallingIdentity(); try { synchronized (this) { Pair<String, Integer> key = getAsyncNotedOpsKey(packageName, uid); RemoteCallbackList<IAppOpsAsyncNotedCallback> callbacks = mAsyncOpWatchers.get(key); AsyncNotedAppOp asyncNotedOp = new AsyncNotedAppOp(opCode, callingUid, attributionTag, message, System.currentTimeMillis()); final boolean[] wasNoteForwarded = {false}; if ((flags & (OP_FLAG_SELF | OP_FLAG_TRUSTED_PROXIED)) != 0 && shouldCollectMessage) { reportRuntimeAppOpAccessMessageAsyncLocked(uid, packageName, opCode, attributionTag, message); } Pair<String, Integer> key = getAsyncNotedOpsKey(packageName, uid); RemoteCallbackList<IAppOpsAsyncNotedCallback> callbacks = mAsyncOpWatchers.get(key); if (callbacks == null) { return; } final boolean[] wasNoteForwarded = {false}; if (Flags.rateLimitBatchedNoteOpAsyncCallbacksEnabled()) { notedCount = 1; } for (int i = 0; i < notedCount; i++) { AsyncNotedAppOp asyncNotedOp = new AsyncNotedAppOp(opCode, callingUid, attributionTag, message, System.currentTimeMillis()); wasNoteForwarded[0] = false; if (callbacks != null) { callbacks.broadcast((cb) -> { try { cb.opNoted(asyncNotedOp); wasNoteForwarded[0] = true; } catch (RemoteException e) { Slog.e(TAG, "Could not forward noteOp of " + opCode + " to " + packageName "Could not forward noteOp of " + opCode + " to " + packageName + "/" + uid + "(" + attributionTag + ")", e); } }); } if (!wasNoteForwarded[0]) { ArrayList<AsyncNotedAppOp> unforwardedOps = mUnforwardedAsyncNotedOps.get( key); ArrayList<AsyncNotedAppOp> unforwardedOps = mUnforwardedAsyncNotedOps.get(key); if (unforwardedOps == null) { unforwardedOps = new ArrayList<>(1); mUnforwardedAsyncNotedOps.put(key, unforwardedOps); Loading @@ -3618,7 +3598,6 @@ public class AppOpsService extends IAppOpsService.Stub { } } } } } finally { Binder.restoreCallingIdentity(token); } Loading Loading @@ -4047,7 +4026,7 @@ public class AppOpsService extends IAppOpsService.Stub { if (shouldCollectAsyncNotedOp && !isRestricted) { collectAsyncNotedOp(uid, packageName, code, attributionTag, AppOpsManager.OP_FLAG_SELF, message, shouldCollectMessage, 1); message, shouldCollectMessage); } return new SyncNotedAppOp(isRestricted ? MODE_IGNORED : MODE_ALLOWED, code, attributionTag, Loading Loading @@ -7595,36 +7574,34 @@ public class AppOpsService extends IAppOpsService.Stub { public SyncNotedAppOp noteOperation(int code, int uid, String packageName, String attributionTag, int virtualDeviceId, boolean shouldCollectAsyncNotedOp, String message, boolean shouldCollectMessage, int notedCount) { String message, boolean shouldCollectMessage) { if (mPolicy != null) { if (mCheckOpsDelegate != null) { return mPolicy.noteOperation(code, uid, packageName, attributionTag, virtualDeviceId, shouldCollectAsyncNotedOp, message, shouldCollectMessage, notedCount, this::noteDelegateOperationImpl shouldCollectMessage, this::noteDelegateOperationImpl ); } else { return mPolicy.noteOperation(code, uid, packageName, attributionTag, virtualDeviceId, shouldCollectAsyncNotedOp, message, shouldCollectMessage, notedCount, AppOpsService.this::noteOperationImpl shouldCollectMessage, AppOpsService.this::noteOperationImpl ); } } else if (mCheckOpsDelegate != null) { return noteDelegateOperationImpl(code, uid, packageName, attributionTag, virtualDeviceId, shouldCollectAsyncNotedOp, message, shouldCollectMessage, notedCount); virtualDeviceId, shouldCollectAsyncNotedOp, message, shouldCollectMessage); } return noteOperationImpl(code, uid, packageName, attributionTag, virtualDeviceId, shouldCollectAsyncNotedOp, message, shouldCollectMessage, notedCount); virtualDeviceId, shouldCollectAsyncNotedOp, message, shouldCollectMessage); } private SyncNotedAppOp noteDelegateOperationImpl(int code, int uid, @Nullable String packageName, @Nullable String featureId, int virtualDeviceId, boolean shouldCollectAsyncNotedOp, @Nullable String message, boolean shouldCollectMessage, int notedCount) { boolean shouldCollectMessage) { return mCheckOpsDelegate.noteOperation(code, uid, packageName, featureId, virtualDeviceId, shouldCollectAsyncNotedOp, message, shouldCollectMessage, notedCount, AppOpsService.this::noteOperationImpl AppOpsService.this::noteOperationImpl ); } Loading Loading
core/java/android/app/AppOpsManager.aidl +0 −1 Original line number Diff line number Diff line Loading @@ -19,7 +19,6 @@ package android.app; parcelable AppOpsManager.PackageOps; parcelable AppOpsManager.NoteOpEventProxyInfo; parcelable AppOpsManager.NoteOpEvent; parcelable AppOpsManager.NotedOp; parcelable AppOpsManager.OpFeatureEntry; parcelable AppOpsManager.OpEntry; Loading
core/java/android/app/AppOpsManager.java +8 −217 Original line number Diff line number Diff line Loading @@ -262,24 +262,6 @@ public class AppOpsManager { private static final Object sLock = new Object(); // A map that records noted times for each op. private final ArrayMap<NotedOp, Integer> mPendingNotedOps = new ArrayMap<>(); private final HandlerThread mHandlerThread; private final Handler mHandler; private static final int NOTE_OP_BATCHING_DELAY_MILLIS = 1000; private boolean isNoteOpBatchingSupported() { // If noteOp is called from system server no IPC is made, hence we don't need batching. if (Process.myUid() == Process.SYSTEM_UID) { return false; } return Flags.noteOpBatchingEnabled(); } private final Object mBatchedNoteOpLock = new Object(); @GuardedBy("mBatchedNoteOpLock") private boolean mIsBatchedNoteOpCallScheduled = false; /** Current {@link OnOpNotedCallback}. Change via {@link #setOnOpNotedCallback} */ @GuardedBy("sLock") private static @Nullable OnOpNotedCallback sOnOpNotedCallback; Loading Loading @@ -7483,135 +7465,6 @@ public class AppOpsManager { }; } /** * A NotedOp is an app op grouped in noteOp API and sent to the system server in a batch * * @hide */ public static final class NotedOp implements Parcelable { private final @IntRange(from = 0, to = _NUM_OP - 1) int mOp; private final @IntRange(from = 0) int mUid; private final @Nullable String mPackageName; private final @Nullable String mAttributionTag; private final int mVirtualDeviceId; private final @Nullable String mMessage; private final boolean mShouldCollectAsyncNotedOp; private final boolean mShouldCollectMessage; public NotedOp(int op, int uid, @Nullable String packageName, @Nullable String attributionTag, int virtualDeviceId, @Nullable String message, boolean shouldCollectAsyncNotedOp, boolean shouldCollectMessage) { mOp = op; mUid = uid; mPackageName = packageName; mAttributionTag = attributionTag; mVirtualDeviceId = virtualDeviceId; mMessage = message; mShouldCollectAsyncNotedOp = shouldCollectAsyncNotedOp; mShouldCollectMessage = shouldCollectMessage; } NotedOp(Parcel source) { mOp = source.readInt(); mUid = source.readInt(); mPackageName = source.readString(); mAttributionTag = source.readString(); mVirtualDeviceId = source.readInt(); mMessage = source.readString(); mShouldCollectAsyncNotedOp = source.readBoolean(); mShouldCollectMessage = source.readBoolean(); } public int getOp() { return mOp; } public int getUid() { return mUid; } public @Nullable String getPackageName() { return mPackageName; } public @Nullable String getAttributionTag() { return mAttributionTag; } public int getVirtualDeviceId() { return mVirtualDeviceId; } public @Nullable String getMessage() { return mMessage; } public boolean getShouldCollectAsyncNotedOp() { return mShouldCollectAsyncNotedOp; } public boolean getShouldCollectMessage() { return mShouldCollectMessage; } @Override public int describeContents() { return 0; } @Override public void writeToParcel(@NonNull Parcel dest, int flags) { dest.writeInt(mOp); dest.writeInt(mUid); dest.writeString(mPackageName); dest.writeString(mAttributionTag); dest.writeInt(mVirtualDeviceId); dest.writeString(mMessage); dest.writeBoolean(mShouldCollectAsyncNotedOp); dest.writeBoolean(mShouldCollectMessage); } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; NotedOp that = (NotedOp) o; return mOp == that.mOp && mUid == that.mUid && Objects.equals(mPackageName, that.mPackageName) && Objects.equals(mAttributionTag, that.mAttributionTag) && mVirtualDeviceId == that.mVirtualDeviceId && Objects.equals(mMessage, that.mMessage) && Objects.equals(mShouldCollectAsyncNotedOp, that.mShouldCollectAsyncNotedOp) && Objects.equals(mShouldCollectMessage, that.mShouldCollectMessage); } @Override public int hashCode() { return Objects.hash(mOp, mUid, mPackageName, mAttributionTag, mVirtualDeviceId, mMessage, mShouldCollectAsyncNotedOp, mShouldCollectMessage); } @Override public String toString() { return "NotedOp{" + "mOp=" + mOp + ", mUid=" + mUid + ", mPackageName=" + mPackageName + ", mAttributionTag=" + mAttributionTag + ", mVirtualDeviceId=" + mVirtualDeviceId + ", mMessage=" + mMessage + ", mShouldCollectAsyncNotedOp=" + mShouldCollectAsyncNotedOp + ", mShouldCollectMessage=" + mShouldCollectMessage + "}"; } public static final @NonNull Creator<NotedOp> CREATOR = new Creator<>() { @Override public NotedOp createFromParcel(Parcel source) { return new NotedOp(source); } @Override public NotedOp[] newArray(int size) { return new NotedOp[size]; } }; } /** * Computes the sum of the counts for the given flags in between the begin and * end UID states. Loading Loading @@ -8126,9 +7979,6 @@ public class AppOpsManager { AppOpsManager(Context context, IAppOpsService service) { mContext = context; mService = service; mHandlerThread = new HandlerThread("AppOpsManager"); mHandlerThread.start(); mHandler = mHandlerThread.getThreadHandler(); if (mContext != null) { final PackageManager pm = mContext.getPackageManager(); Loading Loading @@ -9465,64 +9315,7 @@ public class AppOpsManager { } } SyncNotedAppOp syncOp = null; boolean skipBinderCall = false; if (isNoteOpBatchingSupported()) { int mode = sAppOpModeCache.query( new AppOpModeQuery(op, uid, packageName, virtualDeviceId, attributionTag, "noteOpNoThrow")); // For FOREGROUND mode, we still need to make a binder call to the system service // to translate it to ALLOWED or IGNORED. So no batching is needed. if (mode != MODE_FOREGROUND) { synchronized (mBatchedNoteOpLock) { NotedOp notedOp = new NotedOp(op, uid, packageName, attributionTag, virtualDeviceId, message, collectionMode == COLLECT_ASYNC, shouldCollectMessage); // Batch same noteOp calls and send them with their counters to the system // service asynchronously. The time window for batching is specified in // NOTE_OP_BATCHING_DELAY_MILLIS. Always allow the first noteOp call to go // through binder API. Accumulate subsequent same noteOp calls during the // time window in mPendingNotedOps. if (!mPendingNotedOps.containsKey(notedOp)) { mPendingNotedOps.put(notedOp, 0); } else { skipBinderCall = true; mPendingNotedOps.merge(notedOp, 1, Integer::sum); } if (!mIsBatchedNoteOpCallScheduled) { mHandler.postDelayed(() -> { ArrayMap<NotedOp, Integer> pendingNotedOpsCopy; synchronized(mBatchedNoteOpLock) { mIsBatchedNoteOpCallScheduled = false; pendingNotedOpsCopy = new ArrayMap<NotedOp, Integer>(mPendingNotedOps); mPendingNotedOps.clear(); } for (int i = pendingNotedOpsCopy.size() - 1; i >= 0; i--) { if (pendingNotedOpsCopy.valueAt(i) == 0) { pendingNotedOpsCopy.removeAt(i); } } if (!pendingNotedOpsCopy.isEmpty()) { try { mService.noteOperationsInBatch(pendingNotedOpsCopy); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } }, NOTE_OP_BATCHING_DELAY_MILLIS); mIsBatchedNoteOpCallScheduled = true; } } syncOp = new SyncNotedAppOp(mode, op, attributionTag, packageName); } } if (!skipBinderCall) { SyncNotedAppOp syncOp; if (virtualDeviceId == Context.DEVICE_ID_DEFAULT) { syncOp = mService.noteOperation(op, uid, packageName, attributionTag, collectionMode == COLLECT_ASYNC, message, shouldCollectMessage); Loading @@ -9531,8 +9324,6 @@ public class AppOpsManager { virtualDeviceId, collectionMode == COLLECT_ASYNC, message, shouldCollectMessage); } } if (syncOp.getOpMode() == MODE_ALLOWED) { if (collectionMode == COLLECT_SELF) { collectNotedOpForSelf(syncOp); Loading
core/java/android/app/AppOpsManagerInternal.java +4 −4 Original line number Diff line number Diff line Loading @@ -29,7 +29,7 @@ import com.android.internal.app.IAppOpsCallback; import com.android.internal.util.function.DodecFunction; import com.android.internal.util.function.HexConsumer; import com.android.internal.util.function.HexFunction; import com.android.internal.util.function.NonaFunction; import com.android.internal.util.function.OctFunction; import com.android.internal.util.function.QuadFunction; import com.android.internal.util.function.UndecFunction; Loading Loading @@ -86,9 +86,9 @@ public abstract class AppOpsManagerInternal { */ SyncNotedAppOp noteOperation(int code, int uid, @Nullable String packageName, @Nullable String featureId, int virtualDeviceId, boolean shouldCollectAsyncNotedOp, @Nullable String message, boolean shouldCollectMessage, int notedCount, @NonNull NonaFunction<Integer, Integer, String, String, Integer, Boolean, String, Boolean, Integer, SyncNotedAppOp> superImpl); @Nullable String message, boolean shouldCollectMessage, @NonNull OctFunction<Integer, Integer, String, String, Integer, Boolean, String, Boolean, SyncNotedAppOp> superImpl); /** * Allows overriding note proxy operation behavior. Loading
core/java/com/android/internal/app/IAppOpsService.aidl +0 −1 Original line number Diff line number Diff line Loading @@ -163,5 +163,4 @@ interface IAppOpsService { void finishOperationForDevice(IBinder clientId, int code, int uid, String packageName, @nullable String attributionTag, int virtualDeviceId); List<AppOpsManager.PackageOps> getPackagesForOpsForDevice(in int[] ops, String persistentDeviceId); oneway void noteOperationsInBatch(in Map batchedNoteOps); }
services/core/java/com/android/server/appop/AppOpsService.java +39 −62 Original line number Diff line number Diff line Loading @@ -3191,7 +3191,7 @@ public class AppOpsService extends IAppOpsService.Stub { resolveProxyPackageName, proxyAttributionTag, proxyVirtualDeviceId, Process.INVALID_UID, null, null, Context.DEVICE_ID_DEFAULT, proxyFlags, !isProxyTrusted, "proxy " + message, shouldCollectMessage, 1); "proxy " + message, shouldCollectMessage); if (proxyReturn.getOpMode() != AppOpsManager.MODE_ALLOWED) { return new SyncNotedAppOp(proxyReturn.getOpMode(), code, proxiedAttributionTag, proxiedPackageName); Loading @@ -3210,20 +3210,7 @@ public class AppOpsService extends IAppOpsService.Stub { return noteOperationUnchecked(code, proxiedUid, resolveProxiedPackageName, proxiedAttributionTag, proxiedVirtualDeviceId, proxyUid, resolveProxyPackageName, proxyAttributionTag, proxyVirtualDeviceId, proxiedFlags, shouldCollectAsyncNotedOp, message, shouldCollectMessage, 1); } @Override public void noteOperationsInBatch(Map batchedNoteOps) { for (var entry : ((Map<AppOpsManager.NotedOp, Integer>) batchedNoteOps).entrySet()) { AppOpsManager.NotedOp notedOp = entry.getKey(); int notedCount = entry.getValue(); mCheckOpsDelegateDispatcher.noteOperation( notedOp.getOp(), notedOp.getUid(), notedOp.getPackageName(), notedOp.getAttributionTag(), notedOp.getVirtualDeviceId(), notedOp.getShouldCollectAsyncNotedOp(), notedOp.getMessage(), notedOp.getShouldCollectMessage(), notedCount); } message, shouldCollectMessage); } @Override Loading @@ -3241,7 +3228,7 @@ public class AppOpsService extends IAppOpsService.Stub { } return mCheckOpsDelegateDispatcher.noteOperation(code, uid, packageName, attributionTag, Context.DEVICE_ID_DEFAULT, shouldCollectAsyncNotedOp, message, shouldCollectMessage, 1); shouldCollectMessage); } @Override Loading @@ -3250,12 +3237,13 @@ public class AppOpsService extends IAppOpsService.Stub { String message, boolean shouldCollectMessage) { return mCheckOpsDelegateDispatcher.noteOperation(code, uid, packageName, attributionTag, virtualDeviceId, shouldCollectAsyncNotedOp, message, shouldCollectMessage, 1); shouldCollectMessage); } private SyncNotedAppOp noteOperationImpl(int code, int uid, @Nullable String packageName, @Nullable String attributionTag, int virtualDeviceId, boolean shouldCollectAsyncNotedOp, @Nullable String message, boolean shouldCollectMessage, int notedCount) { @Nullable String attributionTag, int virtualDeviceId, boolean shouldCollectAsyncNotedOp, @Nullable String message, boolean shouldCollectMessage) { String resolvedPackageName; if (!shouldUseNewCheckOp()) { verifyIncomingUid(uid); Loading Loading @@ -3290,14 +3278,14 @@ public class AppOpsService extends IAppOpsService.Stub { return noteOperationUnchecked(code, uid, resolvedPackageName, attributionTag, virtualDeviceId, Process.INVALID_UID, null, null, Context.DEVICE_ID_DEFAULT, AppOpsManager.OP_FLAG_SELF, shouldCollectAsyncNotedOp, message, shouldCollectMessage, notedCount); message, shouldCollectMessage); } private SyncNotedAppOp noteOperationUnchecked(int code, int uid, @NonNull String packageName, @Nullable String attributionTag, int virtualDeviceId, int proxyUid, String proxyPackageName, @Nullable String proxyAttributionTag, int proxyVirtualDeviceId, @OpFlags int flags, boolean shouldCollectAsyncNotedOp, @Nullable String message, boolean shouldCollectMessage, int notedCount) { boolean shouldCollectMessage) { PackageVerificationResult pvr; try { pvr = verifyAndGetBypass(uid, packageName, attributionTag, proxyPackageName); Loading Loading @@ -3400,11 +3388,11 @@ public class AppOpsService extends IAppOpsService.Stub { virtualDeviceId, flags, AppOpsManager.MODE_ALLOWED); attributedOp.accessed(proxyUid, proxyPackageName, proxyAttributionTag, getPersistentId(proxyVirtualDeviceId), uidState.getState(), flags, notedCount); getPersistentId(proxyVirtualDeviceId), uidState.getState(), flags); if (shouldCollectAsyncNotedOp) { collectAsyncNotedOp(uid, packageName, code, attributionTag, flags, message, shouldCollectMessage, notedCount); shouldCollectMessage); } return new SyncNotedAppOp(AppOpsManager.MODE_ALLOWED, code, attributionTag, Loading Loading @@ -3563,7 +3551,7 @@ public class AppOpsService extends IAppOpsService.Stub { */ private void collectAsyncNotedOp(int uid, @NonNull String packageName, int opCode, @Nullable String attributionTag, @OpFlags int flags, @NonNull String message, boolean shouldCollectMessage, int notedCount) { boolean shouldCollectMessage) { Objects.requireNonNull(message); int callingUid = Binder.getCallingUid(); Loading @@ -3571,42 +3559,34 @@ public class AppOpsService extends IAppOpsService.Stub { final long token = Binder.clearCallingIdentity(); try { synchronized (this) { Pair<String, Integer> key = getAsyncNotedOpsKey(packageName, uid); RemoteCallbackList<IAppOpsAsyncNotedCallback> callbacks = mAsyncOpWatchers.get(key); AsyncNotedAppOp asyncNotedOp = new AsyncNotedAppOp(opCode, callingUid, attributionTag, message, System.currentTimeMillis()); final boolean[] wasNoteForwarded = {false}; if ((flags & (OP_FLAG_SELF | OP_FLAG_TRUSTED_PROXIED)) != 0 && shouldCollectMessage) { reportRuntimeAppOpAccessMessageAsyncLocked(uid, packageName, opCode, attributionTag, message); } Pair<String, Integer> key = getAsyncNotedOpsKey(packageName, uid); RemoteCallbackList<IAppOpsAsyncNotedCallback> callbacks = mAsyncOpWatchers.get(key); if (callbacks == null) { return; } final boolean[] wasNoteForwarded = {false}; if (Flags.rateLimitBatchedNoteOpAsyncCallbacksEnabled()) { notedCount = 1; } for (int i = 0; i < notedCount; i++) { AsyncNotedAppOp asyncNotedOp = new AsyncNotedAppOp(opCode, callingUid, attributionTag, message, System.currentTimeMillis()); wasNoteForwarded[0] = false; if (callbacks != null) { callbacks.broadcast((cb) -> { try { cb.opNoted(asyncNotedOp); wasNoteForwarded[0] = true; } catch (RemoteException e) { Slog.e(TAG, "Could not forward noteOp of " + opCode + " to " + packageName "Could not forward noteOp of " + opCode + " to " + packageName + "/" + uid + "(" + attributionTag + ")", e); } }); } if (!wasNoteForwarded[0]) { ArrayList<AsyncNotedAppOp> unforwardedOps = mUnforwardedAsyncNotedOps.get( key); ArrayList<AsyncNotedAppOp> unforwardedOps = mUnforwardedAsyncNotedOps.get(key); if (unforwardedOps == null) { unforwardedOps = new ArrayList<>(1); mUnforwardedAsyncNotedOps.put(key, unforwardedOps); Loading @@ -3618,7 +3598,6 @@ public class AppOpsService extends IAppOpsService.Stub { } } } } } finally { Binder.restoreCallingIdentity(token); } Loading Loading @@ -4047,7 +4026,7 @@ public class AppOpsService extends IAppOpsService.Stub { if (shouldCollectAsyncNotedOp && !isRestricted) { collectAsyncNotedOp(uid, packageName, code, attributionTag, AppOpsManager.OP_FLAG_SELF, message, shouldCollectMessage, 1); message, shouldCollectMessage); } return new SyncNotedAppOp(isRestricted ? MODE_IGNORED : MODE_ALLOWED, code, attributionTag, Loading Loading @@ -7595,36 +7574,34 @@ public class AppOpsService extends IAppOpsService.Stub { public SyncNotedAppOp noteOperation(int code, int uid, String packageName, String attributionTag, int virtualDeviceId, boolean shouldCollectAsyncNotedOp, String message, boolean shouldCollectMessage, int notedCount) { String message, boolean shouldCollectMessage) { if (mPolicy != null) { if (mCheckOpsDelegate != null) { return mPolicy.noteOperation(code, uid, packageName, attributionTag, virtualDeviceId, shouldCollectAsyncNotedOp, message, shouldCollectMessage, notedCount, this::noteDelegateOperationImpl shouldCollectMessage, this::noteDelegateOperationImpl ); } else { return mPolicy.noteOperation(code, uid, packageName, attributionTag, virtualDeviceId, shouldCollectAsyncNotedOp, message, shouldCollectMessage, notedCount, AppOpsService.this::noteOperationImpl shouldCollectMessage, AppOpsService.this::noteOperationImpl ); } } else if (mCheckOpsDelegate != null) { return noteDelegateOperationImpl(code, uid, packageName, attributionTag, virtualDeviceId, shouldCollectAsyncNotedOp, message, shouldCollectMessage, notedCount); virtualDeviceId, shouldCollectAsyncNotedOp, message, shouldCollectMessage); } return noteOperationImpl(code, uid, packageName, attributionTag, virtualDeviceId, shouldCollectAsyncNotedOp, message, shouldCollectMessage, notedCount); virtualDeviceId, shouldCollectAsyncNotedOp, message, shouldCollectMessage); } private SyncNotedAppOp noteDelegateOperationImpl(int code, int uid, @Nullable String packageName, @Nullable String featureId, int virtualDeviceId, boolean shouldCollectAsyncNotedOp, @Nullable String message, boolean shouldCollectMessage, int notedCount) { boolean shouldCollectMessage) { return mCheckOpsDelegate.noteOperation(code, uid, packageName, featureId, virtualDeviceId, shouldCollectAsyncNotedOp, message, shouldCollectMessage, notedCount, AppOpsService.this::noteOperationImpl AppOpsService.this::noteOperationImpl ); } Loading