Merge "Do not allow work profile to see main other profiles"
This commit is contained in:
@@ -127,9 +127,10 @@ public class LauncherApps {
|
||||
public static final String EXTRA_PIN_ITEM_REQUEST =
|
||||
"android.content.pm.extra.PIN_ITEM_REQUEST";
|
||||
|
||||
private Context mContext;
|
||||
private ILauncherApps mService;
|
||||
private PackageManager mPm;
|
||||
private final Context mContext;
|
||||
private final ILauncherApps mService;
|
||||
private final PackageManager mPm;
|
||||
private final UserManager mUserManager;
|
||||
|
||||
private List<CallbackMessageHandler> mCallbacks
|
||||
= new ArrayList<CallbackMessageHandler>();
|
||||
@@ -387,6 +388,7 @@ public class LauncherApps {
|
||||
mContext = context;
|
||||
mService = service;
|
||||
mPm = context.getPackageManager();
|
||||
mUserManager = context.getSystemService(UserManager.class);
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
@@ -396,6 +398,16 @@ public class LauncherApps {
|
||||
ServiceManager.getService(Context.LAUNCHER_APPS_SERVICE)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show an error log on logcat, when the calling user is a managed profile, and the target
|
||||
* user is different from the calling user, in order to help developers to detect it.
|
||||
*/
|
||||
private void logErrorForInvalidProfileAccess(@NonNull UserHandle target) {
|
||||
if (UserHandle.myUserId() != target.getIdentifier() && mUserManager.isManagedProfile()) {
|
||||
Log.e(TAG, "Accessing other profiles/users from managed profile is no longer allowed.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a list of profiles that the caller can access via the {@link LauncherApps} APIs.
|
||||
*
|
||||
@@ -403,14 +415,13 @@ public class LauncherApps {
|
||||
* Otherwise it'll return the same list as {@link UserManager#getUserProfiles()} would.
|
||||
*/
|
||||
public List<UserHandle> getProfiles() {
|
||||
final UserManager um = mContext.getSystemService(UserManager.class);
|
||||
if (um.isManagedProfile()) {
|
||||
if (mUserManager.isManagedProfile()) {
|
||||
// If it's a managed profile, only return the current profile.
|
||||
final List result = new ArrayList(1);
|
||||
result.add(android.os.Process.myUserHandle());
|
||||
return result;
|
||||
} else {
|
||||
return um.getUserProfiles();
|
||||
return mUserManager.getUserProfiles();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -424,6 +435,7 @@ public class LauncherApps {
|
||||
* @return List of launchable activities. Can be an empty list but will not be null.
|
||||
*/
|
||||
public List<LauncherActivityInfo> getActivityList(String packageName, UserHandle user) {
|
||||
logErrorForInvalidProfileAccess(user);
|
||||
try {
|
||||
return convertToActivityList(mService.getLauncherActivities(mContext.getPackageName(),
|
||||
packageName, user), user);
|
||||
@@ -441,6 +453,7 @@ public class LauncherApps {
|
||||
* @return An activity info object if there is a match.
|
||||
*/
|
||||
public LauncherActivityInfo resolveActivity(Intent intent, UserHandle user) {
|
||||
logErrorForInvalidProfileAccess(user);
|
||||
try {
|
||||
ActivityInfo ai = mService.resolveActivity(mContext.getPackageName(),
|
||||
intent.getComponent(), user);
|
||||
@@ -464,6 +477,7 @@ public class LauncherApps {
|
||||
*/
|
||||
public void startMainActivity(ComponentName component, UserHandle user, Rect sourceBounds,
|
||||
Bundle opts) {
|
||||
logErrorForInvalidProfileAccess(user);
|
||||
if (DEBUG) {
|
||||
Log.i(TAG, "StartMainActivity " + component + " " + user.getIdentifier());
|
||||
}
|
||||
@@ -486,6 +500,7 @@ public class LauncherApps {
|
||||
*/
|
||||
public void startAppDetailsActivity(ComponentName component, UserHandle user,
|
||||
Rect sourceBounds, Bundle opts) {
|
||||
logErrorForInvalidProfileAccess(user);
|
||||
try {
|
||||
mService.showAppDetailsAsUser(mContext.getPackageName(),
|
||||
component, sourceBounds, opts, user);
|
||||
@@ -507,6 +522,7 @@ public class LauncherApps {
|
||||
*/
|
||||
public List<LauncherActivityInfo> getShortcutConfigActivityList(@Nullable String packageName,
|
||||
@NonNull UserHandle user) {
|
||||
logErrorForInvalidProfileAccess(user);
|
||||
try {
|
||||
return convertToActivityList(mService.getShortcutConfigActivities(
|
||||
mContext.getPackageName(), packageName, user),
|
||||
@@ -553,6 +569,7 @@ public class LauncherApps {
|
||||
* @see Intent#ACTION_CREATE_SHORTCUT
|
||||
* @see android.app.Activity#startIntentSenderForResult
|
||||
*/
|
||||
@Nullable
|
||||
public IntentSender getShortcutConfigActivityIntent(@NonNull LauncherActivityInfo info) {
|
||||
try {
|
||||
return mService.getShortcutConfigActivityIntent(
|
||||
@@ -571,6 +588,7 @@ public class LauncherApps {
|
||||
* @return true if the package exists and is enabled.
|
||||
*/
|
||||
public boolean isPackageEnabled(String packageName, UserHandle user) {
|
||||
logErrorForInvalidProfileAccess(user);
|
||||
try {
|
||||
return mService.isPackageEnabled(mContext.getPackageName(), packageName, user);
|
||||
} catch (RemoteException re) {
|
||||
@@ -591,6 +609,7 @@ public class LauncherApps {
|
||||
*/
|
||||
public ApplicationInfo getApplicationInfo(String packageName, @ApplicationInfoFlags int flags,
|
||||
UserHandle user) {
|
||||
logErrorForInvalidProfileAccess(user);
|
||||
try {
|
||||
return mService.getApplicationInfo(mContext.getPackageName(), packageName, flags, user);
|
||||
} catch (RemoteException re) {
|
||||
@@ -607,6 +626,7 @@ public class LauncherApps {
|
||||
* @return true if the activity exists and is enabled.
|
||||
*/
|
||||
public boolean isActivityEnabled(ComponentName component, UserHandle user) {
|
||||
logErrorForInvalidProfileAccess(user);
|
||||
try {
|
||||
return mService.isActivityEnabled(mContext.getPackageName(), component, user);
|
||||
} catch (RemoteException re) {
|
||||
@@ -656,6 +676,7 @@ public class LauncherApps {
|
||||
@Nullable
|
||||
public List<ShortcutInfo> getShortcuts(@NonNull ShortcutQuery query,
|
||||
@NonNull UserHandle user) {
|
||||
logErrorForInvalidProfileAccess(user);
|
||||
try {
|
||||
return mService.getShortcuts(mContext.getPackageName(),
|
||||
query.mChangedSince, query.mPackage, query.mShortcutIds, query.mActivity,
|
||||
@@ -699,6 +720,7 @@ public class LauncherApps {
|
||||
*/
|
||||
public void pinShortcuts(@NonNull String packageName, @NonNull List<String> shortcutIds,
|
||||
@NonNull UserHandle user) {
|
||||
logErrorForInvalidProfileAccess(user);
|
||||
try {
|
||||
mService.pinShortcuts(mContext.getPackageName(), packageName, shortcutIds, user);
|
||||
} catch (RemoteException e) {
|
||||
@@ -866,6 +888,8 @@ public class LauncherApps {
|
||||
public void startShortcut(@NonNull String packageName, @NonNull String shortcutId,
|
||||
@Nullable Rect sourceBounds, @Nullable Bundle startActivityOptions,
|
||||
@NonNull UserHandle user) {
|
||||
logErrorForInvalidProfileAccess(user);
|
||||
|
||||
startShortcut(packageName, shortcutId, sourceBounds, startActivityOptions,
|
||||
user.getIdentifier());
|
||||
}
|
||||
|
||||
@@ -64,6 +64,7 @@ import com.android.server.LocalServices;
|
||||
import com.android.server.SystemService;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -216,29 +217,35 @@ public class LauncherAppsService extends SystemService {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the caller is in the same group as the userToCheck.
|
||||
*/
|
||||
private void ensureInUserProfiles(
|
||||
String callingPackage, UserHandle userToCheck, String message) {
|
||||
ensureInUserProfiles(callingPackage, userToCheck.getIdentifier(), message);
|
||||
/** See {@link #canAccessProfile(String, int, String)} */
|
||||
private boolean canAccessProfile(
|
||||
String callingPackage, UserHandle targetUser, String message) {
|
||||
return canAccessProfile(callingPackage, targetUser.getIdentifier(), message);
|
||||
}
|
||||
|
||||
private void ensureInUserProfiles(String callingPackage, int targetUserId, String message) {
|
||||
/**
|
||||
* Checks if the calling user is in the same group as {@code targetUser}, and allowed
|
||||
* to access it.
|
||||
*
|
||||
* @return TRUE if the calling user can access {@code targetUserId}. FALSE if not *but
|
||||
* they're still in the same profile group*.
|
||||
*
|
||||
* @throws SecurityException if the calling user and {@code targetUser} are not in the same
|
||||
* group.
|
||||
*/
|
||||
private boolean canAccessProfile(String callingPackage, int targetUserId, String message) {
|
||||
final int callingUserId = injectCallingUserId();
|
||||
|
||||
if (targetUserId == callingUserId) return;
|
||||
if (targetUserId == callingUserId) return true;
|
||||
|
||||
long ident = injectClearCallingIdentity();
|
||||
try {
|
||||
UserInfo callingUserInfo = mUm.getUserInfo(callingUserId);
|
||||
if (callingUserInfo.isManagedProfile()) {
|
||||
// TODO: Make it SecurityException. See b/34650921
|
||||
// throw new SecurityException(message + " for another profile " + targetUserId);
|
||||
|
||||
// TODO: Report caller package name.
|
||||
Slog.wtfStack(TAG, message + " by " + callingPackage + " for another profile "
|
||||
+ targetUserId + " from " + callingUserId);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
UserInfo targetUserInfo = mUm.getUserInfo(targetUserId);
|
||||
@@ -250,6 +257,7 @@ public class LauncherAppsService extends SystemService {
|
||||
} finally {
|
||||
injectRestoreCallingIdentity(ident);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@VisibleForTesting // We override it in unit tests
|
||||
@@ -301,7 +309,9 @@ public class LauncherAppsService extends SystemService {
|
||||
public ActivityInfo resolveActivity(
|
||||
String callingPackage, ComponentName component, UserHandle user)
|
||||
throws RemoteException {
|
||||
ensureInUserProfiles(callingPackage, user, "Cannot resolve activity");
|
||||
if (!canAccessProfile(callingPackage, user, "Cannot resolve activity")) {
|
||||
return null;
|
||||
}
|
||||
if (!isUserEnabled(user)) {
|
||||
return null;
|
||||
}
|
||||
@@ -328,7 +338,9 @@ public class LauncherAppsService extends SystemService {
|
||||
|
||||
private ParceledListSlice<ResolveInfo> queryActivitiesForUser(String callingPackage,
|
||||
Intent intent, UserHandle user) {
|
||||
ensureInUserProfiles(callingPackage, user, "Cannot retrieve activities");
|
||||
if (!canAccessProfile(callingPackage, user, "Cannot retrieve activities")) {
|
||||
return null;
|
||||
}
|
||||
if (!isUserEnabled(user)) {
|
||||
return null;
|
||||
}
|
||||
@@ -348,7 +360,10 @@ public class LauncherAppsService extends SystemService {
|
||||
@Override
|
||||
public IntentSender getShortcutConfigActivityIntent(String callingPackage,
|
||||
ComponentName component, UserHandle user) throws RemoteException {
|
||||
ensureShortcutPermission(callingPackage, user);
|
||||
ensureShortcutPermission(callingPackage);
|
||||
if (!canAccessProfile(callingPackage, user, "Cannot check package")) {
|
||||
return null;
|
||||
}
|
||||
Preconditions.checkNotNull(component);
|
||||
Preconditions.checkArgument(isUserEnabled(user), "User not enabled");
|
||||
|
||||
@@ -356,11 +371,11 @@ public class LauncherAppsService extends SystemService {
|
||||
Intent intent = new Intent(Intent.ACTION_CREATE_SHORTCUT).setComponent(component);
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
return PendingIntent.getActivityAsUser(
|
||||
final PendingIntent pi = PendingIntent.getActivityAsUser(
|
||||
mContext, 0, intent, PendingIntent.FLAG_ONE_SHOT
|
||||
| PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_CANCEL_CURRENT,
|
||||
null, user)
|
||||
.getIntentSender();
|
||||
null, user);
|
||||
return pi == null ? null : pi.getIntentSender();
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
}
|
||||
@@ -369,7 +384,9 @@ public class LauncherAppsService extends SystemService {
|
||||
@Override
|
||||
public boolean isPackageEnabled(String callingPackage, String packageName, UserHandle user)
|
||||
throws RemoteException {
|
||||
ensureInUserProfiles(callingPackage, user, "Cannot check package");
|
||||
if (!canAccessProfile(callingPackage, user, "Cannot check package")) {
|
||||
return false;
|
||||
}
|
||||
if (!isUserEnabled(user)) {
|
||||
return false;
|
||||
}
|
||||
@@ -391,7 +408,9 @@ public class LauncherAppsService extends SystemService {
|
||||
public ApplicationInfo getApplicationInfo(
|
||||
String callingPackage, String packageName, int flags, UserHandle user)
|
||||
throws RemoteException {
|
||||
ensureInUserProfiles(callingPackage, user, "Cannot check package");
|
||||
if (!canAccessProfile(callingPackage, user, "Cannot check package")) {
|
||||
return null;
|
||||
}
|
||||
if (!isUserEnabled(user)) {
|
||||
return null;
|
||||
}
|
||||
@@ -407,14 +426,8 @@ public class LauncherAppsService extends SystemService {
|
||||
}
|
||||
}
|
||||
|
||||
private void ensureShortcutPermission(@NonNull String callingPackage, UserHandle user) {
|
||||
ensureShortcutPermission(callingPackage, user.getIdentifier());
|
||||
}
|
||||
|
||||
private void ensureShortcutPermission(@NonNull String callingPackage, int userId) {
|
||||
private void ensureShortcutPermission(@NonNull String callingPackage) {
|
||||
verifyCallingPackage(callingPackage);
|
||||
ensureInUserProfiles(callingPackage, userId, "Cannot access shortcuts");
|
||||
|
||||
if (!mShortcutServiceInternal.hasShortcutHostPermission(getCallingUserId(),
|
||||
callingPackage)) {
|
||||
throw new SecurityException("Caller can't access shortcut information");
|
||||
@@ -424,10 +437,11 @@ public class LauncherAppsService extends SystemService {
|
||||
@Override
|
||||
public ParceledListSlice getShortcuts(String callingPackage, long changedSince,
|
||||
String packageName, List shortcutIds, ComponentName componentName, int flags,
|
||||
UserHandle user) {
|
||||
ensureShortcutPermission(callingPackage, user);
|
||||
if (!isUserEnabled(user)) {
|
||||
return new ParceledListSlice<>(new ArrayList(0));
|
||||
UserHandle targetUser) {
|
||||
ensureShortcutPermission(callingPackage);
|
||||
if (!canAccessProfile(callingPackage, targetUser, "Cannot get shortcuts")
|
||||
|| !isUserEnabled(targetUser)) {
|
||||
return new ParceledListSlice<>(Collections.EMPTY_LIST);
|
||||
}
|
||||
if (shortcutIds != null && packageName == null) {
|
||||
throw new IllegalArgumentException(
|
||||
@@ -438,44 +452,53 @@ public class LauncherAppsService extends SystemService {
|
||||
return new ParceledListSlice<>((List<ShortcutInfo>)
|
||||
mShortcutServiceInternal.getShortcuts(getCallingUserId(),
|
||||
callingPackage, changedSince, packageName, shortcutIds,
|
||||
componentName, flags, user.getIdentifier()));
|
||||
componentName, flags, targetUser.getIdentifier()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pinShortcuts(String callingPackage, String packageName, List<String> ids,
|
||||
UserHandle user) {
|
||||
ensureShortcutPermission(callingPackage, user);
|
||||
if (!isUserEnabled(user)) {
|
||||
UserHandle targetUser) {
|
||||
ensureShortcutPermission(callingPackage);
|
||||
if (!canAccessProfile(callingPackage, targetUser, "Cannot pin shortcuts")) {
|
||||
return;
|
||||
}
|
||||
if (!isUserEnabled(targetUser)) {
|
||||
throw new IllegalStateException("Cannot pin shortcuts for disabled profile "
|
||||
+ user);
|
||||
+ targetUser);
|
||||
}
|
||||
|
||||
mShortcutServiceInternal.pinShortcuts(getCallingUserId(),
|
||||
callingPackage, packageName, ids, user.getIdentifier());
|
||||
callingPackage, packageName, ids, targetUser.getIdentifier());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getShortcutIconResId(String callingPackage, String packageName, String id,
|
||||
int userId) {
|
||||
ensureShortcutPermission(callingPackage, userId);
|
||||
if (!isUserEnabled(userId)) {
|
||||
int targetUserId) {
|
||||
ensureShortcutPermission(callingPackage);
|
||||
if (!canAccessProfile(callingPackage, targetUserId, "Cannot access shortcuts")) {
|
||||
return 0;
|
||||
}
|
||||
if (!isUserEnabled(targetUserId)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return mShortcutServiceInternal.getShortcutIconResId(getCallingUserId(),
|
||||
callingPackage, packageName, id, userId);
|
||||
callingPackage, packageName, id, targetUserId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ParcelFileDescriptor getShortcutIconFd(String callingPackage,
|
||||
String packageName, String id, int userId) {
|
||||
ensureShortcutPermission(callingPackage, userId);
|
||||
if (!isUserEnabled(userId)) {
|
||||
String packageName, String id, int targetUserId) {
|
||||
ensureShortcutPermission(callingPackage);
|
||||
if (!canAccessProfile(callingPackage, targetUserId, "Cannot access shortcuts")) {
|
||||
return null;
|
||||
}
|
||||
if (!isUserEnabled(targetUserId)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return mShortcutServiceInternal.getShortcutIconFd(getCallingUserId(),
|
||||
callingPackage, packageName, id, userId);
|
||||
callingPackage, packageName, id, targetUserId);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -487,23 +510,27 @@ public class LauncherAppsService extends SystemService {
|
||||
|
||||
@Override
|
||||
public boolean startShortcut(String callingPackage, String packageName, String shortcutId,
|
||||
Rect sourceBounds, Bundle startActivityOptions, int userId) {
|
||||
Rect sourceBounds, Bundle startActivityOptions, int targetUserId) {
|
||||
verifyCallingPackage(callingPackage);
|
||||
ensureInUserProfiles(callingPackage, userId, "Cannot start activity");
|
||||
|
||||
if (!isUserEnabled(userId)) {
|
||||
if (!canAccessProfile(callingPackage, targetUserId, "Cannot start activity")) {
|
||||
return false;
|
||||
}
|
||||
if (!canAccessProfile(callingPackage, targetUserId, "Cannot access shortcuts")) {
|
||||
return false;
|
||||
}
|
||||
if (!isUserEnabled(targetUserId)) {
|
||||
throw new IllegalStateException("Cannot start a shortcut for disabled profile "
|
||||
+ userId);
|
||||
+ targetUserId);
|
||||
}
|
||||
|
||||
// Even without the permission, pinned shortcuts are always launchable.
|
||||
if (!mShortcutServiceInternal.isPinnedByCaller(getCallingUserId(),
|
||||
callingPackage, packageName, shortcutId, userId)) {
|
||||
ensureShortcutPermission(callingPackage, userId);
|
||||
callingPackage, packageName, shortcutId, targetUserId)) {
|
||||
ensureShortcutPermission(callingPackage);
|
||||
}
|
||||
|
||||
final Intent[] intents = mShortcutServiceInternal.createShortcutIntents(
|
||||
getCallingUserId(), callingPackage, packageName, shortcutId, userId);
|
||||
getCallingUserId(), callingPackage, packageName, shortcutId, targetUserId);
|
||||
if (intents == null || intents.length == 0) {
|
||||
return false;
|
||||
}
|
||||
@@ -513,7 +540,7 @@ public class LauncherAppsService extends SystemService {
|
||||
intents[0].setSourceBounds(sourceBounds);
|
||||
|
||||
return startShortcutIntentsAsPublisher(
|
||||
intents, packageName, startActivityOptions, userId);
|
||||
intents, packageName, startActivityOptions, targetUserId);
|
||||
}
|
||||
|
||||
private boolean startShortcutIntentsAsPublisher(@NonNull Intent[] intents,
|
||||
@@ -543,7 +570,9 @@ public class LauncherAppsService extends SystemService {
|
||||
public boolean isActivityEnabled(
|
||||
String callingPackage, ComponentName component, UserHandle user)
|
||||
throws RemoteException {
|
||||
ensureInUserProfiles(callingPackage , user, "Cannot check component");
|
||||
if (!canAccessProfile(callingPackage , user, "Cannot check component")) {
|
||||
return false;
|
||||
}
|
||||
if (!isUserEnabled(user)) {
|
||||
return false;
|
||||
}
|
||||
@@ -565,7 +594,9 @@ public class LauncherAppsService extends SystemService {
|
||||
public void startActivityAsUser(String callingPackage,
|
||||
ComponentName component, Rect sourceBounds,
|
||||
Bundle opts, UserHandle user) throws RemoteException {
|
||||
ensureInUserProfiles(callingPackage, user, "Cannot start activity");
|
||||
if (!canAccessProfile(callingPackage, user, "Cannot start activity")) {
|
||||
return;
|
||||
}
|
||||
if (!isUserEnabled(user)) {
|
||||
throw new IllegalStateException("Cannot start activity for disabled profile " + user);
|
||||
}
|
||||
@@ -618,7 +649,9 @@ public class LauncherAppsService extends SystemService {
|
||||
@Override
|
||||
public void showAppDetailsAsUser(String callingPackage, ComponentName component,
|
||||
Rect sourceBounds, Bundle opts, UserHandle user) throws RemoteException {
|
||||
ensureInUserProfiles(callingPackage, user, "Cannot show app details");
|
||||
if (!canAccessProfile(callingPackage, user, "Cannot show app details")) {
|
||||
return;
|
||||
}
|
||||
if (!isUserEnabled(user)) {
|
||||
throw new IllegalStateException("Cannot show app details for disabled profile "
|
||||
+ user);
|
||||
@@ -642,9 +675,13 @@ public class LauncherAppsService extends SystemService {
|
||||
private boolean isEnabledProfileOf(UserHandle user, UserHandle listeningUser,
|
||||
String debugMsg) {
|
||||
if (user.getIdentifier() == listeningUser.getIdentifier()) {
|
||||
if (DEBUG) Log.d(TAG, "Delivering msg to same user " + debugMsg);
|
||||
if (DEBUG) Log.d(TAG, "Delivering msg to same user: " + debugMsg);
|
||||
return true;
|
||||
}
|
||||
if (mUm.isManagedProfile(listeningUser.getIdentifier())) {
|
||||
if (DEBUG) Log.d(TAG, "Managed profile can't see other profiles: " + debugMsg);
|
||||
return false;
|
||||
}
|
||||
long ident = injectClearCallingIdentity();
|
||||
try {
|
||||
UserInfo userInfo = mUm.getUserInfo(user.getIdentifier());
|
||||
|
||||
@@ -602,12 +602,14 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase {
|
||||
protected static final int USER_0 = UserHandle.USER_SYSTEM;
|
||||
protected static final int USER_10 = 10;
|
||||
protected static final int USER_11 = 11;
|
||||
protected static final int USER_P0 = 20; // profile of user 0
|
||||
protected static final int USER_P0 = 20; // profile of user 0 (MANAGED_PROFILE *not* set)
|
||||
protected static final int USER_P1 = 21; // another profile of user 0 (MANAGED_PROFILE set)
|
||||
|
||||
protected static final UserHandle HANDLE_USER_0 = UserHandle.of(USER_0);
|
||||
protected static final UserHandle HANDLE_USER_10 = UserHandle.of(USER_10);
|
||||
protected static final UserHandle HANDLE_USER_11 = UserHandle.of(USER_11);
|
||||
protected static final UserHandle HANDLE_USER_P0 = UserHandle.of(USER_P0);
|
||||
protected static final UserHandle HANDLE_USER_P1 = UserHandle.of(USER_P1);
|
||||
|
||||
protected static final UserInfo USER_INFO_0 = withProfileGroupId(
|
||||
new UserInfo(USER_0, "user0",
|
||||
@@ -630,6 +632,10 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase {
|
||||
protected static final UserInfo USER_INFO_P0 = withProfileGroupId(
|
||||
new UserInfo(USER_P0, "userP0", UserInfo.FLAG_INITIALIZED), 0);
|
||||
|
||||
protected static final UserInfo USER_INFO_P1 = withProfileGroupId(
|
||||
new UserInfo(USER_P1, "userP1",
|
||||
UserInfo.FLAG_INITIALIZED | UserInfo.FLAG_MANAGED_PROFILE), 0);
|
||||
|
||||
protected BiPredicate<String, Integer> mDefaultLauncherChecker =
|
||||
(callingPackage, userId) ->
|
||||
LAUNCHER_1.equals(callingPackage) || LAUNCHER_2.equals(callingPackage)
|
||||
@@ -746,6 +752,7 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase {
|
||||
mUserInfos.put(USER_10, USER_INFO_10);
|
||||
mUserInfos.put(USER_11, USER_INFO_11);
|
||||
mUserInfos.put(USER_P0, USER_INFO_P0);
|
||||
mUserInfos.put(USER_P1, USER_INFO_P1);
|
||||
|
||||
// Set up isUserRunning and isUserUnlocked.
|
||||
when(mMockUserManager.isUserRunning(anyInt())).thenAnswer(new AnswerWithSystemCheck<>(
|
||||
@@ -775,6 +782,13 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase {
|
||||
assertNotNull(parent);
|
||||
return parent;
|
||||
}));
|
||||
when(mMockUserManager.isManagedProfile(anyInt()))
|
||||
.thenAnswer(new AnswerWithSystemCheck<>(inv -> {
|
||||
final int userId = (Integer) inv.getArguments()[0];
|
||||
final UserInfo ui = mUserInfos.get(userId);
|
||||
assertNotNull(ui);
|
||||
return ui.isManagedProfile();
|
||||
}));
|
||||
|
||||
when(mMockActivityManagerInternal.getUidProcessState(anyInt())).thenReturn(
|
||||
ActivityManager.PROCESS_STATE_CACHED_EMPTY);
|
||||
@@ -784,12 +798,14 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase {
|
||||
mRunningUsers.put(USER_10, false);
|
||||
mRunningUsers.put(USER_11, false);
|
||||
mRunningUsers.put(USER_P0, true);
|
||||
mRunningUsers.put(USER_P1, true);
|
||||
|
||||
// Unlock all users by default.
|
||||
mUnlockedUsers.put(USER_0, true);
|
||||
mUnlockedUsers.put(USER_10, true);
|
||||
mUnlockedUsers.put(USER_11, true);
|
||||
mUnlockedUsers.put(USER_P0, true);
|
||||
mUnlockedUsers.put(USER_P1, true);
|
||||
|
||||
// Set up resources
|
||||
setUpAppResources();
|
||||
|
||||
@@ -2099,6 +2099,24 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
|
||||
list("s1", "s2", "s3"), HANDLE_USER_10);
|
||||
});
|
||||
|
||||
// First, make sure managed profile can't see other profiles.
|
||||
runWithCaller(LAUNCHER_1, USER_P1, () -> {
|
||||
|
||||
final ShortcutQuery q = new ShortcutQuery().setQueryFlags(
|
||||
ShortcutQuery.FLAG_MATCH_DYNAMIC | ShortcutQuery.FLAG_MATCH_PINNED
|
||||
| ShortcutQuery.FLAG_MATCH_MANIFEST);
|
||||
|
||||
// No shortcuts are visible.
|
||||
assertWith(mLauncherApps.getShortcuts(q, HANDLE_USER_0)).isEmpty();
|
||||
|
||||
mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s1"), HANDLE_USER_0);
|
||||
|
||||
// Should have no effects.
|
||||
assertWith(mLauncherApps.getShortcuts(q, HANDLE_USER_0)).isEmpty();
|
||||
|
||||
assertShortcutNotLaunched(CALLING_PACKAGE_1, "s1", USER_0);
|
||||
});
|
||||
|
||||
// Cross profile pinning.
|
||||
final int PIN_AND_DYNAMIC = ShortcutQuery.FLAG_GET_PINNED | ShortcutQuery.FLAG_GET_DYNAMIC;
|
||||
|
||||
@@ -2930,6 +2948,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
|
||||
final LauncherApps.Callback c0_4 = mock(LauncherApps.Callback.class);
|
||||
|
||||
final LauncherApps.Callback cP0_1 = mock(LauncherApps.Callback.class);
|
||||
final LauncherApps.Callback cP1_1 = mock(LauncherApps.Callback.class);
|
||||
final LauncherApps.Callback c10_1 = mock(LauncherApps.Callback.class);
|
||||
final LauncherApps.Callback c10_2 = mock(LauncherApps.Callback.class);
|
||||
final LauncherApps.Callback c11_1 = mock(LauncherApps.Callback.class);
|
||||
@@ -2943,6 +2962,8 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
|
||||
return LAUNCHER_2.equals(pkg);
|
||||
case USER_P0:
|
||||
return LAUNCHER_1.equals(pkg);
|
||||
case USER_P1:
|
||||
return LAUNCHER_1.equals(pkg);
|
||||
case USER_10:
|
||||
return LAUNCHER_1.equals(pkg);
|
||||
case USER_11:
|
||||
@@ -2957,6 +2978,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
|
||||
runWithCaller(LAUNCHER_3, USER_0, () -> mLauncherApps.registerCallback(c0_3, h));
|
||||
runWithCaller(LAUNCHER_4, USER_0, () -> mLauncherApps.registerCallback(c0_4, h));
|
||||
runWithCaller(LAUNCHER_1, USER_P0, () -> mLauncherApps.registerCallback(cP0_1, h));
|
||||
runWithCaller(LAUNCHER_1, USER_P1, () -> mLauncherApps.registerCallback(cP1_1, h));
|
||||
runWithCaller(LAUNCHER_1, USER_10, () -> mLauncherApps.registerCallback(c10_1, h));
|
||||
runWithCaller(LAUNCHER_2, USER_10, () -> mLauncherApps.registerCallback(c10_2, h));
|
||||
runWithCaller(LAUNCHER_1, USER_11, () -> mLauncherApps.registerCallback(c11_1, h));
|
||||
@@ -2977,6 +2999,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
|
||||
assertCallbackNotReceived(c11_1);
|
||||
assertCallbackReceived(c0_2, HANDLE_USER_0, CALLING_PACKAGE_1, "s1", "s2", "s3");
|
||||
assertCallbackReceived(cP0_1, HANDLE_USER_0, CALLING_PACKAGE_1, "s1", "s2", "s3", "s4");
|
||||
assertCallbackNotReceived(cP1_1);
|
||||
|
||||
// User 0, different package.
|
||||
|
||||
@@ -2995,6 +3018,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
|
||||
assertCallbackReceived(c0_2, HANDLE_USER_0, CALLING_PACKAGE_3, "s1", "s2", "s3", "s4");
|
||||
assertCallbackReceived(cP0_1, HANDLE_USER_0, CALLING_PACKAGE_3,
|
||||
"s1", "s2", "s3", "s4", "s5", "s6");
|
||||
assertCallbackNotReceived(cP1_1);
|
||||
|
||||
// Work profile.
|
||||
resetAll(all);
|
||||
@@ -3011,6 +3035,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
|
||||
assertCallbackNotReceived(c11_1);
|
||||
assertCallbackReceived(c0_2, HANDLE_USER_P0, CALLING_PACKAGE_1, "s1", "s2", "s3", "s5");
|
||||
assertCallbackReceived(cP0_1, HANDLE_USER_P0, CALLING_PACKAGE_1, "s1", "s2", "s3", "s4");
|
||||
assertCallbackNotReceived(cP1_1);
|
||||
|
||||
// Normal secondary user.
|
||||
mRunningUsers.put(USER_10, true);
|
||||
@@ -3030,6 +3055,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
|
||||
assertCallbackNotReceived(c11_1);
|
||||
assertCallbackReceived(c10_1, HANDLE_USER_10, CALLING_PACKAGE_1,
|
||||
"x1", "x2", "x3", "x4", "x5");
|
||||
assertCallbackNotReceived(cP1_1);
|
||||
}
|
||||
|
||||
// === Test for persisting ===
|
||||
|
||||
Reference in New Issue
Block a user