Add CrossProfileAppsInternal#getTargetUserProfiles
This will be used by the logic that updates the app bucket state of cross-profile connected apps that declare the crossProfile manifest attribute. Also makes the following changes: - Fixes CrossProfileAppsServiceImplRoboTest by registering the local service in a different way. - Removes some code duplication in CrossProfileAppsServiceImpl. - Some clean-up. Robolectric tests will be added later. Right now, there seems to be a problem causing log messages not to appear, making debugging impossible. Bug: 140808123 Bug: 136249261 Test: atest com.android.server.pm.CrossProfileAppsServiceImplRoboTest Change-Id: Iefa6b2a7cb7535d5796d5ca8916c10b29c2e0661
This commit is contained in:
@@ -17,6 +17,9 @@
|
||||
package android.content.pm;
|
||||
|
||||
import android.annotation.UserIdInt;
|
||||
import android.os.UserHandle;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Exposes internal methods from {@link com.android.server.pm.CrossProfileAppsServiceImpl} to other
|
||||
@@ -52,4 +55,11 @@ public abstract class CrossProfileAppsInternal {
|
||||
*/
|
||||
public abstract boolean verifyUidHasInteractAcrossProfilePermission(String packageName,
|
||||
int uid);
|
||||
|
||||
/**
|
||||
* Returns the list of target user profiles for the given package on the given user. See {@link
|
||||
* CrossProfileApps#getTargetUserProfiles()}.
|
||||
*/
|
||||
public abstract List<UserHandle> getTargetUserProfiles(
|
||||
String packageName, @UserIdInt int userId);
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package com.android.server.pm;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.CrossProfileAppsInternal;
|
||||
|
||||
import com.android.server.SystemService;
|
||||
|
||||
@@ -30,5 +31,6 @@ public class CrossProfileAppsService extends SystemService {
|
||||
@Override
|
||||
public void onStart() {
|
||||
publishBinderService(Context.CROSS_PROFILE_APPS_SERVICE, mServiceImpl);
|
||||
publishLocalService(CrossProfileAppsInternal.class, mServiceImpl.getLocalService());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,6 +66,8 @@ import java.util.Objects;
|
||||
public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub {
|
||||
private static final String TAG = "CrossProfileAppsService";
|
||||
|
||||
private final LocalService mLocalService = new LocalService();
|
||||
|
||||
private Context mContext;
|
||||
private Injector mInjector;
|
||||
|
||||
@@ -77,8 +79,6 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub {
|
||||
CrossProfileAppsServiceImpl(Context context, Injector injector) {
|
||||
mContext = context;
|
||||
mInjector = injector;
|
||||
|
||||
LocalServices.addService(CrossProfileAppsInternal.class, new LocalService());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -205,7 +205,7 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub {
|
||||
}
|
||||
|
||||
if (callerUserId != userId) {
|
||||
if (!hasInteractAcrossProfilesPermission(callingPackage)) {
|
||||
if (!hasCallerGotInteractAcrossProfilesPermission(callingPackage)) {
|
||||
throw new SecurityException("Attempt to launch activity without required "
|
||||
+ android.Manifest.permission.INTERACT_ACROSS_PROFILES + " permission"
|
||||
+ " or target user is not in the same profile group.");
|
||||
@@ -268,20 +268,12 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub {
|
||||
if (targetUserProfiles.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
return hasInteractAcrossProfilesPermission(callingPackage);
|
||||
return hasCallerGotInteractAcrossProfilesPermission(callingPackage);
|
||||
}
|
||||
|
||||
private boolean hasInteractAcrossProfilesPermission(String callingPackage) {
|
||||
final int callingUid = mInjector.getCallingUid();
|
||||
final int callingPid = mInjector.getCallingPid();
|
||||
return isPermissionGranted(Manifest.permission.INTERACT_ACROSS_USERS_FULL, callingUid)
|
||||
|| isPermissionGranted(Manifest.permission.INTERACT_ACROSS_USERS, callingUid)
|
||||
|| PermissionChecker.checkPermissionForPreflight(
|
||||
mContext,
|
||||
Manifest.permission.INTERACT_ACROSS_PROFILES,
|
||||
callingPid,
|
||||
callingUid,
|
||||
callingPackage) == PermissionChecker.PERMISSION_GRANTED;
|
||||
private boolean hasCallerGotInteractAcrossProfilesPermission(String callingPackage) {
|
||||
return hasInteractAcrossProfilesPermission(
|
||||
callingPackage, mInjector.getCallingUid(), mInjector.getCallingPid());
|
||||
}
|
||||
|
||||
private boolean isCrossProfilePackageWhitelisted(String packageName) {
|
||||
@@ -563,6 +555,10 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub {
|
||||
setInteractAcrossProfilesAppOp(packageName, AppOpsManager.opToDefaultMode(op));
|
||||
}
|
||||
|
||||
CrossProfileAppsInternal getLocalService() {
|
||||
return mLocalService;
|
||||
}
|
||||
|
||||
private boolean isSameProfileGroup(@UserIdInt int callerUserId, @UserIdInt int userId) {
|
||||
return mInjector.withCleanCallingIdentity(() ->
|
||||
mInjector.getUserManager().isSameProfileGroup(callerUserId, userId));
|
||||
@@ -589,6 +585,20 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub {
|
||||
-> mContext.getSystemService(UserManager.class).isManagedProfile(userId));
|
||||
}
|
||||
|
||||
private boolean hasInteractAcrossProfilesPermission(String packageName, int uid, int pid) {
|
||||
if (isPermissionGranted(Manifest.permission.INTERACT_ACROSS_USERS_FULL, uid)
|
||||
|| isPermissionGranted(Manifest.permission.INTERACT_ACROSS_USERS, uid)) {
|
||||
return true;
|
||||
}
|
||||
return PermissionChecker.PERMISSION_GRANTED
|
||||
== PermissionChecker.checkPermissionForPreflight(
|
||||
mContext,
|
||||
Manifest.permission.INTERACT_ACROSS_PROFILES,
|
||||
pid,
|
||||
uid,
|
||||
packageName);
|
||||
}
|
||||
|
||||
private static class InjectorImpl implements Injector {
|
||||
private Context mContext;
|
||||
|
||||
@@ -728,9 +738,11 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub {
|
||||
}
|
||||
|
||||
class LocalService extends CrossProfileAppsInternal {
|
||||
|
||||
@Override
|
||||
public boolean verifyPackageHasInteractAcrossProfilePermission(String packageName,
|
||||
@UserIdInt int userId) throws PackageManager.NameNotFoundException {
|
||||
public boolean verifyPackageHasInteractAcrossProfilePermission(
|
||||
String packageName, @UserIdInt int userId)
|
||||
throws PackageManager.NameNotFoundException {
|
||||
final int uid = Objects.requireNonNull(
|
||||
mInjector.getPackageManager().getApplicationInfoAsUser(
|
||||
Objects.requireNonNull(packageName), /* flags= */ 0, userId)).uid;
|
||||
@@ -740,16 +752,13 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub {
|
||||
@Override
|
||||
public boolean verifyUidHasInteractAcrossProfilePermission(String packageName, int uid) {
|
||||
Objects.requireNonNull(packageName);
|
||||
return hasInteractAcrossProfilesPermission(
|
||||
packageName, uid, PermissionChecker.PID_UNKNOWN);
|
||||
}
|
||||
|
||||
return isPermissionGranted(Manifest.permission.INTERACT_ACROSS_USERS_FULL, uid)
|
||||
|| isPermissionGranted(Manifest.permission.INTERACT_ACROSS_USERS, uid)
|
||||
|| isPermissionGranted(Manifest.permission.INTERACT_ACROSS_PROFILES, uid)
|
||||
|| PermissionChecker.checkPermissionForPreflight(
|
||||
mContext,
|
||||
Manifest.permission.INTERACT_ACROSS_PROFILES,
|
||||
PermissionChecker.PID_UNKNOWN,
|
||||
uid,
|
||||
packageName) == PermissionChecker.PERMISSION_GRANTED;
|
||||
@Override
|
||||
public List<UserHandle> getTargetUserProfiles(String packageName, int userId) {
|
||||
return getTargetUserProfilesUnchecked(packageName, userId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user