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

Commit 4225d565 authored by Michael Groover's avatar Michael Groover Committed by Android (Google) Code Review
Browse files

Merge "Add APIs to allow app to share identity with launched activity"

parents 6c9d3448 022e1e0e
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -4150,6 +4150,8 @@ package android.app {
    method @Deprecated public android.app.FragmentManager getFragmentManager();
    method public android.content.Intent getIntent();
    method @Nullable public Object getLastNonConfigurationInstance();
    method @Nullable public String getLaunchedFromPackage();
    method public int getLaunchedFromUid();
    method @NonNull public android.view.LayoutInflater getLayoutInflater();
    method @Deprecated public android.app.LoaderManager getLoaderManager();
    method @NonNull public String getLocalClassName();
@@ -4622,6 +4624,7 @@ package android.app {
    method public android.app.ActivityOptions setLaunchDisplayId(int);
    method public android.app.ActivityOptions setLockTaskEnabled(boolean);
    method public void setPendingIntentBackgroundActivityLaunchAllowed(boolean);
    method @NonNull public android.app.ActivityOptions setShareIdentityEnabled(boolean);
    method @NonNull public android.app.ActivityOptions setSplashScreenStyle(int);
    method public android.os.Bundle toBundle();
    method public void update(android.app.ActivityOptions);
+52 −4
Original line number Diff line number Diff line
@@ -6654,16 +6654,64 @@ public class Activity extends ContextThemeWrapper
    }

    /**
     * Returns the uid who started this activity.
     * @hide
     * Returns the uid of the app that initially launched this activity.
     *
     * <p>In order to receive the launching app's uid, at least one of the following has to
     * be met:
     * <ul>
     *     <li>The app must call {@link ActivityOptions#setShareIdentityEnabled(boolean)} with a
     *     value of {@code true} and launch this activity with the resulting {@code
     *     ActivityOptions}.
     *     <li>The launched activity has the same uid as the launching app.
     *     <li>The launched activity is running in a package that is signed with the same key
     *     used to sign the platform (typically only system packages such as Settings will
     *     meet this requirement).
     * </ul>.
     * These are the same requirements for {@link #getLaunchedFromPackage()}; if any of these are
     * met, then these methods can be used to obtain the uid and package name of the launching
     * app. If none are met, then {@link Process#INVALID_UID} is returned.
     *
     * <p>Note, even if the above conditions are not met, the launching app's identity may
     * still be available from {@link #getCallingPackage()} if this activity was started with
     * {@code Activity#startActivityForResult} to allow validation of the result's recipient.
     *
     * @return the uid of the launching app or {@link Process#INVALID_UID} if the current
     * activity cannot access the identity of the launching app
     *
     * @see ActivityOptions#setShareIdentityEnabled(boolean)
     * @see #getLaunchedFromPackage()
     */
    public int getLaunchedFromUid() {
        return ActivityClient.getInstance().getLaunchedFromUid(getActivityToken());
    }

    /**
     * Returns the package who started this activity.
     * @hide
     * Returns the package name of the app that initially launched this activity.
     *
     * <p>In order to receive the launching app's package name, at least one of the following has
     * to be met:
     * <ul>
     *     <li>The app must call {@link ActivityOptions#setShareIdentityEnabled(boolean)} with a
     *     value of {@code true} and launch this activity with the resulting
     *     {@code ActivityOptions}.
     *     <li>The launched activity has the same uid as the launching app.
     *     <li>The launched activity is running in a package that is signed with the same key
     *     used to sign the platform (typically only system packages such as Settings will
     *     meet this requirement).
     * </ul>.
     * These are the same requirements for {@link #getLaunchedFromUid()}; if any of these are
     * met, then these methods can be used to obtain the uid and package name of the launching
     * app. If none are met, then {@code null} is returned.
     *
     * <p>Note, even if the above conditions are not met, the launching app's identity may
     * still be available from {@link #getCallingPackage()} if this activity was started with
     * {@code Activity#startActivityForResult} to allow validation of the result's recipient.
     *
     * @return the package name of the launching app or null if the current activity
     * cannot access the identity of the launching app
     *
     * @see ActivityOptions#setShareIdentityEnabled(boolean)
     * @see #getLaunchedFromUid()
     */
    @Nullable
    public String getLaunchedFromPackage() {
+53 −0
Original line number Diff line number Diff line
@@ -201,6 +201,12 @@ public class ActivityOptions extends ComponentOptions {
     */
    private static final String KEY_LOCK_TASK_MODE = "android:activity.lockTaskMode";

    /**
     * Whether the launching app's identity should be available to the launched activity.
     * @see #setShareIdentityEnabled(boolean)
     */
    private static final String KEY_SHARE_IDENTITY = "android:activity.shareIdentity";

    /**
     * The display id the activity should be launched into.
     * @see #setLaunchDisplayId(int)
@@ -457,6 +463,7 @@ public class ActivityOptions extends ComponentOptions {
    private int mLaunchTaskId = -1;
    private int mPendingIntentLaunchFlags;
    private boolean mLockTaskMode = false;
    private boolean mShareIdentity = false;
    private boolean mDisallowEnterPictureInPictureWhileLaunching;
    private boolean mApplyActivityFlagsForBubbles;
    private boolean mTaskAlwaysOnTop;
@@ -1238,6 +1245,7 @@ public class ActivityOptions extends ComponentOptions {
                break;
        }
        mLockTaskMode = opts.getBoolean(KEY_LOCK_TASK_MODE, false);
        mShareIdentity = opts.getBoolean(KEY_SHARE_IDENTITY, false);
        mLaunchDisplayId = opts.getInt(KEY_LAUNCH_DISPLAY_ID, INVALID_DISPLAY);
        mCallerDisplayId = opts.getInt(KEY_CALLER_DISPLAY_ID, INVALID_DISPLAY);
        mLaunchTaskDisplayArea = opts.getParcelable(KEY_LAUNCH_TASK_DISPLAY_AREA_TOKEN, android.window.WindowContainerToken.class);
@@ -1487,6 +1495,20 @@ public class ActivityOptions extends ComponentOptions {
        return mLockTaskMode;
    }

    /**
     * Returns whether the launching app has opted-in to sharing its identity with the launched
     * activity.
     *
     * @see #setShareIdentityEnabled(boolean)
     * @see Activity#getLaunchedFromUid()
     * @see Activity#getLaunchedFromPackage()
     *
     * @hide
     */
    public boolean getShareIdentity() {
        return mShareIdentity;
    }

    /**
     * Gets whether the activity want to be launched as other theme for the splash screen.
     * @hide
@@ -1559,6 +1581,33 @@ public class ActivityOptions extends ComponentOptions {
        return this;
    }

    /**
     * Sets whether the identity of the launching app should be shared with the activity.
     *
     * <p>Use this option when starting an activity that needs to know the identity of the
     * launching app; with this set to {@code true}, the activity will have access to the launching
     * app's package name and uid.
     *
     * <p>Defaults to {@code false} if not set.
     *
     * <p>Note, even if the launching app does not explicitly enable sharing of its identity, if
     * the activity is started with {@code Activity#startActivityForResult}, then {@link
     * Activity#getCallingPackage()} will still return the launching app's package name to
     * allow validation of the result's recipient. Also, an activity running within a package
     * signed by the same key used to sign the platform (some system apps such as Settings will
     * be signed with the platform's key) will have access to the launching app's identity.
     *
     * @param shareIdentity whether the launching app's identity should be shared with the activity
     * @return {@code this} {@link ActivityOptions} instance.
     * @see Activity#getLaunchedFromPackage()
     * @see Activity#getLaunchedFromUid()
     */
    @NonNull
    public ActivityOptions setShareIdentityEnabled(boolean shareIdentity) {
        mShareIdentity = shareIdentity;
        return this;
    }

    /**
     * Gets the id of the display where activity should be launched.
     * @return The id of the display where activity should be launched,
@@ -2039,6 +2088,7 @@ public class ActivityOptions extends ComponentOptions {
                break;
        }
        mLockTaskMode = otherOptions.mLockTaskMode;
        mShareIdentity = otherOptions.mShareIdentity;
        mAnimSpecs = otherOptions.mAnimSpecs;
        mAnimationFinishedListener = otherOptions.mAnimationFinishedListener;
        mSpecsFuture = otherOptions.mSpecsFuture;
@@ -2123,6 +2173,9 @@ public class ActivityOptions extends ComponentOptions {
        if (mLockTaskMode) {
            b.putBoolean(KEY_LOCK_TASK_MODE, mLockTaskMode);
        }
        if (mShareIdentity) {
            b.putBoolean(KEY_SHARE_IDENTITY, mShareIdentity);
        }
        if (mLaunchDisplayId != INVALID_DISPLAY) {
            b.putInt(KEY_LAUNCH_DISPLAY_ID, mLaunchDisplayId);
        }
+14 −11
Original line number Diff line number Diff line
@@ -687,29 +687,32 @@ class ActivityClientController extends IActivityClientController.Stub {

    @Override
    public int getLaunchedFromUid(IBinder token) {
        if (!canGetLaunchedFrom()) {
            return INVALID_UID;
        }
        final int uid = Binder.getCallingUid();
        final boolean isInternalCaller = isInternalCallerGetLaunchedFrom(uid);
        synchronized (mGlobalLock) {
            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
            return r != null ? r.launchedFromUid : INVALID_UID;
            if (r != null && (isInternalCaller || r.mShareIdentity || r.launchedFromUid == uid)) {
                return r.launchedFromUid;
            }
        }
        return INVALID_UID;
    }

    @Override
    public String getLaunchedFromPackage(IBinder token) {
        if (!canGetLaunchedFrom()) {
            return null;
        }
        final int uid = Binder.getCallingUid();
        final boolean isInternalCaller = isInternalCallerGetLaunchedFrom(uid);
        synchronized (mGlobalLock) {
            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
            return r != null ? r.launchedFromPackage : null;
            if (r != null && (isInternalCaller || r.mShareIdentity || r.launchedFromUid == uid)) {
                return r.launchedFromPackage;
            }
        }
        return null;
    }

    /** Whether the caller can get the package or uid that launched its activity. */
    private boolean canGetLaunchedFrom() {
        final int uid = Binder.getCallingUid();
    /** Whether the call to one of the getLaunchedFrom APIs is performed by an internal caller. */
    private boolean isInternalCallerGetLaunchedFrom(int uid) {
        if (UserHandle.getAppId(uid) == SYSTEM_UID) {
            return true;
        }
+2 −0
Original line number Diff line number Diff line
@@ -873,6 +873,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
    boolean mEnteringAnimation;
    boolean mOverrideTaskTransition;
    boolean mDismissKeyguard;
    boolean mShareIdentity;

    /** True if the activity has reported stopped; False if the activity becomes visible. */
    boolean mAppStopped;
@@ -1998,6 +1999,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A

            mOverrideTaskTransition = options.getOverrideTaskTransition();
            mDismissKeyguard = options.getDismissKeyguard();
            mShareIdentity = options.getShareIdentity();
        }

        ColorDisplayService.ColorDisplayServiceInternal cds = LocalServices.getService(