Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 784e2070 authored by Kholoud Mohamed's avatar Kholoud Mohamed Committed by Android (Google) Code Review
Browse files

Merge "Start an activity cross profile in same task." into tm-dev

parents b1c7853e 7a4e6a56
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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";
  }
+1 −0
Original line number Diff line number Diff line
@@ -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);
  }
+81 −2
Original line number Diff line number Diff line
@@ -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();
        }
@@ -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
@@ -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();
        }
+1 −1
Original line number Diff line number Diff line
@@ -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);
+26 −8
Original line number Diff line number Diff line
@@ -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);

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

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