summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipMenuController.java106
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java36
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipMenuController.java (renamed from libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuActivityController.java)68
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java10
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java12
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java16
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java12
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipController.java21
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipMenuView.java (renamed from libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipMenuActivity.java)163
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipNotification.java7
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuController.java98
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java10
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java6
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipTouchHandlerTest.java4
-rw-r--r--packages/SystemUI/AndroidManifest.xml14
-rw-r--r--packages/SystemUI/src/com/android/systemui/wmshell/TvPipModule.java16
-rw-r--r--packages/SystemUI/src/com/android/systemui/wmshell/TvWMShellModule.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/wmshell/WMShellModule.java18
19 files changed, 388 insertions, 235 deletions
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipMenuController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipMenuController.java
new file mode 100644
index 000000000000..8d9ad4d1b96c
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipMenuController.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+package com.android.wm.shell.pip;
+
+import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
+import static android.view.WindowManager.LayoutParams.FLAG_SLIPPERY;
+import static android.view.WindowManager.LayoutParams.FLAG_SPLIT_TOUCH;
+import static android.view.WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
+
+import android.annotation.Nullable;
+import android.app.ActivityManager.RunningTaskInfo;
+import android.app.RemoteAction;
+import android.content.pm.ParceledListSlice;
+import android.graphics.PixelFormat;
+import android.graphics.Rect;
+import android.view.SurfaceControl;
+import android.view.WindowManager;
+
+/**
+ * Interface to allow {@link com.android.wm.shell.pip.PipTaskOrganizer} to call into
+ * PiP menu when certain events happen (task appear/vanish, PiP move, etc.)
+ */
+public interface PipMenuController {
+
+ String MENU_WINDOW_TITLE = "PipMenuView";
+
+ /**
+ * Called when
+ * {@link PipTaskOrganizer#onTaskAppeared(RunningTaskInfo, SurfaceControl)}
+ * is called.
+ */
+ void attach(SurfaceControl leash);
+
+ /**
+ * Called when
+ * {@link PipTaskOrganizer#onTaskVanished(RunningTaskInfo)} is called.
+ */
+ void detach();
+
+ /**
+ * Check if menu is visible or not.
+ */
+ boolean isMenuVisible();
+
+ /**
+ * Show the PIP menu.
+ */
+ void showMenu();
+
+ /**
+ * Given a set of actions, update the menu.
+ */
+ void setAppActions(ParceledListSlice<RemoteAction> appActions);
+
+ /**
+ * Resize the PiP menu with the given bounds. The PiP SurfaceControl is given if there is a
+ * need to synchronize the movements on the same frame as PiP.
+ */
+ default void resizePipMenu(@Nullable SurfaceControl pipLeash,
+ @Nullable SurfaceControl.Transaction t,
+ Rect destinationBounds) {}
+
+ /**
+ * Move the PiP menu with the given bounds. The PiP SurfaceControl is given if there is a
+ * need to synchronize the movements on the same frame as PiP.
+ */
+ default void movePipMenu(@Nullable SurfaceControl pipLeash,
+ @Nullable SurfaceControl.Transaction t,
+ Rect destinationBounds) {}
+
+ /**
+ * Update the PiP menu with the given bounds for re-layout purposes.
+ */
+ default void updateMenuBounds(Rect destinationBounds) {}
+
+ /**
+ * Returns a default LayoutParams for the PIP Menu.
+ * @param width the PIP stack width.
+ * @param height the PIP stack height.
+ */
+ default WindowManager.LayoutParams getPipMenuLayoutParams(String title, int width, int height) {
+ final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(width, height,
+ TYPE_APPLICATION_OVERLAY,
+ FLAG_WATCH_OUTSIDE_TOUCH | FLAG_SPLIT_TOUCH | FLAG_SLIPPERY | FLAG_NOT_TOUCHABLE,
+ PixelFormat.TRANSLUCENT);
+ lp.privateFlags |= PRIVATE_FLAG_TRUSTED_OVERLAY;
+ lp.setTitle(title);
+ return lp;
+ }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
index 7cc2a419354e..98ed822a387f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
@@ -63,7 +63,6 @@ import com.android.internal.os.SomeArgs;
import com.android.wm.shell.R;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.common.DisplayController;
-import com.android.wm.shell.pip.phone.PipMenuActivityController;
import com.android.wm.shell.pip.phone.PipMotionHelper;
import com.android.wm.shell.pip.phone.PipUpdateThread;
import com.android.wm.shell.splitscreen.SplitScreen;
@@ -135,8 +134,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
private final Handler mUpdateHandler;
private final PipBoundsState mPipBoundsState;
private final PipBoundsAlgorithm mPipBoundsAlgorithm;
- // TODO(b/172286265): Remove dependency on .pip.PHONE.PipMenuActivityController
- private final PipMenuActivityController mMenuActivityController;
+ private final @NonNull PipMenuController mPipMenuController;
private final PipAnimationController mPipAnimationController;
private final PipUiEventLogger mPipUiEventLoggerLogger;
private final List<PipTransitionCallback> mPipTransitionCallbacks = new ArrayList<>();
@@ -264,7 +262,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
public PipTaskOrganizer(Context context, @NonNull PipBoundsState pipBoundsState,
@NonNull PipBoundsAlgorithm boundsHandler,
- PipMenuActivityController menuActivityController,
+ @NonNull PipMenuController pipMenuController,
@NonNull PipSurfaceTransactionHelper surfaceTransactionHelper,
Optional<SplitScreen> splitScreenOptional,
@NonNull DisplayController displayController,
@@ -274,7 +272,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
mUpdateHandler = new Handler(PipUpdateThread.get().getLooper(), mUpdateCallbacks);
mPipBoundsState = pipBoundsState;
mPipBoundsAlgorithm = boundsHandler;
- mMenuActivityController = menuActivityController;
+ mPipMenuController = pipMenuController;
mEnterExitAnimationDuration = context.getResources()
.getInteger(R.integer.config_pipResizeAnimationDuration);
mSurfaceTransactionHelper = surfaceTransactionHelper;
@@ -501,9 +499,8 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
mOnDisplayIdChangeCallback.accept(info.displayId);
}
- if (mMenuActivityController != null) {
- mMenuActivityController.onTaskAppeared();
- }
+ mPipMenuController.attach(leash);
+
if (mShouldIgnoreEnteringPipTransition) {
final Rect destinationBounds = mPipBoundsState.getBounds();
@@ -674,9 +671,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
mPictureInPictureParams = null;
mState = State.UNDEFINED;
mPipUiEventLoggerLogger.setTaskInfo(null);
- if (mMenuActivityController != null) {
- mMenuActivityController.onTaskVanished();
- }
+ mPipMenuController.detach();
}
@Override
@@ -956,9 +951,9 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
mSurfaceTransactionHelper
.crop(tx, mLeash, destinationBounds)
.round(tx, mLeash, mState.isInPip());
- if (mMenuActivityController != null && mMenuActivityController.isMenuVisible()) {
+ if (mPipMenuController.isMenuVisible()) {
runOnMainHandler(() ->
- mMenuActivityController.resizePipMenu(mLeash, tx, destinationBounds));
+ mPipMenuController.resizePipMenu(mLeash, tx, destinationBounds));
} else {
tx.apply();
}
@@ -982,9 +977,9 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
final SurfaceControl.Transaction tx = mSurfaceControlTransactionFactory.getTransaction();
mSurfaceTransactionHelper.scale(tx, mLeash, startBounds, destinationBounds);
- if (mMenuActivityController != null && mMenuActivityController.isMenuVisible()) {
+ if (mPipMenuController.isMenuVisible()) {
runOnMainHandler(() ->
- mMenuActivityController.movePipMenu(mLeash, tx, destinationBounds));
+ mPipMenuController.movePipMenu(mLeash, tx, destinationBounds));
} else {
tx.apply();
}
@@ -1001,8 +996,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
if (direction == TRANSITION_DIRECTION_REMOVE_STACK) {
removePipImmediately();
return;
- } else if (isInPipDirection(direction) && type == ANIM_TYPE_ALPHA
- && mMenuActivityController != null) {
+ } else if (isInPipDirection(direction) && type == ANIM_TYPE_ALPHA) {
// TODO: Synchronize this correctly in #applyEnterPipSyncTransaction
finishResizeForMenu(destinationBounds);
return;
@@ -1015,13 +1009,9 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
}
private void finishResizeForMenu(Rect destinationBounds) {
- if (mMenuActivityController == null) {
- if (DEBUG) Log.d(TAG, "mMenuActivityController is null");
- return;
- }
runOnMainHandler(() -> {
- mMenuActivityController.movePipMenu(null, null, destinationBounds);
- mMenuActivityController.updateMenuBounds(destinationBounds);
+ mPipMenuController.movePipMenu(null, null, destinationBounds);
+ mPipMenuController.updateMenuBounds(destinationBounds);
});
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuActivityController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipMenuController.java
index d4217553ef2d..5db8f3d7ef40 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuActivityController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipMenuController.java
@@ -18,12 +18,6 @@ package com.android.wm.shell.pip.phone;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
-import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
-import static android.view.WindowManager.LayoutParams.FLAG_SLIPPERY;
-import static android.view.WindowManager.LayoutParams.FLAG_SPLIT_TOUCH;
-import static android.view.WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY;
-import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
import static android.view.WindowManager.SHELL_ROOT_LAYER_PIP;
import android.annotation.Nullable;
@@ -33,7 +27,6 @@ import android.app.RemoteAction;
import android.content.Context;
import android.content.pm.ParceledListSlice;
import android.graphics.Matrix;
-import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.RectF;
import android.os.Debug;
@@ -44,27 +37,26 @@ import android.view.MotionEvent;
import android.view.SurfaceControl;
import android.view.SyncRtSurfaceTransactionApplier;
import android.view.SyncRtSurfaceTransactionApplier.SurfaceParams;
-import android.view.WindowManager;
import android.view.WindowManagerGlobal;
import com.android.wm.shell.common.SystemWindows;
import com.android.wm.shell.pip.PipMediaController;
import com.android.wm.shell.pip.PipMediaController.ActionListener;
+import com.android.wm.shell.pip.PipMenuController;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
/**
- * Manages the PiP menu activity which can show menu options or a scrim.
+ * Manages the PiP menu view which can show menu options or a scrim.
*
* The current media session provides actions whenever there are no valid actions provided by the
* current PiP activity. Otherwise, those actions always take precedence.
*/
-public class PipMenuActivityController {
+public class PhonePipMenuController implements PipMenuController {
private static final String TAG = "PipMenuActController";
- private static final String MENU_WINDOW_TITLE = "PipMenuView";
private static final boolean DEBUG = false;
public static final int MENU_STATE_NONE = 0;
@@ -124,7 +116,7 @@ public class PipMenuActivityController {
}
};
- public PipMenuActivityController(Context context,
+ public PhonePipMenuController(Context context,
PipMediaController mediaController, SystemWindows systemWindows) {
mContext = context;
mMediaController = mediaController;
@@ -138,20 +130,22 @@ public class PipMenuActivityController {
/**
* Attach the menu when the PiP task first appears.
*/
- public void onTaskAppeared() {
+ @Override
+ public void attach(SurfaceControl leash) {
attachPipMenuView();
}
/**
* Detach the menu when the PiP task is gone.
*/
- public void onTaskVanished() {
+ @Override
+ public void detach() {
hideMenu();
detachPipMenuView();
}
- public void onPinnedStackAnimationEnded() {
+ void onPinnedStackAnimationEnded() {
if (isMenuVisible()) {
mPipMenuView.onPipAnimationEnded();
}
@@ -163,7 +157,9 @@ public class PipMenuActivityController {
detachPipMenuView();
}
mPipMenuView = new PipMenuView(mContext, this);
- mSystemWindows.addView(mPipMenuView, getPipMenuLayoutParams(0, 0), 0, SHELL_ROOT_LAYER_PIP);
+ mSystemWindows.addView(mPipMenuView,
+ getPipMenuLayoutParams(MENU_WINDOW_TITLE, 0 /* width */, 0 /* height */),
+ 0, SHELL_ROOT_LAYER_PIP);
}
private void detachPipMenuView() {
@@ -181,9 +177,11 @@ public class PipMenuActivityController {
* Updates the layout parameters of the menu.
* @param destinationBounds New Menu bounds.
*/
+ @Override
public void updateMenuBounds(Rect destinationBounds) {
mSystemWindows.updateViewLayout(mPipMenuView,
- getPipMenuLayoutParams(destinationBounds.width(), destinationBounds.height()));
+ getPipMenuLayoutParams(MENU_WINDOW_TITLE, destinationBounds.width(),
+ destinationBounds.height()));
}
/**
@@ -206,6 +204,16 @@ public class PipMenuActivityController {
}
/**
+ * When other components requests the menu controller directly to show the menu, we must
+ * first fire off the request to the other listeners who will then propagate the call
+ * back to the controller with the right parameters.
+ */
+ @Override
+ public void showMenu() {
+ mListeners.forEach(Listener::onPipShowMenu);
+ }
+
+ /**
* Similar to {@link #showMenu(int, Rect, boolean, boolean, boolean)} but only show the menu
* upon PiP window transition is finished.
*/
@@ -250,6 +258,7 @@ public class PipMenuActivityController {
/**
* Move the PiP menu, which does a translation and possibly a scale transformation.
*/
+ @Override
public void movePipMenu(@Nullable SurfaceControl pipLeash,
@Nullable SurfaceControl.Transaction t,
Rect destinationBounds) {
@@ -290,6 +299,7 @@ public class PipMenuActivityController {
/**
* Does an immediate window crop of the PiP menu.
*/
+ @Override
public void resizePipMenu(@Nullable SurfaceControl pipLeash,
@Nullable SurfaceControl.Transaction t,
Rect destinationBounds) {
@@ -391,8 +401,9 @@ public class PipMenuActivityController {
}
/**
- * Sets the menu actions to the actions provided by the current PiP activity.
+ * Sets the menu actions to the actions provided by the current PiP menu.
*/
+ @Override
public void setAppActions(ParceledListSlice<RemoteAction> appActions) {
mAppActions = appActions;
updateMenuActions();
@@ -406,10 +417,6 @@ public class PipMenuActivityController {
mListeners.forEach(Listener::onPipDismiss);
}
- void onPipShowMenu() {
- mListeners.forEach(Listener::onPipShowMenu);
- }
-
/**
* @return the best set of actions to show in the PiP menu.
*/
@@ -421,21 +428,6 @@ public class PipMenuActivityController {
}
/**
- * Returns a default LayoutParams for the PIP Menu.
- * @param width the PIP stack width.
- * @param height the PIP stack height.
- */
- public static WindowManager.LayoutParams getPipMenuLayoutParams(int width, int height) {
- final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(width, height,
- TYPE_APPLICATION_OVERLAY,
- FLAG_WATCH_OUTSIDE_TOUCH | FLAG_SPLIT_TOUCH | FLAG_SLIPPERY | FLAG_NOT_TOUCHABLE,
- PixelFormat.TRANSLUCENT);
- lp.privateFlags |= PRIVATE_FLAG_TRUSTED_OVERLAY;
- lp.setTitle(MENU_WINDOW_TITLE);
- return lp;
- }
-
- /**
* Updates the PiP menu with the best set of actions provided.
*/
private void updateMenuActions() {
@@ -521,7 +513,7 @@ public class PipMenuActivityController {
}
}
- public void dump(PrintWriter pw, String prefix) {
+ void dump(PrintWriter pw, String prefix) {
final String innerPrefix = prefix + " ";
pw.println(prefix + TAG);
pw.println(innerPrefix + "mMenuState=" + mMenuState);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
index 598b5d9b5d30..db02e284731e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
@@ -92,7 +92,7 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac
private boolean mIsInFixedRotation;
private Consumer<Boolean> mPinnedStackAnimationRecentsCallback;
- protected PipMenuActivityController mMenuController;
+ protected PhonePipMenuController mMenuController;
protected PipTaskOrganizer mPipTaskOrganizer;
protected PinnedStackListenerForwarder.PinnedStackListener mPinnedStackListener =
new PipControllerPinnedStackListener();
@@ -229,7 +229,7 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac
PipBoundsAlgorithm pipBoundsAlgorithm,
@NonNull PipBoundsState pipBoundsState,
PipMediaController pipMediaController,
- PipMenuActivityController pipMenuActivityController,
+ PhonePipMenuController phonePipMenuController,
PipTaskOrganizer pipTaskOrganizer,
PipTouchHandler pipTouchHandler,
WindowManagerShellWrapper windowManagerShellWrapper,
@@ -250,7 +250,7 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac
mPipTaskOrganizer = pipTaskOrganizer;
mMainExecutor = mainExecutor;
mMediaController = pipMediaController;
- mMenuController = pipMenuActivityController;
+ mMenuController = phonePipMenuController;
mTouchHandler = pipTouchHandler;
mAppOpsListener = pipAppOpsListener;
mPipInputConsumer = new PipInputConsumer(WindowManagerGlobal.getWindowManagerService(),
@@ -632,7 +632,7 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac
public static PipController create(Context context, DisplayController displayController,
PipAppOpsListener pipAppOpsListener, PipBoundsAlgorithm pipBoundsAlgorithm,
PipBoundsState pipBoundsState, PipMediaController pipMediaController,
- PipMenuActivityController pipMenuActivityController, PipTaskOrganizer pipTaskOrganizer,
+ PhonePipMenuController phonePipMenuController, PipTaskOrganizer pipTaskOrganizer,
PipTouchHandler pipTouchHandler, WindowManagerShellWrapper windowManagerShellWrapper,
TaskStackListenerImpl taskStackListener, ShellExecutor mainExecutor) {
if (!context.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE)) {
@@ -641,7 +641,7 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac
}
return new PipController(context, displayController, pipAppOpsListener, pipBoundsAlgorithm,
- pipBoundsState, pipMediaController, pipMenuActivityController, pipTaskOrganizer,
+ pipBoundsState, pipMediaController, phonePipMenuController, pipTaskOrganizer,
pipTouchHandler, windowManagerShellWrapper, taskStackListener, mainExecutor);
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java
index 6e3cd8e9aa09..4e991f2e919b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java
@@ -23,9 +23,9 @@ import static android.view.accessibility.AccessibilityManager.FLAG_CONTENT_CONTR
import static android.view.accessibility.AccessibilityManager.FLAG_CONTENT_ICONS;
import static android.view.accessibility.AccessibilityNodeInfo.ACTION_CLICK;
-import static com.android.wm.shell.pip.phone.PipMenuActivityController.MENU_STATE_CLOSE;
-import static com.android.wm.shell.pip.phone.PipMenuActivityController.MENU_STATE_FULL;
-import static com.android.wm.shell.pip.phone.PipMenuActivityController.MENU_STATE_NONE;
+import static com.android.wm.shell.pip.phone.PhonePipMenuController.MENU_STATE_CLOSE;
+import static com.android.wm.shell.pip.phone.PhonePipMenuController.MENU_STATE_FULL;
+import static com.android.wm.shell.pip.phone.PhonePipMenuController.MENU_STATE_NONE;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -105,7 +105,7 @@ public class PipMenuView extends FrameLayout {
private int mBetweenActionPaddingLand;
private AnimatorSet mMenuContainerAnimator;
- private PipMenuActivityController mController;
+ private PhonePipMenuController mController;
private ValueAnimator.AnimatorUpdateListener mMenuBgUpdateListener =
new ValueAnimator.AnimatorUpdateListener() {
@@ -127,7 +127,7 @@ public class PipMenuView extends FrameLayout {
protected View mTopEndContainer;
protected PipMenuIconsAlgorithm mPipMenuIconsAlgorithm;
- public PipMenuView(Context context, PipMenuActivityController controller) {
+ public PipMenuView(Context context, PhonePipMenuController controller) {
super(context, null, 0);
mContext = context;
mController = controller;
@@ -182,7 +182,7 @@ public class PipMenuView extends FrameLayout {
@Override
public boolean performAccessibilityAction(View host, int action, Bundle args) {
if (action == ACTION_CLICK && mMenuState == MENU_STATE_CLOSE) {
- mController.onPipShowMenu();
+ mController.showMenu();
}
return super.performAccessibilityAction(host, action, args);
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java
index 903f7d773896..e32d3b955081 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java
@@ -70,7 +70,7 @@ public class PipMotionHelper implements PipAppOpsListener.Callback,
private final PipTaskOrganizer mPipTaskOrganizer;
private @NonNull PipBoundsState mPipBoundsState;
- private PipMenuActivityController mMenuController;
+ private PhonePipMenuController mMenuController;
private PipSnapAlgorithm mSnapAlgorithm;
private final Handler mMainHandler = new Handler(Looper.getMainLooper());
@@ -162,7 +162,7 @@ public class PipMotionHelper implements PipAppOpsListener.Callback,
};
public PipMotionHelper(Context context, @NonNull PipBoundsState pipBoundsState,
- PipTaskOrganizer pipTaskOrganizer, PipMenuActivityController menuController,
+ PipTaskOrganizer pipTaskOrganizer, PhonePipMenuController menuController,
PipSnapAlgorithm snapAlgorithm, FloatingContentCoordinator floatingContentCoordinator) {
mContext = context;
mPipTaskOrganizer = pipTaskOrganizer;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java
index e5a49c430d82..bb545bdda922 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java
@@ -103,7 +103,7 @@ public class PipResizeGestureHandler {
private InputMonitor mInputMonitor;
private InputEventReceiver mInputEventReceiver;
private PipTaskOrganizer mPipTaskOrganizer;
- private PipMenuActivityController mPipMenuActivityController;
+ private PhonePipMenuController mPhonePipMenuController;
private PipUiEventLogger mPipUiEventLogger;
private int mCtrlType;
@@ -112,7 +112,7 @@ public class PipResizeGestureHandler {
PipBoundsState pipBoundsState, PipMotionHelper motionHelper,
PipTaskOrganizer pipTaskOrganizer, Function<Rect, Rect> movementBoundsSupplier,
Runnable updateMovementBoundsRunnable, PipUiEventLogger pipUiEventLogger,
- PipMenuActivityController menuActivityController) {
+ PhonePipMenuController menuActivityController) {
mContext = context;
mDisplayId = context.getDisplayId();
mMainExecutor = context.getMainExecutor();
@@ -122,7 +122,7 @@ public class PipResizeGestureHandler {
mPipTaskOrganizer = pipTaskOrganizer;
mMovementBoundsSupplier = movementBoundsSupplier;
mUpdateMovementBoundsRunnable = updateMovementBoundsRunnable;
- mPipMenuActivityController = menuActivityController;
+ mPhonePipMenuController = menuActivityController;
mPipUiEventLogger = pipUiEventLogger;
context.getDisplay().getRealSize(mMaxSize);
@@ -422,8 +422,8 @@ public class PipResizeGestureHandler {
mLastDownBounds.set(mPipBoundsState.getBounds());
}
if (!currentPipBounds.contains((int) ev.getX(), (int) ev.getY())
- && mPipMenuActivityController.isMenuVisible()) {
- mPipMenuActivityController.hideMenu();
+ && mPhonePipMenuController.isMenuVisible()) {
+ mPhonePipMenuController.hideMenu();
}
} else if (mAllowGesture) {
@@ -442,9 +442,9 @@ public class PipResizeGestureHandler {
mInputMonitor.pilferPointers();
}
if (mThresholdCrossed) {
- if (mPipMenuActivityController.isMenuVisible()) {
- mPipMenuActivityController.hideMenuWithoutResize();
- mPipMenuActivityController.hideMenu();
+ if (mPhonePipMenuController.isMenuVisible()) {
+ mPhonePipMenuController.hideMenuWithoutResize();
+ mPhonePipMenuController.hideMenu();
}
final Rect currentPipBounds = mPipBoundsState.getBounds();
mLastResizeBounds.set(TaskResizingAlgorithm.resizeDrag(x, y,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java
index a78c4ecdb39f..99177016c30c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java
@@ -18,9 +18,9 @@ package com.android.wm.shell.pip.phone;
import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.PIP_STASHING;
import static com.android.wm.shell.pip.PipAnimationController.TRANSITION_DIRECTION_TO_PIP;
-import static com.android.wm.shell.pip.phone.PipMenuActivityController.MENU_STATE_CLOSE;
-import static com.android.wm.shell.pip.phone.PipMenuActivityController.MENU_STATE_FULL;
-import static com.android.wm.shell.pip.phone.PipMenuActivityController.MENU_STATE_NONE;
+import static com.android.wm.shell.pip.phone.PhonePipMenuController.MENU_STATE_CLOSE;
+import static com.android.wm.shell.pip.phone.PhonePipMenuController.MENU_STATE_FULL;
+import static com.android.wm.shell.pip.phone.PhonePipMenuController.MENU_STATE_NONE;
import android.annotation.NonNull;
import android.annotation.SuppressLint;
@@ -78,7 +78,7 @@ public class PipTouchHandler {
private IPinnedStackController mPinnedStackController;
private WeakReference<Consumer<Rect>> mPipExclusionBoundsChangeListener;
- private final PipMenuActivityController mMenuController;
+ private final PhonePipMenuController mMenuController;
private final AccessibilityManager mAccessibilityManager;
private boolean mShowPipMenuOnAnimationEnd = false;
@@ -125,7 +125,7 @@ public class PipTouchHandler {
/**
* A listener for the PIP menu activity.
*/
- private class PipMenuListener implements PipMenuActivityController.Listener {
+ private class PipMenuListener implements PhonePipMenuController.Listener {
@Override
public void onPipMenuStateChanged(int menuState, boolean resize, Runnable callback) {
setMenuState(menuState, resize, callback);
@@ -152,7 +152,7 @@ public class PipTouchHandler {
@SuppressLint("InflateParams")
public PipTouchHandler(Context context,
- PipMenuActivityController menuController,
+ PhonePipMenuController menuController,
PipBoundsAlgorithm pipBoundsAlgorithm,
@NonNull PipBoundsState pipBoundsState,
PipTaskOrganizer pipTaskOrganizer,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipController.java
index 56e97b91c9d2..fcc3c9c4cc5d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipController.java
@@ -111,6 +111,7 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac
private final PipBoundsAlgorithm mPipBoundsAlgorithm;
private final PipTaskOrganizer mPipTaskOrganizer;
private final PipMediaController mPipMediaController;
+ private final TvPipMenuController mTvPipMenuController;
private IActivityTaskManager mActivityTaskManager;
private int mState = STATE_NO_PIP;
@@ -217,9 +218,7 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac
public void onActionsChanged(ParceledListSlice<RemoteAction> actions) {
mCustomActions = actions;
mHandler.post(() -> {
- for (int i = mListeners.size() - 1; i >= 0; --i) {
- mListeners.get(i).onPipMenuActionsChanged(mCustomActions);
- }
+ mTvPipMenuController.setAppActions(mCustomActions);
});
}
}
@@ -228,6 +227,7 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac
PipBoundsState pipBoundsState,
PipBoundsAlgorithm pipBoundsAlgorithm,
PipTaskOrganizer pipTaskOrganizer,
+ TvPipMenuController tvPipMenuController,
PipMediaController pipMediaController,
PipNotification pipNotification,
TaskStackListenerImpl taskStackListener,
@@ -237,6 +237,8 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac
mPipNotification = pipNotification;
mPipBoundsAlgorithm = pipBoundsAlgorithm;
mPipMediaController = pipMediaController;
+ mTvPipMenuController = tvPipMenuController;
+ mTvPipMenuController.attachPipController(this);
// Ensure that we have the display info in case we get calls to update the bounds
// before the listener calls back
final DisplayInfo displayInfo = new DisplayInfo();
@@ -289,9 +291,6 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac
PipController.this.onActivityRestartAttempt(task, clearedTask);
}
});
-
- // TODO(b/169395392) Refactor PipMenuActivity to PipMenuView
- PipMenuActivity.setPipController(this);
}
private void loadConfigurationsAndApply(Configuration newConfig) {
@@ -451,7 +450,6 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac
Log.d(TAG,
"suspendPipResizing() reason=" + reason + " callers=" + Debug.getCallers(2));
}
-
mSuspendPipResizingReason |= reason;
}
@@ -478,6 +476,7 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac
* @param state In Pip state also used to determine the new size for the Pip.
*/
public void resizePinnedStack(int state) {
+
if (DEBUG) {
Log.d(TAG, "resizePinnedStack() state=" + stateToName(state) + ", current state="
+ getStateDescription(), new Exception());
@@ -544,10 +543,8 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac
for (int i = mListeners.size() - 1; i >= 0; --i) {
mListeners.get(i).onShowPipMenu();
}
- Intent intent = new Intent(mContext, PipMenuActivity.class);
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- intent.putExtra(PipMenuActivity.EXTRA_CUSTOM_ACTIONS, mCustomActions);
- mContext.startActivity(intent);
+
+ mTvPipMenuController.showMenu();
}
/**
@@ -650,8 +647,6 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac
void onPipActivityClosed();
/** Invoked when the PIP menu gets shown. */
void onShowPipMenu();
- /** Invoked when the PIP menu actions change. */
- void onPipMenuActionsChanged(ParceledListSlice<RemoteAction> actions);
/** Invoked when the PIPed activity is about to return back to the fullscreen. */
void onMoveToFullscreen();
/** Invoked when we are above to start resizing the Pip. */
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipMenuActivity.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipMenuView.java
index d2270c278161..689c3ede9efa 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipMenuActivity.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipMenuView.java
@@ -18,109 +18,110 @@ package com.android.wm.shell.pip.tv;
import android.animation.Animator;
import android.animation.AnimatorInflater;
-import android.app.Activity;
+import android.annotation.Nullable;
import android.app.RemoteAction;
-import android.content.Intent;
+import android.content.Context;
import android.content.pm.ParceledListSlice;
-import android.os.Bundle;
import android.util.Log;
+import android.view.KeyEvent;
+import android.view.SurfaceControl;
+import android.view.ViewRootImpl;
+import android.view.WindowManagerGlobal;
+import android.widget.FrameLayout;
import com.android.wm.shell.R;
import java.util.Collections;
/**
- * Activity to show the PIP menu to control PIP.
- * TODO(b/169395392) Refactor PipMenuActivity to PipMenuView
+ * The Menu View that shows controls of the PiP. Always fullscreen.
*/
-public class PipMenuActivity extends Activity implements PipController.Listener {
- private static final String TAG = "PipMenuActivity";
+public class PipMenuView extends FrameLayout implements PipController.Listener {
+ private static final String TAG = "PipMenuView";
private static final boolean DEBUG = PipController.DEBUG;
- static final String EXTRA_CUSTOM_ACTIONS = "custom_actions";
-
- private static PipController sPipController;
-
- private Animator mFadeInAnimation;
- private Animator mFadeOutAnimation;
+ private final PipController mPipController;
+ private final Animator mFadeInAnimation;
+ private final Animator mFadeOutAnimation;
+ private final PipControlsViewController mPipControlsViewController;
private boolean mRestorePipSizeWhenClose;
- private PipControlsViewController mPipControlsViewController;
- @Override
- protected void onCreate(Bundle bundle) {
- if (DEBUG) Log.d(TAG, "onCreate()");
+ public PipMenuView(Context context, PipController pipController) {
+ super(context, null, 0);
+ mPipController = pipController;
+
+ inflate(context, R.layout.tv_pip_menu, this);
- super.onCreate(bundle);
- if (sPipController == null) {
- finish();
- }
- setContentView(R.layout.tv_pip_menu);
mPipControlsViewController = new PipControlsViewController(
- findViewById(R.id.pip_controls), sPipController);
- sPipController.addListener(this);
+ findViewById(R.id.pip_controls), mPipController);
mRestorePipSizeWhenClose = true;
mFadeInAnimation = AnimatorInflater.loadAnimator(
- this, R.anim.tv_pip_menu_fade_in_animation);
+ mContext, R.anim.tv_pip_menu_fade_in_animation);
mFadeInAnimation.setTarget(mPipControlsViewController.getView());
mFadeOutAnimation = AnimatorInflater.loadAnimator(
- this, R.anim.tv_pip_menu_fade_out_animation);
+ mContext, R.anim.tv_pip_menu_fade_out_animation);
mFadeOutAnimation.setTarget(mPipControlsViewController.getView());
-
- onPipMenuActionsChanged(getIntent().getParcelableExtra(EXTRA_CUSTOM_ACTIONS));
}
@Override
- protected void onNewIntent(Intent intent) {
- if (DEBUG) Log.d(TAG, "onNewIntent(), intent=" + intent);
- super.onNewIntent(intent);
-
- onPipMenuActionsChanged(getIntent().getParcelableExtra(EXTRA_CUSTOM_ACTIONS));
+ public boolean dispatchKeyEvent(KeyEvent event) {
+ if (event.getKeyCode() == KeyEvent.KEYCODE_BACK
+ && event.getAction() == KeyEvent.ACTION_UP) {
+ restorePipAndFinish();
+ return true;
+ }
+ return super.dispatchKeyEvent(event);
}
- private void restorePipAndFinish() {
- if (DEBUG) Log.d(TAG, "restorePipAndFinish()");
-
- if (mRestorePipSizeWhenClose) {
- if (DEBUG) Log.d(TAG, " > restoring to the default position");
-
- // When PIP menu activity is closed, restore to the default position.
- sPipController.resizePinnedStack(PipController.STATE_PIP);
+ @Nullable
+ SurfaceControl getWindowSurfaceControl() {
+ final ViewRootImpl root = getViewRootImpl();
+ if (root == null) {
+ return null;
+ }
+ final SurfaceControl out = root.getSurfaceControl();
+ if (out != null && out.isValid()) {
+ return out;
}
- finish();
+ return null;
}
- @Override
- public void onResume() {
- if (DEBUG) Log.d(TAG, "onResume()");
-
- super.onResume();
+ void showMenu() {
+ mPipController.addListener(this);
mFadeInAnimation.start();
+ setAlpha(1.0f);
+ try {
+ WindowManagerGlobal.getWindowSession().grantEmbeddedWindowFocus(null /* window */,
+ getViewRootImpl().getInputToken(), true /* grantFocus */);
+ } catch (Exception e) {
+ Log.e(TAG, "Unable to update focus as menu appears", e);
+ }
}
- @Override
- public void onPause() {
- if (DEBUG) Log.d(TAG, "onPause()");
-
- super.onPause();
+ void hideMenu() {
+ mPipController.removeListener(this);
+ mPipController.resumePipResizing(
+ PipController.SUSPEND_PIP_RESIZE_REASON_WAITING_FOR_MENU_ACTIVITY_FINISH);
mFadeOutAnimation.start();
- restorePipAndFinish();
+ setAlpha(0.0f);
+ try {
+ WindowManagerGlobal.getWindowSession().grantEmbeddedWindowFocus(null /* window */,
+ getViewRootImpl().getInputToken(), false /* grantFocus */);
+ } catch (Exception e) {
+ Log.e(TAG, "Unable to update focus as menu disappears", e);
+ }
}
- @Override
- protected void onDestroy() {
- if (DEBUG) Log.d(TAG, "onDestroy()");
-
- super.onDestroy();
- sPipController.removeListener(this);
- sPipController.resumePipResizing(
- PipController.SUSPEND_PIP_RESIZE_REASON_WAITING_FOR_MENU_ACTIVITY_FINISH);
- }
+ private void restorePipAndFinish() {
+ if (DEBUG) Log.d(TAG, "restorePipAndFinish()");
- @Override
- public void onBackPressed() {
- if (DEBUG) Log.d(TAG, "onBackPressed()");
+ if (mRestorePipSizeWhenClose) {
+ if (DEBUG) Log.d(TAG, " > restoring to the default position");
- restorePipAndFinish();
+ // When PIP menu activity is closed, restore to the default position.
+ mPipController.resizePinnedStack(PipController.STATE_PIP);
+ }
+ hideMenu();
}
@Override
@@ -132,11 +133,10 @@ public class PipMenuActivity extends Activity implements PipController.Listener
public void onPipActivityClosed() {
if (DEBUG) Log.d(TAG, "onPipActivityClosed()");
- finish();
+ hideMenu();
}
- @Override
- public void onPipMenuActionsChanged(ParceledListSlice<RemoteAction> actions) {
+ void setAppActions(ParceledListSlice<RemoteAction> actions) {
if (DEBUG) Log.d(TAG, "onPipMenuActionsChanged()");
boolean hasCustomActions = actions != null && !actions.getList().isEmpty();
@@ -156,34 +156,15 @@ public class PipMenuActivity extends Activity implements PipController.Listener
// Moving PIP to fullscreen is implemented by resizing PINNED_STACK with null bounds.
// This conflicts with restoring PIP position, so disable it.
mRestorePipSizeWhenClose = false;
- finish();
+ hideMenu();
}
@Override
public void onPipResizeAboutToStart() {
if (DEBUG) Log.d(TAG, "onPipResizeAboutToStart()");
- finish();
- sPipController.suspendPipResizing(
+ hideMenu();
+ mPipController.suspendPipResizing(
PipController.SUSPEND_PIP_RESIZE_REASON_WAITING_FOR_MENU_ACTIVITY_FINISH);
}
-
- @Override
- public void finish() {
- if (DEBUG) Log.d(TAG, "finish()", new RuntimeException());
-
- super.finish();
- }
-
- /**
- * TODO(b/169395392) Refactor PipMenuActivity to PipMenuView
- *
- * @param pipController The singleton pipController instance for TV
- */
- public static void setPipController(PipController pipController) {
- if (sPipController != null) {
- return;
- }
- sPipController = pipController;
- }
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipNotification.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipNotification.java
index b30dee4f331f..d56a88874420 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipNotification.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipNotification.java
@@ -19,12 +19,10 @@ package com.android.wm.shell.pip.tv;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
-import android.app.RemoteAction;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
-import android.content.pm.ParceledListSlice;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.media.MediaMetadata;
@@ -99,11 +97,6 @@ public class PipNotification implements PipController.Listener {
}
@Override
- public void onPipMenuActionsChanged(ParceledListSlice<RemoteAction> actions) {
- // no-op.
- }
-
- @Override
public void onMoveToFullscreen() {
dismissPipNotification();
mPackageName = null;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuController.java
new file mode 100644
index 000000000000..91aef670b946
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuController.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+package com.android.wm.shell.pip.tv;
+
+import static android.view.WindowManager.SHELL_ROOT_LAYER_PIP;
+
+import android.app.RemoteAction;
+import android.content.Context;
+import android.content.pm.ParceledListSlice;
+import android.view.SurfaceControl;
+
+import com.android.wm.shell.common.SystemWindows;
+import com.android.wm.shell.pip.PipBoundsState;
+import com.android.wm.shell.pip.PipMenuController;
+
+/**
+ * Manages the visibility of the PiP Menu as user interacts with PiP.
+ */
+public class TvPipMenuController implements PipMenuController {
+
+ private final Context mContext;
+ private final SystemWindows mSystemWindows;
+ private final PipBoundsState mPipBoundsState;
+ private PipMenuView mMenuView;
+ private PipController mPipController;
+ private SurfaceControl mLeash;
+
+ public TvPipMenuController(Context context, PipBoundsState pipBoundsState,
+ SystemWindows systemWindows) {
+ mContext = context;
+ mPipBoundsState = pipBoundsState;
+ mSystemWindows = systemWindows;
+ }
+
+ void attachPipController(PipController pipController) {
+ mPipController = pipController;
+ }
+
+ @Override
+ public void showMenu() {
+ if (mMenuView != null) {
+ mSystemWindows.updateViewLayout(mMenuView, getPipMenuLayoutParams(MENU_WINDOW_TITLE,
+ mPipBoundsState.getDisplayBounds().width(),
+ mPipBoundsState.getDisplayBounds().height()));
+ mMenuView.showMenu();
+
+ // By default, SystemWindows views are above everything else.
+ // Set the relative z-order so the menu is below PiP.
+ if (mMenuView.getWindowSurfaceControl() != null && mLeash != null) {
+ SurfaceControl.Transaction t = new SurfaceControl.Transaction();
+ t.setRelativeLayer(mMenuView.getWindowSurfaceControl(), mLeash, -1);
+ t.apply();
+ }
+ }
+ }
+
+ @Override
+ public void attach(SurfaceControl leash) {
+ if (mMenuView == null) {
+ mMenuView = new PipMenuView(mContext, mPipController);
+ mSystemWindows.addView(mMenuView,
+ getPipMenuLayoutParams(MENU_WINDOW_TITLE, 0 /* width */, 0 /* height */),
+ 0, SHELL_ROOT_LAYER_PIP);
+ mLeash = leash;
+ }
+ }
+
+ @Override
+ public void detach() {
+ mSystemWindows.removeView(mMenuView);
+ mMenuView = null;
+ mLeash = null;
+ }
+
+ @Override
+ public void setAppActions(ParceledListSlice<RemoteAction> appActions) {
+ mMenuView.setAppActions(appActions);
+ }
+
+ @Override
+ public boolean isMenuVisible() {
+ return mMenuView != null && mMenuView.getAlpha() == 1.0f;
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java
index 8d3774cee1e0..45e4241d5bc6 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java
@@ -44,7 +44,7 @@ import android.window.WindowContainerToken;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.ShellTestCase;
import com.android.wm.shell.common.DisplayController;
-import com.android.wm.shell.pip.phone.PipMenuActivityController;
+import com.android.wm.shell.pip.phone.PhonePipMenuController;
import com.android.wm.shell.splitscreen.SplitScreen;
import org.junit.Before;
@@ -66,7 +66,7 @@ public class PipTaskOrganizerTest extends ShellTestCase {
@Mock private DisplayController mMockdDisplayController;
@Mock private PipBoundsAlgorithm mMockPipBoundsAlgorithm;
- @Mock private PipMenuActivityController mMenuActivityController;
+ @Mock private PhonePipMenuController mMockPhonePipMenuController;
@Mock private PipSurfaceTransactionHelper mMockPipSurfaceTransactionHelper;
@Mock private PipUiEventLogger mMockPipUiEventLogger;
@Mock private Optional<SplitScreen> mMockOptionalSplitScreen;
@@ -83,9 +83,9 @@ public class PipTaskOrganizerTest extends ShellTestCase {
mComponent2 = new ComponentName(mContext, "component2");
mPipBoundsState = new PipBoundsState(mContext);
mSpiedPipTaskOrganizer = spy(new PipTaskOrganizer(mContext, mPipBoundsState,
- mMockPipBoundsAlgorithm, mMenuActivityController, mMockPipSurfaceTransactionHelper,
- mMockOptionalSplitScreen, mMockdDisplayController, mMockPipUiEventLogger,
- mMockShellTaskOrganizer));
+ mMockPipBoundsAlgorithm, mMockPhonePipMenuController,
+ mMockPipSurfaceTransactionHelper, mMockOptionalSplitScreen, mMockdDisplayController,
+ mMockPipUiEventLogger, mMockShellTaskOrganizer));
preparePipTaskOrg();
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java
index 88c8eb902a6f..4687d2d9667c 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java
@@ -61,7 +61,7 @@ public class PipControllerTest extends ShellTestCase {
private PipController mPipController;
@Mock private DisplayController mMockDisplayController;
- @Mock private PipMenuActivityController mMockPipMenuActivityController;
+ @Mock private PhonePipMenuController mMockPhonePipMenuController;
@Mock private PipAppOpsListener mMockPipAppOpsListener;
@Mock private PipBoundsAlgorithm mMockPipBoundsAlgorithm;
@Mock private PipMediaController mMockPipMediaController;
@@ -77,7 +77,7 @@ public class PipControllerTest extends ShellTestCase {
MockitoAnnotations.initMocks(this);
mPipController = new PipController(mContext, mMockDisplayController,
mMockPipAppOpsListener, mMockPipBoundsAlgorithm, mMockPipBoundsState,
- mMockPipMediaController, mMockPipMenuActivityController, mMockPipTaskOrganizer,
+ mMockPipMediaController, mMockPhonePipMenuController, mMockPipTaskOrganizer,
mMockPipTouchHandler, mMockWindowManagerShellWrapper, mMockTaskStackListener,
mMockExecutor);
doAnswer(invocation -> {
@@ -110,7 +110,7 @@ public class PipControllerTest extends ShellTestCase {
assertNull(PipController.create(spyContext, mMockDisplayController,
mMockPipAppOpsListener, mMockPipBoundsAlgorithm, mMockPipBoundsState,
- mMockPipMediaController, mMockPipMenuActivityController, mMockPipTaskOrganizer,
+ mMockPipMediaController, mMockPhonePipMenuController, mMockPipTaskOrganizer,
mMockPipTouchHandler, mMockWindowManagerShellWrapper, mMockTaskStackListener,
mMockExecutor));
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipTouchHandlerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipTouchHandlerTest.java
index abbc681f53fe..e60221943898 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipTouchHandlerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipTouchHandlerTest.java
@@ -60,7 +60,7 @@ public class PipTouchHandlerTest extends ShellTestCase {
private PipTouchHandler mPipTouchHandler;
@Mock
- private PipMenuActivityController mPipMenuActivityController;
+ private PhonePipMenuController mPhonePipMenuController;
@Mock
private PipTaskOrganizer mPipTaskOrganizer;
@@ -92,7 +92,7 @@ public class PipTouchHandlerTest extends ShellTestCase {
mPipBoundsAlgorithm = new PipBoundsAlgorithm(mContext, mPipBoundsState);
mPipSnapAlgorithm = mPipBoundsAlgorithm.getSnapAlgorithm();
mPipSnapAlgorithm = new PipSnapAlgorithm();
- mPipTouchHandler = new PipTouchHandler(mContext, mPipMenuActivityController,
+ mPipTouchHandler = new PipTouchHandler(mContext, mPhonePipMenuController,
mPipBoundsAlgorithm, mPipBoundsState, mPipTaskOrganizer,
mFloatingContentCoordinator, mPipUiEventLogger);
mMotionHelper = Mockito.spy(mPipTouchHandler.getMotionHelper());
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 52b41a43c63e..2da958f6b8b9 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -516,20 +516,6 @@
android:excludeFromRecents="true"
android:visibleToInstantApps="true"/>
- <!-- started from PipController -->
- <activity
- android:name="com.android.wm.shell.pip.tv.PipMenuActivity"
- android:permission="com.android.systemui.permission.SELF"
- android:exported="false"
- android:theme="@style/PipTheme"
- android:launchMode="singleTop"
- android:taskAffinity=""
- android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation|locale|layoutDirection"
- android:resizeableActivity="true"
- android:supportsPictureInPicture="true"
- androidprv:alwaysFocusable="true"
- android:excludeFromRecents="true" />
-
<!-- started from TvNotificationPanel -->
<activity
android:name=".statusbar.tv.notifications.TvNotificationPanelActivity"
diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/TvPipModule.java b/packages/SystemUI/src/com/android/systemui/wmshell/TvPipModule.java
index 86ba5f1f74a9..8dea5b5a19a3 100644
--- a/packages/SystemUI/src/com/android/systemui/wmshell/TvPipModule.java
+++ b/packages/SystemUI/src/com/android/systemui/wmshell/TvPipModule.java
@@ -22,6 +22,7 @@ import com.android.systemui.dagger.WMSingleton;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.WindowManagerShellWrapper;
import com.android.wm.shell.common.DisplayController;
+import com.android.wm.shell.common.SystemWindows;
import com.android.wm.shell.common.TaskStackListenerImpl;
import com.android.wm.shell.pip.Pip;
import com.android.wm.shell.pip.PipBoundsAlgorithm;
@@ -34,6 +35,7 @@ import com.android.wm.shell.pip.tv.PipController;
import com.android.wm.shell.pip.tv.PipControlsView;
import com.android.wm.shell.pip.tv.PipControlsViewController;
import com.android.wm.shell.pip.tv.PipNotification;
+import com.android.wm.shell.pip.tv.TvPipMenuController;
import com.android.wm.shell.splitscreen.SplitScreen;
import java.util.Optional;
@@ -44,7 +46,7 @@ import dagger.Provides;
/**
* Dagger module for TV Pip.
*/
-@Module
+@Module(includes = {WMShellBaseModule.class})
public abstract class TvPipModule {
@WMSingleton
@Provides
@@ -53,6 +55,7 @@ public abstract class TvPipModule {
PipBoundsState pipBoundsState,
PipBoundsAlgorithm pipBoundsAlgorithm,
PipTaskOrganizer pipTaskOrganizer,
+ TvPipMenuController tvPipMenuController,
PipMediaController pipMediaController,
PipNotification pipNotification,
TaskStackListenerImpl taskStackListener,
@@ -63,6 +66,7 @@ public abstract class TvPipModule {
pipBoundsState,
pipBoundsAlgorithm,
pipTaskOrganizer,
+ tvPipMenuController,
pipMediaController,
pipNotification,
taskStackListener,
@@ -104,14 +108,22 @@ public abstract class TvPipModule {
@WMSingleton
@Provides
+ static TvPipMenuController providesPipTvMenuController(Context context,
+ PipBoundsState pipBoundsState, SystemWindows systemWindows) {
+ return new TvPipMenuController(context, pipBoundsState, systemWindows);
+ }
+
+ @WMSingleton
+ @Provides
static PipTaskOrganizer providePipTaskOrganizer(Context context,
+ TvPipMenuController tvMenuController,
PipBoundsState pipBoundsState,
PipBoundsAlgorithm pipBoundsAlgorithm,
PipSurfaceTransactionHelper pipSurfaceTransactionHelper,
Optional<SplitScreen> splitScreenOptional, DisplayController displayController,
PipUiEventLogger pipUiEventLogger, ShellTaskOrganizer shellTaskOrganizer) {
return new PipTaskOrganizer(context, pipBoundsState, pipBoundsAlgorithm,
- null /* menuActivityController */, pipSurfaceTransactionHelper, splitScreenOptional,
+ tvMenuController, pipSurfaceTransactionHelper, splitScreenOptional,
displayController, pipUiEventLogger, shellTaskOrganizer);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/TvWMShellModule.java b/packages/SystemUI/src/com/android/systemui/wmshell/TvWMShellModule.java
index f88bedd88d9f..06f1522a7256 100644
--- a/packages/SystemUI/src/com/android/systemui/wmshell/TvWMShellModule.java
+++ b/packages/SystemUI/src/com/android/systemui/wmshell/TvWMShellModule.java
@@ -41,7 +41,7 @@ import dagger.Provides;
* Provides dependencies from {@link com.android.wm.shell} which could be customized among different
* branches of SystemUI.
*/
-@Module(includes = {WMShellBaseModule.class, TvPipModule.class})
+@Module(includes = {TvPipModule.class})
public class TvWMShellModule {
@WMSingleton
@Provides
diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShellModule.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellModule.java
index 4505b2a87c78..426568ac1963 100644
--- a/packages/SystemUI/src/com/android/systemui/wmshell/WMShellModule.java
+++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellModule.java
@@ -41,9 +41,9 @@ import com.android.wm.shell.pip.PipMediaController;
import com.android.wm.shell.pip.PipSurfaceTransactionHelper;
import com.android.wm.shell.pip.PipTaskOrganizer;
import com.android.wm.shell.pip.PipUiEventLogger;
+import com.android.wm.shell.pip.phone.PhonePipMenuController;
import com.android.wm.shell.pip.phone.PipAppOpsListener;
import com.android.wm.shell.pip.phone.PipController;
-import com.android.wm.shell.pip.phone.PipMenuActivityController;
import com.android.wm.shell.pip.phone.PipTouchHandler;
import com.android.wm.shell.splitscreen.SplitScreen;
import com.android.wm.shell.splitscreen.SplitScreenController;
@@ -95,12 +95,12 @@ public class WMShellModule {
static Optional<Pip> providePip(Context context, DisplayController displayController,
PipAppOpsListener pipAppOpsListener, PipBoundsAlgorithm pipBoundsAlgorithm,
PipBoundsState pipBoundsState, PipMediaController pipMediaController,
- PipMenuActivityController pipMenuActivityController, PipTaskOrganizer pipTaskOrganizer,
+ PhonePipMenuController phonePipMenuController, PipTaskOrganizer pipTaskOrganizer,
PipTouchHandler pipTouchHandler, WindowManagerShellWrapper windowManagerShellWrapper,
TaskStackListenerImpl taskStackListener, ShellExecutor mainExecutor) {
return Optional.ofNullable(PipController.create(context, displayController,
pipAppOpsListener, pipBoundsAlgorithm, pipBoundsState, pipMediaController,
- pipMenuActivityController, pipTaskOrganizer, pipTouchHandler,
+ phonePipMenuController, pipTaskOrganizer, pipTouchHandler,
windowManagerShellWrapper, taskStackListener, mainExecutor));
}
@@ -119,20 +119,20 @@ public class WMShellModule {
@WMSingleton
@Provides
- static PipMenuActivityController providesPipMenuActivityController(Context context,
+ static PhonePipMenuController providesPipPhoneMenuController(Context context,
PipMediaController pipMediaController, SystemWindows systemWindows) {
- return new PipMenuActivityController(context, pipMediaController, systemWindows);
+ return new PhonePipMenuController(context, pipMediaController, systemWindows);
}
@WMSingleton
@Provides
static PipTouchHandler providePipTouchHandler(Context context,
- PipMenuActivityController menuActivityController, PipBoundsAlgorithm pipBoundsAlgorithm,
+ PhonePipMenuController menuPhoneController, PipBoundsAlgorithm pipBoundsAlgorithm,
PipBoundsState pipBoundsState,
PipTaskOrganizer pipTaskOrganizer,
FloatingContentCoordinator floatingContentCoordinator,
PipUiEventLogger pipUiEventLogger) {
- return new PipTouchHandler(context, menuActivityController, pipBoundsAlgorithm,
+ return new PipTouchHandler(context, menuPhoneController, pipBoundsAlgorithm,
pipBoundsState, pipTaskOrganizer, floatingContentCoordinator, pipUiEventLogger);
}
@@ -141,12 +141,12 @@ public class WMShellModule {
static PipTaskOrganizer providePipTaskOrganizer(Context context,
PipBoundsState pipBoundsState,
PipBoundsAlgorithm pipBoundsAlgorithm,
- PipMenuActivityController menuActivityController,
+ PhonePipMenuController menuPhoneController,
PipSurfaceTransactionHelper pipSurfaceTransactionHelper,
Optional<SplitScreen> splitScreenOptional, DisplayController displayController,
PipUiEventLogger pipUiEventLogger, ShellTaskOrganizer shellTaskOrganizer) {
return new PipTaskOrganizer(context, pipBoundsState, pipBoundsAlgorithm,
- menuActivityController, pipSurfaceTransactionHelper, splitScreenOptional,
+ menuPhoneController, pipSurfaceTransactionHelper, splitScreenOptional,
displayController, pipUiEventLogger, shellTaskOrganizer);
}
}