Merge "Add support of AttributionIds and AttributionChains to Discrete registry" into sc-dev

This commit is contained in:
Stanislav Zholnin
2021-06-16 18:44:18 +00:00
committed by Android (Google) Code Review
3 changed files with 82 additions and 34 deletions

View File

@@ -848,7 +848,7 @@ public class AppOpsService extends IAppOpsService.Stub {
return mAttributionFlags; return mAttributionFlags;
} }
/** @return attributoin chiang id for the access */ /** @return attribution chain id for the access */
public int getAttributionChainId() { public int getAttributionChainId() {
return mAttributionChainId; return mAttributionChainId;
} }
@@ -912,7 +912,8 @@ public class AppOpsService extends IAppOpsService.Stub {
proxyAttributionTag, uidState, flags); proxyAttributionTag, uidState, flags);
mHistoricalRegistry.incrementOpAccessedCount(parent.op, parent.uid, parent.packageName, mHistoricalRegistry.incrementOpAccessedCount(parent.op, parent.uid, parent.packageName,
tag, uidState, flags, accessTime); tag, uidState, flags, accessTime, AppOpsManager.ATTRIBUTION_FLAGS_NONE,
AppOpsManager.ATTRIBUTION_CHAIN_ID_NONE);
} }
/** /**
@@ -1053,9 +1054,9 @@ public class AppOpsService extends IAppOpsService.Stub {
event.numUnfinishedStarts++; event.numUnfinishedStarts++;
if (isStarted) { if (isStarted) {
// TODO: Consider storing the attribution chain flags and id
mHistoricalRegistry.incrementOpAccessedCount(parent.op, parent.uid, mHistoricalRegistry.incrementOpAccessedCount(parent.op, parent.uid,
parent.packageName, tag, uidState, flags, startTime); parent.packageName, tag, uidState, flags, startTime, attributionFlags,
attributionChainId);
} }
} }
@@ -1112,7 +1113,8 @@ public class AppOpsService extends IAppOpsService.Stub {
mHistoricalRegistry.increaseOpAccessDuration(parent.op, parent.uid, mHistoricalRegistry.increaseOpAccessDuration(parent.op, parent.uid,
parent.packageName, tag, event.getUidState(), parent.packageName, tag, event.getUidState(),
event.getFlags(), finishedEvent.getNoteTime(), finishedEvent.getDuration()); event.getFlags(), finishedEvent.getNoteTime(), finishedEvent.getDuration(),
event.getAttributionFlags(), event.getAttributionChainId());
if (!isPausing) { if (!isPausing) {
mInProgressStartOpEventPool.release(event); mInProgressStartOpEventPool.release(event);
@@ -1215,7 +1217,8 @@ public class AppOpsService extends IAppOpsService.Stub {
event.mStartElapsedTime = SystemClock.elapsedRealtime(); event.mStartElapsedTime = SystemClock.elapsedRealtime();
event.mStartTime = startTime; event.mStartTime = startTime;
mHistoricalRegistry.incrementOpAccessedCount(parent.op, parent.uid, mHistoricalRegistry.incrementOpAccessedCount(parent.op, parent.uid,
parent.packageName, tag, event.mUidState, event.mFlags, startTime); parent.packageName, tag, event.mUidState, event.mFlags, startTime,
event.getAttributionFlags(), event.getAttributionChainId());
if (shouldSendActive) { if (shouldSendActive) {
scheduleOpActiveChangedIfNeededLocked(parent.op, parent.uid, parent.packageName, scheduleOpActiveChangedIfNeededLocked(parent.op, parent.uid, parent.packageName,
tag, true, event.getAttributionFlags(), event.getAttributionChainId()); tag, true, event.getAttributionFlags(), event.getAttributionChainId());

View File

@@ -26,6 +26,7 @@ import static android.app.AppOpsManager.OP_FINE_LOCATION;
import static android.app.AppOpsManager.OP_FLAGS_ALL; import static android.app.AppOpsManager.OP_FLAGS_ALL;
import static android.app.AppOpsManager.OP_FLAG_SELF; import static android.app.AppOpsManager.OP_FLAG_SELF;
import static android.app.AppOpsManager.OP_FLAG_TRUSTED_PROXIED; import static android.app.AppOpsManager.OP_FLAG_TRUSTED_PROXIED;
import static android.app.AppOpsManager.OP_FLAG_TRUSTED_PROXY;
import static android.app.AppOpsManager.OP_NONE; import static android.app.AppOpsManager.OP_NONE;
import static android.app.AppOpsManager.OP_PHONE_CALL_CAMERA; import static android.app.AppOpsManager.OP_PHONE_CALL_CAMERA;
import static android.app.AppOpsManager.OP_PHONE_CALL_MICROPHONE; import static android.app.AppOpsManager.OP_PHONE_CALL_MICROPHONE;
@@ -156,8 +157,11 @@ final class DiscreteRegistry {
private static final String ATTR_NOTE_DURATION = "nd"; private static final String ATTR_NOTE_DURATION = "nd";
private static final String ATTR_UID_STATE = "us"; private static final String ATTR_UID_STATE = "us";
private static final String ATTR_FLAGS = "f"; private static final String ATTR_FLAGS = "f";
private static final String ATTR_ATTRIBUTION_FLAGS = "af";
private static final String ATTR_CHAIN_ID = "ci";
private static final int OP_FLAGS_DISCRETE = OP_FLAG_SELF | OP_FLAG_TRUSTED_PROXIED; private static final int OP_FLAGS_DISCRETE = OP_FLAG_SELF | OP_FLAG_TRUSTED_PROXIED
| OP_FLAG_TRUSTED_PROXY;
// Lock for read/write access to on disk state // Lock for read/write access to on disk state
private final Object mOnDiskLock = new Object(); private final Object mOnDiskLock = new Object();
@@ -227,13 +231,14 @@ final class DiscreteRegistry {
void recordDiscreteAccess(int uid, String packageName, int op, @Nullable String attributionTag, void recordDiscreteAccess(int uid, String packageName, int op, @Nullable String attributionTag,
@AppOpsManager.OpFlags int flags, @AppOpsManager.UidState int uidState, long accessTime, @AppOpsManager.OpFlags int flags, @AppOpsManager.UidState int uidState, long accessTime,
long accessDuration) { long accessDuration, @AppOpsManager.AttributionFlags int attributionFlags,
int attributionChainId) {
if (!isDiscreteOp(op, flags)) { if (!isDiscreteOp(op, flags)) {
return; return;
} }
synchronized (mInMemoryLock) { synchronized (mInMemoryLock) {
mDiscreteOps.addDiscreteAccess(op, uid, packageName, attributionTag, flags, uidState, mDiscreteOps.addDiscreteAccess(op, uid, packageName, attributionTag, flags, uidState,
accessTime, accessDuration); accessTime, accessDuration, attributionFlags, attributionChainId);
} }
} }
@@ -383,9 +388,10 @@ final class DiscreteRegistry {
void addDiscreteAccess(int op, int uid, @NonNull String packageName, void addDiscreteAccess(int op, int uid, @NonNull String packageName,
@Nullable String attributionTag, @AppOpsManager.OpFlags int flags, @Nullable String attributionTag, @AppOpsManager.OpFlags int flags,
@AppOpsManager.UidState int uidState, long accessTime, long accessDuration) { @AppOpsManager.UidState int uidState, long accessTime, long accessDuration,
@AppOpsManager.AttributionFlags int attributionFlags, int attributionChainId) {
getOrCreateDiscreteUidOps(uid).addDiscreteAccess(op, packageName, attributionTag, flags, getOrCreateDiscreteUidOps(uid).addDiscreteAccess(op, packageName, attributionTag, flags,
uidState, accessTime, accessDuration); uidState, accessTime, accessDuration, attributionFlags, attributionChainId);
} }
private void filter(long beginTimeMillis, long endTimeMillis, private void filter(long beginTimeMillis, long endTimeMillis,
@@ -613,9 +619,10 @@ final class DiscreteRegistry {
void addDiscreteAccess(int op, @NonNull String packageName, @Nullable String attributionTag, void addDiscreteAccess(int op, @NonNull String packageName, @Nullable String attributionTag,
@AppOpsManager.OpFlags int flags, @AppOpsManager.UidState int uidState, @AppOpsManager.OpFlags int flags, @AppOpsManager.UidState int uidState,
long accessTime, long accessDuration) { long accessTime, long accessDuration,
@AppOpsManager.AttributionFlags int attributionFlags, int attributionChainId) {
getOrCreateDiscretePackageOps(packageName).addDiscreteAccess(op, attributionTag, flags, getOrCreateDiscretePackageOps(packageName).addDiscreteAccess(op, attributionTag, flags,
uidState, accessTime, accessDuration); uidState, accessTime, accessDuration, attributionFlags, attributionChainId);
} }
private DiscretePackageOps getOrCreateDiscretePackageOps(String packageName) { private DiscretePackageOps getOrCreateDiscretePackageOps(String packageName) {
@@ -680,9 +687,10 @@ final class DiscreteRegistry {
void addDiscreteAccess(int op, @Nullable String attributionTag, void addDiscreteAccess(int op, @Nullable String attributionTag,
@AppOpsManager.OpFlags int flags, @AppOpsManager.UidState int uidState, @AppOpsManager.OpFlags int flags, @AppOpsManager.UidState int uidState,
long accessTime, long accessDuration) { long accessTime, long accessDuration,
@AppOpsManager.AttributionFlags int attributionFlags, int attributionChainId) {
getOrCreateDiscreteOp(op).addDiscreteAccess(attributionTag, flags, uidState, accessTime, getOrCreateDiscreteOp(op).addDiscreteAccess(attributionTag, flags, uidState, accessTime,
accessDuration); accessDuration, attributionFlags, attributionChainId);
} }
void merge(DiscretePackageOps other) { void merge(DiscretePackageOps other) {
@@ -823,37 +831,39 @@ final class DiscreteRegistry {
for (int j = 0; j < n; j++) { for (int j = 0; j < n; j++) {
DiscreteOpEvent event = list.get(j); DiscreteOpEvent event = list.get(j);
list.set(j, new DiscreteOpEvent(event.mNoteTime - offset, event.mNoteDuration, list.set(j, new DiscreteOpEvent(event.mNoteTime - offset, event.mNoteDuration,
event.mUidState, event.mOpFlag)); event.mUidState, event.mOpFlag, event.mAttributionFlags,
event.mAttributionChainId));
} }
} }
} }
void addDiscreteAccess(@Nullable String attributionTag, void addDiscreteAccess(@Nullable String attributionTag,
@AppOpsManager.OpFlags int flags, @AppOpsManager.UidState int uidState, @AppOpsManager.OpFlags int flags, @AppOpsManager.UidState int uidState,
long accessTime, long accessDuration) { long accessTime, long accessDuration,
@AppOpsManager.AttributionFlags int attributionFlags, int attributionChainId) {
List<DiscreteOpEvent> attributedOps = getOrCreateDiscreteOpEventsList( List<DiscreteOpEvent> attributedOps = getOrCreateDiscreteOpEventsList(
attributionTag); attributionTag);
accessTime = accessTime / sDiscreteHistoryQuantization * sDiscreteHistoryQuantization;
accessDuration = accessDuration == -1 ? -1
: (accessDuration + sDiscreteHistoryQuantization - 1)
/ sDiscreteHistoryQuantization * sDiscreteHistoryQuantization;
int nAttributedOps = attributedOps.size(); int nAttributedOps = attributedOps.size();
int i = nAttributedOps; int i = nAttributedOps;
for (; i > 0; i--) { for (; i > 0; i--) {
DiscreteOpEvent previousOp = attributedOps.get(i - 1); DiscreteOpEvent previousOp = attributedOps.get(i - 1);
if (previousOp.mNoteTime < accessTime) { if (discretizeTimeStamp(previousOp.mNoteTime) < discretizeTimeStamp(accessTime)) {
break; break;
} }
if (previousOp.mOpFlag == flags && previousOp.mUidState == uidState) { if (previousOp.mOpFlag == flags && previousOp.mUidState == uidState
if (accessDuration != previousOp.mNoteDuration) { && previousOp.mAttributionFlags == attributionFlags
&& previousOp.mAttributionChainId == attributionChainId) {
if (discretizeDuration(accessDuration) != discretizeDuration(
previousOp.mNoteDuration)) {
break; break;
} else { } else {
return; return;
} }
} }
} }
attributedOps.add(i, new DiscreteOpEvent(accessTime, accessDuration, uidState, flags)); attributedOps.add(i, new DiscreteOpEvent(accessTime, accessDuration, uidState, flags,
attributionFlags, attributionChainId));
} }
private List<DiscreteOpEvent> getOrCreateDiscreteOpEventsList(String attributionTag) { private List<DiscreteOpEvent> getOrCreateDiscreteOpEventsList(String attributionTag) {
@@ -875,7 +885,8 @@ final class DiscreteRegistry {
for (int j = 0; j < nEvents; j++) { for (int j = 0; j < nEvents; j++) {
DiscreteOpEvent event = events.get(j); DiscreteOpEvent event = events.get(j);
result.addDiscreteAccess(op, uid, packageName, tag, event.mUidState, result.addDiscreteAccess(op, uid, packageName, tag, event.mUidState,
event.mOpFlag, event.mNoteTime, event.mNoteDuration); event.mOpFlag, discretizeTimeStamp(event.mNoteTime),
discretizeDuration(event.mNoteDuration));
} }
} }
} }
@@ -932,11 +943,15 @@ final class DiscreteRegistry {
-1); -1);
int uidState = parser.getAttributeInt(null, ATTR_UID_STATE); int uidState = parser.getAttributeInt(null, ATTR_UID_STATE);
int opFlags = parser.getAttributeInt(null, ATTR_FLAGS); int opFlags = parser.getAttributeInt(null, ATTR_FLAGS);
int attributionFlags = parser.getAttributeInt(null,
ATTR_ATTRIBUTION_FLAGS, AppOpsManager.ATTRIBUTION_FLAGS_NONE);
int attributionChainId = parser.getAttributeInt(null, ATTR_CHAIN_ID,
AppOpsManager.ATTRIBUTION_CHAIN_ID_NONE);
if (noteTime + noteDuration < beginTimeMillis) { if (noteTime + noteDuration < beginTimeMillis) {
continue; continue;
} }
DiscreteOpEvent event = new DiscreteOpEvent(noteTime, noteDuration, DiscreteOpEvent event = new DiscreteOpEvent(noteTime, noteDuration,
uidState, opFlags); uidState, opFlags, attributionFlags, attributionChainId);
events.add(event); events.add(event);
} }
} }
@@ -952,13 +967,18 @@ final class DiscreteRegistry {
final long mNoteDuration; final long mNoteDuration;
final @AppOpsManager.UidState int mUidState; final @AppOpsManager.UidState int mUidState;
final @AppOpsManager.OpFlags int mOpFlag; final @AppOpsManager.OpFlags int mOpFlag;
final @AppOpsManager.AttributionFlags int mAttributionFlags;
final int mAttributionChainId;
DiscreteOpEvent(long noteTime, long noteDuration, @AppOpsManager.UidState int uidState, DiscreteOpEvent(long noteTime, long noteDuration, @AppOpsManager.UidState int uidState,
@AppOpsManager.OpFlags int opFlag) { @AppOpsManager.OpFlags int opFlag,
@AppOpsManager.AttributionFlags int attributionFlags, int attributionChainId) {
mNoteTime = noteTime; mNoteTime = noteTime;
mNoteDuration = noteDuration; mNoteDuration = noteDuration;
mUidState = uidState; mUidState = uidState;
mOpFlag = opFlag; mOpFlag = opFlag;
mAttributionFlags = attributionFlags;
mAttributionChainId = attributionChainId;
} }
private void dump(@NonNull PrintWriter pw, @NonNull SimpleDateFormat sdf, private void dump(@NonNull PrintWriter pw, @NonNull SimpleDateFormat sdf,
@@ -969,13 +989,19 @@ final class DiscreteRegistry {
pw.print("-"); pw.print("-");
pw.print(flagsToString(mOpFlag)); pw.print(flagsToString(mOpFlag));
pw.print("] at "); pw.print("] at ");
date.setTime(mNoteTime); date.setTime(discretizeTimeStamp(mNoteTime));
pw.print(sdf.format(date)); pw.print(sdf.format(date));
if (mNoteDuration != -1) { if (mNoteDuration != -1) {
pw.print(" for "); pw.print(" for ");
pw.print(mNoteDuration); pw.print(discretizeDuration(mNoteDuration));
pw.print(" milliseconds "); pw.print(" milliseconds ");
} }
if (mAttributionFlags != AppOpsManager.ATTRIBUTION_FLAGS_NONE) {
pw.print(" attribution flags=");
pw.print(mAttributionFlags);
pw.print(" with chainId=");
pw.print(mAttributionChainId);
}
pw.println(); pw.println();
} }
@@ -984,6 +1010,12 @@ final class DiscreteRegistry {
if (mNoteDuration != -1) { if (mNoteDuration != -1) {
out.attributeLong(null, ATTR_NOTE_DURATION, mNoteDuration); out.attributeLong(null, ATTR_NOTE_DURATION, mNoteDuration);
} }
if (mAttributionFlags != AppOpsManager.ATTRIBUTION_FLAGS_NONE) {
out.attributeInt(null, ATTR_ATTRIBUTION_FLAGS, mAttributionFlags);
}
if (mAttributionChainId != AppOpsManager.ATTRIBUTION_CHAIN_ID_NONE) {
out.attributeInt(null, ATTR_CHAIN_ID, mAttributionChainId);
}
out.attributeInt(null, ATTR_UID_STATE, mUidState); out.attributeInt(null, ATTR_UID_STATE, mUidState);
out.attributeInt(null, ATTR_FLAGS, mOpFlag); out.attributeInt(null, ATTR_FLAGS, mOpFlag);
} }
@@ -1055,6 +1087,16 @@ final class DiscreteRegistry {
return true; return true;
} }
private static long discretizeTimeStamp(long timeStamp) {
return timeStamp / sDiscreteHistoryQuantization * sDiscreteHistoryQuantization;
}
private static long discretizeDuration(long duration) {
return duration == -1 ? -1 : (duration + sDiscreteHistoryQuantization - 1)
/ sDiscreteHistoryQuantization * sDiscreteHistoryQuantization;
}
void setDebugMode(boolean debugMode) { void setDebugMode(boolean debugMode) {
this.mDebugMode = debugMode; this.mDebugMode = debugMode;
} }

View File

@@ -487,7 +487,8 @@ final class HistoricalRegistry {
void incrementOpAccessedCount(int op, int uid, @NonNull String packageName, void incrementOpAccessedCount(int op, int uid, @NonNull String packageName,
@Nullable String attributionTag, @UidState int uidState, @OpFlags int flags, @Nullable String attributionTag, @UidState int uidState, @OpFlags int flags,
long accessTime) { long accessTime, @AppOpsManager.AttributionFlags int attributionFlags,
int attributionChainId) {
synchronized (mInMemoryLock) { synchronized (mInMemoryLock) {
if (mMode == AppOpsManager.HISTORICAL_MODE_ENABLED_ACTIVE) { if (mMode == AppOpsManager.HISTORICAL_MODE_ENABLED_ACTIVE) {
if (!isPersistenceInitializedMLocked()) { if (!isPersistenceInitializedMLocked()) {
@@ -499,7 +500,7 @@ final class HistoricalRegistry {
attributionTag, uidState, flags, 1); attributionTag, uidState, flags, 1);
mDiscreteRegistry.recordDiscreteAccess(uid, packageName, op, attributionTag, mDiscreteRegistry.recordDiscreteAccess(uid, packageName, op, attributionTag,
flags, uidState, accessTime, -1); flags, uidState, accessTime, -1, attributionFlags, attributionChainId);
} }
} }
} }
@@ -521,7 +522,8 @@ final class HistoricalRegistry {
void increaseOpAccessDuration(int op, int uid, @NonNull String packageName, void increaseOpAccessDuration(int op, int uid, @NonNull String packageName,
@Nullable String attributionTag, @UidState int uidState, @OpFlags int flags, @Nullable String attributionTag, @UidState int uidState, @OpFlags int flags,
long eventStartTime, long increment) { long eventStartTime, long increment,
@AppOpsManager.AttributionFlags int attributionFlags, int attributionChainId) {
synchronized (mInMemoryLock) { synchronized (mInMemoryLock) {
if (mMode == AppOpsManager.HISTORICAL_MODE_ENABLED_ACTIVE) { if (mMode == AppOpsManager.HISTORICAL_MODE_ENABLED_ACTIVE) {
if (!isPersistenceInitializedMLocked()) { if (!isPersistenceInitializedMLocked()) {
@@ -532,7 +534,8 @@ final class HistoricalRegistry {
System.currentTimeMillis()).increaseAccessDuration(op, uid, packageName, System.currentTimeMillis()).increaseAccessDuration(op, uid, packageName,
attributionTag, uidState, flags, increment); attributionTag, uidState, flags, increment);
mDiscreteRegistry.recordDiscreteAccess(uid, packageName, op, attributionTag, mDiscreteRegistry.recordDiscreteAccess(uid, packageName, op, attributionTag,
flags, uidState, eventStartTime, increment); flags, uidState, eventStartTime, increment, attributionFlags,
attributionChainId);
} }
} }
} }