Merge "Do not allow work profile to see main other profiles"

This commit is contained in:
Makoto Onuki
2017-02-13 21:33:19 +00:00
committed by Android (Google) Code Review
4 changed files with 168 additions and 65 deletions

View File

@@ -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());
}

View File

@@ -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());

View File

@@ -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();

View File

@@ -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 ===