From 8e2b31d6f637f709f7c8ea86e3a739f0ab112d8c Mon Sep 17 00:00:00 2001 From: Galia Peycheva Date: Mon, 14 Feb 2022 18:11:35 +0100 Subject: [PATCH] Add API to add custom close action for PiP. Adds option to set a custom remote action to the PiP params to be used instead of the system provided close action. Although PipParamsBuilder gets a new setter, we do *not* add any new getters to PipParams since the convention for this class has been to not have any getters at all. The only existing public APIs are from Parcelable: describeContents, writeToParcel, and CREATOR. Bug: 218487423 Test: atest PinnedStackTests#testCloseActionIsSet Change-Id: I04f1cc6177744e43236876cebbfc80cced1637ff --- core/api/current.txt | 1 + core/api/test-current.txt | 1 + .../android/app/PictureInPictureParams.java | 76 ++++++++++++++++--- 3 files changed, 69 insertions(+), 9 deletions(-) diff --git a/core/api/current.txt b/core/api/current.txt index 5c3f077e816fe..9333e930aaf54 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -6637,6 +6637,7 @@ package android.app { method public android.app.PictureInPictureParams.Builder setActions(java.util.List); method public android.app.PictureInPictureParams.Builder setAspectRatio(android.util.Rational); method @NonNull public android.app.PictureInPictureParams.Builder setAutoEnterEnabled(boolean); + method @NonNull public android.app.PictureInPictureParams.Builder setCloseAction(@Nullable android.app.RemoteAction); method @NonNull public android.app.PictureInPictureParams.Builder setExpandedAspectRatio(@Nullable android.util.Rational); method @NonNull public android.app.PictureInPictureParams.Builder setSeamlessResizeEnabled(boolean); method public android.app.PictureInPictureParams.Builder setSourceRectHint(android.graphics.Rect); diff --git a/core/api/test-current.txt b/core/api/test-current.txt index f95515a381fef..f51105d32e233 100644 --- a/core/api/test-current.txt +++ b/core/api/test-current.txt @@ -354,6 +354,7 @@ package android.app { public final class PictureInPictureParams implements android.os.Parcelable { method public java.util.List getActions(); method public float getAspectRatio(); + method @Nullable public android.app.RemoteAction getCloseAction(); method public float getExpandedAspectRatio(); method public android.graphics.Rect getSourceRectHint(); method @Nullable public CharSequence getSubtitle(); diff --git a/core/java/android/app/PictureInPictureParams.java b/core/java/android/app/PictureInPictureParams.java index 0a74bba8fee3e..5ecddfd929d57 100644 --- a/core/java/android/app/PictureInPictureParams.java +++ b/core/java/android/app/PictureInPictureParams.java @@ -50,6 +50,9 @@ public final class PictureInPictureParams implements Parcelable { @Nullable private List mUserActions; + @Nullable + private RemoteAction mCloseAction; + @Nullable private Rect mSourceRectHint; @@ -113,6 +116,25 @@ public final class PictureInPictureParams implements Parcelable { return this; } + /** + * Sets a close action that should be invoked before the default close PiP action. The + * custom action must close the activity quickly using {@link Activity#finish()}. + * Otherwise, the system will forcibly close the PiP as if no custom close action was + * provided. + * + * If the action matches one set via {@link PictureInPictureParams.Builder#setActions(List)} + * it may be shown in place of that custom action in the menu. + * + * @param action to replace the system close action + * @return this builder instance. + * @see RemoteAction + */ + @NonNull + public Builder setCloseAction(@Nullable RemoteAction action) { + mCloseAction = action; + return this; + } + /** * Sets the source bounds hint. These bounds are only used when an activity first enters * picture-in-picture, and describe the bounds in window coordinates of activity entering @@ -209,8 +231,8 @@ public final class PictureInPictureParams implements Parcelable { */ public PictureInPictureParams build() { PictureInPictureParams params = new PictureInPictureParams(mAspectRatio, - mExpandedAspectRatio, mUserActions, - mSourceRectHint, mAutoEnterEnabled, mSeamlessResizeEnabled, mTitle, mSubtitle); + mExpandedAspectRatio, mUserActions, mCloseAction, mSourceRectHint, + mAutoEnterEnabled, mSeamlessResizeEnabled, mTitle, mSubtitle); return params; } } @@ -233,6 +255,12 @@ public final class PictureInPictureParams implements Parcelable { @Nullable private List mUserActions; + /** + * Action to replace the system close action. + */ + @Nullable + private RemoteAction mCloseAction; + /** * The source bounds hint used when entering picture-in-picture, relative to the window bounds. * We can use this internally for the transition into picture-in-picture to ensure that a @@ -278,6 +306,7 @@ public final class PictureInPictureParams implements Parcelable { mUserActions = new ArrayList<>(); in.readTypedList(mUserActions, RemoteAction.CREATOR); } + mCloseAction = in.readTypedObject(RemoteAction.CREATOR); if (in.readInt() != 0) { mSourceRectHint = Rect.CREATOR.createFromParcel(in); } @@ -297,11 +326,13 @@ public final class PictureInPictureParams implements Parcelable { /** {@hide} */ PictureInPictureParams(Rational aspectRatio, Rational expandedAspectRatio, - List actions, Rect sourceRectHint, Boolean autoEnterEnabled, - Boolean seamlessResizeEnabled, CharSequence title, CharSequence subtitle) { + List actions, RemoteAction closeAction, Rect sourceRectHint, + Boolean autoEnterEnabled, Boolean seamlessResizeEnabled, CharSequence title, + CharSequence subtitle) { mAspectRatio = aspectRatio; mExpandedAspectRatio = expandedAspectRatio; mUserActions = actions; + mCloseAction = closeAction; mSourceRectHint = sourceRectHint; mAutoEnterEnabled = autoEnterEnabled; mSeamlessResizeEnabled = seamlessResizeEnabled; @@ -314,7 +345,7 @@ public final class PictureInPictureParams implements Parcelable { * @hide */ public PictureInPictureParams(PictureInPictureParams other) { - this(other.mAspectRatio, other.mExpandedAspectRatio, other.mUserActions, + this(other.mAspectRatio, other.mExpandedAspectRatio, other.mUserActions, other.mCloseAction, other.hasSourceBoundsHint() ? new Rect(other.getSourceRectHint()) : null, other.mAutoEnterEnabled, other.mSeamlessResizeEnabled, other.mTitle, other.mSubtitle); @@ -335,6 +366,9 @@ public final class PictureInPictureParams implements Parcelable { if (otherArgs.hasSetActions()) { mUserActions = otherArgs.mUserActions; } + if (otherArgs.hasSetCloseAction()) { + mCloseAction = otherArgs.mCloseAction; + } if (otherArgs.hasSourceBoundsHint()) { mSourceRectHint = new Rect(otherArgs.getSourceRectHint()); } @@ -414,8 +448,27 @@ public final class PictureInPictureParams implements Parcelable { return mUserActions != null; } + /** + * @return the close action. + * @hide + */ + @TestApi + @Nullable + public RemoteAction getCloseAction() { + return mCloseAction; + } + + /** + * @return whether the close action was set. + * @hide + */ + public boolean hasSetCloseAction() { + return mCloseAction != null; + } + /** * Truncates the set of actions to the given {@param size}. + * * @hide */ public void truncateActions(int size) { @@ -499,8 +552,8 @@ public final class PictureInPictureParams implements Parcelable { * @hide */ public boolean empty() { - return !hasSourceBoundsHint() && !hasSetActions() && !hasSetAspectRatio() - && !hasSetExpandedAspectRatio() && mAutoEnterEnabled != null + return !hasSourceBoundsHint() && !hasSetActions() && !hasSetCloseAction() + && !hasSetAspectRatio() && !hasSetExpandedAspectRatio() && mAutoEnterEnabled != null && mSeamlessResizeEnabled != null && !hasSetTitle() && !hasSetSubtitle(); } @@ -515,6 +568,7 @@ public final class PictureInPictureParams implements Parcelable { && Objects.equals(mAspectRatio, that.mAspectRatio) && Objects.equals(mExpandedAspectRatio, that.mExpandedAspectRatio) && Objects.equals(mUserActions, that.mUserActions) + && Objects.equals(mCloseAction, that.mCloseAction) && Objects.equals(mSourceRectHint, that.mSourceRectHint) && Objects.equals(mTitle, that.mTitle) && Objects.equals(mSubtitle, that.mSubtitle); @@ -522,8 +576,8 @@ public final class PictureInPictureParams implements Parcelable { @Override public int hashCode() { - return Objects.hash(mAspectRatio, mExpandedAspectRatio, mUserActions, mSourceRectHint, - mAutoEnterEnabled, mSeamlessResizeEnabled, mTitle, mSubtitle); + return Objects.hash(mAspectRatio, mExpandedAspectRatio, mUserActions, mCloseAction, + mSourceRectHint, mAutoEnterEnabled, mSeamlessResizeEnabled, mTitle, mSubtitle); } @Override @@ -541,6 +595,9 @@ public final class PictureInPictureParams implements Parcelable { } else { out.writeInt(0); } + + out.writeTypedObject(mCloseAction, 0); + if (mSourceRectHint != null) { out.writeInt(1); mSourceRectHint.writeToParcel(out, 0); @@ -597,6 +654,7 @@ public final class PictureInPictureParams implements Parcelable { + " expandedAspectRatio=" + mExpandedAspectRatio + " sourceRectHint=" + getSourceRectHint() + " hasSetActions=" + hasSetActions() + + " hasSetCloseAction=" + hasSetCloseAction() + " isAutoPipEnabled=" + isAutoEnterEnabled() + " isSeamlessResizeEnabled=" + isSeamlessResizeEnabled() + " title=" + getTitle()