Merge "Implement custom PiP close action on TV." into tm-dev

This commit is contained in:
Jacqueline Bronger
2022-03-21 07:56:37 +00:00
committed by Android (Google) Code Review
17 changed files with 179 additions and 41 deletions

View File

@@ -47,7 +47,7 @@ oneway interface IPinnedTaskListener {
* Called when the set of actions for the current PiP activity changes, or when the listener * Called when the set of actions for the current PiP activity changes, or when the listener
* is first registered to allow the listener to synchronize its state with the controller. * is first registered to allow the listener to synchronize its state with the controller.
*/ */
void onActionsChanged(in ParceledListSlice<RemoteAction> actions); void onActionsChanged(in ParceledListSlice<RemoteAction> actions, in RemoteAction closeAction);
/** /**
* Called by the window manager to notify the listener that Activity (was or is in pinned mode) * Called by the window manager to notify the listener that Activity (was or is in pinned mode)

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2022 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@color/tv_pip_menu_icon_unfocused" />
</selector>

View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2022 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_focused="true"
android:color="@color/tv_pip_menu_close_icon_bg_focused" />
<item android:color="@color/tv_pip_menu_close_icon_bg_unfocused" />
</selector>

View File

@@ -39,4 +39,8 @@
<!-- Duration (in milliseconds) the PiP stays stashed before automatically unstashing. --> <!-- Duration (in milliseconds) the PiP stays stashed before automatically unstashing. -->
<integer name="config_pipStashDuration">5000</integer> <integer name="config_pipStashDuration">5000</integer>
<!-- Time (duration in milliseconds) that the shell waits for an app to close the PiP by itself
if a custom action is present before closing it. -->
<integer name="config_pipForceCloseDelay">5000</integer>
</resources> </resources>

View File

@@ -16,8 +16,10 @@
--> -->
<resources> <resources>
<color name="tv_pip_menu_icon_focused">#0E0E0F</color> <color name="tv_pip_menu_icon_focused">#0E0E0F</color>
<color name="tv_pip_menu_icon_unfocused">#E8EAED</color> <color name="tv_pip_menu_icon_unfocused">#F8F9FA</color>
<color name="tv_pip_menu_icon_disabled">#80868B</color> <color name="tv_pip_menu_icon_disabled">#80868B</color>
<color name="tv_pip_menu_close_icon_bg_focused">#D93025</color>
<color name="tv_pip_menu_close_icon_bg_unfocused">#D69F261F</color>
<color name="tv_pip_menu_icon_bg_focused">#E8EAED</color> <color name="tv_pip_menu_icon_bg_focused">#E8EAED</color>
<color name="tv_pip_menu_icon_bg_unfocused">#990E0E0F</color> <color name="tv_pip_menu_icon_bg_unfocused">#990E0E0F</color>
<color name="tv_pip_menu_focus_border">#E8EAED</color> <color name="tv_pip_menu_focus_border">#E8EAED</color>

View File

@@ -72,9 +72,10 @@ public class PinnedStackListenerForwarder {
} }
} }
private void onActionsChanged(ParceledListSlice<RemoteAction> actions) { private void onActionsChanged(ParceledListSlice<RemoteAction> actions,
RemoteAction closeAction) {
for (PinnedTaskListener listener : mListeners) { for (PinnedTaskListener listener : mListeners) {
listener.onActionsChanged(actions); listener.onActionsChanged(actions, closeAction);
} }
} }
@@ -113,9 +114,10 @@ public class PinnedStackListenerForwarder {
} }
@Override @Override
public void onActionsChanged(ParceledListSlice<RemoteAction> actions) { public void onActionsChanged(ParceledListSlice<RemoteAction> actions,
RemoteAction closeAction) {
mMainExecutor.execute(() -> { mMainExecutor.execute(() -> {
PinnedStackListenerForwarder.this.onActionsChanged(actions); PinnedStackListenerForwarder.this.onActionsChanged(actions, closeAction);
}); });
} }
@@ -152,7 +154,8 @@ public class PinnedStackListenerForwarder {
public void onImeVisibilityChanged(boolean imeVisible, int imeHeight) {} public void onImeVisibilityChanged(boolean imeVisible, int imeHeight) {}
public void onActionsChanged(ParceledListSlice<RemoteAction> actions) {} public void onActionsChanged(ParceledListSlice<RemoteAction> actions,
RemoteAction closeAction) {}
public void onActivityHidden(ComponentName componentName) {} public void onActivityHidden(ComponentName componentName) {}

View File

@@ -66,7 +66,7 @@ public interface PipMenuController {
/** /**
* Given a set of actions, update the menu. * Given a set of actions, update the menu.
*/ */
void setAppActions(ParceledListSlice<RemoteAction> appActions); void setAppActions(ParceledListSlice<RemoteAction> appActions, RemoteAction closeAction);
/** /**
* Resize the PiP menu with the given bounds. The PiP SurfaceControl is given if there is a * Resize the PiP menu with the given bounds. The PiP SurfaceControl is given if there is a

View File

@@ -474,7 +474,8 @@ public class PhonePipMenuController implements PipMenuController {
* Sets the menu actions to the actions provided by the current PiP menu. * Sets the menu actions to the actions provided by the current PiP menu.
*/ */
@Override @Override
public void setAppActions(ParceledListSlice<RemoteAction> appActions) { public void setAppActions(ParceledListSlice<RemoteAction> appActions,
RemoteAction closeAction) {
mAppActions = appActions; mAppActions = appActions;
updateMenuActions(); updateMenuActions();
} }

View File

@@ -246,8 +246,9 @@ public class PipController implements PipTransitionController.PipTransitionCallb
} }
@Override @Override
public void onActionsChanged(ParceledListSlice<RemoteAction> actions) { public void onActionsChanged(ParceledListSlice<RemoteAction> actions,
mMenuController.setAppActions(actions); RemoteAction closeAction) {
mMenuController.setAppActions(actions, closeAction);
} }
@Override @Override

