Merge "TV Pip fixes after menu migration to Window"
This commit is contained in:
committed by
Android (Google) Code Review
commit
7bd311cf7a
@@ -37,7 +37,6 @@ import android.content.IntentFilter;
|
||||
import android.content.pm.ParceledListSlice;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Debug;
|
||||
import android.os.Handler;
|
||||
import android.os.RemoteException;
|
||||
import android.os.UserHandle;
|
||||
@@ -56,8 +55,6 @@ import com.android.wm.shell.pip.PipBoundsState;
|
||||
import com.android.wm.shell.pip.PipMediaController;
|
||||
import com.android.wm.shell.pip.PipTaskOrganizer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
@@ -87,42 +84,21 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac
|
||||
private static final int TASK_ID_NO_PIP = -1;
|
||||
private static final int INVALID_RESOURCE_TYPE = -1;
|
||||
|
||||
public static final int SUSPEND_PIP_RESIZE_REASON_WAITING_FOR_MENU_ACTIVITY_FINISH = 0x1;
|
||||
|
||||
/**
|
||||
* PIPed activity is playing a media and it can be paused.
|
||||
*/
|
||||
static final int PLAYBACK_STATE_PLAYING = 0;
|
||||
/**
|
||||
* PIPed activity has a paused media and it can be played.
|
||||
*/
|
||||
static final int PLAYBACK_STATE_PAUSED = 1;
|
||||
/**
|
||||
* Users are unable to control PIPed activity's media playback.
|
||||
*/
|
||||
static final int PLAYBACK_STATE_UNAVAILABLE = 2;
|
||||
|
||||
private static final int CLOSE_PIP_WHEN_MEDIA_SESSION_GONE_TIMEOUT_MS = 3000;
|
||||
|
||||
private int mSuspendPipResizingReason;
|
||||
|
||||
private final Context mContext;
|
||||
private final PipBoundsState mPipBoundsState;
|
||||
private final PipBoundsAlgorithm mPipBoundsAlgorithm;
|
||||
private final PipTaskOrganizer mPipTaskOrganizer;
|
||||
private final PipMediaController mPipMediaController;
|
||||
private final TvPipMenuController mTvPipMenuController;
|
||||
private final PipNotification mPipNotification;
|
||||
|
||||
private IActivityTaskManager mActivityTaskManager;
|
||||
private int mState = STATE_NO_PIP;
|
||||
private int mResumeResizePinnedStackRunnableState = STATE_NO_PIP;
|
||||
private final Handler mHandler = new Handler();
|
||||
private List<Listener> mListeners = new ArrayList<>();
|
||||
private int mLastOrientation = Configuration.ORIENTATION_UNDEFINED;
|
||||
private int mPipTaskId = TASK_ID_NO_PIP;
|
||||
private int mPinnedStackId = INVALID_STACK_ID;
|
||||
private String[] mLastPackagesResourceGranted;
|
||||
private PipNotification mPipNotification;
|
||||
private ParceledListSlice<RemoteAction> mCustomActions;
|
||||
private WindowManagerShellWrapper mWindowManagerShellWrapper;
|
||||
private int mResizeAnimationDuration;
|
||||
@@ -135,9 +111,7 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac
|
||||
private boolean mImeVisible;
|
||||
private int mImeHeightAdjustment;
|
||||
|
||||
private final Runnable mResizePinnedStackRunnable =
|
||||
() -> resizePinnedStack(mResumeResizePinnedStackRunnableState);
|
||||
private final Runnable mClosePipRunnable = () -> closePip();
|
||||
private final Runnable mClosePipRunnable = this::closePip;
|
||||
private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
@@ -237,8 +211,6 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac
|
||||
mPipTaskOrganizer.registerPipTransitionCallback(this);
|
||||
mActivityTaskManager = ActivityTaskManager.getService();
|
||||
|
||||
addListener(mPipNotification);
|
||||
|
||||
final IntentFilter intentFilter = new IntentFilter();
|
||||
intentFilter.addAction(ACTION_CLOSE);
|
||||
intentFilter.addAction(ACTION_MENU);
|
||||
@@ -340,9 +312,8 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac
|
||||
mPinnedStackId = INVALID_STACK_ID;
|
||||
}
|
||||
}
|
||||
for (int i = mListeners.size() - 1; i >= 0; --i) {
|
||||
mListeners.get(i).onPipActivityClosed();
|
||||
}
|
||||
mPipNotification.dismiss();
|
||||
mTvPipMenuController.hideMenu();
|
||||
mHandler.removeCallbacks(mClosePipRunnable);
|
||||
}
|
||||
|
||||
@@ -353,9 +324,9 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac
|
||||
if (DEBUG) Log.d(TAG, "movePipToFullscreen(), current state=" + getStateDescription());
|
||||
|
||||
mPipTaskId = TASK_ID_NO_PIP;
|
||||
for (int i = mListeners.size() - 1; i >= 0; --i) {
|
||||
mListeners.get(i).onMoveToFullscreen();
|
||||
}
|
||||
mTvPipMenuController.hideMenu();
|
||||
mPipNotification.dismiss();
|
||||
|
||||
resizePinnedStack(STATE_NO_PIP);
|
||||
}
|
||||
|
||||
@@ -379,9 +350,7 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac
|
||||
// Set state to STATE_PIP so we show it when the pinned stack animation ends.
|
||||
mState = STATE_PIP;
|
||||
mPipMediaController.onActivityPinned();
|
||||
for (int i = mListeners.size() - 1; i >= 0; i--) {
|
||||
mListeners.get(i).onPipEntered(packageName);
|
||||
}
|
||||
mPipNotification.show(packageName);
|
||||
}
|
||||
|
||||
private void onActivityRestartAttempt(ActivityManager.RunningTaskInfo task,
|
||||
@@ -427,62 +396,18 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Suspends resizing operation on the Pip until {@link #resumePipResizing} is called
|
||||
*
|
||||
* @param reason The reason for suspending resizing operations on the Pip.
|
||||
*/
|
||||
public void suspendPipResizing(int reason) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG,
|
||||
"suspendPipResizing() reason=" + reason + " callers=" + Debug.getCallers(2));
|
||||
}
|
||||
mSuspendPipResizingReason |= reason;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resumes resizing operation on the Pip that was previously suspended.
|
||||
*
|
||||
* @param reason The reason resizing operations on the Pip was suspended.
|
||||
*/
|
||||
public void resumePipResizing(int reason) {
|
||||
if ((mSuspendPipResizingReason & reason) == 0) {
|
||||
return;
|
||||
}
|
||||
if (DEBUG) {
|
||||
Log.d(TAG,
|
||||
"resumePipResizing() reason=" + reason + " callers=" + Debug.getCallers(2));
|
||||
}
|
||||
mSuspendPipResizingReason &= ~reason;
|
||||
mHandler.post(mResizePinnedStackRunnable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resize the Pip to the appropriate size for the input state.
|
||||
*
|
||||
* @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());
|
||||
}
|
||||
|
||||
boolean wasStateNoPip = (mState == STATE_NO_PIP);
|
||||
for (int i = mListeners.size() - 1; i >= 0; --i) {
|
||||
mListeners.get(i).onPipResizeAboutToStart();
|
||||
}
|
||||
if (mSuspendPipResizingReason != 0) {
|
||||
mResumeResizePinnedStackRunnableState = state;
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "resizePinnedStack() deferring"
|
||||
+ " mSuspendPipResizingReason=" + mSuspendPipResizingReason
|
||||
+ " mResumeResizePinnedStackRunnableState="
|
||||
+ stateToName(mResumeResizePinnedStackRunnableState));
|
||||
}
|
||||
return;
|
||||
}
|
||||
final boolean wasStateNoPip = (mState == STATE_NO_PIP);
|
||||
mTvPipMenuController.hideMenu();
|
||||
mState = state;
|
||||
final Rect newBounds;
|
||||
switch (mState) {
|
||||
@@ -510,44 +435,19 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the current state, or the pending state if the state change was previously suspended.
|
||||
* @return the current state.
|
||||
*/
|
||||
private int getState() {
|
||||
if (mSuspendPipResizingReason != 0) {
|
||||
return mResumeResizePinnedStackRunnableState;
|
||||
}
|
||||
return mState;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows PIP menu UI by launching {@link PipMenuActivity}. It also locates the pinned
|
||||
* stack to the centered PIP bound {@link R.config_centeredPictureInPictureBounds}.
|
||||
*/
|
||||
private void showPipMenu() {
|
||||
if (DEBUG) Log.d(TAG, "showPipMenu(), current state=" + getStateDescription());
|
||||
|
||||
mState = STATE_PIP_MENU;
|
||||
for (int i = mListeners.size() - 1; i >= 0; --i) {
|
||||
mListeners.get(i).onShowPipMenu();
|
||||
}
|
||||
|
||||
mTvPipMenuController.showMenu();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a {@link Listener} to PipController.
|
||||
*/
|
||||
void addListener(Listener listener) {
|
||||
mListeners.add(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a {@link Listener} from PipController.
|
||||
*/
|
||||
void removeListener(Listener listener) {
|
||||
mListeners.remove(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if PIP is shown.
|
||||
*/
|
||||
@@ -619,33 +519,8 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A listener interface to receive notification on changes in PIP.
|
||||
*/
|
||||
public interface Listener {
|
||||
/**
|
||||
* Invoked when an activity is pinned and PIP manager is set corresponding information.
|
||||
* Classes must use this instead of {@link android.app.ITaskStackListener.onActivityPinned}
|
||||
* because there's no guarantee for the PIP manager be return relavent information
|
||||
* correctly. (e.g. {@link Pip.isPipShown}).
|
||||
*/
|
||||
void onPipEntered(String packageName);
|
||||
/** Invoked when a PIPed activity is closed. */
|
||||
void onPipActivityClosed();
|
||||
/** Invoked when the PIP menu gets shown. */
|
||||
void onShowPipMenu();
|
||||
/** 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. */
|
||||
void onPipResizeAboutToStart();
|
||||
}
|
||||
|
||||
private String getStateDescription() {
|
||||
if (mSuspendPipResizingReason == 0) {
|
||||
return stateToName(mState);
|
||||
}
|
||||
return stateToName(mResumeResizePinnedStackRunnableState) + " (while " + stateToName(mState)
|
||||
+ " is suspended)";
|
||||
return stateToName(mState);
|
||||
}
|
||||
|
||||
private static String stateToName(int state) {
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
|
||||
package com.android.wm.shell.pip.tv;
|
||||
|
||||
import static android.view.KeyEvent.ACTION_UP;
|
||||
import static android.view.KeyEvent.KEYCODE_BACK;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorInflater;
|
||||
import android.annotation.Nullable;
|
||||
@@ -36,25 +39,22 @@ import java.util.Collections;
|
||||
/**
|
||||
* The Menu View that shows controls of the PiP. Always fullscreen.
|
||||
*/
|
||||
public class PipMenuView extends FrameLayout implements PipController.Listener {
|
||||
public class PipMenuView extends FrameLayout {
|
||||
private static final String TAG = "PipMenuView";
|
||||
private static final boolean DEBUG = PipController.DEBUG;
|
||||
|
||||
private final PipController mPipController;
|
||||
private final Animator mFadeInAnimation;
|
||||
private final Animator mFadeOutAnimation;
|
||||
private final PipControlsViewController mPipControlsViewController;
|
||||
private boolean mRestorePipSizeWhenClose;
|
||||
@Nullable
|
||||
private OnBackPressListener mOnBackPressListener;
|
||||
|
||||
public PipMenuView(Context context, PipController pipController) {
|
||||
super(context, null, 0);
|
||||
mPipController = pipController;
|
||||
|
||||
inflate(context, R.layout.tv_pip_menu, this);
|
||||
|
||||
mPipControlsViewController = new PipControlsViewController(
|
||||
findViewById(R.id.pip_controls), mPipController);
|
||||
mRestorePipSizeWhenClose = true;
|
||||
findViewById(R.id.pip_controls), pipController);
|
||||
mFadeInAnimation = AnimatorInflater.loadAnimator(
|
||||
mContext, R.anim.tv_pip_menu_fade_in_animation);
|
||||
mFadeInAnimation.setTarget(mPipControlsViewController.getView());
|
||||
@@ -63,16 +63,6 @@ public class PipMenuView extends FrameLayout implements PipController.Listener {
|
||||
mFadeOutAnimation.setTarget(mPipControlsViewController.getView());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean dispatchKeyEvent(KeyEvent event) {
|
||||
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK
|
||||
&& event.getAction() == KeyEvent.ACTION_UP) {
|
||||
restorePipAndFinish();
|
||||
return true;
|
||||
}
|
||||
return super.dispatchKeyEvent(event);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
SurfaceControl getWindowSurfaceControl() {
|
||||
final ViewRootImpl root = getViewRootImpl();
|
||||
@@ -87,53 +77,39 @@ public class PipMenuView extends FrameLayout implements PipController.Listener {
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
grantWindowFocus(true);
|
||||
}
|
||||
|
||||
void hideMenu() {
|
||||
mPipController.removeListener(this);
|
||||
mPipController.resumePipResizing(
|
||||
PipController.SUSPEND_PIP_RESIZE_REASON_WAITING_FOR_MENU_ACTIVITY_FINISH);
|
||||
mFadeOutAnimation.start();
|
||||
setAlpha(0.0f);
|
||||
grantWindowFocus(false);
|
||||
}
|
||||
|
||||
private void grantWindowFocus(boolean grantFocus) {
|
||||
try {
|
||||
WindowManagerGlobal.getWindowSession().grantEmbeddedWindowFocus(null /* window */,
|
||||
getViewRootImpl().getInputToken(), false /* grantFocus */);
|
||||
getViewRootImpl().getInputToken(), grantFocus);
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Unable to update focus as menu disappears", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void restorePipAndFinish() {
|
||||
if (DEBUG) Log.d(TAG, "restorePipAndFinish()");
|
||||
void setOnBackPressListener(OnBackPressListener onBackPressListener) {
|
||||
mOnBackPressListener = onBackPressListener;
|
||||
}
|
||||
|
||||
if (mRestorePipSizeWhenClose) {
|
||||
if (DEBUG) Log.d(TAG, " > restoring to the default position");
|
||||
|
||||
// When PIP menu activity is closed, restore to the default position.
|
||||
mPipController.resizePinnedStack(PipController.STATE_PIP);
|
||||
@Override
|
||||
public boolean dispatchKeyEvent(KeyEvent event) {
|
||||
if (event.getKeyCode() == KEYCODE_BACK && event.getAction() == ACTION_UP
|
||||
&& mOnBackPressListener != null) {
|
||||
mOnBackPressListener.onBackPress();
|
||||
return true;
|
||||
} else {
|
||||
return super.dispatchKeyEvent(event);
|
||||
}
|
||||
hideMenu();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPipEntered(String packageName) {
|
||||
if (DEBUG) Log.d(TAG, "onPipEntered(), packageName=" + packageName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPipActivityClosed() {
|
||||
if (DEBUG) Log.d(TAG, "onPipActivityClosed()");
|
||||
|
||||
hideMenu();
|
||||
}
|
||||
|
||||
void setAppActions(ParceledListSlice<RemoteAction> actions) {
|
||||
@@ -144,27 +120,7 @@ public class PipMenuView extends FrameLayout implements PipController.Listener {
|
||||
hasCustomActions ? actions.getList() : Collections.emptyList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onShowPipMenu() {
|
||||
if (DEBUG) Log.d(TAG, "onShowPipMenu()");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMoveToFullscreen() {
|
||||
if (DEBUG) Log.d(TAG, "onMoveToFullscreen()");
|
||||
|
||||
// Moving PIP to fullscreen is implemented by resizing PINNED_STACK with null bounds.
|
||||
// This conflicts with restoring PIP position, so disable it.
|
||||
mRestorePipSizeWhenClose = false;
|
||||
hideMenu();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPipResizeAboutToStart() {
|
||||
if (DEBUG) Log.d(TAG, "onPipResizeAboutToStart()");
|
||||
|
||||
hideMenu();
|
||||
mPipController.suspendPipResizing(
|
||||
PipController.SUSPEND_PIP_RESIZE_REASON_WAITING_FOR_MENU_ACTIVITY_FINISH);
|
||||
interface OnBackPressListener {
|
||||
void onBackPress();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ import java.util.Objects;
|
||||
* <p>Once it's created, it will manage the PIP notification UI by itself except for handling
|
||||
* configuration changes.
|
||||
*/
|
||||
public class PipNotification implements PipController.Listener {
|
||||
public class PipNotification {
|
||||
private static final boolean DEBUG = PipController.DEBUG;
|
||||
private static final String TAG = "PipNotification";
|
||||
|
||||
@@ -79,38 +79,21 @@ public class PipNotification implements PipController.Listener {
|
||||
onConfigurationChanged(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPipEntered(String packageName) {
|
||||
void show(String packageName) {
|
||||
mPackageName = packageName;
|
||||
notifyPipNotification();
|
||||
update();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPipActivityClosed() {
|
||||
dismissPipNotification();
|
||||
void dismiss() {
|
||||
mNotificationManager.cancel(NOTIFICATION_TAG, SystemMessage.NOTE_TV_PIP);
|
||||
mNotified = false;
|
||||
mPackageName = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onShowPipMenu() {
|
||||
// no-op.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMoveToFullscreen() {
|
||||
dismissPipNotification();
|
||||
mPackageName = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPipResizeAboutToStart() {
|
||||
// no-op.
|
||||
}
|
||||
|
||||
private void onMediaMetadataChanged(MediaMetadata metadata) {
|
||||
if (updateMediaControllerMetadata(metadata) && mNotified) {
|
||||
// update notification
|
||||
notifyPipNotification();
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,11 +106,11 @@ public class PipNotification implements PipController.Listener {
|
||||
mDefaultIconResId = R.drawable.pip_icon;
|
||||
if (mNotified) {
|
||||
// update notification
|
||||
notifyPipNotification();
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyPipNotification() {
|
||||
private void update() {
|
||||
mNotified = true;
|
||||
mNotificationBuilder
|
||||
.setShowWhen(true)
|
||||
@@ -144,11 +127,6 @@ public class PipNotification implements PipController.Listener {
|
||||
mNotificationBuilder.build());
|
||||
}
|
||||
|
||||
private void dismissPipNotification() {
|
||||
mNotified = false;
|
||||
mNotificationManager.cancel(NOTIFICATION_TAG, SystemMessage.NOTE_TV_PIP);
|
||||
}
|
||||
|
||||
private boolean updateMediaControllerMetadata(MediaMetadata metadata) {
|
||||
String title = null;
|
||||
Bitmap art = null;
|
||||
|
||||
@@ -21,6 +21,7 @@ import static android.view.WindowManager.SHELL_ROOT_LAYER_PIP;
|
||||
import android.app.RemoteAction;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ParceledListSlice;
|
||||
import android.util.Log;
|
||||
import android.view.SurfaceControl;
|
||||
|
||||
import com.android.wm.shell.common.SystemWindows;
|
||||
@@ -31,6 +32,8 @@ 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 static final String TAG = "TvPipMenuController";
|
||||
private static final boolean DEBUG = PipController.DEBUG;
|
||||
|
||||
private final Context mContext;
|
||||
private final SystemWindows mSystemWindows;
|
||||
@@ -52,6 +55,8 @@ public class TvPipMenuController implements PipMenuController {
|
||||
|
||||
@Override
|
||||
public void showMenu() {
|
||||
if (DEBUG) Log.d(TAG, "showMenu()");
|
||||
|
||||
if (mMenuView != null) {
|
||||
mSystemWindows.updateViewLayout(mMenuView, getPipMenuLayoutParams(MENU_WINDOW_TITLE,
|
||||
mPipBoundsState.getDisplayBounds().width(),
|
||||
@@ -68,27 +73,62 @@ public class TvPipMenuController implements PipMenuController {
|
||||
}
|
||||
}
|
||||
|
||||
@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;
|
||||
void hideMenu() {
|
||||
if (DEBUG) Log.d(TAG, "hideMenu()");
|
||||
|
||||
if (isMenuVisible()) {
|
||||
mMenuView.hideMenu();
|
||||
mPipController.resizePinnedStack(PipController.STATE_PIP);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void attach(SurfaceControl leash) {
|
||||
mLeash = leash;
|
||||
attachPipMenuView();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void detach() {
|
||||
hideMenu();
|
||||
detachPipMenuView();
|
||||
mLeash = null;
|
||||
}
|
||||
|
||||
private void attachPipMenuView() {
|
||||
if (DEBUG) Log.d(TAG, "attachPipMenuView()");
|
||||
|
||||
if (mMenuView != null) {
|
||||
detachPipMenuView();
|
||||
}
|
||||
|
||||
mMenuView = new PipMenuView(mContext, mPipController);
|
||||
mMenuView.setOnBackPressListener(this::hideMenu);
|
||||
mSystemWindows.addView(mMenuView,
|
||||
getPipMenuLayoutParams(MENU_WINDOW_TITLE, 0 /* width */, 0 /* height */),
|
||||
0, SHELL_ROOT_LAYER_PIP);
|
||||
}
|
||||
|
||||
private void detachPipMenuView() {
|
||||
if (DEBUG) Log.d(TAG, "detachPipMenuView()");
|
||||
|
||||
if (mMenuView == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
mSystemWindows.removeView(mMenuView);
|
||||
mMenuView = null;
|
||||
mLeash = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAppActions(ParceledListSlice<RemoteAction> appActions) {
|
||||
mMenuView.setAppActions(appActions);
|
||||
if (DEBUG) Log.d(TAG, "setAppActions(), actions=" + appActions);
|
||||
|
||||
if (mMenuView != null) {
|
||||
mMenuView.setAppActions(appActions);
|
||||
} else {
|
||||
Log.w(TAG, "Cannot set remote actions, there is no View");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user