Merge "Add support for excluding tags from restrictions" into sc-dev am: fe40442304
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/14503384 Change-Id: Iccc7f519dfcfe9429067249dce36ade6e4f2a0f5
This commit is contained in:
@@ -7394,20 +7394,27 @@ public class AppOpsManager {
|
||||
|
||||
/** @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 class AppOpsManager {
|
||||
*/
|
||||
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();
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ import com.android.internal.util.function.HexFunction;
|
||||
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 @@ public abstract class AppOpsManagerInternal {
|
||||
* @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.
|
||||
|
||||
@@ -92,7 +92,7 @@ interface IAppOpsService {
|
||||
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 @@ interface IAppOpsService {
|
||||
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();
|
||||
|
||||
|
||||
@@ -1320,12 +1320,12 @@ public final class SensorPrivacyService extends SystemService {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -351,6 +351,7 @@ import com.android.internal.util.function.HexFunction;
|
||||
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;
|
||||
@@ -16750,19 +16751,20 @@ public class ActivityManagerService extends IActivityManager.Stub
|
||||
}
|
||||
|
||||
@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
|
||||
|
||||
@@ -3063,16 +3063,20 @@ public class AppOpsService extends IAppOpsService.Stub {
|
||||
}
|
||||
|
||||
@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));
|
||||
|
||||
@@ -3080,7 +3084,7 @@ public class AppOpsService extends IAppOpsService.Stub {
|
||||
if (resolvedPackageName == null) {
|
||||
return AppOpsManager.MODE_IGNORED;
|
||||
}
|
||||
return checkOperationUnchecked(code, uid, resolvedPackageName, raw);
|
||||
return checkOperationUnchecked(code, uid, resolvedPackageName, attributionTag, raw);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3094,7 +3098,7 @@ public class AppOpsService extends IAppOpsService.Stub {
|
||||
* @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);
|
||||
@@ -3107,7 +3111,7 @@ public class AppOpsService extends IAppOpsService.Stub {
|
||||
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);
|
||||
@@ -3326,7 +3330,7 @@ public class AppOpsService extends IAppOpsService.Stub {
|
||||
|
||||
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);
|
||||
@@ -3813,7 +3817,7 @@ public class AppOpsService extends IAppOpsService.Stub {
|
||||
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.
|
||||
@@ -4555,7 +4559,7 @@ public class AppOpsService extends IAppOpsService.Stub {
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
@@ -4563,7 +4567,7 @@ public class AppOpsService extends IAppOpsService.Stub {
|
||||
// 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
|
||||
@@ -6177,25 +6181,20 @@ public class AppOpsService extends IAppOpsService.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -6210,8 +6209,24 @@ public class AppOpsService extends IAppOpsService.Stub {
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6245,7 +6260,7 @@ public class AppOpsService extends IAppOpsService.Stub {
|
||||
|
||||
@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);
|
||||
@@ -6261,11 +6276,11 @@ public class AppOpsService extends IAppOpsService.Stub {
|
||||
}
|
||||
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);
|
||||
|
||||
@@ -6278,7 +6293,8 @@ public class AppOpsService extends IAppOpsService.Stub {
|
||||
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(
|
||||
@@ -6808,7 +6824,7 @@ public class AppOpsService extends IAppOpsService.Stub {
|
||||
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 {
|
||||
@@ -6817,7 +6833,7 @@ public class AppOpsService extends IAppOpsService.Stub {
|
||||
}
|
||||
|
||||
public boolean setRestriction(int code, boolean restricted,
|
||||
String[] excludedPackages, int userId) {
|
||||
Map<String, String[]> excludedPackageTags, int userId) {
|
||||
boolean changed = false;
|
||||
|
||||
if (perUserRestrictions == null && restricted) {
|
||||
@@ -6859,19 +6875,27 @@ public class AppOpsService extends IAppOpsService.Stub {
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -6882,7 +6906,8 @@ public class AppOpsService extends IAppOpsService.Stub {
|
||||
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;
|
||||
}
|
||||
@@ -6893,21 +6918,29 @@ public class AppOpsService extends IAppOpsService.Stub {
|
||||
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) {
|
||||
@@ -7139,23 +7172,25 @@ public class AppOpsService extends IAppOpsService.Stub {
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@@ -139,6 +139,7 @@ import java.io.PrintWriter;
|
||||
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 @@ public class LocationManagerService extends ILocationManager.Stub implements
|
||||
|
||||
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(
|
||||
|
||||
@@ -20,6 +20,7 @@ import android.content.Context;
|
||||
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 @@ class LocationShellCommand extends BasicShellCommandHandler {
|
||||
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();
|
||||
|
||||
@@ -44,6 +44,7 @@ import com.android.internal.util.function.HexFunction;
|
||||
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 @@ public final class AppOpsPolicy implements AppOpsManagerInternal.CheckOpsDelegat
|
||||
}
|
||||
|
||||
@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
|
||||
|
||||
@@ -66,7 +66,6 @@ import com.android.server.FgThread;
|
||||
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.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
@@ -856,12 +856,15 @@ public class VrManagerService extends SystemService
|
||||
// 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);
|
||||
|
||||
Reference in New Issue
Block a user