View File

@@ -22,6 +22,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import android.annotation.IntDef; import android.annotation.IntDef;
import android.app.ActivityManager; import android.app.ActivityManager;
import android.app.ActivityTaskManager; import android.app.ActivityTaskManager;
import android.app.PendingIntent;
import android.app.RemoteAction; import android.app.RemoteAction;
import android.app.TaskInfo; import android.app.TaskInfo;
import android.content.ComponentName; import android.content.ComponentName;
@@ -69,7 +70,7 @@ public class TvPipController implements PipTransitionController.PipTransitionCal
private static final int NONEXISTENT_TASK_ID = -1; private static final int NONEXISTENT_TASK_ID = -1;
@Retention(RetentionPolicy.SOURCE) @Retention(RetentionPolicy.SOURCE)
@IntDef(prefix = { "STATE_" }, value = { @IntDef(prefix = {"STATE_"}, value = {
STATE_NO_PIP, STATE_NO_PIP,
STATE_PIP, STATE_PIP,
STATE_PIP_MENU, STATE_PIP_MENU,
@@ -109,6 +110,10 @@ public class TvPipController implements PipTransitionController.PipTransitionCal
private int mPinnedTaskId = NONEXISTENT_TASK_ID; private int mPinnedTaskId = NONEXISTENT_TASK_ID;
private Runnable mUnstashRunnable; private Runnable mUnstashRunnable;
private RemoteAction mCloseAction;
// How long the shell will wait for the app to close the PiP if a custom action is set.
private int mPipForceCloseDelay;
private int mResizeAnimationDuration; private int mResizeAnimationDuration;
public static Pip create( public static Pip create(
@@ -369,9 +374,29 @@ public class TvPipController implements PipTransitionController.PipTransitionCal
public void closePip() { public void closePip() {
if (DEBUG) { if (DEBUG) {
ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
"%s: closePip(), state=%s", TAG, stateToName(mState)); "%s: closePip(), state=%s, loseAction=%s", TAG, stateToName(mState),
mCloseAction);
} }
if (mCloseAction != null) {
try {
mCloseAction.getActionIntent().send();
} catch (PendingIntent.CanceledException e) {
ProtoLog.w(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
"%s: Failed to send close action, %s", TAG, e);
}
mMainExecutor.executeDelayed(() -> closeCurrentPiP(mPinnedTaskId), mPipForceCloseDelay);
} else {
closeCurrentPiP(mPinnedTaskId);
}
}
private void closeCurrentPiP(int pinnedTaskId) {
if (mPinnedTaskId != pinnedTaskId) {
ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
"%s: PiP has already been closed by custom close action", TAG);
return;
}
removeTask(mPinnedTaskId); removeTask(mPinnedTaskId);
onPipDisappeared(); onPipDisappeared();
} }
@@ -468,6 +493,7 @@ public class TvPipController implements PipTransitionController.PipTransitionCal
private void loadConfigurations() { private void loadConfigurations() {
final Resources res = mContext.getResources(); final Resources res = mContext.getResources();
mResizeAnimationDuration = res.getInteger(R.integer.config_pipResizeAnimationDuration); mResizeAnimationDuration = res.getInteger(R.integer.config_pipResizeAnimationDuration);
mPipForceCloseDelay = res.getInteger(R.integer.config_pipForceCloseDelay);
} }
private void registerTaskStackListenerCallback(TaskStackListenerImpl taskStackListener) { private void registerTaskStackListenerCallback(TaskStackListenerImpl taskStackListener) {
@@ -592,13 +618,15 @@ public class TvPipController implements PipTransitionController.PipTransitionCal
public void onMovementBoundsChanged(boolean fromImeAdjustment) {} public void onMovementBoundsChanged(boolean fromImeAdjustment) {}
@Override @Override
public void onActionsChanged(ParceledListSlice<RemoteAction> actions) { public void onActionsChanged(ParceledListSlice<RemoteAction> actions,
RemoteAction closeAction) {
if (DEBUG) { if (DEBUG) {
ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
"%s: onActionsChanged()", TAG); "%s: onActionsChanged()", TAG);
} }
mTvPipMenuController.setAppActions(actions); mTvPipMenuController.setAppActions(actions, closeAction);
mCloseAction = closeAction;
} }
}); });
} catch (RemoteException e) { } catch (RemoteException e) {
@@ -617,7 +645,7 @@ public class TvPipController implements PipTransitionController.PipTransitionCal
WINDOWING_MODE_PINNED, ACTIVITY_TYPE_UNDEFINED); WINDOWING_MODE_PINNED, ACTIVITY_TYPE_UNDEFINED);
if (DEBUG) { if (DEBUG) {
ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
"%s: > taskInfo=%s", TAG, taskInfo); "%s: taskInfo=%s", TAG, taskInfo);
} }
return taskInfo; return taskInfo;
} catch (RemoteException e) { } catch (RemoteException e) {

View File

@@ -126,4 +126,15 @@ public class TvPipMenuActionButton extends RelativeLayout implements View.OnClic
public boolean isEnabled() { public boolean isEnabled() {
return mButtonView.isEnabled(); return mButtonView.isEnabled();
} }
void setIsCustomCloseAction(boolean isCustomCloseAction) {
mIconImageView.setImageTintList(
getResources().getColorStateList(
isCustomCloseAction ? R.color.tv_pip_menu_close_icon
: R.color.tv_pip_menu_icon));
mButtonView.setBackgroundTintList(getResources()
.getColorStateList(isCustomCloseAction ? R.color.tv_pip_menu_close_icon_bg
: R.color.tv_pip_menu_icon_bg));
}
} }

