Check cross-user interactions for permissions and app-ops operations
We want to be quite permissive here as without being able to check
permissions or appops nothing else works. Hence allow cross-user
interactions if any cross-user permission is granted.
Also we need to prevent infinite recursion as we are checking permission
and appops inside of permission and app-op checks.
Test: atest CtsPermissionHostTestCases CtsAppOpHostTestCases which
execute the new paths for both full users and profiles
Fixes: 153996875
Change-Id: I04256a51e7f6c3658000ca7941654aea698b3199
This commit is contained in:
@@ -52,14 +52,23 @@ public abstract class ActivityManagerInternal {
|
||||
* if in the same profile group.
|
||||
* Otherwise, {@link android.Manifest.permission#INTERACT_ACROSS_USERS_FULL} is required.
|
||||
*/
|
||||
public static final int ALLOW_NON_FULL_IN_PROFILE = 1;
|
||||
public static final int ALLOW_NON_FULL_IN_PROFILE_OR_FULL = 1;
|
||||
public static final int ALLOW_FULL_ONLY = 2;
|
||||
/**
|
||||
* Allows access to a caller with {@link android.Manifest.permission#INTERACT_ACROSS_PROFILES}
|
||||
* or {@link android.Manifest.permission#INTERACT_ACROSS_USERS} if in the same profile group.
|
||||
* Otherwise, {@link android.Manifest.permission#INTERACT_ACROSS_USERS_FULL} is required.
|
||||
*/
|
||||
public static final int ALLOW_ALL_PROFILE_PERMISSIONS_IN_PROFILE = 3;
|
||||
public static final int ALLOW_ACROSS_PROFILES_IN_PROFILE_OR_FULL = 3;
|
||||
/**
|
||||
* Requires {@link android.Manifest.permission#INTERACT_ACROSS_PROFILES},
|
||||
* {@link android.Manifest.permission#INTERACT_ACROSS_USERS}, or
|
||||
* {@link android.Manifest.permission#INTERACT_ACROSS_USERS_FULL} if in same profile group,
|
||||
* otherwise {@link android.Manifest.permission#INTERACT_ACROSS_USERS} or
|
||||
* {@link android.Manifest.permission#INTERACT_ACROSS_USERS_FULL}. (so this is an extension
|
||||
* to {@link #ALLOW_NON_FULL})
|
||||
*/
|
||||
public static final int ALLOW_ACROSS_PROFILES_IN_PROFILE_OR_NON_FULL = 4;
|
||||
|
||||
/**
|
||||
* Verify that calling app has access to the given provider.
|
||||
|
||||
@@ -2559,12 +2559,12 @@ public final class ActiveServices {
|
||||
|
||||
private int getAllowMode(Intent service, @Nullable String callingPackage) {
|
||||
if (callingPackage == null || service.getComponent() == null) {
|
||||
return ActivityManagerInternal.ALLOW_NON_FULL_IN_PROFILE;
|
||||
return ActivityManagerInternal.ALLOW_NON_FULL_IN_PROFILE_OR_FULL;
|
||||
}
|
||||
if (callingPackage.equals(service.getComponent().getPackageName())) {
|
||||
return ActivityManagerInternal.ALLOW_ALL_PROFILE_PERMISSIONS_IN_PROFILE;
|
||||
return ActivityManagerInternal.ALLOW_ACROSS_PROFILES_IN_PROFILE_OR_FULL;
|
||||
} else {
|
||||
return ActivityManagerInternal.ALLOW_NON_FULL_IN_PROFILE;
|
||||
return ActivityManagerInternal.ALLOW_NON_FULL_IN_PROFILE_OR_FULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,10 +23,11 @@ import static android.app.ActivityManager.USER_OP_ERROR_IS_SYSTEM;
|
||||
import static android.app.ActivityManager.USER_OP_ERROR_RELATED_USERS_CANNOT_STOP;
|
||||
import static android.app.ActivityManager.USER_OP_IS_CURRENT;
|
||||
import static android.app.ActivityManager.USER_OP_SUCCESS;
|
||||
import static android.app.ActivityManagerInternal.ALLOW_ALL_PROFILE_PERMISSIONS_IN_PROFILE;
|
||||
import static android.app.ActivityManagerInternal.ALLOW_ACROSS_PROFILES_IN_PROFILE_OR_NON_FULL;
|
||||
import static android.app.ActivityManagerInternal.ALLOW_ACROSS_PROFILES_IN_PROFILE_OR_FULL;
|
||||
import static android.app.ActivityManagerInternal.ALLOW_FULL_ONLY;
|
||||
import static android.app.ActivityManagerInternal.ALLOW_NON_FULL;
|
||||
import static android.app.ActivityManagerInternal.ALLOW_NON_FULL_IN_PROFILE;
|
||||
import static android.app.ActivityManagerInternal.ALLOW_NON_FULL_IN_PROFILE_OR_FULL;
|
||||
import static android.os.Process.SHELL_UID;
|
||||
import static android.os.Process.SYSTEM_UID;
|
||||
|
||||
@@ -1909,11 +1910,12 @@ class UserController implements Handler.Callback {
|
||||
callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
|
||||
// If the caller does not have either permission, they are always doomed.
|
||||
allow = false;
|
||||
} else if (allowMode == ALLOW_NON_FULL) {
|
||||
} else if (allowMode == ALLOW_NON_FULL
|
||||
|| allowMode == ALLOW_ACROSS_PROFILES_IN_PROFILE_OR_NON_FULL) {
|
||||
// We are blanket allowing non-full access, you lucky caller!
|
||||
allow = true;
|
||||
} else if (allowMode == ALLOW_NON_FULL_IN_PROFILE
|
||||
|| allowMode == ALLOW_ALL_PROFILE_PERMISSIONS_IN_PROFILE) {
|
||||
} else if (allowMode == ALLOW_NON_FULL_IN_PROFILE_OR_FULL
|
||||
|| allowMode == ALLOW_ACROSS_PROFILES_IN_PROFILE_OR_FULL) {
|
||||
// We may or may not allow this depending on whether the two users are
|
||||
// in the same profile.
|
||||
allow = isSameProfileGroup;
|
||||
@@ -1940,12 +1942,15 @@ class UserController implements Handler.Callback {
|
||||
builder.append("; this requires ");
|
||||
builder.append(INTERACT_ACROSS_USERS_FULL);
|
||||
if (allowMode != ALLOW_FULL_ONLY) {
|
||||
if (allowMode == ALLOW_NON_FULL || isSameProfileGroup) {
|
||||
if (allowMode == ALLOW_NON_FULL
|
||||
|| allowMode == ALLOW_ACROSS_PROFILES_IN_PROFILE_OR_NON_FULL
|
||||
|| isSameProfileGroup) {
|
||||
builder.append(" or ");
|
||||
builder.append(INTERACT_ACROSS_USERS);
|
||||
}
|
||||
if (isSameProfileGroup
|
||||
&& allowMode == ALLOW_ALL_PROFILE_PERMISSIONS_IN_PROFILE) {
|
||||
&& (allowMode == ALLOW_ACROSS_PROFILES_IN_PROFILE_OR_FULL
|
||||
|| allowMode == ALLOW_ACROSS_PROFILES_IN_PROFILE_OR_NON_FULL)) {
|
||||
builder.append(" or ");
|
||||
builder.append(INTERACT_ACROSS_PROFILES);
|
||||
}
|
||||
@@ -1972,7 +1977,8 @@ class UserController implements Handler.Callback {
|
||||
private boolean canInteractWithAcrossProfilesPermission(
|
||||
int allowMode, boolean isSameProfileGroup, int callingPid, int callingUid,
|
||||
String callingPackage) {
|
||||
if (allowMode != ALLOW_ALL_PROFILE_PERMISSIONS_IN_PROFILE) {
|
||||
if (allowMode != ALLOW_ACROSS_PROFILES_IN_PROFILE_OR_FULL
|
||||
&& allowMode != ALLOW_ACROSS_PROFILES_IN_PROFILE_OR_NON_FULL) {
|
||||
return false;
|
||||
}
|
||||
if (!isSameProfileGroup) {
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.android.server.appop;
|
||||
import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_CAMERA;
|
||||
import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_LOCATION;
|
||||
import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_MICROPHONE;
|
||||
import static android.app.ActivityManagerInternal.ALLOW_ACROSS_PROFILES_IN_PROFILE_OR_NON_FULL;
|
||||
import static android.app.AppOpsManager.CALL_BACK_ON_SWITCHED_OP;
|
||||
import static android.app.AppOpsManager.FILTER_BY_ATTRIBUTION_TAG;
|
||||
import static android.app.AppOpsManager.FILTER_BY_OP_NAMES;
|
||||
@@ -128,6 +129,7 @@ import android.provider.Settings;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.ArraySet;
|
||||
import android.util.AtomicFile;
|
||||
import android.util.EventLog;
|
||||
import android.util.KeyValueListParser;
|
||||
import android.util.LongSparseArray;
|
||||
import android.util.Pair;
|
||||
@@ -161,6 +163,7 @@ import com.android.server.LocalServices;
|
||||
import com.android.server.LockGuard;
|
||||
import com.android.server.SystemServerInitThreadPool;
|
||||
import com.android.server.SystemServiceManager;
|
||||
import com.android.server.am.ActivityManagerService;
|
||||
import com.android.server.pm.PackageList;
|
||||
import com.android.server.pm.parsing.pkg.AndroidPackage;
|
||||
|
||||
@@ -2197,8 +2200,11 @@ public class AppOpsService extends IAppOpsService.Stub {
|
||||
+ " by uid " + Binder.getCallingUid());
|
||||
}
|
||||
|
||||
int userId = UserHandle.getUserId(uid);
|
||||
|
||||
enforceManageAppOpsModes(Binder.getCallingPid(), Binder.getCallingUid(), uid);
|
||||
verifyIncomingOp(code);
|
||||
verifyIncomingUser(userId);
|
||||
code = AppOpsManager.opToSwitch(code);
|
||||
|
||||
if (permissionPolicyCallback == null) {
|
||||
@@ -2443,8 +2449,12 @@ public class AppOpsService extends IAppOpsService.Stub {
|
||||
private void setMode(int code, int uid, @NonNull String packageName, int mode,
|
||||
@Nullable IAppOpsCallback permissionPolicyCallback) {
|
||||
enforceManageAppOpsModes(Binder.getCallingPid(), Binder.getCallingUid(), uid);
|
||||
|
||||
int userId = UserHandle.getUserId(uid);
|
||||
|
||||
verifyIncomingOp(code);
|
||||
verifyIncomingPackage(packageName, UserHandle.getUserId(uid));
|
||||
verifyIncomingUser(userId);
|
||||
verifyIncomingPackage(packageName, userId);
|
||||
|
||||
ArraySet<ModeCallback> repCbs = null;
|
||||
code = AppOpsManager.opToSwitch(code);
|
||||
@@ -2857,8 +2867,11 @@ public class AppOpsService extends IAppOpsService.Stub {
|
||||
|
||||
private int checkOperationImpl(int code, int uid, String packageName,
|
||||
boolean raw) {
|
||||
int userId = UserHandle.getUserId(uid);
|
||||
|
||||
verifyIncomingOp(code);
|
||||
verifyIncomingPackage(packageName, UserHandle.getUserId(uid));
|
||||
verifyIncomingUser(userId);
|
||||
verifyIncomingPackage(packageName, userId);
|
||||
|
||||
String resolvedPackageName = resolvePackageName(uid, packageName);
|
||||
if (resolvedPackageName == null) {
|
||||
@@ -2977,10 +2990,15 @@ public class AppOpsService extends IAppOpsService.Stub {
|
||||
String proxiedAttributionTag, int proxyUid, String proxyPackageName,
|
||||
String proxyAttributionTag, boolean shouldCollectAsyncNotedOp, String message,
|
||||
boolean shouldCollectMessage) {
|
||||
int proxiedUserId = UserHandle.getUserId(proxiedUid);
|
||||
int proxyUserId = UserHandle.getUserId(proxyUid);
|
||||
|
||||
verifyIncomingUid(proxyUid);
|
||||
verifyIncomingOp(code);
|
||||
verifyIncomingPackage(proxiedPackageName, UserHandle.getUserId(proxiedUid));
|
||||
verifyIncomingPackage(proxyPackageName, UserHandle.getUserId(proxyUid));
|
||||
verifyIncomingUser(proxiedUserId);
|
||||
verifyIncomingUser(proxyUserId);
|
||||
verifyIncomingPackage(proxiedPackageName, proxiedUserId);
|
||||
verifyIncomingPackage(proxyPackageName, proxyUserId);
|
||||
|
||||
String resolveProxyPackageName = resolvePackageName(proxyUid, proxyPackageName);
|
||||
if (resolveProxyPackageName == null) {
|
||||
@@ -3030,9 +3048,12 @@ public class AppOpsService extends IAppOpsService.Stub {
|
||||
private int noteOperationImpl(int code, int uid, @Nullable String packageName,
|
||||
@Nullable String attributionTag, boolean shouldCollectAsyncNotedOp,
|
||||
@Nullable String message, boolean shouldCollectMessage) {
|
||||
int userId = UserHandle.getUserId(uid);
|
||||
|
||||
verifyIncomingUid(uid);
|
||||
verifyIncomingOp(code);
|
||||
verifyIncomingPackage(packageName, UserHandle.getUserId(uid));
|
||||
verifyIncomingUser(userId);
|
||||
verifyIncomingPackage(packageName, userId);
|
||||
|
||||
String resolvedPackageName = resolvePackageName(uid, packageName);
|
||||
if (resolvedPackageName == null) {
|
||||
@@ -3409,9 +3430,12 @@ public class AppOpsService extends IAppOpsService.Stub {
|
||||
public int startOperation(IBinder clientId, int code, int uid, String packageName,
|
||||
String attributionTag, boolean startIfModeDefault, boolean shouldCollectAsyncNotedOp,
|
||||
String message, boolean shouldCollectMessage) {
|
||||
int userId = UserHandle.getUserId(uid);
|
||||
|
||||
verifyIncomingUid(uid);
|
||||
verifyIncomingOp(code);
|
||||
verifyIncomingPackage(packageName, UserHandle.getUserId(uid));
|
||||
verifyIncomingUser(userId);
|
||||
verifyIncomingPackage(packageName, userId);
|
||||
|
||||
String resolvedPackageName = resolvePackageName(uid, packageName);
|
||||
if (resolvedPackageName == null) {
|
||||
@@ -3491,9 +3515,12 @@ public class AppOpsService extends IAppOpsService.Stub {
|
||||
@Override
|
||||
public void finishOperation(IBinder clientId, int code, int uid, String packageName,
|
||||
String attributionTag) {
|
||||
int userId = UserHandle.getUserId(uid);
|
||||
|
||||
verifyIncomingUid(uid);
|
||||
verifyIncomingOp(code);
|
||||
verifyIncomingPackage(packageName, UserHandle.getUserId(uid));
|
||||
verifyIncomingUser(userId);
|
||||
verifyIncomingPackage(packageName, userId);
|
||||
|
||||
String resolvedPackageName = resolvePackageName(uid, packageName);
|
||||
if (resolvedPackageName == null) {
|
||||
@@ -3722,6 +3749,33 @@ public class AppOpsService extends IAppOpsService.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
private void verifyIncomingUser(@UserIdInt int userId) {
|
||||
int callingUid = Binder.getCallingUid();
|
||||
int callingUserId = UserHandle.getUserId(callingUid);
|
||||
int callingPid = Binder.getCallingPid();
|
||||
|
||||
if (callingUserId != userId) {
|
||||
// Prevent endless loop between when checking appops inside of handleIncomingUser
|
||||
if (Binder.getCallingPid() == ActivityManagerService.MY_PID) {
|
||||
return;
|
||||
}
|
||||
long token = Binder.clearCallingIdentity();
|
||||
try {
|
||||
try {
|
||||
LocalServices.getService(ActivityManagerInternal.class).handleIncomingUser(
|
||||
callingPid, callingUid, userId, /* allowAll */ false,
|
||||
ALLOW_ACROSS_PROFILES_IN_PROFILE_OR_NON_FULL, "appop operation", null);
|
||||
} catch (Exception e) {
|
||||
EventLog.writeEvent(0x534e4554, "153996875", "appop", userId);
|
||||
|
||||
throw e;
|
||||
}
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(token);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private @Nullable UidState getUidStateLocked(int uid, boolean edit) {
|
||||
UidState uidState = mUidStates.get(uid);
|
||||
if (uidState == null) {
|
||||
@@ -5801,8 +5855,11 @@ public class AppOpsService extends IAppOpsService.Stub {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
int userId = UserHandle.getUserId(uid);
|
||||
|
||||
verifyIncomingOp(code);
|
||||
verifyIncomingPackage(packageName, UserHandle.getUserId(uid));
|
||||
verifyIncomingUser(userId);
|
||||
verifyIncomingPackage(packageName, userId);
|
||||
|
||||
final String resolvedPackageName = resolvePackageName(uid, packageName);
|
||||
if (resolvedPackageName == null) {
|
||||
|
||||
@@ -6,6 +6,9 @@
|
||||
{
|
||||
"name": "CtsAppOps2TestCases"
|
||||
},
|
||||
{
|
||||
"name": "CtsAppOpHostTestCases"
|
||||
},
|
||||
{
|
||||
"name": "FrameworksServicesTests",
|
||||
"options": [
|
||||
|
||||
@@ -137,6 +137,7 @@ import com.android.server.LocalServices;
|
||||
import com.android.server.ServiceThread;
|
||||
import com.android.server.SystemConfig;
|
||||
import com.android.server.Watchdog;
|
||||
import com.android.server.am.ActivityManagerService;
|
||||
import com.android.server.pm.ApexManager;
|
||||
import com.android.server.pm.PackageManagerServiceUtils;
|
||||
import com.android.server.pm.PackageSetting;
|
||||
@@ -920,6 +921,16 @@ public class PermissionManagerService extends IPermissionManager.Stub {
|
||||
}
|
||||
|
||||
final int uid = UserHandle.getUid(userId, pkg.getUid());
|
||||
|
||||
try {
|
||||
enforceCrossUserOrProfilePermission(Binder.getCallingUid(), UserHandle.getUserId(uid),
|
||||
false, false, "checkPermissionInternal");
|
||||
} catch (Exception e) {
|
||||
EventLog.writeEvent(0x534e4554, "153996875", "checkPermission", uid);
|
||||
|
||||
throw e;
|
||||
}
|
||||
|
||||
final PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting(
|
||||
pkg.getPackageName());
|
||||
if (ps == null) {
|
||||
@@ -4414,7 +4425,7 @@ public class PermissionManagerService extends IPermissionManager.Stub {
|
||||
}
|
||||
final int callingUserId = UserHandle.getUserId(callingUid);
|
||||
if (hasCrossUserPermission(
|
||||
callingUid, callingUserId, userId, requireFullPermission,
|
||||
Binder.getCallingPid(), callingUid, callingUserId, userId, requireFullPermission,
|
||||
requirePermissionWhenSameUser)) {
|
||||
return;
|
||||
}
|
||||
@@ -4441,37 +4452,54 @@ public class PermissionManagerService extends IPermissionManager.Stub {
|
||||
private void enforceCrossUserOrProfilePermission(int callingUid, int userId,
|
||||
boolean requireFullPermission, boolean checkShell,
|
||||
String message) {
|
||||
int callingPid = Binder.getCallingPid();
|
||||
final int callingUserId = UserHandle.getUserId(callingUid);
|
||||
|
||||
if (userId < 0) {
|
||||
throw new IllegalArgumentException("Invalid userId " + userId);
|
||||
}
|
||||
if (checkShell) {
|
||||
PackageManagerServiceUtils.enforceShellRestriction(mUserManagerInt,
|
||||
UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
|
||||
}
|
||||
final int callingUserId = UserHandle.getUserId(callingUid);
|
||||
if (hasCrossUserPermission(callingUid, callingUserId, userId, requireFullPermission,
|
||||
/*requirePermissionWhenSameUser= */ false)) {
|
||||
|
||||
if (callingUserId == userId) {
|
||||
return;
|
||||
}
|
||||
final boolean isSameProfileGroup = isSameProfileGroup(callingUserId, userId);
|
||||
if (isSameProfileGroup && PermissionChecker.checkPermissionForPreflight(
|
||||
mContext,
|
||||
android.Manifest.permission.INTERACT_ACROSS_PROFILES,
|
||||
PermissionChecker.PID_UNKNOWN,
|
||||
callingUid,
|
||||
mPackageManagerInt.getPackage(callingUid).getPackageName())
|
||||
== PermissionChecker.PERMISSION_GRANTED) {
|
||||
|
||||
// Prevent endless loop between when checking permission while checking a permission
|
||||
if (callingPid == ActivityManagerService.MY_PID) {
|
||||
return;
|
||||
}
|
||||
String errorMessage = buildInvalidCrossUserOrProfilePermissionMessage(
|
||||
message, requireFullPermission, isSameProfileGroup);
|
||||
Slog.w(TAG, errorMessage);
|
||||
throw new SecurityException(errorMessage);
|
||||
|
||||
long token = Binder.clearCallingIdentity();
|
||||
try {
|
||||
if (checkShell) {
|
||||
PackageManagerServiceUtils.enforceShellRestriction(mUserManagerInt,
|
||||
UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
|
||||
}
|
||||
if (hasCrossUserPermission(callingPid, callingUid, callingUserId, userId,
|
||||
requireFullPermission, /*requirePermissionWhenSameUser= */ false)) {
|
||||
return;
|
||||
}
|
||||
final boolean isSameProfileGroup = isSameProfileGroup(callingUserId, userId);
|
||||
if (isSameProfileGroup && PermissionChecker.checkPermissionForPreflight(
|
||||
mContext,
|
||||
android.Manifest.permission.INTERACT_ACROSS_PROFILES,
|
||||
PermissionChecker.PID_UNKNOWN,
|
||||
callingUid,
|
||||
mPackageManagerInt.getPackage(callingUid).getPackageName())
|
||||
== PermissionChecker.PERMISSION_GRANTED) {
|
||||
return;
|
||||
}
|
||||
|
||||
String errorMessage = buildInvalidCrossUserOrProfilePermissionMessage(
|
||||
message, requireFullPermission, isSameProfileGroup);
|
||||
Slog.w(TAG, errorMessage);
|
||||
throw new SecurityException(errorMessage);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(token);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hasCrossUserPermission(
|
||||
int callingUid, int callingUserId, int userId, boolean requireFullPermission,
|
||||
boolean requirePermissionWhenSameUser) {
|
||||
private boolean hasCrossUserPermission(int callingPid, int callingUid, int callingUserId,
|
||||
int userId, boolean requireFullPermission, boolean requirePermissionWhenSameUser) {
|
||||
if (!requirePermissionWhenSameUser && userId == callingUserId) {
|
||||
return true;
|
||||
}
|
||||
@@ -4479,15 +4507,11 @@ public class PermissionManagerService extends IPermissionManager.Stub {
|
||||
return true;
|
||||
}
|
||||
if (requireFullPermission) {
|
||||
return hasPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL);
|
||||
return mContext.checkPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL,
|
||||
callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
|
||||
}
|
||||
return hasPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
|
||||
|| hasPermission(Manifest.permission.INTERACT_ACROSS_USERS);
|
||||
}
|
||||
|
||||
private boolean hasPermission(String permission) {
|
||||
return mContext.checkCallingOrSelfPermission(permission)
|
||||
== PackageManager.PERMISSION_GRANTED;
|
||||
return mContext.checkPermission(android.Manifest.permission.INTERACT_ACROSS_USERS,
|
||||
callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
|
||||
}
|
||||
|
||||
private boolean isSameProfileGroup(@UserIdInt int callerUserId, @UserIdInt int userId) {
|
||||
|
||||
@@ -17,14 +17,6 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "CtsAppSecurityHostTestCases",
|
||||
"options": [
|
||||
{
|
||||
"include-filter": "android.appsecurity.cts.AppSecurityTests#rebootWithDuplicatePermission"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "CtsPermission2TestCases",
|
||||
"options": [
|
||||
@@ -36,6 +28,17 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "CtsPermissionHostTestCases"
|
||||
},
|
||||
{
|
||||
"name": "CtsAppSecurityHostTestCases",
|
||||
"options": [
|
||||
{
|
||||
"include-filter": "android.appsecurity.cts.AppSecurityTests#rebootWithDuplicatePermission"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "CtsStatsdHostTestCases",
|
||||
"options": [
|
||||
|
||||
Reference in New Issue
Block a user