Add support for excluding tags from restrictions
Allow user restrictions to provide an excluded map of packages and tags
rather than just packages.
Bug: 187421886
Test: manual
Change-Id: I8f90ba6cdd288068664b352fdb540d0f11fe3dfc
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 010f4e4..ed00436 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -7394,20 +7394,27 @@
/** @hide */
public void setUserRestriction(int code, boolean restricted, IBinder token) {
- setUserRestriction(code, restricted, token, /*exceptionPackages*/null);
+ setUserRestriction(code, restricted, token, (Map<String, String[]>) null);
}
- /** @hide */
+ /**
+ * An empty array of attribution tags means exclude all tags under that package.
+ * @hide
+ */
public void setUserRestriction(int code, boolean restricted, IBinder token,
- String[] exceptionPackages) {
- setUserRestrictionForUser(code, restricted, token, exceptionPackages, mContext.getUserId());
+ @Nullable Map<String, String[]> excludedPackageTags) {
+ setUserRestrictionForUser(code, restricted, token, excludedPackageTags,
+ mContext.getUserId());
}
- /** @hide */
+ /**
+ * An empty array of attribution tags means exclude all tags under that package.
+ * @hide
+ */
public void setUserRestrictionForUser(int code, boolean restricted, IBinder token,
- String[] exceptionPackages, int userId) {
+ @Nullable Map<String, String[]> excludedPackageTags, int userId) {
try {
- mService.setUserRestriction(code, restricted, token, userId, exceptionPackages);
+ mService.setUserRestriction(code, restricted, token, userId, excludedPackageTags);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -7949,7 +7956,7 @@
*/
public int unsafeCheckOpRawNoThrow(int op, int uid, @NonNull String packageName) {
try {
- return mService.checkOperationRaw(op, uid, packageName);
+ return mService.checkOperationRaw(op, uid, packageName, null);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/core/java/android/app/AppOpsManagerInternal.java b/core/java/android/app/AppOpsManagerInternal.java
index 341b9c5..2de0ddb 100644
--- a/core/java/android/app/AppOpsManagerInternal.java
+++ b/core/java/android/app/AppOpsManagerInternal.java
@@ -29,6 +29,7 @@
import com.android.internal.util.function.NonaFunction;
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;
/**
@@ -45,12 +46,14 @@
* @param code The op code to check.
* @param uid The UID for which to check.
* @param packageName The package for which to check.
- * @param superImpl The super implementation.
+ * @param attributionTag The attribution tag for which to check.
* @param raw Whether to check the raw op i.e. not interpret the mode based on UID state.
+ * @param superImpl The super implementation.
* @return The app op check result.
*/
- int checkOperation(int code, int uid, String packageName, boolean raw,
- QuadFunction<Integer, Integer, String, Boolean, Integer> superImpl);
+ int checkOperation(int code, int uid, String packageName, @Nullable String attributionTag,
+ boolean raw,
+ QuintFunction<Integer, Integer, String, String, Boolean, Integer> superImpl);
/**
* Allows overriding check audio operation behavior.
diff --git a/core/java/com/android/internal/app/IAppOpsService.aidl b/core/java/com/android/internal/app/IAppOpsService.aidl
index 281702e..3cf4621 100644
--- a/core/java/com/android/internal/app/IAppOpsService.aidl
+++ b/core/java/com/android/internal/app/IAppOpsService.aidl
@@ -92,7 +92,7 @@
void setAudioRestriction(int code, int usage, int uid, int mode, in String[] exceptionPackages);
void setUserRestrictions(in Bundle restrictions, IBinder token, int userHandle);
- void setUserRestriction(int code, boolean restricted, IBinder token, int userHandle, in String[] exceptionPackages);
+ void setUserRestriction(int code, boolean restricted, IBinder token, int userHandle, in Map<String, String[]> excludedPackageTags);
void removeUser(int userHandle);
void startWatchingActive(in int[] ops, IAppOpsActiveCallback callback);
@@ -113,7 +113,7 @@
void stopWatchingAsyncNoted(String packageName, IAppOpsAsyncNotedCallback callback);
List<AsyncNotedAppOp> extractAsyncOps(String packageName);
- int checkOperationRaw(int code, int uid, String packageName);
+ int checkOperationRaw(int code, int uid, String packageName, @nullable String attributionTag);
void reloadNonHistoricalState();
diff --git a/services/core/java/com/android/server/SensorPrivacyService.java b/services/core/java/com/android/server/SensorPrivacyService.java
index ca59ce3..baec544 100644
--- a/services/core/java/com/android/server/SensorPrivacyService.java
+++ b/services/core/java/com/android/server/SensorPrivacyService.java
@@ -1320,12 +1320,12 @@
private void setUserRestriction(int userId, int sensor, boolean enabled) {
if (sensor == CAMERA) {
mAppOpsManager.setUserRestrictionForUser(OP_CAMERA, enabled,
- mAppOpsRestrictionToken, new String[]{}, userId);
+ mAppOpsRestrictionToken, null, userId);
} else if (sensor == MICROPHONE) {
mAppOpsManager.setUserRestrictionForUser(OP_RECORD_AUDIO, enabled,
- mAppOpsRestrictionToken, new String[]{}, userId);
+ mAppOpsRestrictionToken, null, userId);
mAppOpsManager.setUserRestrictionForUser(OP_RECORD_AUDIO_HOTWORD, enabled,
- mAppOpsRestrictionToken, new String[]{}, userId);
+ mAppOpsRestrictionToken, null, userId);
}
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 6661f88..5d1243b 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -351,6 +351,7 @@
import com.android.internal.util.function.NonaFunction;
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;
@@ -16741,19 +16742,20 @@
}
@Override
- public int checkOperation(int code, int uid, String packageName, boolean raw,
- QuadFunction<Integer, Integer, String, Boolean, Integer> superImpl) {
+ public int checkOperation(int code, int uid, String packageName,
+ String attributionTag, boolean raw,
+ QuintFunction<Integer, Integer, String, String, Boolean, Integer> superImpl) {
if (uid == mTargetUid && isTargetOp(code)) {
final int shellUid = UserHandle.getUid(UserHandle.getUserId(uid),
Process.SHELL_UID);
final long identity = Binder.clearCallingIdentity();
try {
- return superImpl.apply(code, shellUid, "com.android.shell", raw);
+ return superImpl.apply(code, shellUid, "com.android.shell", null, raw);
} finally {
Binder.restoreCallingIdentity(identity);
}
}
- return superImpl.apply(code, uid, packageName, raw);
+ return superImpl.apply(code, uid, packageName, attributionTag, raw);
}
@Override
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index a23b5eb..76abfbf 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -3059,16 +3059,20 @@
}
@Override
- public int checkOperationRaw(int code, int uid, String packageName) {
- return mCheckOpsDelegateDispatcher.checkOperation(code, uid, packageName, true /*raw*/);
+ public int checkOperationRaw(int code, int uid, String packageName,
+ @Nullable String attributionTag) {
+ return mCheckOpsDelegateDispatcher.checkOperation(code, uid, packageName, attributionTag,
+ true /*raw*/);
}
@Override
public int checkOperation(int code, int uid, String packageName) {
- return mCheckOpsDelegateDispatcher.checkOperation(code, uid, packageName, false /*raw*/);
+ return mCheckOpsDelegateDispatcher.checkOperation(code, uid, packageName, null,
+ false /*raw*/);
}
- private int checkOperationImpl(int code, int uid, String packageName, boolean raw) {
+ private int checkOperationImpl(int code, int uid, String packageName,
+ @Nullable String attributionTag, boolean raw) {
verifyIncomingOp(code);
verifyIncomingPackage(packageName, UserHandle.getUserId(uid));
@@ -3076,7 +3080,7 @@
if (resolvedPackageName == null) {
return AppOpsManager.MODE_IGNORED;
}
- return checkOperationUnchecked(code, uid, resolvedPackageName, raw);
+ return checkOperationUnchecked(code, uid, resolvedPackageName, attributionTag, raw);
}
/**
@@ -3090,7 +3094,7 @@
* @return The mode of the op
*/
private @Mode int checkOperationUnchecked(int code, int uid, @NonNull String packageName,
- boolean raw) {
+ @Nullable String attributionTag, boolean raw) {
RestrictionBypass bypass;
try {
bypass = verifyAndGetBypass(uid, packageName, null);
@@ -3103,7 +3107,7 @@
return AppOpsManager.MODE_IGNORED;
}
synchronized (this) {
- if (isOpRestrictedLocked(uid, code, packageName, bypass)) {
+ if (isOpRestrictedLocked(uid, code, packageName, attributionTag, bypass)) {
return AppOpsManager.MODE_IGNORED;
}
code = AppOpsManager.opToSwitch(code);
@@ -3322,7 +3326,7 @@
final int switchCode = AppOpsManager.opToSwitch(code);
final UidState uidState = ops.uidState;
- if (isOpRestrictedLocked(uid, code, packageName, bypass)) {
+ if (isOpRestrictedLocked(uid, code, packageName, attributionTag, bypass)) {
attributedOp.rejected(uidState.state, flags);
scheduleOpNotedIfNeededLocked(code, uid, packageName, attributionTag, flags,
AppOpsManager.MODE_IGNORED);
@@ -3809,7 +3813,7 @@
final Op op = getOpLocked(ops, code, uid, true);
final AttributedOp attributedOp = op.getOrCreateAttribution(op, attributionTag);
final UidState uidState = ops.uidState;
- isRestricted = isOpRestrictedLocked(uid, code, packageName, bypass);
+ isRestricted = isOpRestrictedLocked(uid, code, packageName, attributionTag, bypass);
final int switchCode = AppOpsManager.opToSwitch(code);
// 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.
@@ -4551,7 +4555,7 @@
}
private boolean isOpRestrictedLocked(int uid, int code, String packageName,
- @Nullable RestrictionBypass appBypass) {
+ String attributionTag, @Nullable RestrictionBypass appBypass) {
int userHandle = UserHandle.getUserId(uid);
final int restrictionSetCount = mOpUserRestrictions.size();
@@ -4559,7 +4563,7 @@
// For each client, check that the given op is not restricted, or that the given
// package is exempt from the restriction.
ClientRestrictionState restrictionState = mOpUserRestrictions.valueAt(i);
- if (restrictionState.hasRestriction(code, packageName, userHandle)) {
+ if (restrictionState.hasRestriction(code, packageName, attributionTag, userHandle)) {
RestrictionBypass opBypass = opAllowSystemBypassRestriction(code);
if (opBypass != null) {
// If we are the system, bypass user restrictions for certain codes
@@ -6173,25 +6177,20 @@
}
}
- final int excludedPackageCount = restrictionState.perUserExcludedPackages != null
- ? restrictionState.perUserExcludedPackages.size() : 0;
+ final int excludedPackageCount = restrictionState.perUserExcludedPackageTags != null
+ ? restrictionState.perUserExcludedPackageTags.size() : 0;
if (excludedPackageCount > 0 && dumpOp < 0) {
boolean printedPackagesHeader = false;
for (int j = 0; j < excludedPackageCount; j++) {
- int userId = restrictionState.perUserExcludedPackages.keyAt(j);
- String[] packageNames = restrictionState.perUserExcludedPackages.valueAt(j);
+ int userId = restrictionState.perUserExcludedPackageTags.keyAt(j);
+ Map<String, String[]> packageNames =
+ restrictionState.perUserExcludedPackageTags.valueAt(j);
if (packageNames == null) {
continue;
}
boolean hasPackage;
if (dumpPackage != null) {
- hasPackage = false;
- for (String pkg : packageNames) {
- if (dumpPackage.equals(pkg)) {
- hasPackage = true;
- break;
- }
- }
+ hasPackage = packageNames.containsKey(dumpPackage);
} else {
hasPackage = true;
}
@@ -6206,8 +6205,24 @@
pw.println(" Excluded packages:");
printedPackagesHeader = true;
}
- pw.print(" "); pw.print("user: "); pw.print(userId);
- pw.print(" packages: "); pw.println(Arrays.toString(packageNames));
+ pw.print(" ");
+ pw.print("user: ");
+ pw.print(userId);
+ pw.println(" packages: ");
+ for (Map.Entry<String, String[]> entry : packageNames.entrySet()) {
+ if (entry.getValue() == null) {
+ continue;
+ }
+ pw.print(" ");
+ pw.print(entry.getKey());
+ pw.print(": ");
+ if (entry.getValue().length == 0) {
+ pw.print("*");
+ } else {
+ pw.print(Arrays.toString(entry.getValue()));
+ }
+ pw.println();
+ }
}
}
}
@@ -6241,7 +6256,7 @@
@Override
public void setUserRestriction(int code, boolean restricted, IBinder token, int userHandle,
- String[] exceptionPackages) {
+ Map<String, String[]> excludedPackageTags) {
if (Binder.getCallingPid() != Process.myPid()) {
mContext.enforcePermission(Manifest.permission.MANAGE_APP_OPS_RESTRICTIONS,
Binder.getCallingPid(), Binder.getCallingUid(), null);
@@ -6257,11 +6272,11 @@
}
verifyIncomingOp(code);
Objects.requireNonNull(token);
- setUserRestrictionNoCheck(code, restricted, token, userHandle, exceptionPackages);
+ setUserRestrictionNoCheck(code, restricted, token, userHandle, excludedPackageTags);
}
private void setUserRestrictionNoCheck(int code, boolean restricted, IBinder token,
- int userHandle, String[] exceptionPackages) {
+ int userHandle, Map<String, String[]> excludedPackageTags) {
synchronized (AppOpsService.this) {
ClientRestrictionState restrictionState = mOpUserRestrictions.get(token);
@@ -6274,7 +6289,8 @@
mOpUserRestrictions.put(token, restrictionState);
}
- if (restrictionState.setRestriction(code, restricted, exceptionPackages, userHandle)) {
+ if (restrictionState.setRestriction(code, restricted, excludedPackageTags,
+ userHandle)) {
mHandler.sendMessage(PooledLambda.obtainMessage(
AppOpsService::notifyWatchersOfChange, this, code, UID_ANY));
mHandler.sendMessage(PooledLambda.obtainMessage(
@@ -6804,7 +6820,7 @@
private final class ClientRestrictionState implements DeathRecipient {
private final IBinder token;
SparseArray<boolean[]> perUserRestrictions;
- SparseArray<String[]> perUserExcludedPackages;
+ SparseArray<Map<String, String[]>> perUserExcludedPackageTags;
public ClientRestrictionState(IBinder token)
throws RemoteException {
@@ -6813,7 +6829,7 @@
}
public boolean setRestriction(int code, boolean restricted,
- String[] excludedPackages, int userId) {
+ Map<String, String[]> excludedPackageTags, int userId) {
boolean changed = false;
if (perUserRestrictions == null && restricted) {
@@ -6855,19 +6871,27 @@
}
if (userRestrictions != null) {
- final boolean noExcludedPackages = ArrayUtils.isEmpty(excludedPackages);
- if (perUserExcludedPackages == null && !noExcludedPackages) {
- perUserExcludedPackages = new SparseArray<>();
+ final boolean noExcludedPackages = ArrayUtils.isEmpty(excludedPackageTags);
+ if (perUserExcludedPackageTags == null && !noExcludedPackages) {
+ perUserExcludedPackageTags = new SparseArray<>();
}
- if (perUserExcludedPackages != null && !Arrays.equals(excludedPackages,
- perUserExcludedPackages.get(thisUserId))) {
+ if (perUserExcludedPackageTags != null) {
if (noExcludedPackages) {
- perUserExcludedPackages.remove(thisUserId);
- if (perUserExcludedPackages.size() <= 0) {
- perUserExcludedPackages = null;
+ perUserExcludedPackageTags.remove(thisUserId);
+ if (perUserExcludedPackageTags.size() <= 0) {
+ perUserExcludedPackageTags = null;
}
} else {
- perUserExcludedPackages.put(thisUserId, excludedPackages);
+ Map<String, String[]> userExcludedPackageTags =
+ perUserExcludedPackageTags.get(thisUserId);
+ if (userExcludedPackageTags == null) {
+ userExcludedPackageTags = new ArrayMap<>(
+ excludedPackageTags.size());
+ perUserExcludedPackageTags.put(thisUserId,
+ userExcludedPackageTags);
+ }
+ userExcludedPackageTags.clear();
+ userExcludedPackageTags.putAll(excludedPackageTags);
}
changed = true;
}
@@ -6878,7 +6902,8 @@
return changed;
}
- public boolean hasRestriction(int restriction, String packageName, int userId) {
+ public boolean hasRestriction(int restriction, String packageName, String attributionTag,
+ int userId) {
if (perUserRestrictions == null) {
return false;
}
@@ -6889,21 +6914,29 @@
if (!restrictions[restriction]) {
return false;
}
- if (perUserExcludedPackages == null) {
+ if (perUserExcludedPackageTags == null) {
return true;
}
- String[] perUserExclusions = perUserExcludedPackages.get(userId);
+ Map<String, String[]> perUserExclusions = perUserExcludedPackageTags.get(userId);
if (perUserExclusions == null) {
return true;
}
- return !ArrayUtils.contains(perUserExclusions, packageName);
+ String[] excludedTags = perUserExclusions.get(packageName);
+ if (excludedTags == null) {
+ return true;
+ }
+ if (excludedTags.length == 0) {
+ // all attribution tags within the package are excluded
+ return false;
+ }
+ return !ArrayUtils.contains(excludedTags, attributionTag);
}
public void removeUser(int userId) {
- if (perUserExcludedPackages != null) {
- perUserExcludedPackages.remove(userId);
- if (perUserExcludedPackages.size() <= 0) {
- perUserExcludedPackages = null;
+ if (perUserExcludedPackageTags != null) {
+ perUserExcludedPackageTags.remove(userId);
+ if (perUserExcludedPackageTags.size() <= 0) {
+ perUserExcludedPackageTags = null;
}
}
if (perUserRestrictions != null) {
@@ -7135,23 +7168,25 @@
return mCheckOpsDelegate;
}
- public int checkOperation(int code, int uid, String packageName, boolean raw) {
+ public int checkOperation(int code, int uid, String packageName,
+ @Nullable String attributionTag, boolean raw) {
if (mPolicy != null) {
if (mCheckOpsDelegate != null) {
- return mPolicy.checkOperation(code, uid, packageName, raw,
+ return mPolicy.checkOperation(code, uid, packageName, attributionTag, raw,
this::checkDelegateOperationImpl);
} else {
- return mPolicy.checkOperation(code, uid, packageName, raw,
+ return mPolicy.checkOperation(code, uid, packageName, attributionTag, raw,
AppOpsService.this::checkOperationImpl);
}
} else if (mCheckOpsDelegate != null) {
- return checkDelegateOperationImpl(code, uid, packageName, raw);
+ return checkDelegateOperationImpl(code, uid, packageName, attributionTag, raw);
}
- return checkOperationImpl(code, uid, packageName, raw);
+ return checkOperationImpl(code, uid, packageName, attributionTag, raw);
}
- private int checkDelegateOperationImpl(int code, int uid, String packageName, boolean raw) {
- return mCheckOpsDelegate.checkOperation(code, uid, packageName, raw,
+ private int checkDelegateOperationImpl(int code, int uid, String packageName,
+ @Nullable String attributionTag, boolean raw) {
+ return mCheckOpsDelegate.checkOperation(code, uid, packageName, attributionTag, raw,
AppOpsService.this::checkOperationImpl);
}
diff --git a/services/core/java/com/android/server/location/LocationManagerService.java b/services/core/java/com/android/server/location/LocationManagerService.java
index 8829fa9..1e8d904 100644
--- a/services/core/java/com/android/server/location/LocationManagerService.java
+++ b/services/core/java/com/android/server/location/LocationManagerService.java
@@ -139,6 +139,7 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import java.util.Map;
import java.util.Objects;
import java.util.concurrent.CopyOnWriteArrayList;
@@ -1405,21 +1406,28 @@
Preconditions.checkArgument(userId >= 0);
-
boolean enabled = mInjector.getSettingsHelper().isLocationEnabled(userId);
- String[] allowedPackages = null;
+ ArrayMap<String, String[]> allowedPackages = null;
if (!enabled) {
- ArraySet<String> packages = new ArraySet<>();
+ ArrayMap<String, ArraySet<String>> packages = new ArrayMap<>();
for (LocationProviderManager manager : mProviderManagers) {
CallerIdentity identity = manager.getIdentity();
if (identity != null) {
- packages.add(identity.getPackageName());
+ packages.computeIfAbsent(identity.getPackageName(), k -> new ArraySet<>()).add(
+ identity.getAttributionTag());
}
}
- packages.add(mContext.getPackageName());
- packages.addAll(mInjector.getSettingsHelper().getIgnoreSettingsPackageWhitelist());
- allowedPackages = packages.toArray(new String[0]);
+ for (String packageName :
+ mInjector.getSettingsHelper().getIgnoreSettingsPackageWhitelist()) {
+ packages.computeIfAbsent(packageName, k -> new ArraySet<>());
+ }
+ packages.computeIfAbsent(mContext.getPackageName(), k -> new ArraySet<>());
+
+ allowedPackages = new ArrayMap<>();
+ for (Map.Entry<String, ArraySet<String>> entry : packages.entrySet()) {
+ allowedPackages.put(entry.getKey(), entry.getValue().toArray(new String[0]));
+ }
}
AppOpsManager appOpsManager = Objects.requireNonNull(
diff --git a/services/core/java/com/android/server/location/LocationShellCommand.java b/services/core/java/com/android/server/location/LocationShellCommand.java
index 5dc3ed8..9378493 100644
--- a/services/core/java/com/android/server/location/LocationShellCommand.java
+++ b/services/core/java/com/android/server/location/LocationShellCommand.java
@@ -20,6 +20,7 @@
import android.location.Criteria;
import android.location.Location;
import android.location.provider.ProviderProperties;
+import android.os.SystemClock;
import android.os.UserHandle;
import com.android.modules.utils.BasicShellCommandHandler;
@@ -236,7 +237,7 @@
Location location = new Location(provider);
location.setAccuracy(DEFAULT_TEST_LOCATION_ACCURACY);
location.setTime(System.currentTimeMillis());
- location.setElapsedRealtimeNanos(System.nanoTime());
+ location.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());
do {
String option = getNextOption();
diff --git a/services/core/java/com/android/server/policy/AppOpsPolicy.java b/services/core/java/com/android/server/policy/AppOpsPolicy.java
index 3a097a7..2cfbf26 100644
--- a/services/core/java/com/android/server/policy/AppOpsPolicy.java
+++ b/services/core/java/com/android/server/policy/AppOpsPolicy.java
@@ -44,6 +44,7 @@
import com.android.internal.util.function.NonaFunction;
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.LocalServices;
@@ -140,9 +141,10 @@
}
@Override
- public int checkOperation(int code, int uid, String packageName, boolean raw,
- QuadFunction<Integer, Integer, String, Boolean, Integer> superImpl) {
- return superImpl.apply(code, uid, packageName, raw);
+ public int checkOperation(int code, int uid, String packageName,
+ @Nullable String attributionTag, boolean raw,
+ QuintFunction<Integer, Integer, String, String, Boolean, Integer> superImpl) {
+ return superImpl.apply(code, uid, packageName, attributionTag, raw);
}
@Override
diff --git a/services/core/java/com/android/server/vr/VrManagerService.java b/services/core/java/com/android/server/vr/VrManagerService.java
index ae873e2..2ac50b6 100644
--- a/services/core/java/com/android/server/vr/VrManagerService.java
+++ b/services/core/java/com/android/server/vr/VrManagerService.java
@@ -66,7 +66,6 @@
import com.android.server.LocalServices;
import com.android.server.SystemConfig;
import com.android.server.SystemService;
-import com.android.server.SystemService.TargetUser;
import com.android.server.utils.ManagedApplicationService;
import com.android.server.utils.ManagedApplicationService.BinderChecker;
import com.android.server.utils.ManagedApplicationService.LogEvent;
@@ -86,6 +85,7 @@
import java.util.Collection;
import java.util.Date;
import java.util.List;
+import java.util.Map;
import java.util.Objects;
/**
@@ -856,12 +856,15 @@
// If user changed drop restrictions for the old user.
if (oldUserId != newUserId) {
appOpsManager.setUserRestrictionForUser(AppOpsManager.OP_SYSTEM_ALERT_WINDOW,
- false, mOverlayToken, null, oldUserId);
+ false, mOverlayToken, (Map<String, String[]>) null, oldUserId);
}
// Apply the restrictions for the current user based on vr state
- String[] exemptions = (exemptedPackage == null) ? new String[0] :
- new String[] { exemptedPackage };
+ ArrayMap<String, String[]> exemptions = null;
+ if (exemptedPackage != null) {
+ exemptions = new ArrayMap<>(1);
+ exemptions.put(exemptedPackage, new String[0]);
+ }
appOpsManager.setUserRestrictionForUser(AppOpsManager.OP_SYSTEM_ALERT_WINDOW,
mVrModeEnabled, mOverlayToken, exemptions, newUserId);