Merge "Add attribution info to start callbacks" into sc-dev
This commit is contained in:
@@ -7205,6 +7205,34 @@ public class AppOpsManager {
|
|||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public interface OnOpStartedListener {
|
public interface OnOpStartedListener {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a start operation that was unsuccessful
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public int START_TYPE_FAILED = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a successful start operation
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public int START_TYPE_STARTED = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents an operation where a restricted operation became unrestricted, and resumed.
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public int START_TYPE_RESUMED = 2;
|
||||||
|
|
||||||
|
/** @hide */
|
||||||
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
|
@IntDef(flag = true, prefix = { "TYPE_" }, value = {
|
||||||
|
START_TYPE_FAILED,
|
||||||
|
START_TYPE_STARTED,
|
||||||
|
START_TYPE_RESUMED
|
||||||
|
})
|
||||||
|
public @interface StartedType {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when an op was started.
|
* Called when an op was started.
|
||||||
*
|
*
|
||||||
@@ -7213,11 +7241,35 @@ public class AppOpsManager {
|
|||||||
* @param uid The UID performing the operation.
|
* @param uid The UID performing the operation.
|
||||||
* @param packageName The package performing the operation.
|
* @param packageName The package performing the operation.
|
||||||
* @param attributionTag The attribution tag performing the operation.
|
* @param attributionTag The attribution tag performing the operation.
|
||||||
* @param flags The flags of this op
|
* @param flags The flags of this op.
|
||||||
* @param result The result of the start.
|
* @param result The result of the start.
|
||||||
*/
|
*/
|
||||||
void onOpStarted(int op, int uid, String packageName, String attributionTag,
|
void onOpStarted(int op, int uid, String packageName, String attributionTag,
|
||||||
@OpFlags int flags, @Mode int result);
|
@OpFlags int flags, @Mode int result);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when an op was started.
|
||||||
|
*
|
||||||
|
* Note: This is only for op starts. It is not called when an op is noted or stopped.
|
||||||
|
* By default, unless this method is overridden, no code will be executed for resume
|
||||||
|
* events.
|
||||||
|
* @param op The op code.
|
||||||
|
* @param uid The UID performing the operation.
|
||||||
|
* @param packageName The package performing the operation.
|
||||||
|
* @param attributionTag The attribution tag performing the operation.
|
||||||
|
* @param flags The flags of this op.
|
||||||
|
* @param result The result of the start.
|
||||||
|
* @param startType The start type of this start event. Either failed, resumed, or started.
|
||||||
|
* @param attributionFlags The location of this started op in an attribution chain.
|
||||||
|
* @param attributionChainId The ID of the attribution chain of this op, if it is in one.
|
||||||
|
*/
|
||||||
|
default void onOpStarted(int op, int uid, String packageName, String attributionTag,
|
||||||
|
@OpFlags int flags, @Mode int result, @StartedType int startType,
|
||||||
|
@AttributionFlags int attributionFlags, int attributionChainId) {
|
||||||
|
if (startType != START_TYPE_RESUMED) {
|
||||||
|
onOpStarted(op, uid, packageName, attributionTag, flags, result);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AppOpsManager(Context context, IAppOpsService service) {
|
AppOpsManager(Context context, IAppOpsService service) {
|
||||||
@@ -7858,8 +7910,10 @@ public class AppOpsManager {
|
|||||||
cb = new IAppOpsStartedCallback.Stub() {
|
cb = new IAppOpsStartedCallback.Stub() {
|
||||||
@Override
|
@Override
|
||||||
public void opStarted(int op, int uid, String packageName, String attributionTag,
|
public void opStarted(int op, int uid, String packageName, String attributionTag,
|
||||||
int flags, int mode) {
|
int flags, int mode, int startType, int attributionFlags,
|
||||||
callback.onOpStarted(op, uid, packageName, attributionTag, flags, mode);
|
int attributionChainId) {
|
||||||
|
callback.onOpStarted(op, uid, packageName, attributionTag, flags, mode,
|
||||||
|
startType, attributionFlags, attributionChainId);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
mStartedWatchers.put(callback, cb);
|
mStartedWatchers.put(callback, cb);
|
||||||
|
|||||||
@@ -31,7 +31,9 @@ import static android.app.AppOpsManager.OPSTR_FINE_LOCATION;
|
|||||||
import static android.app.AppOpsManager.OPSTR_PHONE_CALL_CAMERA;
|
import static android.app.AppOpsManager.OPSTR_PHONE_CALL_CAMERA;
|
||||||
import static android.app.AppOpsManager.OPSTR_PHONE_CALL_MICROPHONE;
|
import static android.app.AppOpsManager.OPSTR_PHONE_CALL_MICROPHONE;
|
||||||
import static android.app.AppOpsManager.OPSTR_RECORD_AUDIO;
|
import static android.app.AppOpsManager.OPSTR_RECORD_AUDIO;
|
||||||
|
import static android.app.AppOpsManager.OP_CAMERA;
|
||||||
import static android.app.AppOpsManager.OP_FLAGS_ALL_TRUSTED;
|
import static android.app.AppOpsManager.OP_FLAGS_ALL_TRUSTED;
|
||||||
|
import static android.app.AppOpsManager.OP_RECORD_AUDIO;
|
||||||
import static android.media.AudioSystem.MODE_IN_COMMUNICATION;
|
import static android.media.AudioSystem.MODE_IN_COMMUNICATION;
|
||||||
import static android.telephony.TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
|
import static android.telephony.TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
|
||||||
|
|
||||||
@@ -63,7 +65,8 @@ import java.util.Objects;
|
|||||||
*
|
*
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public class PermissionUsageHelper implements AppOpsManager.OnOpActiveChangedListener {
|
public class PermissionUsageHelper implements AppOpsManager.OnOpActiveChangedListener,
|
||||||
|
AppOpsManager.OnOpStartedListener {
|
||||||
|
|
||||||
/** Whether to show the mic and camera icons. */
|
/** Whether to show the mic and camera icons. */
|
||||||
private static final String PROPERTY_CAMERA_MIC_ICONS_ENABLED = "camera_mic_icons_enabled";
|
private static final String PROPERTY_CAMERA_MIC_ICONS_ENABLED = "camera_mic_icons_enabled";
|
||||||
@@ -160,9 +163,10 @@ public class PermissionUsageHelper implements AppOpsManager.OnOpActiveChangedLis
|
|||||||
mUserContexts = new ArrayMap<>();
|
mUserContexts = new ArrayMap<>();
|
||||||
mUserContexts.put(Process.myUserHandle(), mContext);
|
mUserContexts.put(Process.myUserHandle(), mContext);
|
||||||
// TODO ntmyren: make this listen for flag enable/disable changes
|
// TODO ntmyren: make this listen for flag enable/disable changes
|
||||||
String[] ops = { OPSTR_CAMERA, OPSTR_RECORD_AUDIO };
|
String[] opStrs = { OPSTR_CAMERA, OPSTR_RECORD_AUDIO };
|
||||||
mContext.getSystemService(AppOpsManager.class).startWatchingActive(ops,
|
mAppOpsManager.startWatchingActive(opStrs, context.getMainExecutor(), this);
|
||||||
context.getMainExecutor(), this);
|
int[] ops = { OP_CAMERA, OP_RECORD_AUDIO };
|
||||||
|
mAppOpsManager.startWatchingStarted(ops, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Context getUserContext(UserHandle user) {
|
private Context getUserContext(UserHandle user) {
|
||||||
@@ -182,25 +186,65 @@ public class PermissionUsageHelper implements AppOpsManager.OnOpActiveChangedLis
|
|||||||
public void onOpActiveChanged(@NonNull String op, int uid, @NonNull String packageName,
|
public void onOpActiveChanged(@NonNull String op, int uid, @NonNull String packageName,
|
||||||
@Nullable String attributionTag, boolean active, @AttributionFlags int attributionFlags,
|
@Nullable String attributionTag, boolean active, @AttributionFlags int attributionFlags,
|
||||||
int attributionChainId) {
|
int attributionChainId) {
|
||||||
if (attributionChainId == ATTRIBUTION_CHAIN_ID_NONE
|
if (active) {
|
||||||
|| attributionFlags == ATTRIBUTION_FLAGS_NONE
|
// Started callback handles these
|
||||||
|| (attributionFlags & ATTRIBUTION_FLAG_TRUSTED) == 0) {
|
|
||||||
// If this is not a chain, or it is untrusted, return
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!active) {
|
// if any link in the chain is finished, remove the chain. Then, find any other chains that
|
||||||
// if any link in the chain is finished, remove the chain.
|
// contain this op/package/uid/tag combination, and remove them, as well.
|
||||||
// TODO ntmyren: be smarter about this
|
// TODO ntmyren: be smarter about this
|
||||||
mAttributionChains.remove(attributionChainId);
|
mAttributionChains.remove(attributionChainId);
|
||||||
|
int numChains = mAttributionChains.size();
|
||||||
|
ArrayList<Integer> toRemove = new ArrayList<>();
|
||||||
|
for (int i = 0; i < numChains; i++) {
|
||||||
|
int chainId = mAttributionChains.keyAt(i);
|
||||||
|
ArrayList<AccessChainLink> chain = mAttributionChains.valueAt(i);
|
||||||
|
int chainSize = chain.size();
|
||||||
|
for (int j = 0; j < chainSize; j++) {
|
||||||
|
AccessChainLink link = chain.get(j);
|
||||||
|
if (link.packageAndOpEquals(op, packageName, attributionTag, uid)) {
|
||||||
|
toRemove.add(chainId);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mAttributionChains.removeAll(toRemove);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onOpStarted(int op, int uid, String packageName, String attributionTag,
|
||||||
|
@AppOpsManager.OpFlags int flags, @AppOpsManager.Mode int result) {
|
||||||
|
// not part of an attribution chain. Do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onOpStarted(int op, int uid, String packageName, String attributionTag,
|
||||||
|
@AppOpsManager.OpFlags int flags, @AppOpsManager.Mode int result,
|
||||||
|
@StartedType int startedType, @AttributionFlags int attributionFlags,
|
||||||
|
int attributionChainId) {
|
||||||
|
if (startedType == START_TYPE_FAILED || attributionChainId == ATTRIBUTION_CHAIN_ID_NONE
|
||||||
|
|| attributionFlags == ATTRIBUTION_FLAGS_NONE
|
||||||
|
|| (attributionFlags & ATTRIBUTION_FLAG_TRUSTED) == 0) {
|
||||||
|
// If this is not a successful start, or it is not a chain, or it is untrusted, return
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
addLinkToChainIfNotPresent(AppOpsManager.opToPublicName(op), packageName, uid,
|
||||||
|
attributionTag, attributionFlags, attributionChainId);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addLinkToChainIfNotPresent(String op, String packageName, int uid,
|
||||||
|
String attributionTag, int attributionFlags, int attributionChainId) {
|
||||||
|
|
||||||
ArrayList<AccessChainLink> currentChain = mAttributionChains.computeIfAbsent(
|
ArrayList<AccessChainLink> currentChain = mAttributionChains.computeIfAbsent(
|
||||||
attributionChainId, k -> new ArrayList<>());
|
attributionChainId, k -> new ArrayList<>());
|
||||||
AccessChainLink link = new AccessChainLink(op, packageName, attributionTag, uid,
|
AccessChainLink link = new AccessChainLink(op, packageName, attributionTag, uid,
|
||||||
attributionFlags);
|
attributionFlags);
|
||||||
|
|
||||||
|
if (currentChain.contains(link)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
int currSize = currentChain.size();
|
int currSize = currentChain.size();
|
||||||
if (currSize == 0 || link.isEnd() || !currentChain.get(currSize - 1).isEnd()) {
|
if (currSize == 0 || link.isEnd() || !currentChain.get(currSize - 1).isEnd()) {
|
||||||
// if the list is empty, this link is the end, or the last link in the current chain
|
// if the list is empty, this link is the end, or the last link in the current chain
|
||||||
@@ -613,5 +657,21 @@ public class PermissionUsageHelper implements AppOpsManager.OnOpActiveChangedLis
|
|||||||
public boolean isStart() {
|
public boolean isStart() {
|
||||||
return (flags & ATTRIBUTION_FLAG_RECEIVER) != 0;
|
return (flags & ATTRIBUTION_FLAG_RECEIVER) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (!(obj instanceof AccessChainLink)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
AccessChainLink other = (AccessChainLink) obj;
|
||||||
|
return other.flags == flags && packageAndOpEquals(other.usage.op,
|
||||||
|
other.usage.packageName, other.usage.attributionTag, other.usage.uid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean packageAndOpEquals(String op, String packageName, String attributionTag,
|
||||||
|
int uid) {
|
||||||
|
return Objects.equals(op, usage.op) && Objects.equals(packageName, usage.packageName)
|
||||||
|
&& Objects.equals(attributionTag, usage.attributionTag) && uid == usage.uid;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,5 +18,6 @@ package com.android.internal.app;
|
|||||||
|
|
||||||
// Iterface to observe op starts
|
// Iterface to observe op starts
|
||||||
oneway interface IAppOpsStartedCallback {
|
oneway interface IAppOpsStartedCallback {
|
||||||
void opStarted(int op, int uid, String packageName, String attributionTag, int flags, int mode);
|
void opStarted(int op, int uid, String packageName, String attributionTag, int flags, int mode,
|
||||||
|
int startedType, int attributionFlags, int attributionChainId);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,6 +45,9 @@ import static android.app.AppOpsManager.OP_NONE;
|
|||||||
import static android.app.AppOpsManager.OP_PLAY_AUDIO;
|
import static android.app.AppOpsManager.OP_PLAY_AUDIO;
|
||||||
import static android.app.AppOpsManager.OP_RECORD_AUDIO;
|
import static android.app.AppOpsManager.OP_RECORD_AUDIO;
|
||||||
import static android.app.AppOpsManager.OP_RECORD_AUDIO_HOTWORD;
|
import static android.app.AppOpsManager.OP_RECORD_AUDIO_HOTWORD;
|
||||||
|
import static android.app.AppOpsManager.OnOpStartedListener.START_TYPE_FAILED;
|
||||||
|
import static android.app.AppOpsManager.OnOpStartedListener.START_TYPE_RESUMED;
|
||||||
|
import static android.app.AppOpsManager.OnOpStartedListener.START_TYPE_STARTED;
|
||||||
import static android.app.AppOpsManager.OpEventProxyInfo;
|
import static android.app.AppOpsManager.OpEventProxyInfo;
|
||||||
import static android.app.AppOpsManager.RestrictionBypass;
|
import static android.app.AppOpsManager.RestrictionBypass;
|
||||||
import static android.app.AppOpsManager.SAMPLING_STRATEGY_BOOT_TIME_SAMPLING;
|
import static android.app.AppOpsManager.SAMPLING_STRATEGY_BOOT_TIME_SAMPLING;
|
||||||
@@ -1238,6 +1241,11 @@ public class AppOpsService extends IAppOpsService.Stub {
|
|||||||
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());
|
||||||
}
|
}
|
||||||
|
// Note: this always sends MODE_ALLOWED, even if the mode is FOREGROUND
|
||||||
|
// TODO ntmyren: figure out how to get the real mode.
|
||||||
|
scheduleOpStartedIfNeededLocked(parent.op, parent.uid, parent.packageName,
|
||||||
|
tag, event.getFlags(), MODE_ALLOWED, START_TYPE_RESUMED,
|
||||||
|
event.getAttributionFlags(), event.getAttributionChainId());
|
||||||
}
|
}
|
||||||
mPausedInProgressEvents = null;
|
mPausedInProgressEvents = null;
|
||||||
}
|
}
|
||||||
@@ -3945,13 +3953,15 @@ public class AppOpsService extends IAppOpsService.Stub {
|
|||||||
}
|
}
|
||||||
|
|
||||||
boolean isRestricted = false;
|
boolean isRestricted = false;
|
||||||
|
int startType = START_TYPE_FAILED;
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
final Ops ops = getOpsLocked(uid, packageName, attributionTag,
|
final Ops ops = getOpsLocked(uid, packageName, attributionTag,
|
||||||
pvr.isAttributionTagValid, pvr.bypass, /* edit */ true);
|
pvr.isAttributionTagValid, pvr.bypass, /* edit */ true);
|
||||||
if (ops == null) {
|
if (ops == null) {
|
||||||
if (!dryRun) {
|
if (!dryRun) {
|
||||||
scheduleOpStartedIfNeededLocked(code, uid, packageName, attributionTag,
|
scheduleOpStartedIfNeededLocked(code, uid, packageName, attributionTag,
|
||||||
flags, AppOpsManager.MODE_IGNORED);
|
flags, AppOpsManager.MODE_IGNORED, startType, attributionFlags,
|
||||||
|
attributionChainId);
|
||||||
}
|
}
|
||||||
if (DEBUG) Slog.d(TAG, "startOperation: no op for code " + code + " uid " + uid
|
if (DEBUG) Slog.d(TAG, "startOperation: no op for code " + code + " uid " + uid
|
||||||
+ " package " + packageName + " flags: "
|
+ " package " + packageName + " flags: "
|
||||||
@@ -3977,7 +3987,7 @@ public class AppOpsService extends IAppOpsService.Stub {
|
|||||||
if (!dryRun) {
|
if (!dryRun) {
|
||||||
attributedOp.rejected(uidState.state, flags);
|
attributedOp.rejected(uidState.state, flags);
|
||||||
scheduleOpStartedIfNeededLocked(code, uid, packageName, attributionTag,
|
scheduleOpStartedIfNeededLocked(code, uid, packageName, attributionTag,
|
||||||
flags, uidMode);
|
flags, uidMode, startType, attributionFlags, attributionChainId);
|
||||||
}
|
}
|
||||||
return new SyncNotedAppOp(uidMode, code, attributionTag, packageName);
|
return new SyncNotedAppOp(uidMode, code, attributionTag, packageName);
|
||||||
}
|
}
|
||||||
@@ -3993,7 +4003,7 @@ public class AppOpsService extends IAppOpsService.Stub {
|
|||||||
if (!dryRun) {
|
if (!dryRun) {
|
||||||
attributedOp.rejected(uidState.state, flags);
|
attributedOp.rejected(uidState.state, flags);
|
||||||
scheduleOpStartedIfNeededLocked(code, uid, packageName, attributionTag,
|
scheduleOpStartedIfNeededLocked(code, uid, packageName, attributionTag,
|
||||||
flags, mode);
|
flags, mode, startType, attributionFlags, attributionChainId);
|
||||||
}
|
}
|
||||||
return new SyncNotedAppOp(mode, code, attributionTag, packageName);
|
return new SyncNotedAppOp(mode, code, attributionTag, packageName);
|
||||||
}
|
}
|
||||||
@@ -4011,12 +4021,14 @@ public class AppOpsService extends IAppOpsService.Stub {
|
|||||||
attributedOp.started(clientId, proxyUid, proxyPackageName,
|
attributedOp.started(clientId, proxyUid, proxyPackageName,
|
||||||
proxyAttributionTag, uidState.state, flags, attributionFlags,
|
proxyAttributionTag, uidState.state, flags, attributionFlags,
|
||||||
attributionChainId);
|
attributionChainId);
|
||||||
|
startType = START_TYPE_STARTED;
|
||||||
}
|
}
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
scheduleOpStartedIfNeededLocked(code, uid, packageName, attributionTag, flags,
|
scheduleOpStartedIfNeededLocked(code, uid, packageName, attributionTag, flags,
|
||||||
isRestricted ? MODE_IGNORED : MODE_ALLOWED);
|
isRestricted ? MODE_IGNORED : MODE_ALLOWED, startType, attributionFlags,
|
||||||
|
attributionChainId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4187,7 +4199,9 @@ public class AppOpsService extends IAppOpsService.Stub {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void scheduleOpStartedIfNeededLocked(int code, int uid, String pkgName,
|
private void scheduleOpStartedIfNeededLocked(int code, int uid, String pkgName,
|
||||||
String attributionTag, @OpFlags int flags, @Mode int result) {
|
String attributionTag, @OpFlags int flags, @Mode int result,
|
||||||
|
@AppOpsManager.OnOpStartedListener.StartedType int startedType,
|
||||||
|
@AttributionFlags int attributionFlags, int attributionChainId) {
|
||||||
ArraySet<StartedCallback> dispatchedCallbacks = null;
|
ArraySet<StartedCallback> dispatchedCallbacks = null;
|
||||||
final int callbackListCount = mStartedWatchers.size();
|
final int callbackListCount = mStartedWatchers.size();
|
||||||
for (int i = 0; i < callbackListCount; i++) {
|
for (int i = 0; i < callbackListCount; i++) {
|
||||||
@@ -4213,12 +4227,13 @@ public class AppOpsService extends IAppOpsService.Stub {
|
|||||||
mHandler.sendMessage(PooledLambda.obtainMessage(
|
mHandler.sendMessage(PooledLambda.obtainMessage(
|
||||||
AppOpsService::notifyOpStarted,
|
AppOpsService::notifyOpStarted,
|
||||||
this, dispatchedCallbacks, code, uid, pkgName, attributionTag, flags,
|
this, dispatchedCallbacks, code, uid, pkgName, attributionTag, flags,
|
||||||
result));
|
result, startedType, attributionFlags, attributionChainId));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void notifyOpStarted(ArraySet<StartedCallback> callbacks,
|
private void notifyOpStarted(ArraySet<StartedCallback> callbacks,
|
||||||
int code, int uid, String packageName, String attributionTag, @OpFlags int flags,
|
int code, int uid, String packageName, String attributionTag, @OpFlags int flags,
|
||||||
@Mode int result) {
|
@Mode int result, @AppOpsManager.OnOpStartedListener.StartedType int startedType,
|
||||||
|
@AttributionFlags int attributionFlags, int attributionChainId) {
|
||||||
final long identity = Binder.clearCallingIdentity();
|
final long identity = Binder.clearCallingIdentity();
|
||||||
try {
|
try {
|
||||||
final int callbackCount = callbacks.size();
|
final int callbackCount = callbacks.size();
|
||||||
@@ -4226,7 +4241,7 @@ public class AppOpsService extends IAppOpsService.Stub {
|
|||||||
final StartedCallback callback = callbacks.valueAt(i);
|
final StartedCallback callback = callbacks.valueAt(i);
|
||||||
try {
|
try {
|
||||||
callback.mCallback.opStarted(code, uid, packageName, attributionTag, flags,
|
callback.mCallback.opStarted(code, uid, packageName, attributionTag, flags,
|
||||||
result);
|
result, startedType, attributionFlags, attributionChainId);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
/* do nothing */
|
/* do nothing */
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,12 +64,16 @@ public class AppOpsStartedWatcherTest {
|
|||||||
.times(1)).onOpStarted(eq(AppOpsManager.OP_FINE_LOCATION),
|
.times(1)).onOpStarted(eq(AppOpsManager.OP_FINE_LOCATION),
|
||||||
eq(Process.myUid()), eq(getContext().getPackageName()),
|
eq(Process.myUid()), eq(getContext().getPackageName()),
|
||||||
eq(getContext().getAttributionTag()), eq(AppOpsManager.OP_FLAG_SELF),
|
eq(getContext().getAttributionTag()), eq(AppOpsManager.OP_FLAG_SELF),
|
||||||
eq(AppOpsManager.MODE_ALLOWED));
|
eq(AppOpsManager.MODE_ALLOWED), eq(OnOpStartedListener.START_TYPE_STARTED),
|
||||||
|
eq(AppOpsManager.ATTRIBUTION_FLAGS_NONE),
|
||||||
|
eq(AppOpsManager.ATTRIBUTION_CHAIN_ID_NONE));
|
||||||
inOrder.verify(listener, timeout(NOTIFICATION_TIMEOUT_MILLIS)
|
inOrder.verify(listener, timeout(NOTIFICATION_TIMEOUT_MILLIS)
|
||||||
.times(1)).onOpStarted(eq(AppOpsManager.OP_CAMERA),
|
.times(1)).onOpStarted(eq(AppOpsManager.OP_CAMERA),
|
||||||
eq(Process.myUid()), eq(getContext().getPackageName()),
|
eq(Process.myUid()), eq(getContext().getPackageName()),
|
||||||
eq(getContext().getAttributionTag()), eq(AppOpsManager.OP_FLAG_SELF),
|
eq(getContext().getAttributionTag()), eq(AppOpsManager.OP_FLAG_SELF),
|
||||||
eq(AppOpsManager.MODE_ALLOWED));
|
eq(AppOpsManager.MODE_ALLOWED), eq(OnOpStartedListener.START_TYPE_STARTED),
|
||||||
|
eq(AppOpsManager.ATTRIBUTION_FLAGS_NONE),
|
||||||
|
eq(AppOpsManager.ATTRIBUTION_CHAIN_ID_NONE));
|
||||||
|
|
||||||
// Stop watching
|
// Stop watching
|
||||||
appOpsManager.stopWatchingStarted(listener);
|
appOpsManager.stopWatchingStarted(listener);
|
||||||
@@ -94,7 +98,9 @@ public class AppOpsStartedWatcherTest {
|
|||||||
.times(2)).onOpStarted(eq(AppOpsManager.OP_CAMERA),
|
.times(2)).onOpStarted(eq(AppOpsManager.OP_CAMERA),
|
||||||
eq(Process.myUid()), eq(getContext().getPackageName()),
|
eq(Process.myUid()), eq(getContext().getPackageName()),
|
||||||
eq(getContext().getAttributionTag()), eq(AppOpsManager.OP_FLAG_SELF),
|
eq(getContext().getAttributionTag()), eq(AppOpsManager.OP_FLAG_SELF),
|
||||||
eq(AppOpsManager.MODE_ALLOWED));
|
eq(AppOpsManager.MODE_ALLOWED), eq(OnOpStartedListener.START_TYPE_STARTED),
|
||||||
|
eq(AppOpsManager.ATTRIBUTION_FLAGS_NONE),
|
||||||
|
eq(AppOpsManager.ATTRIBUTION_CHAIN_ID_NONE));
|
||||||
verifyNoMoreInteractions(listener);
|
verifyNoMoreInteractions(listener);
|
||||||
|
|
||||||
// Finish up
|
// Finish up
|
||||||
|
|||||||
Reference in New Issue
Block a user