Bug:
34340531
Test: adb shell am instrument -e class com.android.server.pm.ShortcutManagerTest1 -w com.android.frameworks.servicestests
Test: adb shell am instrument -e class com.android.server.pm.ShortcutManagerTest2 -w com.android.frameworks.servicestests
Test: adb shell am instrument -e class com.android.server.pm.ShortcutManagerTest3 -w com.android.frameworks.servicestests
Test: adb shell am instrument -e class com.android.server.pm.ShortcutManagerTest4 -w com.android.frameworks.servicestests
Test: adb shell am instrument -e class com.android.server.pm.ShortcutManagerTest5 -w com.android.frameworks.servicestests
Test: adb shell am instrument -e class com.android.server.pm.ShortcutManagerTest6 -w com.android.frameworks.servicestests
Test: adb shell am instrument -e class com.android.server.pm.ShortcutManagerTest7 -w com.android.frameworks.servicestests
Test: adb shell am instrument -e class com.android.server.pm.ShortcutManagerTest8 -w com.android.frameworks.servicestests
Test: adb shell am instrument -e class com.android.server.pm.ShortcutManagerTest9 -w com.android.frameworks.servicestests
Test: adb shell am instrument -e class com.android.server.pm.ShortcutManagerTest10 -w com.android.frameworks.servicestests
Test: cts-tradefed run cts --skip-device-info --skip-preconditions --skip-system-status-check com.android.compatibility.common.tradefed.targetprep.NetworkConnectivityChecker -a armeabi-v7a -m CtsShortcutHostTestCases -t 'android.content.pm.cts.shortcuthost.ShortcutManagerMultiuserTest#testManagedUser'
Test: cts-tradefed run cts --skip-device-info --skip-preconditions --skip-system-status-check com.android.compatibility.common.tradefed.targetprep.NetworkConnectivityChecker -a armeabi-v7a -m CtsDevicePolicyManagerTestCases -t 'com.android.cts.devicepolicy.LauncherAppsProfileTest'
Change-Id: I34e9f351d2a8addf65a5a928c3dd4363f08611dc
method public java.util.List<android.content.pm.LauncherActivityInfo> getActivityList(java.lang.String, android.os.UserHandle);
method public android.content.pm.ApplicationInfo getApplicationInfo(java.lang.String, int, android.os.UserHandle);
method public android.content.pm.LauncherApps.PinItemRequest getPinItemRequest(android.content.Intent);
+ method public java.util.List<android.os.UserHandle> getProfiles();
method public android.graphics.drawable.Drawable getShortcutBadgedIconDrawable(android.content.pm.ShortcutInfo, int);
method public android.content.IntentSender getShortcutConfigActivityIntent(android.content.pm.LauncherActivityInfo);
method public java.util.List<android.content.pm.LauncherActivityInfo> getShortcutConfigActivityList(java.lang.String, android.os.UserHandle);
method public java.util.List<android.content.pm.LauncherActivityInfo> getActivityList(java.lang.String, android.os.UserHandle);
method public android.content.pm.ApplicationInfo getApplicationInfo(java.lang.String, int, android.os.UserHandle);
method public android.content.pm.LauncherApps.PinItemRequest getPinItemRequest(android.content.Intent);
+ method public java.util.List<android.os.UserHandle> getProfiles();
method public android.graphics.drawable.Drawable getShortcutBadgedIconDrawable(android.content.pm.ShortcutInfo, int);
method public android.content.IntentSender getShortcutConfigActivityIntent(android.content.pm.LauncherActivityInfo);
method public java.util.List<android.content.pm.LauncherActivityInfo> getShortcutConfigActivityList(java.lang.String, android.os.UserHandle);
method public java.util.List<android.content.pm.LauncherActivityInfo> getActivityList(java.lang.String, android.os.UserHandle);
method public android.content.pm.ApplicationInfo getApplicationInfo(java.lang.String, int, android.os.UserHandle);
method public android.content.pm.LauncherApps.PinItemRequest getPinItemRequest(android.content.Intent);
+ method public java.util.List<android.os.UserHandle> getProfiles();
method public android.graphics.drawable.Drawable getShortcutBadgedIconDrawable(android.content.pm.ShortcutInfo, int);
method public android.content.IntentSender getShortcutConfigActivityIntent(android.content.pm.LauncherActivityInfo);
method public java.util.List<android.content.pm.LauncherActivityInfo> getShortcutConfigActivityList(java.lang.String, android.os.UserHandle);
/**
* Class for retrieving a list of launchable activities for the current user and any associated
- * managed profiles. This is mainly for use by launchers. Apps can be queried for each user profile.
+ * managed profiles that are visible to the current user, which can be retrieved with
+ * {@link #getProfiles}. This is mainly for use by launchers.
+ *
+ * Apps can be queried for each user profile.
* Since the PackageManager will not deliver package broadcasts for other profiles, you can register
* for package changes here.
* <p>
* To watch for managed profiles being added or removed, register for the following broadcasts:
* {@link Intent#ACTION_MANAGED_PROFILE_ADDED} and {@link Intent#ACTION_MANAGED_PROFILE_REMOVED}.
* <p>
- * You can retrieve the list of profiles associated with this user with
- * {@link UserManager#getUserProfiles()}.
+ * Note as of Android O, apps on a managed profile are no longer allowed to access apps on the
+ * main profile. Apps can only access profiles returned by {@link #getProfiles()}.
*/
public class LauncherApps {
}
/**
+ * Return a list of profiles that the caller can access via the {@link LauncherApps} APIs.
+ *
+ * <p>If the caller is running on a managed profile, it'll return only the current profile.
+ * 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 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();
+ }
+ }
+
+ /**
* Retrieves a list of launchable activities that match {@link Intent#ACTION_MAIN} and
* {@link Intent#CATEGORY_LAUNCHER}, for a specified user.
*
long ident = injectClearCallingIdentity();
try {
UserInfo callingUserInfo = mUm.getUserInfo(callingUserId);
+ if (callingUserInfo.isManagedProfile()) {
+ throw new SecurityException(message + " for another profile " + targetUserId);
+ }
+
UserInfo targetUserInfo = mUm.getUserInfo(targetUserId);
if (targetUserInfo == null
|| targetUserInfo.profileGroupId == UserInfo.NO_PROFILE_GROUP_ID
|| targetUserInfo.profileGroupId != callingUserInfo.profileGroupId) {
- throw new SecurityException(message);
+ throw new SecurityException(message + " for unrelated profile " + targetUserId);
}
} finally {
injectRestoreCallingIdentity(ident);
@Override
public ActivityInfo resolveActivity(ComponentName component, UserHandle user)
throws RemoteException {
- ensureInUserProfiles(user, "Cannot resolve activity for unrelated profile " + user);
+ ensureInUserProfiles(user, "Cannot resolve activity");
if (!isUserEnabled(user)) {
return null;
}
private ParceledListSlice<ResolveInfo> queryActivitiesForUser(Intent intent,
UserHandle user) {
- ensureInUserProfiles(user, "Cannot retrieve activities for unrelated profile " + user);
+ ensureInUserProfiles(user, "Cannot retrieve activities");
if (!isUserEnabled(user)) {
return null;
}
@Override
public boolean isPackageEnabled(String packageName, UserHandle user)
throws RemoteException {
- ensureInUserProfiles(user, "Cannot check package for unrelated profile " + user);
+ ensureInUserProfiles(user, "Cannot check package");
if (!isUserEnabled(user)) {
return false;
}
@Override
public ApplicationInfo getApplicationInfo(String packageName, int flags, UserHandle user)
throws RemoteException {
- ensureInUserProfiles(user, "Cannot check package for unrelated profile " + user);
+ ensureInUserProfiles(user, "Cannot check package");
if (!isUserEnabled(user)) {
return null;
}
private void ensureShortcutPermission(@NonNull String callingPackage, int userId) {
verifyCallingPackage(callingPackage);
- ensureInUserProfiles(userId, "Cannot access shortcuts for unrelated profile " + userId);
+ ensureInUserProfiles(userId, "Cannot access shortcuts");
if (!mShortcutServiceInternal.hasShortcutHostPermission(getCallingUserId(),
callingPackage)) {
public boolean startShortcut(String callingPackage, String packageName, String shortcutId,
Rect sourceBounds, Bundle startActivityOptions, int userId) {
verifyCallingPackage(callingPackage);
- ensureInUserProfiles(userId, "Cannot start activity for unrelated profile " + userId);
+ ensureInUserProfiles(userId, "Cannot start activity");
if (!isUserEnabled(userId)) {
throw new IllegalStateException("Cannot start a shortcut for disabled profile "
@Override
public boolean isActivityEnabled(ComponentName component, UserHandle user)
throws RemoteException {
- ensureInUserProfiles(user, "Cannot check component for unrelated profile " + user);
+ ensureInUserProfiles(user, "Cannot check component");
if (!isUserEnabled(user)) {
return false;
}
@Override
public void startActivityAsUser(ComponentName component, Rect sourceBounds,
Bundle opts, UserHandle user) throws RemoteException {
- ensureInUserProfiles(user, "Cannot start activity for unrelated profile " + user);
+ ensureInUserProfiles(user, "Cannot start activity");
if (!isUserEnabled(user)) {
throw new IllegalStateException("Cannot start activity for disabled profile " + user);
}
@Override
public void showAppDetailsAsUser(ComponentName component, Rect sourceBounds,
Bundle opts, UserHandle user) throws RemoteException {
- ensureInUserProfiles(user, "Cannot show app details for unrelated profile " + user);
+ ensureInUserProfiles(user, "Cannot show app details");
if (!isUserEnabled(user)) {
throw new IllegalStateException("Cannot show app details for disabled profile "
+ user);
protected static final UserInfo USER_INFO_11 =
new UserInfo(USER_11, "user11", UserInfo.FLAG_INITIALIZED);
+ /*
+ * Cheat: USER_P0 is a sub profile of USER_0, but it doesn't have the MANAGED_PROFILE flag set.
+ * Due to a change made to LauncherApps (b/34340531), work profile apps a no longer able
+ * to see the main profile, which would break tons of unit tests. We avoid it by not setting
+ * MANAGED_PROFILE for P0.
+ * We cover this negative case in CTS. (i.e. CTS has tests to make sure maanged profile
+ * can't access main profile's shortcuts.)
+ */
protected static final UserInfo USER_INFO_P0 = withProfileGroupId(
- new UserInfo(USER_P0, "userP0",
- UserInfo.FLAG_MANAGED_PROFILE), 0);
+ new UserInfo(USER_P0, "userP0", UserInfo.FLAG_INITIALIZED), 0);
protected BiPredicate<String, Integer> mDefaultLauncherChecker =
(callingPackage, userId) ->