Merge "Revert sync app op chain changes" into sc-dev
This commit is contained in:
@@ -2849,14 +2849,14 @@ public class AppOpsManager {
|
|||||||
private static final ThreadLocal<Integer> sBinderThreadCallingUid = new ThreadLocal<>();
|
private static final ThreadLocal<Integer> sBinderThreadCallingUid = new ThreadLocal<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If a thread is currently executing a two-way binder transaction, this stores the
|
* If a thread is currently executing a two-way binder transaction, this stores the op-codes of
|
||||||
* ops that were noted blaming any app (the caller, the caller of the caller, etc).
|
* the app-ops that were noted during this transaction.
|
||||||
*
|
*
|
||||||
* @see #getNotedOpCollectionMode
|
* @see #getNotedOpCollectionMode
|
||||||
* @see #collectNotedOpSync
|
* @see #collectNotedOpSync
|
||||||
*/
|
*/
|
||||||
private static final ThreadLocal<ArrayMap<String, ArrayMap<String, long[]>>>
|
private static final ThreadLocal<ArrayMap<String, long[]>> sAppOpsNotedInThisBinderTransaction =
|
||||||
sAppOpsNotedInThisBinderTransaction = new ThreadLocal<>();
|
new ThreadLocal<>();
|
||||||
|
|
||||||
/** Whether noting for an appop should be collected */
|
/** Whether noting for an appop should be collected */
|
||||||
private static final @ShouldCollectNoteOp byte[] sAppOpsToNote = new byte[_NUM_OP];
|
private static final @ShouldCollectNoteOp byte[] sAppOpsToNote = new byte[_NUM_OP];
|
||||||
@@ -9051,6 +9051,66 @@ public class AppOpsManager {
|
|||||||
sBinderThreadCallingUid.set(callingUid);
|
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.
|
* Finish collection of noted appops on this thread.
|
||||||
*
|
*
|
||||||
@@ -9091,47 +9151,26 @@ public class AppOpsManager {
|
|||||||
*/
|
*/
|
||||||
@TestApi
|
@TestApi
|
||||||
public static void collectNotedOpSync(@NonNull SyncNotedAppOp syncOp) {
|
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:
|
// If this is inside of a two-way binder call:
|
||||||
// We are inside of a two-way binder call. Delivered to caller via
|
// We are inside of a two-way binder call. Delivered to caller via
|
||||||
// {@link #prefixParcelWithAppOpsIfNeeded}
|
// {@link #prefixParcelWithAppOpsIfNeeded}
|
||||||
ArrayMap<String, ArrayMap<String, long[]>> appOpsNoted =
|
int op = sOpStrToOp.get(syncOp.getOp());
|
||||||
sAppOpsNotedInThisBinderTransaction.get();
|
ArrayMap<String, long[]> appOpsNoted = sAppOpsNotedInThisBinderTransaction.get();
|
||||||
if (appOpsNoted == null) {
|
if (appOpsNoted == null) {
|
||||||
appOpsNoted = new ArrayMap<>(1);
|
appOpsNoted = new ArrayMap<>(1);
|
||||||
sAppOpsNotedInThisBinderTransaction.set(appOpsNoted);
|
sAppOpsNotedInThisBinderTransaction.set(appOpsNoted);
|
||||||
}
|
}
|
||||||
|
|
||||||
ArrayMap<String, long[]> packageAppOpsNotedForAttribution = appOpsNoted.get(packageName);
|
long[] appOpsNotedForAttribution = appOpsNoted.get(syncOp.getAttributionTag());
|
||||||
if (packageAppOpsNotedForAttribution == null) {
|
|
||||||
packageAppOpsNotedForAttribution = new ArrayMap<>(1);
|
|
||||||
appOpsNoted.put(packageName, packageAppOpsNotedForAttribution);
|
|
||||||
}
|
|
||||||
|
|
||||||
long[] appOpsNotedForAttribution = packageAppOpsNotedForAttribution.get(attributionTag);
|
|
||||||
if (appOpsNotedForAttribution == null) {
|
if (appOpsNotedForAttribution == null) {
|
||||||
appOpsNotedForAttribution = new long[2];
|
appOpsNotedForAttribution = new long[2];
|
||||||
packageAppOpsNotedForAttribution.put(attributionTag, appOpsNotedForAttribution);
|
appOpsNoted.put(syncOp.getAttributionTag(), appOpsNotedForAttribution);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (code < 64) {
|
if (op < 64) {
|
||||||
appOpsNotedForAttribution[0] |= 1L << code;
|
appOpsNotedForAttribution[0] |= 1L << op;
|
||||||
} else {
|
} 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;
|
return COLLECT_SYNC;
|
||||||
} else {
|
} else {
|
||||||
return COLLECT_ASYNC;
|
return COLLECT_ASYNC;
|
||||||
@@ -9204,32 +9245,20 @@ public class AppOpsManager {
|
|||||||
*/
|
*/
|
||||||
// TODO (b/186872903) Refactor how sync noted ops are propagated.
|
// TODO (b/186872903) Refactor how sync noted ops are propagated.
|
||||||
public static void prefixParcelWithAppOpsIfNeeded(@NonNull Parcel p) {
|
public static void prefixParcelWithAppOpsIfNeeded(@NonNull Parcel p) {
|
||||||
if (!isListeningForOpNotedInBinderTransaction()) {
|
ArrayMap<String, long[]> notedAppOps = sAppOpsNotedInThisBinderTransaction.get();
|
||||||
return;
|
|
||||||
}
|
|
||||||
final ArrayMap<String, ArrayMap<String, long[]>> notedAppOps =
|
|
||||||
sAppOpsNotedInThisBinderTransaction.get();
|
|
||||||
if (notedAppOps == null) {
|
if (notedAppOps == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
p.writeInt(Parcel.EX_HAS_NOTED_APPOPS_REPLY_HEADER);
|
p.writeInt(Parcel.EX_HAS_NOTED_APPOPS_REPLY_HEADER);
|
||||||
|
|
||||||
final int packageCount = notedAppOps.size();
|
int numAttributionWithNotesAppOps = notedAppOps.size();
|
||||||
p.writeInt(packageCount);
|
p.writeInt(numAttributionWithNotesAppOps);
|
||||||
|
|
||||||
for (int i = 0; i < packageCount; i++) {
|
for (int i = 0; i < numAttributionWithNotesAppOps; i++) {
|
||||||
p.writeString(notedAppOps.keyAt(i));
|
p.writeString(notedAppOps.keyAt(i));
|
||||||
|
p.writeLong(notedAppOps.valueAt(i)[0]);
|
||||||
final ArrayMap<String, long[]> notedTagAppOps = notedAppOps.valueAt(i);
|
p.writeLong(notedAppOps.valueAt(i)[1]);
|
||||||
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]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -9244,55 +9273,37 @@ public class AppOpsManager {
|
|||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public static void readAndLogNotedAppops(@NonNull Parcel p) {
|
public static void readAndLogNotedAppops(@NonNull Parcel p) {
|
||||||
final int packageCount = p.readInt();
|
int numAttributionsWithNotedAppOps = p.readInt();
|
||||||
if (packageCount <= 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final String myPackageName = ActivityThread.currentPackageName();
|
for (int i = 0; i < numAttributionsWithNotedAppOps; i++) {
|
||||||
|
String attributionTag = p.readString();
|
||||||
|
long[] rawNotedAppOps = new long[2];
|
||||||
|
rawNotedAppOps[0] = p.readLong();
|
||||||
|
rawNotedAppOps[1] = p.readLong();
|
||||||
|
|
||||||
synchronized (sLock) {
|
if (rawNotedAppOps[0] != 0 || rawNotedAppOps[1] != 0) {
|
||||||
for (int i = 0; i < packageCount; i++) {
|
BitSet notedAppOps = BitSet.valueOf(rawNotedAppOps);
|
||||||
final String packageName = p.readString();
|
|
||||||
|
|
||||||
final int tagCount = p.readInt();
|
synchronized (sLock) {
|
||||||
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) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
final BitSet notedAppOps = BitSet.valueOf(rawNotedAppOps);
|
|
||||||
for (int code = notedAppOps.nextSetBit(0); code != -1;
|
for (int code = notedAppOps.nextSetBit(0); code != -1;
|
||||||
code = notedAppOps.nextSetBit(code + 1)) {
|
code = notedAppOps.nextSetBit(code + 1)) {
|
||||||
if (Objects.equals(myPackageName, packageName)) {
|
if (sOnOpNotedCallback != null) {
|
||||||
if (sOnOpNotedCallback != null) {
|
sOnOpNotedCallback.onNoted(new SyncNotedAppOp(code, attributionTag));
|
||||||
sOnOpNotedCallback.onNoted(new SyncNotedAppOp(code,
|
} else {
|
||||||
attributionTag, packageName));
|
String message = getFormattedStackTrace();
|
||||||
} else {
|
sUnforwardedOps.add(
|
||||||
String message = getFormattedStackTrace();
|
new AsyncNotedAppOp(code, Process.myUid(), attributionTag,
|
||||||
sUnforwardedOps.add(new AsyncNotedAppOp(code, Process.myUid(),
|
message, System.currentTimeMillis()));
|
||||||
attributionTag, message, System.currentTimeMillis()));
|
if (sUnforwardedOps.size() > MAX_UNFORWARDED_OPS) {
|
||||||
if (sUnforwardedOps.size() > MAX_UNFORWARDED_OPS) {
|
sUnforwardedOps.remove(0);
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (int code = notedAppOps.nextSetBit(0); code != -1;
|
||||||
|
code = notedAppOps.nextSetBit(code + 1)) {
|
||||||
|
sMessageCollector.onNoted(new SyncNotedAppOp(code, attributionTag));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -9398,15 +9409,7 @@ public class AppOpsManager {
|
|||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public static boolean isListeningForOpNoted() {
|
public static boolean isListeningForOpNoted() {
|
||||||
return sOnOpNotedCallback != null || isListeningForOpNotedInBinderTransaction()
|
return sOnOpNotedCallback != null || isCollectingStackTraces();
|
||||||
|| isCollectingStackTraces();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return whether we are in a binder transaction and collecting appops.
|
|
||||||
*/
|
|
||||||
private static boolean isListeningForOpNotedInBinderTransaction() {
|
|
||||||
return sBinderThreadCallingUid.get() != null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ import android.annotation.NonNull;
|
|||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
import android.annotation.TestApi;
|
import android.annotation.TestApi;
|
||||||
import android.os.Parcelable;
|
import android.os.Parcelable;
|
||||||
import android.os.Process;
|
|
||||||
|
|
||||||
import com.android.internal.annotations.Immutable;
|
import com.android.internal.annotations.Immutable;
|
||||||
import com.android.internal.util.DataClass;
|
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.
|
* 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
|
* <p>This is either delivered after a
|
||||||
* {@link AppOpsManager.OnOpNotedCallback#onNoted(SyncNotedAppOp) two way binder call} or
|
* {@link AppOpsManager.OnOpNotedCallback#onNoted(SyncNotedAppOp) two way binder call} or
|
||||||
* when the app
|
* when the app
|
||||||
|
|||||||
@@ -560,6 +560,9 @@ public final class BinderProxy implements IBinder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final AppOpsManager.PausedNotedAppOpsCollection prevCollection =
|
||||||
|
AppOpsManager.pauseNotedAppOpsCollection();
|
||||||
|
|
||||||
if ((flags & FLAG_ONEWAY) == 0 && AppOpsManager.isListeningForOpNoted()) {
|
if ((flags & FLAG_ONEWAY) == 0 && AppOpsManager.isListeningForOpNoted()) {
|
||||||
flags |= FLAG_COLLECT_NOTED_APP_OPS;
|
flags |= FLAG_COLLECT_NOTED_APP_OPS;
|
||||||
}
|
}
|
||||||
@@ -567,6 +570,8 @@ public final class BinderProxy implements IBinder {
|
|||||||
try {
|
try {
|
||||||
return transactNative(code, data, reply, flags);
|
return transactNative(code, data, reply, flags);
|
||||||
} finally {
|
} finally {
|
||||||
|
AppOpsManager.resumeNotedAppOpsCollection(prevCollection);
|
||||||
|
|
||||||
if (transactListener != null) {
|
if (transactListener != null) {
|
||||||
transactListener.onTransactEnded(session);
|
transactListener.onTransactEnded(session);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3438,7 +3438,7 @@ public class AppOpsService extends IAppOpsService.Stub {
|
|||||||
+ " package " + packageName + "flags: " +
|
+ " package " + packageName + "flags: " +
|
||||||
AppOpsManager.flagsToString(flags));
|
AppOpsManager.flagsToString(flags));
|
||||||
return new SyncNotedAppOp(AppOpsManager.MODE_ERRORED, code, attributionTag,
|
return new SyncNotedAppOp(AppOpsManager.MODE_ERRORED, code, attributionTag,
|
||||||
packageName + " flags: " + AppOpsManager.flagsToString(flags));
|
packageName);
|
||||||
}
|
}
|
||||||
final Op op = getOpLocked(ops, code, uid, true);
|
final Op op = getOpLocked(ops, code, uid, true);
|
||||||
final AttributedOp attributedOp = op.getOrCreateAttribution(op, attributionTag);
|
final AttributedOp attributedOp = op.getOrCreateAttribution(op, attributionTag);
|
||||||
|
|||||||
Reference in New Issue
Block a user