diff options
11 files changed, 96 insertions, 62 deletions
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index eb895ff7f49c..2fc1187b4977 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -3071,6 +3071,13 @@ public class View implements Drawable.Callback, KeyEvent.Callback, /** * @hide * + * Whether the TV's picture-in-picture is visible or not. + */ + public static final int TV_PICTURE_IN_PICTURE_VISIBLE = 0x00010000; + + /** + * @hide + * * Makes navigation bar transparent (but not the status bar). */ public static final int NAVIGATION_BAR_TRANSPARENT = 0x00008000; diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java index e3abb5d70031..e598113bb3b1 100644 --- a/core/java/android/view/Window.java +++ b/core/java/android/view/Window.java @@ -24,6 +24,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.StyleRes; import android.annotation.SystemApi; +import android.app.ActivityManagerNative; import android.content.Context; import android.content.res.Configuration; import android.content.res.Resources; @@ -1256,6 +1257,18 @@ public abstract class Window { } /** + * Puts the activity in picture-in-picture mode. + * @see android.R.attr#supportsPictureInPicture + * @hide + */ + protected void enterPictureInPictureMode() { + try { + ActivityManagerNative.getDefault().enterPictureInPictureMode(mAppToken); + } catch (IllegalArgumentException|RemoteException e) { + } + } + + /** * Convenience for * {@link #setContentView(View, android.view.ViewGroup.LayoutParams)} * to set the screen content from a layout resource. The resource will be diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java index 151c530eea3c..16198433d99f 100644 --- a/core/java/com/android/internal/policy/PhoneWindow.java +++ b/core/java/com/android/internal/policy/PhoneWindow.java @@ -2002,6 +2002,13 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { } return true; } + + case KeyEvent.KEYCODE_WINDOW: { + if (!event.isCanceled()) { + enterPictureInPictureMode(); + } + return true; + } } return false; diff --git a/core/java/com/android/internal/statusbar/IStatusBar.aidl b/core/java/com/android/internal/statusbar/IStatusBar.aidl index 5cbe1cec8956..7706ff7f173f 100644 --- a/core/java/com/android/internal/statusbar/IStatusBar.aidl +++ b/core/java/com/android/internal/statusbar/IStatusBar.aidl @@ -105,14 +105,9 @@ oneway interface IStatusBar void onCameraLaunchGestureDetected(int source); /** - * Request picture-in-picture. - * - * <p> - * This is called when an user presses picture-in-picture key or equivalent. - * TV device may start picture-in-picture from foreground activity if there's none. - * Picture-in-picture overlay menu will be shown instead otherwise. + * Shows the TV's picture-in-picture menu if an activity is in picture-in-picture mode. */ - void requestTvPictureInPicture(); + void showTvPictureInPictureMenu(); void addQsTile(in ComponentName tile); void remQsTile(in ComponentName tile); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java index 1bc2ebcbef8b..7b23c809fd4e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java @@ -68,7 +68,7 @@ public class CommandQueue extends IStatusBar.Stub { private static final int MSG_START_ASSIST = 23 << MSG_SHIFT; private static final int MSG_CAMERA_LAUNCH_GESTURE = 24 << MSG_SHIFT; private static final int MSG_TOGGLE_KEYBOARD_SHORTCUTS = 25 << MSG_SHIFT; - private static final int MSG_REQUEST_TV_PICTURE_IN_PICTURE = 26 << MSG_SHIFT; + private static final int MSG_SHOW_TV_PICTURE_IN_PICTURE_MENU = 26 << MSG_SHIFT; private static final int MSG_ADD_QS_TILE = 27 << MSG_SHIFT; private static final int MSG_REMOVE_QS_TILE = 28 << MSG_SHIFT; private static final int MSG_CLICK_QS_TILE = 29 << MSG_SHIFT; @@ -124,7 +124,7 @@ public class CommandQueue extends IStatusBar.Stub { void showAssistDisclosure(); void startAssist(Bundle args); void onCameraLaunchGestureDetected(int source); - void requestTvPictureInPicture(); + void showTvPictureInPictureMenu(); void addQsTile(ComponentName tile); void remQsTile(ComponentName tile); @@ -274,10 +274,10 @@ public class CommandQueue extends IStatusBar.Stub { } @Override - public void requestTvPictureInPicture() { + public void showTvPictureInPictureMenu() { synchronized (mLock) { - mHandler.removeMessages(MSG_REQUEST_TV_PICTURE_IN_PICTURE); - mHandler.obtainMessage(MSG_REQUEST_TV_PICTURE_IN_PICTURE).sendToTarget(); + mHandler.removeMessages(MSG_SHOW_TV_PICTURE_IN_PICTURE_MENU); + mHandler.obtainMessage(MSG_SHOW_TV_PICTURE_IN_PICTURE_MENU).sendToTarget(); } } @@ -488,8 +488,8 @@ public class CommandQueue extends IStatusBar.Stub { case MSG_CAMERA_LAUNCH_GESTURE: mCallbacks.onCameraLaunchGestureDetected(msg.arg1); break; - case MSG_REQUEST_TV_PICTURE_IN_PICTURE: - mCallbacks.requestTvPictureInPicture(); + case MSG_SHOW_TV_PICTURE_IN_PICTURE_MENU: + mCallbacks.showTvPictureInPictureMenu(); break; case MSG_ADD_QS_TILE: mCallbacks.addQsTile((ComponentName) msg.obj); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java index 436dc9d914c3..23e3561710a3 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -4503,7 +4503,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, } @Override - public void requestTvPictureInPicture() { + public void showTvPictureInPictureMenu() { // no-op. } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java index f9202c49d7e4..27726afdafa3 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java @@ -189,8 +189,8 @@ public class TvStatusBar extends BaseStatusBar { } @Override - public void requestTvPictureInPicture() { - PipManager.getInstance().requestTvPictureInPicture(); + public void showTvPictureInPictureMenu() { + PipManager.getInstance().showTvPictureInPictureMenu(); } @Override @@ -224,8 +224,22 @@ public class TvStatusBar extends BaseStatusBar { putComponent(TvStatusBar.class, this); } + /** + * Updates the visibility of the picture-in-picture. + */ + public void updatePipVisibility(boolean visible) { + if (visible) { + mSystemUiVisibility |= View.TV_PICTURE_IN_PICTURE_VISIBLE; + } else { + mSystemUiVisibility &= ~View.TV_PICTURE_IN_PICTURE_VISIBLE; + } + notifyUiVisibilityChanged(mSystemUiVisibility); + } + + /** + * Updates the visibility of the Recents + */ public void updateRecentsVisibility(boolean visible) { - // Update the recents visibility flag if (visible) { mSystemUiVisibility |= View.RECENT_APPS_VISIBLE; } else { diff --git a/packages/SystemUI/src/com/android/systemui/tv/pip/PipManager.java b/packages/SystemUI/src/com/android/systemui/tv/pip/PipManager.java index d7efca7cac50..984263453b9b 100644 --- a/packages/SystemUI/src/com/android/systemui/tv/pip/PipManager.java +++ b/packages/SystemUI/src/com/android/systemui/tv/pip/PipManager.java @@ -41,8 +41,10 @@ import android.util.Pair; import com.android.systemui.Prefs; import com.android.systemui.R; -import com.android.systemui.recents.misc.SystemServicesProxy; +import com.android.systemui.SystemUIApplication; import com.android.systemui.recents.misc.SystemServicesProxy.TaskStackListener; +import com.android.systemui.recents.misc.SystemServicesProxy; +import com.android.systemui.statusbar.tv.TvStatusBar; import java.util.ArrayList; import java.util.List; @@ -225,26 +227,14 @@ public class PipManager { } /** - * Request PIP. - * It could either start PIP if there's none, and show PIP menu otherwise. + * Shows the picture-in-picture menu if an activity is in picture-in-picture mode. */ - public void requestTvPictureInPicture() { - if (DEBUG) Log.d(TAG, "requestTvPictureInPicture()"); - if (!isPipShown()) { - startPip(); - } else if (mState == STATE_PIP_OVERLAY) { + public void showTvPictureInPictureMenu() { + if (mState == STATE_PIP_OVERLAY) { resizePinnedStack(STATE_PIP_MENU); } } - private void startPip() { - try { - mActivityManager.moveTopActivityToPinnedStack(FULLSCREEN_WORKSPACE_STACK_ID, mPipBounds); - } catch (RemoteException|IllegalArgumentException e) { - Log.e(TAG, "moveTopActivityToPinnedStack failed", e); - } - } - /** * Closes PIP (PIPed activity and PIP system UI). */ @@ -268,6 +258,7 @@ public class PipManager { mListeners.get(i).onPipActivityClosed(); } mHandler.removeCallbacks(mClosePipRunnable); + updatePipVisibility(false); } /** @@ -622,6 +613,7 @@ public class PipManager { for (int i = mListeners.size() - 1; i >= 0; i--) { mListeners.get(i).onPipEntered(); } + updatePipVisibility(true); } @Override @@ -706,4 +698,11 @@ public class PipManager { public PipRecentsOverlayManager getPipRecentsOverlayManager() { return mPipRecentsOverlayManager; } + + private void updatePipVisibility(boolean visible) { + TvStatusBar statusBar = ((SystemUIApplication) mContext).getComponent(TvStatusBar.class); + if (statusBar != null) { + statusBar.updatePipVisibility(visible); + } + } } diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index 4e4b2f3b07c5..4ac94be72574 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -404,8 +404,9 @@ public class PhoneWindowManager implements WindowManagerPolicy { volatile boolean mEndCallKeyHandled; volatile boolean mCameraGestureTriggeredDuringGoingToSleep; volatile boolean mGoingToSleep; + volatile boolean mRecentsVisible; + volatile boolean mTvPictureInPictureVisible; - boolean mRecentsVisible; int mRecentAppsHeldModifiers; boolean mLanguageSwitchKeyPressed; @@ -712,7 +713,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { private static final int MSG_POWER_LONG_PRESS = 14; private static final int MSG_UPDATE_DREAMING_SLEEP_TOKEN = 15; private static final int MSG_REQUEST_TRANSIENT_BARS = 16; - private static final int MSG_REQUEST_TV_PICTURE_IN_PICTURE = 17; + private static final int MSG_SHOW_TV_PICTURE_IN_PICTURE_MENU = 17; private static final int MSG_BACK_LONG_PRESS = 18; private static final int MSG_REQUEST_TRANSIENT_BARS_ARG_STATUS = 0; @@ -775,8 +776,8 @@ public class PhoneWindowManager implements WindowManagerPolicy { requestTransientBars(targetBar); } break; - case MSG_REQUEST_TV_PICTURE_IN_PICTURE: - requestTvPictureInPictureInternal(); + case MSG_SHOW_TV_PICTURE_IN_PICTURE_MENU: + showTvPictureInPictureMenuInternal(); break; case MSG_BACK_LONG_PRESS: backLongPress(); @@ -1457,22 +1458,18 @@ public class PhoneWindowManager implements WindowManagerPolicy { } } - private void requestTvPictureInPicture(KeyEvent event) { - if (DEBUG_INPUT) Log.d(TAG, "requestTvPictureInPicture event=" + event); - mHandler.removeMessages(MSG_REQUEST_TV_PICTURE_IN_PICTURE); - Message msg = mHandler.obtainMessage(MSG_REQUEST_TV_PICTURE_IN_PICTURE); + private void showTvPictureInPictureMenu(KeyEvent event) { + if (DEBUG_INPUT) Log.d(TAG, "showTvPictureInPictureMenu event=" + event); + mHandler.removeMessages(MSG_SHOW_TV_PICTURE_IN_PICTURE_MENU); + Message msg = mHandler.obtainMessage(MSG_SHOW_TV_PICTURE_IN_PICTURE_MENU); msg.setAsynchronous(true); msg.sendToTarget(); } - private void requestTvPictureInPictureInternal() { - try { - StatusBarManagerInternal statusbar = getStatusBarManagerInternal(); - if (statusbar != null) { - statusbar.requestTvPictureInPicture(); - } - } catch (IllegalArgumentException e) { - Slog.e(TAG, "Cannot handle picture-in-picture key", e); + private void showTvPictureInPictureMenuInternal() { + StatusBarManagerInternal statusbar = getStatusBarManagerInternal(); + if (statusbar != null) { + statusbar.showTvPictureInPictureMenu(); } } @@ -3787,6 +3784,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { mStatusBarController.adjustSystemUiVisibilityLw(mLastSystemUiFlags, visibility); mNavigationBarController.adjustSystemUiVisibilityLw(mLastSystemUiFlags, visibility); mRecentsVisible = (visibility & View.RECENT_APPS_VISIBLE) > 0; + mTvPictureInPictureVisible = (visibility & View.TV_PICTURE_IN_PICTURE_VISIBLE) > 0; // Reset any bits in mForceClearingStatusBarVisibility that // are now clear. @@ -5674,10 +5672,16 @@ public class PhoneWindowManager implements WindowManagerPolicy { } case KeyEvent.KEYCODE_WINDOW: { if (mShortPressWindowBehavior == SHORT_PRESS_WINDOW_PICTURE_IN_PICTURE) { - if (!down) { - requestTvPictureInPicture(event); + if (mTvPictureInPictureVisible) { + // Consumes the key only if picture-in-picture is visible + // to show picture-in-picture control menu. + // This gives a chance to the foreground activity + // to customize PIP key behavior. + if (!down) { + showTvPictureInPictureMenu(event); + } + result &= ~ACTION_PASS_TO_USER; } - result &= ~ACTION_PASS_TO_USER; } break; } diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java b/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java index 52b2439baa79..fb0dd2aba556 100644 --- a/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java +++ b/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java @@ -41,14 +41,9 @@ public interface StatusBarManagerInternal { void toggleKeyboardShortcutsMenu(int deviceId); /** - * Request picture-in-picture. - * - * <p> - * This is called when an user presses picture-in-picture key or equivalent. - * TV device may start picture-in-picture from foreground activity if there's none. - * Picture-in-picture overlay menu will be shown instead otherwise. + * Show TV picture-in-picture menu. */ - void requestTvPictureInPicture(); + void showTvPictureInPictureMenu(); void setWindowState(int window, int state); diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java index c630d4a12a30..baa7f1e38e44 100644 --- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java +++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java @@ -295,10 +295,10 @@ public class StatusBarManagerService extends IStatusBarService.Stub { } @Override - public void requestTvPictureInPicture() { + public void showTvPictureInPictureMenu() { if (mBar != null) { try { - mBar.requestTvPictureInPicture(); + mBar.showTvPictureInPictureMenu(); } catch (RemoteException ex) {} } } |