summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Yuting Fang <yutingfang@google.com> 2024-02-15 02:16:51 +0000
committer Yuting Fang <yutingfang@google.com> 2024-02-15 07:04:51 +0000
commit3b4eb3573227c19f856e57f65ab0c99f2d5931b3 (patch)
tree439ba51cb1c65a98473ebd397b18ca671337f6aa
parent6371887903fe697cdf603c8a45f13aeead29bdfc (diff)
Add new AppOp APIs to facilitate Privacy Indicators
Bug: 308720988 Test: presubmit Change-Id: I240263f03a014b790089436cabe4f348a445636c
-rw-r--r--core/api/system-current.txt3
-rw-r--r--core/java/android/app/AppOpsManager.java68
-rw-r--r--core/java/android/permission/PermissionGroupUsage.java34
-rw-r--r--core/java/android/permission/PermissionManager.java4
-rw-r--r--core/java/android/permission/PermissionUsageHelper.java63
-rw-r--r--core/java/com/android/internal/app/IAppOpsService.aidl1
-rw-r--r--services/core/java/com/android/server/appop/AppOpsService.java38
7 files changed, 182 insertions, 29 deletions
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 8fe38768b459..4407c427dbb2 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -625,6 +625,8 @@ package android.app {
method public static String[] getOpStrs();
method @NonNull @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS) public java.util.List<android.app.AppOpsManager.PackageOps> getOpsForPackage(int, @NonNull String, @Nullable java.lang.String...);
method @NonNull @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS) public java.util.List<android.app.AppOpsManager.PackageOps> getPackagesForOps(@Nullable String[]);
+ method @FlaggedApi("android.permission.flags.device_aware_permission_apis_enabled") @NonNull @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS) public java.util.List<android.app.AppOpsManager.PackageOps> getPackagesForOps(@Nullable String[], @NonNull String);
+ method @FlaggedApi("android.permission.flags.device_aware_permission_apis_enabled") @NonNull @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS) public java.util.List<android.permission.PermissionGroupUsage> getPermissionGroupUsageForPrivacyIndicator(boolean);
method public static int opToDefaultMode(@NonNull String);
method @Nullable public static String opToPermission(@NonNull String);
method @RequiresPermission("android.permission.MANAGE_APP_OPS_MODES") public void setMode(@NonNull String, int, @Nullable String, int);
@@ -11374,6 +11376,7 @@ package android.permission {
method public long getLastAccessTimeMillis();
method @NonNull public String getPackageName();
method @NonNull public String getPermissionGroupName();
+ method @FlaggedApi("android.permission.flags.device_aware_permission_apis_enabled") @NonNull public String getPersistentDeviceId();
method @Nullable public CharSequence getProxyLabel();
method public int getUid();
method public boolean isActive();
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 409badb347c4..16c7753c7f46 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -72,6 +72,8 @@ import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.UserHandle;
import android.os.UserManager;
+import android.permission.PermissionGroupUsage;
+import android.permission.PermissionUsageHelper;
import android.provider.DeviceConfig;
import android.util.ArrayMap;
import android.util.ArraySet;
@@ -226,6 +228,7 @@ public class AppOpsManager {
private static Boolean sFullLog = null;
final Context mContext;
+ private PermissionUsageHelper mUsageHelper;
@UnsupportedAppUsage
final IAppOpsService mService;
@@ -7765,6 +7768,44 @@ public class AppOpsManager {
}
/**
+ * Retrieve current operation state for all applications for a device.
+ *
+ * The mode of the ops returned are set for the package but may not reflect their effective
+ * state due to UID policy or because it's controlled by a different global op.
+ *
+ * Use {@link #unsafeCheckOp(String, int, String)}} or
+ * {@link #noteOp(String, int, String, String, String)} if the effective mode is needed.
+ *
+ * @param ops The set of operations you are interested in, or null if you want all of them.
+ * @param persistentDeviceId The device that the ops are attributed to.
+ *
+ * @hide
+ */
+ @SystemApi
+ @FlaggedApi(android.permission.flags.Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED)
+ @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS)
+ public @NonNull List<AppOpsManager.PackageOps> getPackagesForOps(@Nullable String[] ops,
+ @NonNull String persistentDeviceId) {
+ final int[] opCodes;
+ if (ops != null) {
+ final int opCount = ops.length;
+ opCodes = new int[opCount];
+ for (int i = 0; i < opCount; i++) {
+ opCodes[i] = sOpStrToOp.get(ops[i]);
+ }
+ } else {
+ opCodes = null;
+ }
+ final List<AppOpsManager.PackageOps> result;
+ try {
+ result = mService.getPackagesForOpsForDevice(opCodes, persistentDeviceId);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ return (result != null) ? result : Collections.emptyList();
+ }
+
+ /**
* Retrieve current operation state for all applications.
*
* The mode of the ops returned are set for the package but may not reflect their effective
@@ -7780,7 +7821,8 @@ public class AppOpsManager {
@UnsupportedAppUsage
public List<AppOpsManager.PackageOps> getPackagesForOps(int[] ops) {
try {
- return mService.getPackagesForOps(ops);
+ return mService.getPackagesForOpsForDevice(ops,
+ VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -9946,6 +9988,30 @@ public class AppOpsManager {
appOpsNotedForAttribution.set(op);
}
+ /**
+ * Get recent op usage data for CAMERA, MICROPHONE and LOCATION from all connected devices
+ * to power privacy indicator.
+ *
+ * @param includeMicrophoneUsage whether to retrieve microphone usage
+ * @return A list of permission groups currently or recently used by all apps by all users in
+ * the current profile group.
+ *
+ * @hide
+ */
+ @SystemApi
+ @NonNull
+ @FlaggedApi(android.permission.flags.Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED)
+ @RequiresPermission(Manifest.permission.GET_APP_OPS_STATS)
+ public List<PermissionGroupUsage> getPermissionGroupUsageForPrivacyIndicator(
+ boolean includeMicrophoneUsage) {
+ // Lazily initialize the usage helper
+ if (mUsageHelper == null) {
+ mUsageHelper = new PermissionUsageHelper(mContext);
+ }
+
+ return mUsageHelper.getOpUsageDataForAllDevices(includeMicrophoneUsage);
+ }
+
/** @hide */
@Retention(RetentionPolicy.SOURCE)
@IntDef(value = {
diff --git a/core/java/android/permission/PermissionGroupUsage.java b/core/java/android/permission/PermissionGroupUsage.java
index 49b7463533e4..6895d3c67f06 100644
--- a/core/java/android/permission/PermissionGroupUsage.java
+++ b/core/java/android/permission/PermissionGroupUsage.java
@@ -17,6 +17,7 @@
package android.permission;
import android.annotation.CurrentTimeMillisLong;
+import android.annotation.FlaggedApi;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
@@ -26,8 +27,8 @@ import com.android.internal.util.DataClass;
/**
* Represents the usage of a permission group by an app. Supports package name, user, permission
- * group, whether or not the access is running or recent, whether the access is tied to a phone
- * call, and an optional special attribution tag, label and proxy label.
+ * group, persistent device Id, whether or not the access is running or recent, whether the access
+ * is tied to a phone call, and an optional special attribution tag, label and proxy label.
*
* @hide
*/
@@ -48,6 +49,7 @@ public final class PermissionGroupUsage implements Parcelable {
private final @Nullable CharSequence mAttributionTag;
private final @Nullable CharSequence mAttributionLabel;
private final @Nullable CharSequence mProxyLabel;
+ private final @NonNull String mPersistentDeviceId;
@@ -79,7 +81,8 @@ public final class PermissionGroupUsage implements Parcelable {
boolean phoneCall,
@Nullable CharSequence attributionTag,
@Nullable CharSequence attributionLabel,
- @Nullable CharSequence proxyLabel) {
+ @Nullable CharSequence proxyLabel,
+ @NonNull String persistentDeviceId) {
this.mPackageName = packageName;
com.android.internal.util.AnnotationValidations.validate(
NonNull.class, null, mPackageName);
@@ -93,6 +96,9 @@ public final class PermissionGroupUsage implements Parcelable {
this.mAttributionTag = attributionTag;
this.mAttributionLabel = attributionLabel;
this.mProxyLabel = proxyLabel;
+ this.mPersistentDeviceId = persistentDeviceId;
+ com.android.internal.util.AnnotationValidations.validate(
+ NonNull.class, null, mPersistentDeviceId);
// onConstructed(); // You can define this method to get a callback
}
@@ -170,6 +176,12 @@ public final class PermissionGroupUsage implements Parcelable {
return mProxyLabel;
}
+ @DataClass.Generated.Member
+ @FlaggedApi(android.permission.flags.Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED)
+ public @NonNull String getPersistentDeviceId() {
+ return mPersistentDeviceId;
+ }
+
@Override
@DataClass.Generated.Member
public String toString() {
@@ -185,7 +197,8 @@ public final class PermissionGroupUsage implements Parcelable {
"phoneCall = " + mPhoneCall + ", " +
"attributionTag = " + mAttributionTag + ", " +
"attributionLabel = " + mAttributionLabel + ", " +
- "proxyLabel = " + mProxyLabel +
+ "proxyLabel = " + mProxyLabel + ", " +
+ "persistentDeviceId = " + mPersistentDeviceId +
" }";
}
@@ -210,7 +223,8 @@ public final class PermissionGroupUsage implements Parcelable {
&& mPhoneCall == that.mPhoneCall
&& java.util.Objects.equals(mAttributionTag, that.mAttributionTag)
&& java.util.Objects.equals(mAttributionLabel, that.mAttributionLabel)
- && java.util.Objects.equals(mProxyLabel, that.mProxyLabel);
+ && java.util.Objects.equals(mProxyLabel, that.mProxyLabel)
+ && java.util.Objects.equals(mPersistentDeviceId, that.mPersistentDeviceId);
}
@Override
@@ -229,6 +243,7 @@ public final class PermissionGroupUsage implements Parcelable {
_hash = 31 * _hash + java.util.Objects.hashCode(mAttributionTag);
_hash = 31 * _hash + java.util.Objects.hashCode(mAttributionLabel);
_hash = 31 * _hash + java.util.Objects.hashCode(mProxyLabel);
+ _hash = 31 * _hash + java.util.Objects.hashCode(mPersistentDeviceId);
return _hash;
}
@@ -252,6 +267,7 @@ public final class PermissionGroupUsage implements Parcelable {
if (mAttributionTag != null) dest.writeCharSequence(mAttributionTag);
if (mAttributionLabel != null) dest.writeCharSequence(mAttributionLabel);
if (mProxyLabel != null) dest.writeCharSequence(mProxyLabel);
+ dest.writeString(mPersistentDeviceId);
}
@Override
@@ -275,6 +291,7 @@ public final class PermissionGroupUsage implements Parcelable {
CharSequence attributionTag = (flg & 0x40) == 0 ? null : (CharSequence) in.readCharSequence();
CharSequence attributionLabel = (flg & 0x80) == 0 ? null : (CharSequence) in.readCharSequence();
CharSequence proxyLabel = (flg & 0x100) == 0 ? null : (CharSequence) in.readCharSequence();
+ String persistentDeviceId = in.readString();
this.mPackageName = packageName;
com.android.internal.util.AnnotationValidations.validate(
@@ -289,6 +306,9 @@ public final class PermissionGroupUsage implements Parcelable {
this.mAttributionTag = attributionTag;
this.mAttributionLabel = attributionLabel;
this.mProxyLabel = proxyLabel;
+ this.mPersistentDeviceId = persistentDeviceId;
+ com.android.internal.util.AnnotationValidations.validate(
+ NonNull.class, null, mPersistentDeviceId);
// onConstructed(); // You can define this method to get a callback
}
@@ -308,10 +328,10 @@ public final class PermissionGroupUsage implements Parcelable {
};
@DataClass.Generated(
- time = 1645067417023L,
+ time = 1706285211875L,
codegenVersion = "1.0.23",
sourceFile = "frameworks/base/core/java/android/permission/PermissionGroupUsage.java",
- inputSignatures = "private final @android.annotation.NonNull java.lang.String mPackageName\nprivate final int mUid\nprivate final long mLastAccessTimeMillis\nprivate final @android.annotation.NonNull java.lang.String mPermissionGroupName\nprivate final boolean mActive\nprivate final boolean mPhoneCall\nprivate final @android.annotation.Nullable java.lang.CharSequence mAttributionTag\nprivate final @android.annotation.Nullable java.lang.CharSequence mAttributionLabel\nprivate final @android.annotation.Nullable java.lang.CharSequence mProxyLabel\nclass PermissionGroupUsage extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genHiddenConstructor=true, genEqualsHashCode=true, genToString=true)")
+ inputSignatures = "private final @android.annotation.NonNull java.lang.String mPackageName\nprivate final int mUid\nprivate final long mLastAccessTimeMillis\nprivate final @android.annotation.NonNull java.lang.String mPermissionGroupName\nprivate final boolean mActive\nprivate final boolean mPhoneCall\nprivate final @android.annotation.Nullable java.lang.CharSequence mAttributionTag\nprivate final @android.annotation.Nullable java.lang.CharSequence mAttributionLabel\nprivate final @android.annotation.Nullable java.lang.CharSequence mProxyLabel\nprivate final @android.annotation.NonNull java.lang.String mPersistentDeviceId\nclass PermissionGroupUsage extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genHiddenConstructor=true, genEqualsHashCode=true, genToString=true)")
@Deprecated
private void __metadata() {}
diff --git a/core/java/android/permission/PermissionManager.java b/core/java/android/permission/PermissionManager.java
index e6b8102764eb..fd52c769e408 100644
--- a/core/java/android/permission/PermissionManager.java
+++ b/core/java/android/permission/PermissionManager.java
@@ -1329,7 +1329,9 @@ public final class PermissionManager {
public List<PermissionGroupUsage> getIndicatorAppOpUsageData(boolean micMuted) {
// Lazily initialize the usage helper
initializeUsageHelper();
- return mUsageHelper.getOpUsageData(micMuted);
+ boolean includeMicrophoneUsage = !micMuted;
+ return mUsageHelper.getOpUsageDataByDevice(includeMicrophoneUsage,
+ VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT);
}
/**
diff --git a/core/java/android/permission/PermissionUsageHelper.java b/core/java/android/permission/PermissionUsageHelper.java
index 1f798baf1bd6..460b4dd9b86c 100644
--- a/core/java/android/permission/PermissionUsageHelper.java
+++ b/core/java/android/permission/PermissionUsageHelper.java
@@ -41,6 +41,8 @@ import static android.telephony.TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_AC
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.AppOpsManager;
+import android.companion.virtual.VirtualDevice;
+import android.companion.virtual.VirtualDeviceManager;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.Attribution;
@@ -52,10 +54,12 @@ import android.location.LocationManager;
import android.media.AudioManager;
import android.os.Process;
import android.os.UserHandle;
+import android.permission.flags.Flags;
import android.provider.DeviceConfig;
import android.telephony.TelephonyManager;
import android.util.ArrayMap;
import android.util.ArraySet;
+import android.util.Slog;
import com.android.internal.annotations.GuardedBy;
@@ -75,6 +79,8 @@ import java.util.Objects;
public class PermissionUsageHelper implements AppOpsManager.OnOpActiveChangedListener,
AppOpsManager.OnOpStartedListener {
+ private static final String LOG_TAG = PermissionUsageHelper.class.getName();
+
/**
* Whether to show the mic and camera icons.
*/
@@ -159,6 +165,7 @@ public class PermissionUsageHelper implements AppOpsManager.OnOpActiveChangedLis
private ArrayMap<UserHandle, Context> mUserContexts;
private PackageManager mPkgManager;
private AppOpsManager mAppOpsManager;
+ private VirtualDeviceManager mVirtualDeviceManager;
@GuardedBy("mAttributionChains")
private final ArrayMap<Integer, ArrayList<AccessChainLink>> mAttributionChains =
new ArrayMap<>();
@@ -172,6 +179,7 @@ public class PermissionUsageHelper implements AppOpsManager.OnOpActiveChangedLis
mContext = context;
mPkgManager = context.getPackageManager();
mAppOpsManager = context.getSystemService(AppOpsManager.class);
+ mVirtualDeviceManager = context.getSystemService(VirtualDeviceManager.class);
mUserContexts = new ArrayMap<>();
mUserContexts.put(Process.myUserHandle(), mContext);
// TODO ntmyren: make this listen for flag enable/disable changes
@@ -280,9 +288,11 @@ public class PermissionUsageHelper implements AppOpsManager.OnOpActiveChangedLis
}
/**
- * @see PermissionManager.getIndicatorAppOpUsageData
+ * Return Op usage for CAMERA, LOCATION AND MICROPHONE for all packages for a device.
+ * The returned data is to power privacy indicator.
*/
- public @NonNull List<PermissionGroupUsage> getOpUsageData(boolean isMicMuted) {
+ public @NonNull List<PermissionGroupUsage> getOpUsageDataByDevice(
+ boolean includeMicrophoneUsage, String deviceId) {
List<PermissionGroupUsage> usages = new ArrayList<>();
if (!shouldShowIndicators()) {
@@ -293,11 +303,11 @@ public class PermissionUsageHelper implements AppOpsManager.OnOpActiveChangedLis
if (shouldShowLocationIndicator()) {
ops.addAll(LOCATION_OPS);
}
- if (!isMicMuted) {
+ if (includeMicrophoneUsage) {
ops.addAll(MIC_OPS);
}
- Map<String, List<OpUsage>> rawUsages = getOpUsages(ops);
+ Map<String, List<OpUsage>> rawUsages = getOpUsagesByDevice(ops, deviceId);
ArrayList<String> usedPermGroups = new ArrayList<>(rawUsages.keySet());
@@ -349,13 +359,40 @@ public class PermissionUsageHelper implements AppOpsManager.OnOpActiveChangedLis
new PermissionGroupUsage(usage.packageName, usage.uid, usage.lastAccessTime,
permGroup,
usage.isRunning, isPhone, usage.attributionTag, attributionLabel,
- usagesWithLabels.valueAt(usageNum)));
+ usagesWithLabels.valueAt(usageNum),
+ VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT));
}
}
return usages;
}
+ /**
+ * Return Op usage for CAMERA, LOCATION AND MICROPHONE for all packages and all connected
+ * devices.
+ * The returned data is to power privacy indicator.
+ */
+ public @NonNull List<PermissionGroupUsage> getOpUsageDataForAllDevices(
+ boolean includeMicrophoneUsage) {
+ List<PermissionGroupUsage> allUsages = new ArrayList<>();
+ List<VirtualDevice> virtualDevices = mVirtualDeviceManager.getVirtualDevices();
+ ArraySet<String> persistentDeviceIds = new ArraySet<>();
+
+ for (int num = 0; num < virtualDevices.size(); num++) {
+ persistentDeviceIds.add(virtualDevices.get(num).getPersistentDeviceId());
+ }
+ persistentDeviceIds.add(VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT);
+
+ for (int index = 0; index < persistentDeviceIds.size(); index++) {
+ allUsages.addAll(
+ getOpUsageDataByDevice(includeMicrophoneUsage,
+ persistentDeviceIds.valueAt(index)));
+ }
+
+ return allUsages;
+ }
+
+
private void updateSubattributionLabelsMap(List<OpUsage> usages,
ArrayMap<String, Map<String, String>> subAttributionLabelsMap) {
if (usages == null || usages.isEmpty()) {
@@ -443,12 +480,24 @@ public class PermissionUsageHelper implements AppOpsManager.OnOpActiveChangedLis
* running/recent info, if the usage is a phone call, per permission group.
*
* @param opNames a list of op names to get usage for
+ * @param deviceId which device to get op usage for
* @return A map of permission group -> list of usages that are recent or running
*/
- private Map<String, List<OpUsage>> getOpUsages(List<String> opNames) {
+ private Map<String, List<OpUsage>> getOpUsagesByDevice(List<String> opNames, String deviceId) {
List<AppOpsManager.PackageOps> ops;
try {
- ops = mAppOpsManager.getPackagesForOps(opNames.toArray(new String[opNames.size()]));
+ if (Flags.deviceAwarePermissionApisEnabled()) {
+ ops = mAppOpsManager.getPackagesForOps(opNames.toArray(new String[opNames.size()]),
+ deviceId);
+ } else if (!Objects.equals(deviceId,
+ VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT)) {
+ Slog.w(LOG_TAG,
+ "device_aware_permission_apis_enabled flag not enabled when deviceId is "
+ + "not default");
+ return Collections.emptyMap();
+ } else {
+ ops = mAppOpsManager.getPackagesForOps(opNames.toArray(new String[opNames.size()]));
+ }
} catch (NullPointerException e) {
// older builds might not support all the app-ops requested
return Collections.emptyMap();
diff --git a/core/java/com/android/internal/app/IAppOpsService.aidl b/core/java/com/android/internal/app/IAppOpsService.aidl
index 3a321e5c26f7..3ec70649294b 100644
--- a/core/java/com/android/internal/app/IAppOpsService.aidl
+++ b/core/java/com/android/internal/app/IAppOpsService.aidl
@@ -162,4 +162,5 @@ interface IAppOpsService {
int attributionFlags, int attributionChainId);
void finishOperationForDevice(IBinder clientId, int code, int uid, String packageName,
@nullable String attributionTag, int virtualDeviceId);
+ List<AppOpsManager.PackageOps> getPackagesForOpsForDevice(in int[] ops, String persistentDeviceId);
}
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index fd09ad187f2a..fca119917fd0 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -658,11 +658,11 @@ public class AppOpsService extends IAppOpsService.Stub {
return attributedOp;
}
- @NonNull OpEntry createEntryLocked() {
+ @NonNull OpEntry createEntryLocked(String persistentDeviceId) {
// TODO(b/308201969): Update this method when we introduce disk persistence of events
// for accesses on external devices.
final ArrayMap<String, AttributedOp> attributedOps = mDeviceAttributedOps.get(
- PERSISTENT_DEVICE_ID_DEFAULT);
+ persistentDeviceId);
final ArrayMap<String, AppOpsManager.AttributedOpEntry> attributionEntries =
new ArrayMap<>(attributedOps.size());
for (int i = 0; i < attributedOps.size(); i++) {
@@ -1550,13 +1550,14 @@ public class AppOpsService extends IAppOpsService.Stub {
mHistoricalRegistry.shutdown();
}
- private ArrayList<AppOpsManager.OpEntry> collectOps(Ops pkgOps, int[] ops) {
+ private ArrayList<AppOpsManager.OpEntry> collectOps(Ops pkgOps, int[] ops,
+ String persistentDeviceId) {
ArrayList<AppOpsManager.OpEntry> resOps = null;
if (ops == null) {
resOps = new ArrayList<>();
for (int j=0; j<pkgOps.size(); j++) {
Op curOp = pkgOps.valueAt(j);
- resOps.add(getOpEntryForResult(curOp));
+ resOps.add(getOpEntryForResult(curOp, persistentDeviceId));
}
} else {
for (int j=0; j<ops.length; j++) {
@@ -1565,7 +1566,7 @@ public class AppOpsService extends IAppOpsService.Stub {
if (resOps == null) {
resOps = new ArrayList<>();
}
- resOps.add(getOpEntryForResult(curOp));
+ resOps.add(getOpEntryForResult(curOp, persistentDeviceId));
}
}
}
@@ -1609,16 +1610,23 @@ public class AppOpsService extends IAppOpsService.Stub {
return resOps;
}
- private static @NonNull OpEntry getOpEntryForResult(@NonNull Op op) {
- return op.createEntryLocked();
+ private static @NonNull OpEntry getOpEntryForResult(@NonNull Op op, String persistentDeviceId) {
+ return op.createEntryLocked(persistentDeviceId);
}
@Override
public List<AppOpsManager.PackageOps> getPackagesForOps(int[] ops) {
+ return getPackagesForOpsForDevice(ops, PERSISTENT_DEVICE_ID_DEFAULT);
+ }
+
+ @Override
+ public List<AppOpsManager.PackageOps> getPackagesForOpsForDevice(int[] ops,
+ @NonNull String persistentDeviceId) {
final int callingUid = Binder.getCallingUid();
final boolean hasAllPackageAccess = mContext.checkPermission(
Manifest.permission.GET_APP_OPS_STATS, Binder.getCallingPid(),
Binder.getCallingUid(), null) == PackageManager.PERMISSION_GRANTED;
+
ArrayList<AppOpsManager.PackageOps> res = null;
synchronized (this) {
final int uidStateCount = mUidStates.size();
@@ -1627,21 +1635,24 @@ public class AppOpsService extends IAppOpsService.Stub {
if (uidState.pkgOps.isEmpty()) {
continue;
}
+ // Caller can always see their packages and with a permission all.
+ if (!hasAllPackageAccess && callingUid != uidState.uid) {
+ continue;
+ }
+
ArrayMap<String, Ops> packages = uidState.pkgOps;
final int packageCount = packages.size();
for (int j = 0; j < packageCount; j++) {
Ops pkgOps = packages.valueAt(j);
- ArrayList<AppOpsManager.OpEntry> resOps = collectOps(pkgOps, ops);
+ ArrayList<AppOpsManager.OpEntry> resOps = collectOps(pkgOps, ops,
+ persistentDeviceId);
if (resOps != null) {
if (res == null) {
res = new ArrayList<>();
}
AppOpsManager.PackageOps resPackage = new AppOpsManager.PackageOps(
pkgOps.packageName, pkgOps.uidState.uid, resOps);
- // Caller can always see their packages and with a permission all.
- if (hasAllPackageAccess || callingUid == pkgOps.uidState.uid) {
- res.add(resPackage);
- }
+ res.add(resPackage);
}
}
}
@@ -1663,7 +1674,8 @@ public class AppOpsService extends IAppOpsService.Stub {
if (pkgOps == null) {
return null;
}
- ArrayList<AppOpsManager.OpEntry> resOps = collectOps(pkgOps, ops);
+ ArrayList<AppOpsManager.OpEntry> resOps = collectOps(pkgOps, ops,
+ PERSISTENT_DEVICE_ID_DEFAULT);
if (resOps == null || resOps.size() == 0) {
return null;
}