Loading core/api/current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -11300,6 +11300,7 @@ package android.content.pm { method @RequiresPermission(anyOf={android.Manifest.permission.INTERACT_ACROSS_PROFILES, "android.permission.INTERACT_ACROSS_USERS"}) public void startActivity(@NonNull android.content.Intent, @NonNull android.os.UserHandle, @Nullable android.app.Activity); method @RequiresPermission(anyOf={android.Manifest.permission.INTERACT_ACROSS_PROFILES, "android.permission.INTERACT_ACROSS_USERS"}) public void startActivity(@NonNull android.content.Intent, @NonNull android.os.UserHandle, @Nullable android.app.Activity, @Nullable android.os.Bundle); method public void startMainActivity(@NonNull android.content.ComponentName, @NonNull android.os.UserHandle); method public void startMainActivity(@NonNull android.content.ComponentName, @NonNull android.os.UserHandle, @Nullable android.app.Activity, @Nullable android.os.Bundle); field public static final String ACTION_CAN_INTERACT_ACROSS_PROFILES_CHANGED = "android.content.pm.action.CAN_INTERACT_ACROSS_PROFILES_CHANGED"; } core/api/system-current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -3192,6 +3192,7 @@ package android.content.pm { } public class CrossProfileApps { method @RequiresPermission(anyOf={android.Manifest.permission.INTERACT_ACROSS_PROFILES, android.Manifest.permission.START_CROSS_PROFILE_ACTIVITIES}) public void startActivity(@NonNull android.content.ComponentName, @NonNull android.os.UserHandle, @Nullable android.app.Activity, @Nullable android.os.Bundle); method @RequiresPermission(anyOf={android.Manifest.permission.INTERACT_ACROSS_PROFILES, android.Manifest.permission.START_CROSS_PROFILE_ACTIVITIES}) public void startActivity(@NonNull android.content.ComponentName, @NonNull android.os.UserHandle); } core/java/android/content/pm/CrossProfileApps.java +81 −2 Original line number Diff line number Diff line Loading @@ -104,7 +104,44 @@ public class CrossProfileApps { mContext.getAttributionTag(), component, targetUser.getIdentifier(), true); true, null, null); } catch (RemoteException ex) { throw ex.rethrowFromSystemServer(); } } /** * Starts the specified main activity of the caller package in the specified profile, launching * in the specified activity. * * @param component The ComponentName of the activity to launch, it must be exported and has * action {@link android.content.Intent#ACTION_MAIN}, category * {@link android.content.Intent#CATEGORY_LAUNCHER}. Otherwise, SecurityException will * be thrown. * @param targetUser The UserHandle of the profile, must be one of the users returned by * {@link #getTargetUserProfiles()}, otherwise a {@link SecurityException} will * be thrown. * @param callingActivity The activity to start the new activity from for the purposes of * deciding which task the new activity should belong to. If {@code null}, the activity * will always be started in a new task. * @param options The activity options or {@code null}. See {@link android.app.ActivityOptions}. */ public void startMainActivity(@NonNull ComponentName component, @NonNull UserHandle targetUser, @Nullable Activity callingActivity, @Nullable Bundle options) { try { mService.startActivityAsUser( mContext.getIApplicationThread(), mContext.getPackageName(), mContext.getAttributionTag(), component, targetUser.getIdentifier(), true, callingActivity != null ? callingActivity.getActivityToken() : null, options); } catch (RemoteException ex) { throw ex.rethrowFromSystemServer(); } Loading Loading @@ -179,6 +216,48 @@ public class CrossProfileApps { } } /** * Starts the specified activity of the caller package in the specified profile. Unlike * {@link #startMainActivity}, this can start any activity of the caller package, not just * the main activity. * The caller must have the {@link android.Manifest.permission#INTERACT_ACROSS_PROFILES} * or {@link android.Manifest.permission#START_CROSS_PROFILE_ACTIVITIES} * permission and both the caller and target user profiles must be in the same profile group. * * @param component The ComponentName of the activity to launch. It must be exported. * @param targetUser The UserHandle of the profile, must be one of the users returned by * {@link #getTargetUserProfiles()}, otherwise a {@link SecurityException} will * be thrown. * @param callingActivity The activity to start the new activity from for the purposes of * deciding which task the new activity should belong to. If {@code null}, the activity * will always be started in a new task. * @param options The activity options or {@code null}. See {@link android.app.ActivityOptions}. * @hide */ @SystemApi @RequiresPermission(anyOf = { android.Manifest.permission.INTERACT_ACROSS_PROFILES, android.Manifest.permission.START_CROSS_PROFILE_ACTIVITIES}) public void startActivity( @NonNull ComponentName component, @NonNull UserHandle targetUser, @Nullable Activity callingActivity, @Nullable Bundle options) { try { mService.startActivityAsUser( mContext.getIApplicationThread(), mContext.getPackageName(), mContext.getAttributionTag(), component, targetUser.getIdentifier(), false, callingActivity != null ? callingActivity.getActivityToken() : null, options); } catch (RemoteException ex) { throw ex.rethrowFromSystemServer(); } } /** * Starts the specified activity of the caller package in the specified profile. Unlike * {@link #startMainActivity}, this can start any activity of the caller package, not just Loading @@ -201,7 +280,7 @@ public class CrossProfileApps { try { mService.startActivityAsUser(mContext.getIApplicationThread(), mContext.getPackageName(), mContext.getAttributionTag(), component, targetUser.getIdentifier(), false); targetUser.getIdentifier(), false, null, null); } catch (RemoteException ex) { throw ex.rethrowFromSystemServer(); } Loading core/java/android/content/pm/ICrossProfileApps.aidl +1 −1 Original line number Diff line number Diff line Loading @@ -29,7 +29,7 @@ import android.os.UserHandle; interface ICrossProfileApps { void startActivityAsUser(in IApplicationThread caller, in String callingPackage, in String callingFeatureId, in ComponentName component, int userId, boolean launchMainActivity); boolean launchMainActivity, in IBinder task, in Bundle options); void startActivityAsUserByIntent(in IApplicationThread caller, in String callingPackage, in String callingFeatureId, in Intent intent, int userId, in IBinder callingActivity, in Bundle options); Loading services/core/java/com/android/server/pm/CrossProfileAppsServiceImpl.java +26 −8 Original line number Diff line number Diff line Loading @@ -112,7 +112,9 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub { String callingFeatureId, ComponentName component, @UserIdInt int userId, boolean launchMainActivity) throws RemoteException { boolean launchMainActivity, IBinder targetTask, Bundle options) throws RemoteException { Objects.requireNonNull(callingPackage); Objects.requireNonNull(component); Loading Loading @@ -145,8 +147,12 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub { if (launchMainActivity) { launchIntent.setAction(Intent.ACTION_MAIN); launchIntent.addCategory(Intent.CATEGORY_LAUNCHER); if (targetTask == null) { launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); } else { launchIntent.addFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); } // Only package name is set here, as opposed to component name, because intent action // and category are ignored if component name is present while we are resolving intent. launchIntent.setPackage(component.getPackageName()); Loading @@ -170,15 +176,20 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub { } verifyActivityCanHandleIntentAndExported(launchIntent, component, callingUid, userId); // Always show the cross profile animation if (options == null) { options = ActivityOptions.makeOpenCrossProfileAppsAnimation().toBundle(); } else { options.putAll(ActivityOptions.makeOpenCrossProfileAppsAnimation().toBundle()); } launchIntent.setPackage(null); launchIntent.setComponent(component); mInjector.getActivityTaskManagerInternal().startActivityAsUser( caller, callingPackage, callingFeatureId, launchIntent, /* resultTo= */ null, Intent.FLAG_ACTIVITY_NEW_TASK, launchMainActivity ? ActivityOptions.makeOpenCrossProfileAppsAnimation().toBundle() : null, targetTask, /* startFlags= */ 0, options, userId); } Loading Loading @@ -225,6 +236,13 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub { verifyActivityCanHandleIntent(launchIntent, callingUid, userId); // Always show the cross profile animation if (options == null) { options = ActivityOptions.makeOpenCrossProfileAppsAnimation().toBundle(); } else { options.putAll(ActivityOptions.makeOpenCrossProfileAppsAnimation().toBundle()); } mInjector.getActivityTaskManagerInternal() .startActivityAsUser( caller, Loading Loading
core/api/current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -11300,6 +11300,7 @@ package android.content.pm { method @RequiresPermission(anyOf={android.Manifest.permission.INTERACT_ACROSS_PROFILES, "android.permission.INTERACT_ACROSS_USERS"}) public void startActivity(@NonNull android.content.Intent, @NonNull android.os.UserHandle, @Nullable android.app.Activity); method @RequiresPermission(anyOf={android.Manifest.permission.INTERACT_ACROSS_PROFILES, "android.permission.INTERACT_ACROSS_USERS"}) public void startActivity(@NonNull android.content.Intent, @NonNull android.os.UserHandle, @Nullable android.app.Activity, @Nullable android.os.Bundle); method public void startMainActivity(@NonNull android.content.ComponentName, @NonNull android.os.UserHandle); method public void startMainActivity(@NonNull android.content.ComponentName, @NonNull android.os.UserHandle, @Nullable android.app.Activity, @Nullable android.os.Bundle); field public static final String ACTION_CAN_INTERACT_ACROSS_PROFILES_CHANGED = "android.content.pm.action.CAN_INTERACT_ACROSS_PROFILES_CHANGED"; }
core/api/system-current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -3192,6 +3192,7 @@ package android.content.pm { } public class CrossProfileApps { method @RequiresPermission(anyOf={android.Manifest.permission.INTERACT_ACROSS_PROFILES, android.Manifest.permission.START_CROSS_PROFILE_ACTIVITIES}) public void startActivity(@NonNull android.content.ComponentName, @NonNull android.os.UserHandle, @Nullable android.app.Activity, @Nullable android.os.Bundle); method @RequiresPermission(anyOf={android.Manifest.permission.INTERACT_ACROSS_PROFILES, android.Manifest.permission.START_CROSS_PROFILE_ACTIVITIES}) public void startActivity(@NonNull android.content.ComponentName, @NonNull android.os.UserHandle); }
core/java/android/content/pm/CrossProfileApps.java +81 −2 Original line number Diff line number Diff line Loading @@ -104,7 +104,44 @@ public class CrossProfileApps { mContext.getAttributionTag(), component, targetUser.getIdentifier(), true); true, null, null); } catch (RemoteException ex) { throw ex.rethrowFromSystemServer(); } } /** * Starts the specified main activity of the caller package in the specified profile, launching * in the specified activity. * * @param component The ComponentName of the activity to launch, it must be exported and has * action {@link android.content.Intent#ACTION_MAIN}, category * {@link android.content.Intent#CATEGORY_LAUNCHER}. Otherwise, SecurityException will * be thrown. * @param targetUser The UserHandle of the profile, must be one of the users returned by * {@link #getTargetUserProfiles()}, otherwise a {@link SecurityException} will * be thrown. * @param callingActivity The activity to start the new activity from for the purposes of * deciding which task the new activity should belong to. If {@code null}, the activity * will always be started in a new task. * @param options The activity options or {@code null}. See {@link android.app.ActivityOptions}. */ public void startMainActivity(@NonNull ComponentName component, @NonNull UserHandle targetUser, @Nullable Activity callingActivity, @Nullable Bundle options) { try { mService.startActivityAsUser( mContext.getIApplicationThread(), mContext.getPackageName(), mContext.getAttributionTag(), component, targetUser.getIdentifier(), true, callingActivity != null ? callingActivity.getActivityToken() : null, options); } catch (RemoteException ex) { throw ex.rethrowFromSystemServer(); } Loading Loading @@ -179,6 +216,48 @@ public class CrossProfileApps { } } /** * Starts the specified activity of the caller package in the specified profile. Unlike * {@link #startMainActivity}, this can start any activity of the caller package, not just * the main activity. * The caller must have the {@link android.Manifest.permission#INTERACT_ACROSS_PROFILES} * or {@link android.Manifest.permission#START_CROSS_PROFILE_ACTIVITIES} * permission and both the caller and target user profiles must be in the same profile group. * * @param component The ComponentName of the activity to launch. It must be exported. * @param targetUser The UserHandle of the profile, must be one of the users returned by * {@link #getTargetUserProfiles()}, otherwise a {@link SecurityException} will * be thrown. * @param callingActivity The activity to start the new activity from for the purposes of * deciding which task the new activity should belong to. If {@code null}, the activity * will always be started in a new task. * @param options The activity options or {@code null}. See {@link android.app.ActivityOptions}. * @hide */ @SystemApi @RequiresPermission(anyOf = { android.Manifest.permission.INTERACT_ACROSS_PROFILES, android.Manifest.permission.START_CROSS_PROFILE_ACTIVITIES}) public void startActivity( @NonNull ComponentName component, @NonNull UserHandle targetUser, @Nullable Activity callingActivity, @Nullable Bundle options) { try { mService.startActivityAsUser( mContext.getIApplicationThread(), mContext.getPackageName(), mContext.getAttributionTag(), component, targetUser.getIdentifier(), false, callingActivity != null ? callingActivity.getActivityToken() : null, options); } catch (RemoteException ex) { throw ex.rethrowFromSystemServer(); } } /** * Starts the specified activity of the caller package in the specified profile. Unlike * {@link #startMainActivity}, this can start any activity of the caller package, not just Loading @@ -201,7 +280,7 @@ public class CrossProfileApps { try { mService.startActivityAsUser(mContext.getIApplicationThread(), mContext.getPackageName(), mContext.getAttributionTag(), component, targetUser.getIdentifier(), false); targetUser.getIdentifier(), false, null, null); } catch (RemoteException ex) { throw ex.rethrowFromSystemServer(); } Loading
core/java/android/content/pm/ICrossProfileApps.aidl +1 −1 Original line number Diff line number Diff line Loading @@ -29,7 +29,7 @@ import android.os.UserHandle; interface ICrossProfileApps { void startActivityAsUser(in IApplicationThread caller, in String callingPackage, in String callingFeatureId, in ComponentName component, int userId, boolean launchMainActivity); boolean launchMainActivity, in IBinder task, in Bundle options); void startActivityAsUserByIntent(in IApplicationThread caller, in String callingPackage, in String callingFeatureId, in Intent intent, int userId, in IBinder callingActivity, in Bundle options); Loading
services/core/java/com/android/server/pm/CrossProfileAppsServiceImpl.java +26 −8 Original line number Diff line number Diff line Loading @@ -112,7 +112,9 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub { String callingFeatureId, ComponentName component, @UserIdInt int userId, boolean launchMainActivity) throws RemoteException { boolean launchMainActivity, IBinder targetTask, Bundle options) throws RemoteException { Objects.requireNonNull(callingPackage); Objects.requireNonNull(component); Loading Loading @@ -145,8 +147,12 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub { if (launchMainActivity) { launchIntent.setAction(Intent.ACTION_MAIN); launchIntent.addCategory(Intent.CATEGORY_LAUNCHER); if (targetTask == null) { launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); } else { launchIntent.addFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); } // Only package name is set here, as opposed to component name, because intent action // and category are ignored if component name is present while we are resolving intent. launchIntent.setPackage(component.getPackageName()); Loading @@ -170,15 +176,20 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub { } verifyActivityCanHandleIntentAndExported(launchIntent, component, callingUid, userId); // Always show the cross profile animation if (options == null) { options = ActivityOptions.makeOpenCrossProfileAppsAnimation().toBundle(); } else { options.putAll(ActivityOptions.makeOpenCrossProfileAppsAnimation().toBundle()); } launchIntent.setPackage(null); launchIntent.setComponent(component); mInjector.getActivityTaskManagerInternal().startActivityAsUser( caller, callingPackage, callingFeatureId, launchIntent, /* resultTo= */ null, Intent.FLAG_ACTIVITY_NEW_TASK, launchMainActivity ? ActivityOptions.makeOpenCrossProfileAppsAnimation().toBundle() : null, targetTask, /* startFlags= */ 0, options, userId); } Loading Loading @@ -225,6 +236,13 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub { verifyActivityCanHandleIntent(launchIntent, callingUid, userId); // Always show the cross profile animation if (options == null) { options = ActivityOptions.makeOpenCrossProfileAppsAnimation().toBundle(); } else { options.putAll(ActivityOptions.makeOpenCrossProfileAppsAnimation().toBundle()); } mInjector.getActivityTaskManagerInternal() .startActivityAsUser( caller, Loading