Make note/startOperation return SyncNotedAppOp, add mode

Use the SyncNotedAppOp when collecting self/sync ops in AppOpsManager.
Also adds "mode" to SyncNotedAppOp

Fixes: 184111263
Test: Atest AppOpsServiceTest
Change-Id: Ia20c7054d06e241cbe017a641d728e11c7eccd06
This commit is contained in:
Nate Myren
2021-04-01 15:20:41 -07:00
parent 276b4887da
commit ee9a4741d4
9 changed files with 181 additions and 140 deletions

View File

@@ -33,6 +33,7 @@ import android.compat.Compatibility;
import android.compat.annotation.ChangeId;
import android.compat.annotation.EnabledAfter;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.AttributionSource;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
@@ -50,7 +51,6 @@ import android.os.IBinder;
import android.os.Looper;
import android.os.Parcel;
import android.os.Parcelable;
import android.content.AttributionSource;
import android.os.Process;
import android.os.RemoteCallback;
import android.os.RemoteException;
@@ -8015,18 +8015,18 @@ public class AppOpsManager {
}
}
int mode = mService.noteOperation(op, uid, packageName, attributionTag,
SyncNotedAppOp syncOp = mService.noteOperation(op, uid, packageName, attributionTag,
collectionMode == COLLECT_ASYNC, message, shouldCollectMessage);
if (mode == MODE_ALLOWED) {
if (syncOp.getOpMode()== MODE_ALLOWED) {
if (collectionMode == COLLECT_SELF) {
collectNotedOpForSelf(op, attributionTag);
collectNotedOpForSelf(syncOp);
} else if (collectionMode == COLLECT_SYNC) {
collectNotedOpSync(op, attributionTag);
collectNotedOpSync(syncOp);
}
}
return mode;
return syncOp.getOpMode();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -8183,23 +8183,23 @@ public class AppOpsManager {
}
}
int mode = mService.noteProxyOperation(op, attributionSource,
SyncNotedAppOp syncOp = mService.noteProxyOperation(op, attributionSource,
collectionMode == COLLECT_ASYNC, message,
shouldCollectMessage, skipProxyOperation);
if (mode == MODE_ALLOWED) {
if (syncOp.getOpMode() == MODE_ALLOWED) {
if (collectionMode == COLLECT_SELF) {
collectNotedOpForSelf(op, attributionSource.getNextAttributionTag());
collectNotedOpForSelf(syncOp);
} else if (collectionMode == COLLECT_SYNC
// Only collect app-ops when the proxy is trusted
&& (mContext.checkPermission(Manifest.permission.UPDATE_APP_OPS_STATS, -1,
myUid) == PackageManager.PERMISSION_GRANTED ||
Binder.getCallingUid() == attributionSource.getNextUid())) {
collectNotedOpSync(op, attributionSource.getNextAttributionTag());
collectNotedOpSync(syncOp);
}
}
return mode;
return syncOp.getOpMode();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -8496,19 +8496,19 @@ public class AppOpsManager {
}
}
int mode = mService.startOperation(getClientId(), op, uid, packageName,
SyncNotedAppOp syncOp = mService.startOperation(getClientId(), op, uid, packageName,
attributionTag, startIfModeDefault, collectionMode == COLLECT_ASYNC, message,
shouldCollectMessage);
if (mode == MODE_ALLOWED) {
if (syncOp.getOpMode() == MODE_ALLOWED) {
if (collectionMode == COLLECT_SELF) {
collectNotedOpForSelf(op, attributionTag);
collectNotedOpForSelf(syncOp);
} else if (collectionMode == COLLECT_SYNC) {
collectNotedOpSync(op, attributionTag);
collectNotedOpSync(syncOp);
}
}
return mode;
return syncOp.getOpMode();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -8611,24 +8611,23 @@ public class AppOpsManager {
}
}
int mode = mService.startProxyOperation(getClientId(), op,
SyncNotedAppOp syncOp = mService.startProxyOperation(getClientId(), op,
attributionSource, false, collectionMode == COLLECT_ASYNC, message,
shouldCollectMessage, skipProxyOperation);
if (mode == MODE_ALLOWED) {
if (syncOp.getOpMode() == MODE_ALLOWED) {
if (collectionMode == COLLECT_SELF) {
collectNotedOpForSelf(op,
attributionSource.getNextAttributionTag());
collectNotedOpForSelf(syncOp);
} else if (collectionMode == COLLECT_SYNC
// Only collect app-ops when the proxy is trusted
&& (mContext.checkPermission(Manifest.permission.UPDATE_APP_OPS_STATS, -1,
Process.myUid()) == PackageManager.PERMISSION_GRANTED
|| Binder.getCallingUid() == attributionSource.getNextUid())) {
collectNotedOpSync(op, attributionSource.getNextAttributionTag());
collectNotedOpSync(syncOp);
}
}
return mode;
return syncOp.getOpMode();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -8869,13 +8868,13 @@ public class AppOpsManager {
* @param op The noted op
* @param attributionTag The attribution tag the op is noted for
*/
private void collectNotedOpForSelf(int op, @Nullable String attributionTag) {
private void collectNotedOpForSelf(SyncNotedAppOp syncOp) {
synchronized (sLock) {
if (sOnOpNotedCallback != null) {
sOnOpNotedCallback.onSelfNoted(new SyncNotedAppOp(op, attributionTag));
sOnOpNotedCallback.onSelfNoted(syncOp);
}
}
sMessageCollector.onSelfNoted(new SyncNotedAppOp(op, attributionTag));
sMessageCollector.onSelfNoted(syncOp);
}
/**
@@ -8883,23 +8882,23 @@ public class AppOpsManager {
*
* <p> Delivered to caller via {@link #prefixParcelWithAppOpsIfNeeded}
*
* @param op The noted op
* @param attributionTag The attribution tag the op is noted for
* @param syncOp the op and attribution tag to note for
*/
private void collectNotedOpSync(int op, @Nullable String attributionTag) {
private void collectNotedOpSync(@NonNull SyncNotedAppOp syncOp) {
// 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}
int op = sOpStrToOp.get(syncOp.getOp());
ArrayMap<String, long[]> appOpsNoted = sAppOpsNotedInThisBinderTransaction.get();
if (appOpsNoted == null) {
appOpsNoted = new ArrayMap<>(1);
sAppOpsNotedInThisBinderTransaction.set(appOpsNoted);
}
long[] appOpsNotedForAttribution = appOpsNoted.get(attributionTag);
long[] appOpsNotedForAttribution = appOpsNoted.get(syncOp.getAttributionTag());
if (appOpsNotedForAttribution == null) {
appOpsNotedForAttribution = new long[2];
appOpsNoted.put(attributionTag, appOpsNotedForAttribution);
appOpsNoted.put(syncOp.getAttributionTag(), appOpsNotedForAttribution);
}
if (op < 64) {

View File

@@ -76,11 +76,11 @@ public abstract class AppOpsManagerInternal {
* @param superImpl The super implementation.
* @return The app op note result.
*/
int noteOperation(int code, int uid, @Nullable String packageName,
SyncNotedAppOp noteOperation(int code, int uid, @Nullable String packageName,
@Nullable String featureId, boolean shouldCollectAsyncNotedOp,
@Nullable String message, boolean shouldCollectMessage,
@NonNull HeptFunction<Integer, Integer, String, String, Boolean, String, Boolean,
Integer> superImpl);
SyncNotedAppOp> superImpl);
/**
* Allows overriding note proxy operation behavior.
@@ -94,11 +94,11 @@ public abstract class AppOpsManagerInternal {
* @param superImpl The super implementation.
* @return The app op note result.
*/
int noteProxyOperation(int code, @NonNull AttributionSource attributionSource,
SyncNotedAppOp noteProxyOperation(int code, @NonNull AttributionSource attributionSource,
boolean shouldCollectAsyncNotedOp, @Nullable String message,
boolean shouldCollectMessage, boolean skipProxyOperation,
@NonNull HexFunction<Integer, AttributionSource, Boolean, String, Boolean,
Boolean, Integer> superImpl);
Boolean, SyncNotedAppOp> superImpl);
/**
* Allows overriding start proxy operation behavior.
@@ -113,12 +113,12 @@ public abstract class AppOpsManagerInternal {
* @param superImpl The super implementation.
* @return The app op note result.
*/
int startProxyOperation(IBinder token, int code,
SyncNotedAppOp startProxyOperation(IBinder token, int code,
@NonNull AttributionSource attributionSource, boolean startIfModeDefault,
boolean shouldCollectAsyncNotedOp, String message, boolean shouldCollectMessage,
boolean skipProxyOperation, @NonNull OctFunction<IBinder, Integer,
AttributionSource, Boolean, Boolean, String, Boolean, Boolean,
Integer> superImpl);
SyncNotedAppOp> superImpl);
/**
* Allows overriding finish proxy op.

View File

@@ -34,18 +34,36 @@ import com.android.internal.util.DataClass;
* itself}.
*/
@Immutable
/*@DataClass(
@DataClass(
genEqualsHashCode = true,
genAidl = true,
genConstructor = false
)
@DataClass.Suppress("getOpCode")*/
@DataClass.Suppress({"getOpCode", "getOpMode"})
public final class SyncNotedAppOp implements Parcelable {
/** mode returned by the system on a call to note/startOp, if applicable */
private final int mOpMode;
/** op code of synchronous appop noted */
private final @IntRange(from = 0L, to = AppOpsManager._NUM_OP - 1) int mOpCode;
/** attributionTag of synchronous appop noted */
private final @Nullable String mAttributionTag;
/**
* Native code relies on parcel ordering, do not change
* @hide
*/
public SyncNotedAppOp(int opMode, @IntRange(from = 0L) int opCode,
@Nullable String attributionTag) {
this.mOpCode = opCode;
com.android.internal.util.AnnotationValidations.validate(
IntRange.class, null, mOpCode,
"from", 0,
"to", AppOpsManager._NUM_OP - 1);
this.mAttributionTag = attributionTag;
this.mOpMode = opMode;
}
/**
* Creates a new SyncNotedAppOp.
*
@@ -55,12 +73,7 @@ public final class SyncNotedAppOp implements Parcelable {
* attributionTag of synchronous appop noted
*/
public SyncNotedAppOp(@IntRange(from = 0L) int opCode, @Nullable String attributionTag) {
this.mOpCode = opCode;
com.android.internal.util.AnnotationValidations.validate(
IntRange.class, null, mOpCode,
"from", 0,
"to", AppOpsManager._NUM_OP - 1);
this.mAttributionTag = attributionTag;
this(AppOpsManager.MODE_IGNORED, opCode, attributionTag);
}
/**
@@ -70,7 +83,16 @@ public final class SyncNotedAppOp implements Parcelable {
return AppOpsManager.opToPublicName(mOpCode);
}
// Code below generated by codegen v1.0.14.
/**
* @hide
*/
public int getOpMode() {
return mOpMode;
}
// Code below generated by codegen v1.0.23.
//
// DO NOT MODIFY!
// CHECKSTYLE:OFF Generated code
@@ -104,6 +126,7 @@ public final class SyncNotedAppOp implements Parcelable {
SyncNotedAppOp that = (SyncNotedAppOp) o;
//noinspection PointlessBooleanExpression
return true
&& mOpMode == that.mOpMode
&& mOpCode == that.mOpCode
&& java.util.Objects.equals(mAttributionTag, that.mAttributionTag);
}
@@ -115,6 +138,7 @@ public final class SyncNotedAppOp implements Parcelable {
// int fieldNameHashCode() { ... }
int _hash = 1;
_hash = 31 * _hash + mOpMode;
_hash = 31 * _hash + mOpCode;
_hash = 31 * _hash + java.util.Objects.hashCode(mAttributionTag);
return _hash;
@@ -127,8 +151,9 @@ public final class SyncNotedAppOp implements Parcelable {
// void parcelFieldName(Parcel dest, int flags) { ... }
byte flg = 0;
if (mAttributionTag != null) flg |= 0x2;
if (mAttributionTag != null) flg |= 0x4;
dest.writeByte(flg);
dest.writeInt(mOpMode);
dest.writeInt(mOpCode);
if (mAttributionTag != null) dest.writeString(mAttributionTag);
}
@@ -145,13 +170,15 @@ public final class SyncNotedAppOp implements Parcelable {
// static FieldType unparcelFieldName(Parcel in) { ... }
byte flg = in.readByte();
int opMode = in.readInt();
int opCode = in.readInt();
String attributionTag = (flg & 0x2) == 0 ? null : in.readString();
String attributionTag = (flg & 0x4) == 0 ? null : in.readString();
this.mOpMode = opMode;
this.mOpCode = opCode;
com.android.internal.util.AnnotationValidations.validate(
IntRange.class, null, mOpCode,
"from", 0,
"from", 0L,
"to", AppOpsManager._NUM_OP - 1);
this.mAttributionTag = attributionTag;
@@ -172,11 +199,11 @@ public final class SyncNotedAppOp implements Parcelable {
}
};
/*@DataClass.Generated(
time = 1579188889960L,
codegenVersion = "1.0.14",
@DataClass.Generated(
time = 1617317997768L,
codegenVersion = "1.0.23",
sourceFile = "frameworks/base/core/java/android/app/SyncNotedAppOp.java",
inputSignatures = "private final @android.annotation.IntRange(from=0L, to=AppOpsManager._NUM_OP - 1) int mOpCode\nprivate final @android.annotation.Nullable java.lang.String mAttributionTag\npublic @android.annotation.NonNull java.lang.String getOp()\npublic @android.annotation.SystemApi int getOpCode()\nclass SyncNotedAppOp extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genEqualsHashCode=true, genConstructor=false)")*/
inputSignatures = "private final int mOpMode\nprivate final @android.annotation.IntRange int mOpCode\nprivate final @android.annotation.Nullable java.lang.String mAttributionTag\npublic @android.annotation.NonNull java.lang.String getOp()\npublic int getOpMode()\nclass SyncNotedAppOp extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genEqualsHashCode=true, genAidl=true, genConstructor=false)")
@Deprecated
private void __metadata() {}

View File

@@ -36,9 +36,9 @@ interface IAppOpsService {
// be kept in sync with frameworks/native/libs/binder/include/binder/IAppOpsService.h
// and not be reordered
int checkOperation(int code, int uid, String packageName);
int noteOperation(int code, int uid, String packageName, @nullable String attributionTag,
SyncNotedAppOp noteOperation(int code, int uid, String packageName, @nullable String attributionTag,
boolean shouldCollectAsyncNotedOp, String message, boolean shouldCollectMessage);
int startOperation(IBinder clientId, int code, int uid, String packageName,
SyncNotedAppOp startOperation(IBinder clientId, int code, int uid, String packageName,
@nullable String attributionTag, boolean startIfModeDefault,
boolean shouldCollectAsyncNotedOp, String message, boolean shouldCollectMessage);
@UnsupportedAppUsage
@@ -53,10 +53,10 @@ interface IAppOpsService {
// End of methods also called by native code.
// Any new method exposed to native must be added after the last one, do not reorder
int noteProxyOperation(int code, in AttributionSource attributionSource,
SyncNotedAppOp noteProxyOperation(int code, in AttributionSource attributionSource,
boolean shouldCollectAsyncNotedOp, String message, boolean shouldCollectMessage,
boolean skipProxyOperation);
int startProxyOperation(IBinder clientId, int code, in AttributionSource attributionSource,
SyncNotedAppOp startProxyOperation(IBinder clientId, int code, in AttributionSource attributionSource,
boolean startIfModeDefault, boolean shouldCollectAsyncNotedOp, String message,
boolean shouldCollectMessage, boolean skipProxyOperation);
void finishProxyOperation(IBinder clientId, int code, in AttributionSource attributionSource);

View File

@@ -179,6 +179,7 @@ import android.app.PendingIntent;
import android.app.ProcessMemoryState;
import android.app.ProfilerInfo;
import android.app.PropertyInvalidatedCache;
import android.app.SyncNotedAppOp;
import android.app.WaitResult;
import android.app.backup.BackupManager.OperationType;
import android.app.backup.IBackupManager;
@@ -344,7 +345,6 @@ import com.android.internal.util.function.HeptFunction;
import com.android.internal.util.function.HexFunction;
import com.android.internal.util.function.OctFunction;
import com.android.internal.util.function.QuadFunction;
import com.android.internal.util.function.QuintFunction;
import com.android.internal.util.function.TriFunction;
import com.android.server.AlarmManagerInternal;
import com.android.server.DeviceIdleInternal;
@@ -2744,7 +2744,7 @@ public class ActivityManagerService extends IActivityManager.Stub
private boolean hasUsageStatsPermission(String callingPackage) {
final int mode = mAppOpsService.noteOperation(AppOpsManager.OP_GET_USAGE_STATS,
Binder.getCallingUid(), callingPackage, null, false, "", false);
Binder.getCallingUid(), callingPackage, null, false, "", false).getOpMode();
if (mode == AppOpsManager.MODE_DEFAULT) {
return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
== PackageManager.PERMISSION_GRANTED;
@@ -5244,7 +5244,7 @@ public class ActivityManagerService extends IActivityManager.Stub
// TODO moltmann: Allow to specify featureId
return mActivityManagerService.mAppOpsService
.noteOperation(AppOpsManager.strOpToOp(op), uid, packageName, null,
false, "", false);
false, "", false).getOpMode();
}
@Override
@@ -16595,11 +16595,11 @@ public class ActivityManagerService extends IActivityManager.Stub
}
@Override
public int noteOperation(int code, int uid, @Nullable String packageName,
public SyncNotedAppOp noteOperation(int code, int uid, @Nullable String packageName,
@Nullable String featureId, boolean shouldCollectAsyncNotedOp,
@Nullable String message, boolean shouldCollectMessage,
@NonNull HeptFunction<Integer, Integer, String, String, Boolean, String, Boolean,
Integer> superImpl) {
SyncNotedAppOp> superImpl) {
if (uid == mTargetUid && isTargetOp(code)) {
final int shellUid = UserHandle.getUid(UserHandle.getUserId(uid),
Process.SHELL_UID);
@@ -16616,11 +16616,11 @@ public class ActivityManagerService extends IActivityManager.Stub
}
@Override
public int noteProxyOperation(int code, @NonNull AttributionSource attributionSource,
boolean shouldCollectAsyncNotedOp, @Nullable String message,
boolean shouldCollectMessage, boolean skiProxyOperation,
public SyncNotedAppOp noteProxyOperation(int code,
@NonNull AttributionSource attributionSource, boolean shouldCollectAsyncNotedOp,
@Nullable String message, boolean shouldCollectMessage, boolean skiProxyOperation,
@NonNull HexFunction<Integer, AttributionSource, Boolean, String, Boolean,
Boolean, Integer> superImpl) {
Boolean, SyncNotedAppOp> superImpl) {
if (attributionSource.getUid() == mTargetUid && isTargetOp(code)) {
final int shellUid = UserHandle.getUid(UserHandle.getUserId(
attributionSource.getUid()), Process.SHELL_UID);
@@ -16640,12 +16640,12 @@ public class ActivityManagerService extends IActivityManager.Stub
}
@Override
public int startProxyOperation(IBinder token, int code,
public SyncNotedAppOp startProxyOperation(IBinder token, int code,
@NonNull AttributionSource attributionSource, boolean startIfModeDefault,
boolean shouldCollectAsyncNotedOp, String message, boolean shouldCollectMessage,
boolean skipProsyOperation, @NonNull OctFunction<IBinder, Integer,
AttributionSource, Boolean, Boolean, String, Boolean, Boolean,
Integer> superImpl) {
SyncNotedAppOp> superImpl) {
if (attributionSource.getUid() == mTargetUid && isTargetOp(code)) {
final int shellUid = UserHandle.getUid(UserHandle.getUserId(
attributionSource.getUid()), Process.SHELL_UID);

View File

@@ -132,7 +132,6 @@ import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.AtomicFile;
import android.util.KeyValueListParser;
import android.util.Log;
import android.util.LongSparseArray;
import android.util.Pair;
import android.util.Pools;
@@ -161,9 +160,6 @@ import com.android.internal.util.ArrayUtils;
import com.android.internal.util.DumpUtils;
import com.android.internal.util.Preconditions;
import com.android.internal.util.XmlUtils;
import com.android.internal.util.function.HeptFunction;
import com.android.internal.util.function.QuintFunction;
import com.android.internal.util.function.TriFunction;
import com.android.internal.util.function.pooled.PooledLambda;
import com.android.server.LocalServices;
import com.android.server.LockGuard;
@@ -3103,7 +3099,7 @@ public class AppOpsService extends IAppOpsService.Stub {
}
@Override
public int noteProxyOperation(int code, AttributionSource attributionSource,
public SyncNotedAppOp noteProxyOperation(int code, AttributionSource attributionSource,
boolean shouldCollectAsyncNotedOp, String message, boolean shouldCollectMessage,
boolean skipProxyOperation) {
final CheckOpsDelegate policy;
@@ -3132,7 +3128,7 @@ public class AppOpsService extends IAppOpsService.Stub {
message, shouldCollectMessage,skipProxyOperation);
}
private int noteProxyOperationImpl(int code, AttributionSource attributionSource,
private SyncNotedAppOp noteProxyOperationImpl(int code, AttributionSource attributionSource,
boolean shouldCollectAsyncNotedOp, String message, boolean shouldCollectMessage,
boolean skipProxyOperation) {
final int proxyUid = attributionSource.getUid();
@@ -3152,7 +3148,7 @@ public class AppOpsService extends IAppOpsService.Stub {
String resolveProxyPackageName = AppOpsManager.resolvePackageName(proxyUid,
proxyPackageName);
if (resolveProxyPackageName == null) {
return AppOpsManager.MODE_IGNORED;
return new SyncNotedAppOp(AppOpsManager.MODE_IGNORED, code, proxiedAttributionTag);
}
final boolean isSelfBlame = Binder.getCallingUid() == proxiedUid;
@@ -3164,18 +3160,18 @@ public class AppOpsService extends IAppOpsService.Stub {
final int proxyFlags = isProxyTrusted ? AppOpsManager.OP_FLAG_TRUSTED_PROXY
: AppOpsManager.OP_FLAG_UNTRUSTED_PROXY;
final int proxyMode = noteOperationUnchecked(code, proxyUid, resolveProxyPackageName,
proxyAttributionTag, Process.INVALID_UID, null, null, proxyFlags,
!isProxyTrusted, "proxy " + message, shouldCollectMessage);
if (proxyMode != AppOpsManager.MODE_ALLOWED) {
return proxyMode;
final SyncNotedAppOp proxyReturn = noteOperationUnchecked(code, proxyUid,
resolveProxyPackageName, proxyAttributionTag, Process.INVALID_UID, null, null,
proxyFlags, !isProxyTrusted, "proxy " + message, shouldCollectMessage);
if (proxyReturn.getOpMode() != AppOpsManager.MODE_ALLOWED) {
return new SyncNotedAppOp(proxyReturn.getOpMode(), code, proxiedAttributionTag);
}
}
String resolveProxiedPackageName = AppOpsManager.resolvePackageName(proxiedUid,
proxiedPackageName);
if (resolveProxiedPackageName == null) {
return AppOpsManager.MODE_IGNORED;
return new SyncNotedAppOp(AppOpsManager.MODE_IGNORED, code, proxiedAttributionTag);
}
final int proxiedFlags = isProxyTrusted ? AppOpsManager.OP_FLAG_TRUSTED_PROXIED
@@ -3186,8 +3182,9 @@ public class AppOpsService extends IAppOpsService.Stub {
}
@Override
public int noteOperation(int code, int uid, String packageName, String attributionTag,
boolean shouldCollectAsyncNotedOp, String message, boolean shouldCollectMessage) {
public SyncNotedAppOp noteOperation(int code, int uid, String packageName,
String attributionTag, boolean shouldCollectAsyncNotedOp, String message,
boolean shouldCollectMessage) {
final CheckOpsDelegate policy;
final CheckOpsDelegateDispatcher delegateDispatcher;
synchronized (AppOpsService.this) {
@@ -3213,7 +3210,7 @@ public class AppOpsService extends IAppOpsService.Stub {
shouldCollectAsyncNotedOp, message, shouldCollectMessage);
}
private int noteOperationImpl(int code, int uid, @Nullable String packageName,
private SyncNotedAppOp noteOperationImpl(int code, int uid, @Nullable String packageName,
@Nullable String attributionTag, boolean shouldCollectAsyncNotedOp,
@Nullable String message, boolean shouldCollectMessage) {
verifyIncomingUid(uid);
@@ -3222,14 +3219,14 @@ public class AppOpsService extends IAppOpsService.Stub {
String resolvedPackageName = AppOpsManager.resolvePackageName(uid, packageName);
if (resolvedPackageName == null) {
return AppOpsManager.MODE_IGNORED;
return new SyncNotedAppOp(AppOpsManager.MODE_IGNORED, code, attributionTag);
}
return noteOperationUnchecked(code, uid, resolvedPackageName, attributionTag,
Process.INVALID_UID, null, null, AppOpsManager.OP_FLAG_SELF,
shouldCollectAsyncNotedOp, message, shouldCollectMessage);
}
private int noteOperationUnchecked(int code, int uid, @NonNull String packageName,
private SyncNotedAppOp noteOperationUnchecked(int code, int uid, @NonNull String packageName,
@Nullable String attributionTag, int proxyUid, String proxyPackageName,
@Nullable String proxyAttributionTag, @OpFlags int flags,
boolean shouldCollectAsyncNotedOp, @Nullable String message,
@@ -3239,7 +3236,7 @@ public class AppOpsService extends IAppOpsService.Stub {
bypass = verifyAndGetBypass(uid, packageName, attributionTag);
} catch (SecurityException e) {
Slog.e(TAG, "noteOperation", e);
return AppOpsManager.MODE_ERRORED;
return new SyncNotedAppOp(AppOpsManager.MODE_ERRORED, code, attributionTag);
}
synchronized (this) {
@@ -3250,7 +3247,7 @@ public class AppOpsService extends IAppOpsService.Stub {
AppOpsManager.MODE_IGNORED);
if (DEBUG) Slog.d(TAG, "noteOperation: no op for code " + code + " uid " + uid
+ " package " + packageName);
return AppOpsManager.MODE_ERRORED;
return new SyncNotedAppOp(AppOpsManager.MODE_ERRORED, code, attributionTag);
}
final Op op = getOpLocked(ops, code, uid, true);
final AttributedOp attributedOp = op.getOrCreateAttribution(op, attributionTag);
@@ -3266,7 +3263,7 @@ public class AppOpsService extends IAppOpsService.Stub {
attributedOp.rejected(uidState.state, flags);
scheduleOpNotedIfNeededLocked(code, uid, packageName, attributionTag, flags,
AppOpsManager.MODE_IGNORED);
return AppOpsManager.MODE_IGNORED;
return new SyncNotedAppOp(AppOpsManager.MODE_IGNORED, code, attributionTag);
}
// If there is a non-default per UID policy (we set UID op mode only if
// non-default) it takes over, otherwise use the per package policy.
@@ -3279,7 +3276,7 @@ public class AppOpsService extends IAppOpsService.Stub {
attributedOp.rejected(uidState.state, flags);
scheduleOpNotedIfNeededLocked(code, uid, packageName, attributionTag, flags,
uidMode);
return uidMode;
return new SyncNotedAppOp(uidMode, code, attributionTag);
}
} else {
final Op switchOp = switchCode != code ? getOpLocked(ops, switchCode, uid, true)
@@ -3292,7 +3289,7 @@ public class AppOpsService extends IAppOpsService.Stub {
attributedOp.rejected(uidState.state, flags);
scheduleOpNotedIfNeededLocked(code, uid, packageName, attributionTag, flags,
mode);
return mode;
return new SyncNotedAppOp(mode, code, attributionTag);
}
}
if (DEBUG) {
@@ -3311,7 +3308,7 @@ public class AppOpsService extends IAppOpsService.Stub {
shouldCollectMessage);
}
return AppOpsManager.MODE_ALLOWED;
return new SyncNotedAppOp(AppOpsManager.MODE_ALLOWED, code, attributionTag);
}
}
@@ -3596,7 +3593,7 @@ public class AppOpsService extends IAppOpsService.Stub {
}
@Override
public int startOperation(IBinder clientId, int code, int uid, String packageName,
public SyncNotedAppOp startOperation(IBinder clientId, int code, int uid, String packageName,
String attributionTag, boolean startIfModeDefault, boolean shouldCollectAsyncNotedOp,
String message, boolean shouldCollectMessage) {
verifyIncomingUid(uid);
@@ -3605,7 +3602,7 @@ public class AppOpsService extends IAppOpsService.Stub {
String resolvedPackageName = AppOpsManager.resolvePackageName(uid, packageName);
if (resolvedPackageName == null) {
return AppOpsManager.MODE_IGNORED;
return new SyncNotedAppOp(AppOpsManager.MODE_IGNORED, code, attributionTag);
}
// As a special case for OP_RECORD_AUDIO_HOTWORD, which we use only for attribution
@@ -3616,7 +3613,7 @@ public class AppOpsService extends IAppOpsService.Stub {
if (code == OP_RECORD_AUDIO_HOTWORD) {
int result = checkOperation(OP_RECORD_AUDIO, uid, packageName);
if (result != AppOpsManager.MODE_ALLOWED) {
return result;
return new SyncNotedAppOp(result, code, attributionTag);
}
}
return startOperationUnchecked(clientId, code, uid, packageName, attributionTag,
@@ -3626,7 +3623,7 @@ public class AppOpsService extends IAppOpsService.Stub {
}
@Override
public int startProxyOperation(IBinder clientId, int code,
public SyncNotedAppOp startProxyOperation(IBinder clientId, int code,
@NonNull AttributionSource attributionSource, boolean startIfModeDefault,
boolean shouldCollectAsyncNotedOp, String message, boolean shouldCollectMessage,
boolean skipProxyOperation) {
@@ -3658,7 +3655,7 @@ public class AppOpsService extends IAppOpsService.Stub {
shouldCollectAsyncNotedOp, message, shouldCollectMessage, skipProxyOperation);
}
private int startProxyOperationImpl(IBinder clientId, int code,
private SyncNotedAppOp startProxyOperationImpl(IBinder clientId, int code,
@NonNull AttributionSource attributionSource,
boolean startIfModeDefault, boolean shouldCollectAsyncNotedOp, String message,
boolean shouldCollectMessage, boolean skipProxyOperation) {
@@ -3679,7 +3676,7 @@ public class AppOpsService extends IAppOpsService.Stub {
String resolvedProxyPackageName = AppOpsManager.resolvePackageName(proxyUid,
proxyPackageName);
if (resolvedProxyPackageName == null) {
return AppOpsManager.MODE_IGNORED;
return new SyncNotedAppOp(AppOpsManager.MODE_IGNORED, code, proxiedAttributionTag);
}
final boolean isSelfBlame = Binder.getCallingUid() == proxiedUid;
@@ -3690,7 +3687,7 @@ public class AppOpsService extends IAppOpsService.Stub {
String resolvedProxiedPackageName = AppOpsManager.resolvePackageName(proxiedUid,
proxiedPackageName);
if (resolvedProxiedPackageName == null) {
return AppOpsManager.MODE_IGNORED;
return new SyncNotedAppOp(AppOpsManager.MODE_IGNORED, code, proxiedAttributionTag);
}
final int proxiedFlags = isProxyTrusted ? AppOpsManager.OP_FLAG_TRUSTED_PROXIED
@@ -3698,23 +3695,23 @@ public class AppOpsService extends IAppOpsService.Stub {
if (!skipProxyOperation) {
// Test if the proxied operation will succeed before starting the proxy operation
final int testProxiedMode = startOperationUnchecked(clientId, code, proxiedUid,
final SyncNotedAppOp testProxiedOp = startOperationUnchecked(clientId, code, proxiedUid,
resolvedProxiedPackageName, proxiedAttributionTag, proxyUid,
resolvedProxyPackageName, proxyAttributionTag, proxiedFlags, startIfModeDefault,
shouldCollectAsyncNotedOp, message, shouldCollectMessage, true);
if (!shouldStartForMode(testProxiedMode, startIfModeDefault)) {
return testProxiedMode;
if (!shouldStartForMode(testProxiedOp.getOpMode(), startIfModeDefault)) {
return testProxiedOp;
}
final int proxyFlags = isProxyTrusted ? AppOpsManager.OP_FLAG_TRUSTED_PROXY
: AppOpsManager.OP_FLAG_UNTRUSTED_PROXY;
final int proxyMode = startOperationUnchecked(clientId, code, proxyUid,
final SyncNotedAppOp proxyAppOp = startOperationUnchecked(clientId, code, proxyUid,
resolvedProxyPackageName, proxyAttributionTag, Process.INVALID_UID, null, null,
proxyFlags, startIfModeDefault, !isProxyTrusted, "proxy " + message,
shouldCollectMessage, false);
if (!shouldStartForMode(proxyMode, startIfModeDefault)) {
return proxyMode;
if (!shouldStartForMode(proxyAppOp.getOpMode(), startIfModeDefault)) {
return proxyAppOp;
}
}
@@ -3728,7 +3725,7 @@ public class AppOpsService extends IAppOpsService.Stub {
return (mode == MODE_ALLOWED || (mode == MODE_DEFAULT && startIfModeDefault));
}
private int startOperationUnchecked(IBinder clientId, int code, int uid,
private SyncNotedAppOp startOperationUnchecked(IBinder clientId, int code, int uid,
@NonNull String packageName, @Nullable String attributionTag, int proxyUid,
String proxyPackageName, @Nullable String proxyAttributionTag, @OpFlags int flags,
boolean startIfModeDefault, boolean shouldCollectAsyncNotedOp, @Nullable String message,
@@ -3738,7 +3735,7 @@ public class AppOpsService extends IAppOpsService.Stub {
bypass = verifyAndGetBypass(uid, packageName, attributionTag);
} catch (SecurityException e) {
Slog.e(TAG, "startOperation", e);
return AppOpsManager.MODE_ERRORED;
return new SyncNotedAppOp(AppOpsManager.MODE_ERRORED, code, attributionTag);
}
synchronized (this) {
@@ -3750,7 +3747,7 @@ public class AppOpsService extends IAppOpsService.Stub {
}
if (DEBUG) Slog.d(TAG, "startOperation: no op for code " + code + " uid " + uid
+ " package " + packageName);
return AppOpsManager.MODE_ERRORED;
return new SyncNotedAppOp(AppOpsManager.MODE_ERRORED, code, attributionTag);
}
final Op op = getOpLocked(ops, code, uid, true);
if (isOpRestrictedLocked(uid, code, packageName, bypass)) {
@@ -3758,7 +3755,7 @@ public class AppOpsService extends IAppOpsService.Stub {
scheduleOpStartedIfNeededLocked(code, uid, packageName, attributionTag,
flags, AppOpsManager.MODE_IGNORED);
}
return AppOpsManager.MODE_IGNORED;
return new SyncNotedAppOp(AppOpsManager.MODE_IGNORED, code, attributionTag);
}
final AttributedOp attributedOp = op.getOrCreateAttribution(op, attributionTag);
@@ -3779,7 +3776,7 @@ public class AppOpsService extends IAppOpsService.Stub {
scheduleOpStartedIfNeededLocked(code, uid, packageName, attributionTag,
flags, uidMode);
}
return uidMode;
return new SyncNotedAppOp(uidMode, code, attributionTag);
}
} else {
final Op switchOp = switchCode != code ? getOpLocked(ops, switchCode, uid, true)
@@ -3795,7 +3792,7 @@ public class AppOpsService extends IAppOpsService.Stub {
scheduleOpStartedIfNeededLocked(code, uid, packageName, attributionTag,
flags, mode);
}
return mode;
return new SyncNotedAppOp(mode, code, attributionTag);
}
}
if (DEBUG) Slog.d(TAG, "startOperation: allowing code " + code + " uid " + uid
@@ -3817,7 +3814,7 @@ public class AppOpsService extends IAppOpsService.Stub {
message, shouldCollectMessage);
}
return AppOpsManager.MODE_ALLOWED;
return new SyncNotedAppOp(AppOpsManager.MODE_ALLOWED, code, attributionTag);
}
@Override
@@ -7035,7 +7032,7 @@ public class AppOpsService extends IAppOpsService.Stub {
AppOpsService.this::checkAudioOperationImpl);
}
public int noteOperationImpl(int code, int uid, @Nullable String packageName,
public SyncNotedAppOp noteOperationImpl(int code, int uid, @Nullable String packageName,
@Nullable String featureId, boolean shouldCollectAsyncNotedOp,
@Nullable String message, boolean shouldCollectMessage) {
return mCheckOpsDelegate.noteOperation(code, uid, packageName, featureId,
@@ -7043,15 +7040,16 @@ public class AppOpsService extends IAppOpsService.Stub {
AppOpsService.this::noteOperationImpl);
}
public int noteProxyOperationImpl(int code, @NonNull AttributionSource attributionSource,
boolean shouldCollectAsyncNotedOp, @Nullable String message,
boolean shouldCollectMessage, boolean skipProxyOperation) {
public SyncNotedAppOp noteProxyOperationImpl(int code,
@NonNull AttributionSource attributionSource, boolean shouldCollectAsyncNotedOp,
@Nullable String message, boolean shouldCollectMessage,
boolean skipProxyOperation) {
return mCheckOpsDelegate.noteProxyOperation(code, attributionSource,
shouldCollectAsyncNotedOp, message, shouldCollectMessage, skipProxyOperation,
AppOpsService.this::noteProxyOperationImpl);
}
public int startProxyOperationImpl(IBinder token, int code,
public SyncNotedAppOp startProxyOperationImpl(IBinder token, int code,
@NonNull AttributionSource attributionSource, boolean startIfModeDefault,
boolean shouldCollectAsyncNotedOp, String message, boolean shouldCollectMessage,
boolean skipProxyOperation) {

View File

@@ -20,6 +20,7 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.AppOpsManager;
import android.app.AppOpsManagerInternal;
import android.app.SyncNotedAppOp;
import android.content.AttributionSource;
import android.location.LocationManagerInternal;
import android.os.IBinder;
@@ -116,20 +117,21 @@ public final class AppOpsPolicy implements AppOpsManagerInternal.CheckOpsDelegat
}
@Override
public int noteOperation(int code, int uid, @Nullable String packageName,
public SyncNotedAppOp noteOperation(int code, int uid, @Nullable String packageName,
@Nullable String attributionTag, boolean shouldCollectAsyncNotedOp, @Nullable
String message, boolean shouldCollectMessage, @NonNull HeptFunction<Integer, Integer,
String, String, Boolean, String, Boolean, Integer> superImpl) {
String, String, Boolean, String, Boolean, SyncNotedAppOp> superImpl) {
return superImpl.apply(resolveOpCode(code, uid, packageName, attributionTag), uid,
packageName, attributionTag, shouldCollectAsyncNotedOp,
message, shouldCollectMessage);
}
@Override
public int noteProxyOperation(int code, @NonNull AttributionSource attributionSource,
public SyncNotedAppOp noteProxyOperation(int code, @NonNull AttributionSource attributionSource,
boolean shouldCollectAsyncNotedOp, @Nullable String message,
boolean shouldCollectMessage, boolean skipProxyOperation, @NonNull HexFunction<Integer,
AttributionSource, Boolean, String, Boolean, Boolean, Integer> superImpl) {
AttributionSource, Boolean, String, Boolean, Boolean,
SyncNotedAppOp> superImpl) {
return superImpl.apply(resolveOpCode(code, attributionSource.getUid(),
attributionSource.getPackageName(), attributionSource.getAttributionTag()),
attributionSource, shouldCollectAsyncNotedOp, message, shouldCollectMessage,
@@ -137,11 +139,11 @@ public final class AppOpsPolicy implements AppOpsManagerInternal.CheckOpsDelegat
}
@Override
public int startProxyOperation(IBinder token, int code,
public SyncNotedAppOp startProxyOperation(IBinder token, int code,
@NonNull AttributionSource attributionSource, boolean startIfModeDefault,
boolean shouldCollectAsyncNotedOp, String message, boolean shouldCollectMessage,
boolean skipProxyOperation, @NonNull OctFunction<IBinder, Integer, AttributionSource,
Boolean, Boolean, String, Boolean, Boolean, Integer> superImpl) {
Boolean, Boolean, String, Boolean, Boolean, SyncNotedAppOp> superImpl) {
return superImpl.apply(token, resolveOpCode(code, attributionSource.getUid(),
attributionSource.getPackageName(), attributionSource.getAttributionTag()),
attributionSource, startIfModeDefault, shouldCollectAsyncNotedOp, message,

View File

@@ -188,7 +188,7 @@ public class AppOpsServiceTest {
mAppOpsService.setMode(OP_COARSE_LOCATION, mMyUid, sMyPackageName, MODE_ALLOWED);
assertThat(mAppOpsService.noteOperation(OP_WIFI_SCAN, mMyUid, sMyPackageName, null, false,
null, false)).isEqualTo(MODE_ALLOWED);
null, false).getOpMode()).isEqualTo(MODE_ALLOWED);
assertContainsOp(getLoggedOps(), OP_WIFI_SCAN, mTestStartMillis, -1,
MODE_ALLOWED /* default for WIFI_SCAN; this is not changed or used in this test */);
@@ -196,7 +196,7 @@ public class AppOpsServiceTest {
// Now set COARSE_LOCATION to ERRORED -> this will make WIFI_SCAN disabled as well.
mAppOpsService.setMode(OP_COARSE_LOCATION, mMyUid, sMyPackageName, MODE_ERRORED);
assertThat(mAppOpsService.noteOperation(OP_WIFI_SCAN, mMyUid, sMyPackageName, null, false,
null, false)).isEqualTo(MODE_ERRORED);
null, false).getOpMode()).isEqualTo(MODE_ERRORED);
assertContainsOp(getLoggedOps(), OP_WIFI_SCAN, mTestStartMillis, mTestStartMillis,
MODE_ALLOWED /* default for WIFI_SCAN; this is not changed or used in this test */);
@@ -348,12 +348,12 @@ public class AppOpsServiceTest {
mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_CACHED_EMPTY,
ActivityManager.PROCESS_CAPABILITY_NONE);
assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName, null,
false, null, false)).isNotEqualTo(MODE_ALLOWED);
false, null, false).getOpMode()).isNotEqualTo(MODE_ALLOWED);
mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_TOP,
ActivityManager.PROCESS_CAPABILITY_FOREGROUND_LOCATION);
assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName, null,
false, null, false)).isEqualTo(MODE_ALLOWED);
false, null, false).getOpMode()).isEqualTo(MODE_ALLOWED);
mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_CACHED_EMPTY,
ActivityManager.PROCESS_CAPABILITY_NONE);
@@ -362,7 +362,7 @@ public class AppOpsServiceTest {
mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_CACHED_EMPTY,
ActivityManager.PROCESS_CAPABILITY_NONE);
assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName, null,
false, null, false)).isNotEqualTo(MODE_ALLOWED);
false, null, false).getOpMode()).isNotEqualTo(MODE_ALLOWED);
}
@Test
@@ -371,12 +371,12 @@ public class AppOpsServiceTest {
mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_CACHED_EMPTY,
ActivityManager.PROCESS_CAPABILITY_NONE);
assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName, null,
false, null, false)).isNotEqualTo(MODE_ALLOWED);
false, null, false).getOpMode()).isNotEqualTo(MODE_ALLOWED);
mAppOpsService.updateUidProcState(mMyUid, PROCESS_STATE_FOREGROUND_SERVICE,
ActivityManager.PROCESS_CAPABILITY_NONE);
assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName, null,
false, null, false)).isNotEqualTo(MODE_ALLOWED);
false, null, false).getOpMode()).isNotEqualTo(MODE_ALLOWED);
}
@Test
@@ -386,12 +386,12 @@ public class AppOpsServiceTest {
mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_CACHED_EMPTY,
ActivityManager.PROCESS_CAPABILITY_NONE);
assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName, null,
false, null, false)).isNotEqualTo(MODE_ALLOWED);
false, null, false).getOpMode()).isNotEqualTo(MODE_ALLOWED);
mAppOpsService.updateUidProcState(mMyUid, PROCESS_STATE_FOREGROUND_SERVICE,
ActivityManager.PROCESS_CAPABILITY_FOREGROUND_LOCATION);
assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName, null,
false, null, false)).isEqualTo(MODE_ALLOWED);
false, null, false).getOpMode()).isEqualTo(MODE_ALLOWED);
}
@Test
@@ -401,12 +401,12 @@ public class AppOpsServiceTest {
mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_CACHED_EMPTY,
ActivityManager.PROCESS_CAPABILITY_NONE);
assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName, null,
false, null, false)).isNotEqualTo(MODE_ALLOWED);
false, null, false).getOpMode()).isNotEqualTo(MODE_ALLOWED);
mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_TOP,
ActivityManager.PROCESS_CAPABILITY_FOREGROUND_LOCATION);
assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName, null,
false, null, false)).isEqualTo(MODE_ALLOWED);
false, null, false).getOpMode()).isEqualTo(MODE_ALLOWED);
mAppOpsService.updateUidProcState(mMyUid, PROCESS_STATE_FOREGROUND_SERVICE,
ActivityManager.PROCESS_CAPABILITY_NONE);
@@ -415,7 +415,7 @@ public class AppOpsServiceTest {
mAppOpsService.updateUidProcState(mMyUid, PROCESS_STATE_FOREGROUND_SERVICE,
ActivityManager.PROCESS_CAPABILITY_NONE);
assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName, null,
false, null, false)).isNotEqualTo(MODE_ALLOWED);
false, null, false).getOpMode()).isNotEqualTo(MODE_ALLOWED);
}
@Test
@@ -425,12 +425,12 @@ public class AppOpsServiceTest {
mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_CACHED_EMPTY,
ActivityManager.PROCESS_CAPABILITY_NONE);
assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName, null,
false, null, false)).isNotEqualTo(MODE_ALLOWED);
false, null, false).getOpMode()).isNotEqualTo(MODE_ALLOWED);
mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_TOP,
ActivityManager.PROCESS_CAPABILITY_FOREGROUND_LOCATION);
assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName, null,
false, null, false)).isEqualTo(MODE_ALLOWED);
false, null, false).getOpMode()).isEqualTo(MODE_ALLOWED);
mAppOpsService.updateUidProcState(mMyUid, PROCESS_STATE_FOREGROUND_SERVICE,
ActivityManager.PROCESS_CAPABILITY_FOREGROUND_LOCATION);
@@ -439,7 +439,7 @@ public class AppOpsServiceTest {
mAppOpsService.updateUidProcState(mMyUid, PROCESS_STATE_FOREGROUND_SERVICE,
ActivityManager.PROCESS_CAPABILITY_FOREGROUND_LOCATION);
assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName, null,
false, null, false)).isEqualTo(MODE_ALLOWED);
false, null, false).getOpMode()).isEqualTo(MODE_ALLOWED);
mAppOpsService.updateUidProcState(mMyUid, PROCESS_STATE_FOREGROUND_SERVICE,
ActivityManager.PROCESS_CAPABILITY_NONE);
@@ -448,7 +448,7 @@ public class AppOpsServiceTest {
mAppOpsService.updateUidProcState(mMyUid, PROCESS_STATE_FOREGROUND_SERVICE,
ActivityManager.PROCESS_CAPABILITY_NONE);
assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName, null,
false, null, false)).isNotEqualTo(MODE_ALLOWED);
false, null, false).getOpMode()).isNotEqualTo(MODE_ALLOWED);
}
private List<PackageOps> getLoggedOps() {

View File

@@ -44,6 +44,9 @@ import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
@@ -55,6 +58,7 @@ import android.app.ActivityManager;
import android.app.AppOpsManager;
import android.app.IApplicationThread;
import android.app.IUidObserver;
import android.app.SyncNotedAppOp;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.ApplicationInfo;
@@ -160,6 +164,14 @@ public class ActivityManagerServiceTest {
mAms.mActivityTaskManager.initialize(null, null, mHandler.getLooper());
}
private void mockNoteOperation() {
SyncNotedAppOp allowed = new SyncNotedAppOp(AppOpsManager.MODE_ALLOWED,
AppOpsManager.OP_GET_USAGE_STATS, null);
when(mAppOpsService.noteOperation(eq(AppOpsManager.OP_GET_USAGE_STATS), eq(Process.myUid()),
nullable(String.class), nullable(String.class), any(Boolean.class),
nullable(String.class), any(Boolean.class))).thenReturn(allowed);
}
@After
public void tearDown() {
mHandlerThread.quit();
@@ -509,8 +521,7 @@ public class ActivityManagerServiceTest {
*/
@Test
public void testDispatchUids_dispatchNeededChanges() throws RemoteException {
when(mAppOpsService.noteOperation(AppOpsManager.OP_GET_USAGE_STATS, Process.myUid(), null,
null, false, null, false)).thenReturn(AppOpsManager.MODE_ALLOWED);
mockNoteOperation();
final int[] changesToObserve = {
ActivityManager.UID_OBSERVER_PROCSTATE,
@@ -635,6 +646,8 @@ public class ActivityManagerServiceTest {
*/
@Test
public void testDispatchUidChanges_procStateCutpoint() throws RemoteException {
mockNoteOperation();
final IUidObserver observer = mock(IUidObserver.Stub.class);
when(observer.asBinder()).thenReturn((IBinder) observer);
@@ -703,6 +716,8 @@ public class ActivityManagerServiceTest {
*/
@Test
public void testDispatchUidChanges_validateUidsUpdated() {
mockNoteOperation();
final int[] changesForPendingItems = UID_RECORD_CHANGES;
final int[] procStatesForPendingItems = {