View File

@@ -45,6 +45,7 @@ import com.android.wm.shell.protolog.ShellProtoLogGroup;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects;
/** /**
* Manages the visibility of the PiP Menu as user interacts with PiP. * Manages the visibility of the PiP Menu as user interacts with PiP.
@@ -67,6 +68,7 @@ public class TvPipMenuController implements PipMenuController, TvPipMenuView.Lis
private final List<RemoteAction> mMediaActions = new ArrayList<>(); private final List<RemoteAction> mMediaActions = new ArrayList<>();
private final List<RemoteAction> mAppActions = new ArrayList<>(); private final List<RemoteAction> mAppActions = new ArrayList<>();
private RemoteAction mCloseAction;
private SyncRtSurfaceTransactionApplier mApplier; private SyncRtSurfaceTransactionApplier mApplier;
RectF mTmpSourceRectF = new RectF(); RectF mTmpSourceRectF = new RectF();
@@ -270,12 +272,12 @@ public class TvPipMenuController implements PipMenuController, TvPipMenuView.Lis
} }
@Override @Override
public void setAppActions(ParceledListSlice<RemoteAction> actions) { public void setAppActions(ParceledListSlice<RemoteAction> actions, RemoteAction closeAction) {
if (DEBUG) { if (DEBUG) {
ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
"%s: setAppActions()", TAG); "%s: setAppActions()", TAG);
} }
updateAdditionalActionsList(mAppActions, actions.getList()); updateAdditionalActionsList(mAppActions, actions.getList(), closeAction);
} }
private void onMediaActionsChanged(List<RemoteAction> actions) { private void onMediaActionsChanged(List<RemoteAction> actions) {
@@ -291,17 +293,19 @@ public class TvPipMenuController implements PipMenuController, TvPipMenuView.Lis
enabledActions.add(remoteAction); enabledActions.add(remoteAction);
} }
} }
updateAdditionalActionsList(mMediaActions, enabledActions); updateAdditionalActionsList(mMediaActions, enabledActions, mCloseAction);
} }
private void updateAdditionalActionsList( private void updateAdditionalActionsList(List<RemoteAction> destination,
List<RemoteAction> destination, @Nullable List<RemoteAction> source) { @Nullable List<RemoteAction> source, RemoteAction closeAction) {
final int number = source != null ? source.size() : 0; final int number = source != null ? source.size() : 0;
if (number == 0 && destination.isEmpty()) { if (number == 0 && destination.isEmpty() && Objects.equals(closeAction, mCloseAction)) {
// Nothing changed. // Nothing changed.
return; return;
} }
mCloseAction = closeAction;
destination.clear(); destination.clear();
if (number > 0) { if (number > 0) {
destination.addAll(source); destination.addAll(source);
@@ -314,9 +318,9 @@ public class TvPipMenuController implements PipMenuController, TvPipMenuView.Lis
return; return;
} }
if (!mAppActions.isEmpty()) { if (!mAppActions.isEmpty()) {
mPipMenuView.setAdditionalActions(mAppActions, mMainHandler); mPipMenuView.setAdditionalActions(mAppActions, mCloseAction, mMainHandler);
} else { } else {
mPipMenuView.setAdditionalActions(mMediaActions, mMainHandler); mPipMenuView.setAdditionalActions(mMediaActions, mCloseAction, mMainHandler);
} }
} }

View File

@@ -50,6 +50,7 @@ import com.android.wm.shell.protolog.ShellProtoLogGroup;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects;
/** /**
* A View that represents Pip Menu on TV. It's responsible for displaying 3 ever-present Pip Menu * A View that represents Pip Menu on TV. It's responsible for displaying 3 ever-present Pip Menu
@@ -78,6 +79,7 @@ public class TvPipMenuView extends FrameLayout implements View.OnClickListener {
private Rect mCurrentBounds; private Rect mCurrentBounds;
private final TvPipMenuActionButton mExpandButton; private final TvPipMenuActionButton mExpandButton;
private final TvPipMenuActionButton mCloseButton;
public TvPipMenuView(@NonNull Context context) { public TvPipMenuView(@NonNull Context context) {
this(context, null); this(context, null);
@@ -100,8 +102,11 @@ public class TvPipMenuView extends FrameLayout implements View.OnClickListener {
mActionButtonsContainer = findViewById(R.id.tv_pip_menu_action_buttons); mActionButtonsContainer = findViewById(R.id.tv_pip_menu_action_buttons);
mActionButtonsContainer.findViewById(R.id.tv_pip_menu_fullscreen_button) mActionButtonsContainer.findViewById(R.id.tv_pip_menu_fullscreen_button)
.setOnClickListener(this); .setOnClickListener(this);
mActionButtonsContainer.findViewById(R.id.tv_pip_menu_close_button)
.setOnClickListener(this); mCloseButton = mActionButtonsContainer.findViewById(R.id.tv_pip_menu_close_button);
mCloseButton.setOnClickListener(this);
mCloseButton.setIsCustomCloseAction(true);
mActionButtonsContainer.findViewById(R.id.tv_pip_menu_move_button) mActionButtonsContainer.findViewById(R.id.tv_pip_menu_move_button)
.setOnClickListener(this); .setOnClickListener(this);
mExpandButton = findViewById(R.id.tv_pip_menu_expand_button); mExpandButton = findViewById(R.id.tv_pip_menu_expand_button);
@@ -220,12 +225,24 @@ public class TvPipMenuView extends FrameLayout implements View.OnClickListener {
|| mArrowLeft.getAlpha() != 0f; || mArrowLeft.getAlpha() != 0f;
} }
void setAdditionalActions(List<RemoteAction> actions, Handler mainHandler) { void setAdditionalActions(List<RemoteAction> actions, RemoteAction closeAction,
Handler mainHandler) {
if (DEBUG) { if (DEBUG) {
ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
"%s: setAdditionalActions()", TAG); "%s: setAdditionalActions()", TAG);
} }
// Replace system close action with custom close action if available
if (closeAction != null) {
setActionForButton(closeAction, mCloseButton, mainHandler);
} else {
mCloseButton.setTextAndDescription(R.string.pip_close);
mCloseButton.setImageResource(R.drawable.pip_ic_close_white);
}
mCloseButton.setIsCustomCloseAction(closeAction != null);
// Make sure the close action is always enabled
mCloseButton.setEnabled(true);
// Make sure we exactly as many additional buttons as we have actions to display. // Make sure we exactly as many additional buttons as we have actions to display.
final int actionsNumber = actions.size(); final int actionsNumber = actions.size();
int buttonsNumber = mAdditionalButtons.size(); int buttonsNumber = mAdditionalButtons.size();
@@ -256,14 +273,37 @@ public class TvPipMenuView extends FrameLayout implements View.OnClickListener {
for (int index = 0; index < actionsNumber; index++) { for (int index = 0; index < actionsNumber; index++) {
final RemoteAction action = actions.get(index); final RemoteAction action = actions.get(index);
final TvPipMenuActionButton button = mAdditionalButtons.get(index); final TvPipMenuActionButton button = mAdditionalButtons.get(index);
button.setVisibility(View.VISIBLE); // Ensure the button is visible.
button.setTextAndDescription(action.getContentDescription()); // Remove action if it matches the custom close action.
button.setEnabled(action.isEnabled()); if (actionsMatch(action, closeAction)) {
button.setTag(action); button.setVisibility(GONE);
action.getIcon().loadDrawableAsync(mContext, button::setImageDrawable, mainHandler); continue;
}
setActionForButton(action, button, mainHandler);
} }
} }
/**
* Checks whether title, description and intent match.
* Comparing icons would be good, but using equals causes false negatives
*/
private boolean actionsMatch(RemoteAction action1, RemoteAction action2) {
if (action1 == action2) return true;
if (action1 == null) return false;
return Objects.equals(action1.getTitle(), action2.getTitle())
&& Objects.equals(action1.getContentDescription(), action2.getContentDescription())
&& Objects.equals(action1.getActionIntent(), action2.getActionIntent());
}
private void setActionForButton(RemoteAction action, TvPipMenuActionButton button,
Handler mainHandler) {
button.setVisibility(View.VISIBLE); // Ensure the button is visible.
button.setTextAndDescription(action.getContentDescription());
button.setEnabled(action.isEnabled());
button.setTag(action);
action.getIcon().loadDrawableAsync(mContext, button::setImageDrawable, mainHandler);
}
@Nullable @Nullable
SurfaceControl getWindowSurfaceControl() { SurfaceControl getWindowSurfaceControl() {
final ViewRootImpl root = getViewRootImpl(); final ViewRootImpl root = getViewRootImpl();

View File

@@ -749,7 +749,8 @@ class ActivityClientController extends IActivityClientController.Stub {
rootTask.setPictureInPictureAspectRatio( rootTask.setPictureInPictureAspectRatio(
r.pictureInPictureArgs.getAspectRatioFloat(), r.pictureInPictureArgs.getAspectRatioFloat(),
r.pictureInPictureArgs.getExpandedAspectRatioFloat()); r.pictureInPictureArgs.getExpandedAspectRatioFloat());
rootTask.setPictureInPictureActions(r.pictureInPictureArgs.getActions()); rootTask.setPictureInPictureActions(r.pictureInPictureArgs.getActions(),
r.pictureInPictureArgs.getCloseAction());
} }
} }
} finally { } finally {

View File

@@ -3527,11 +3527,12 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
final float expandedAspectRatio = final float expandedAspectRatio =
r.pictureInPictureArgs.getExpandedAspectRatioFloat(); r.pictureInPictureArgs.getExpandedAspectRatioFloat();
final List<RemoteAction> actions = r.pictureInPictureArgs.getActions(); final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
final RemoteAction closeAction = r.pictureInPictureArgs.getCloseAction();
mRootWindowContainer.moveActivityToPinnedRootTask(r, mRootWindowContainer.moveActivityToPinnedRootTask(r,
null /* launchIntoPipHostActivity */, "enterPictureInPictureMode"); null /* launchIntoPipHostActivity */, "enterPictureInPictureMode");
final Task task = r.getTask(); final Task task = r.getTask();
task.setPictureInPictureAspectRatio(aspectRatio, expandedAspectRatio); task.setPictureInPictureAspectRatio(aspectRatio, expandedAspectRatio);
task.setPictureInPictureActions(actions); task.setPictureInPictureActions(actions, closeAction);
// Continue the pausing process after entering pip. // Continue the pausing process after entering pip.
if (task.getPausingActivity() == r) { if (task.getPausingActivity() == r) {

View File

@@ -92,6 +92,7 @@ class PinnedTaskController {
// The set of actions and aspect-ratio for the that are currently allowed on the PiP activity // The set of actions and aspect-ratio for the that are currently allowed on the PiP activity
private ArrayList<RemoteAction> mActions = new ArrayList<>(); private ArrayList<RemoteAction> mActions = new ArrayList<>();
private RemoteAction mCloseAction;
private float mAspectRatio = -1f; private float mAspectRatio = -1f;
private float mExpandedAspectRatio = 0f; private float mExpandedAspectRatio = 0f;
@@ -154,7 +155,7 @@ class PinnedTaskController {
mPinnedTaskListener = listener; mPinnedTaskListener = listener;
notifyImeVisibilityChanged(mIsImeShowing, mImeHeight); notifyImeVisibilityChanged(mIsImeShowing, mImeHeight);
notifyMovementBoundsChanged(false /* fromImeAdjustment */); notifyMovementBoundsChanged(false /* fromImeAdjustment */);
notifyActionsChanged(mActions); notifyActionsChanged(mActions, mCloseAction);
} catch (RemoteException e) { } catch (RemoteException e) {
Log.e(TAG, "Failed to register pinned task listener", e); Log.e(TAG, "Failed to register pinned task listener", e);
} }
@@ -408,12 +409,13 @@ class PinnedTaskController {
/** /**
* Sets the current set of actions. * Sets the current set of actions.
*/ */
void setActions(List<RemoteAction> actions) { void setActions(List<RemoteAction> actions, RemoteAction closeAction) {
mActions.clear(); mActions.clear();
if (actions != null) { if (actions != null) {
mActions.addAll(actions); mActions.addAll(actions);
} }
notifyActionsChanged(mActions); mCloseAction = closeAction;
notifyActionsChanged(mActions, closeAction);
} }
/** /**
@@ -450,10 +452,10 @@ class PinnedTaskController {
/** /**
* Notifies listeners that the PIP actions have changed. * Notifies listeners that the PIP actions have changed.
*/ */
private void notifyActionsChanged(List<RemoteAction> actions) { private void notifyActionsChanged(List<RemoteAction> actions, RemoteAction closeAction) {
if (mPinnedTaskListener != null) { if (mPinnedTaskListener != null) {
try { try {
mPinnedTaskListener.onActionsChanged(new ParceledListSlice(actions)); mPinnedTaskListener.onActionsChanged(new ParceledListSlice(actions), closeAction);
} catch (RemoteException e) { } catch (RemoteException e) {
Slog.e(TAG_WM, "Error delivering actions changed event.", e); Slog.e(TAG_WM, "Error delivering actions changed event.", e);
} }

View File

@@ -6098,7 +6098,7 @@ class Task extends TaskFragment {
/** /**
* Sets the current picture-in-picture actions. * Sets the current picture-in-picture actions.
*/ */
void setPictureInPictureActions(List<RemoteAction> actions) { void setPictureInPictureActions(List<RemoteAction> actions, RemoteAction closeAction) {
if (!mWmService.mAtmService.mSupportsPictureInPicture) { if (!mWmService.mAtmService.mSupportsPictureInPicture) {
return; return;
} }
@@ -6107,7 +6107,7 @@ class Task extends TaskFragment {
return; return;
} }
getDisplayContent().getPinnedTaskController().setActions(actions); getDisplayContent().getPinnedTaskController().setActions(actions, closeAction);
} }
public DisplayInfo getDisplayInfo() { public DisplayInfo getDisplayInfo() {