197a60d9d00240949b9642c28a34be118469eb727Winson Chung/* 297a60d9d00240949b9642c28a34be118469eb727Winson Chung * Copyright (C) 2016 The Android Open Source Project 397a60d9d00240949b9642c28a34be118469eb727Winson Chung * 497a60d9d00240949b9642c28a34be118469eb727Winson Chung * Licensed under the Apache License, Version 2.0 (the "License"); 597a60d9d00240949b9642c28a34be118469eb727Winson Chung * you may not use this file except in compliance with the License. 697a60d9d00240949b9642c28a34be118469eb727Winson Chung * You may obtain a copy of the License at 797a60d9d00240949b9642c28a34be118469eb727Winson Chung * 897a60d9d00240949b9642c28a34be118469eb727Winson Chung * http://www.apache.org/licenses/LICENSE-2.0 997a60d9d00240949b9642c28a34be118469eb727Winson Chung * 1097a60d9d00240949b9642c28a34be118469eb727Winson Chung * Unless required by applicable law or agreed to in writing, software 1197a60d9d00240949b9642c28a34be118469eb727Winson Chung * distributed under the License is distributed on an "AS IS" BASIS, 1297a60d9d00240949b9642c28a34be118469eb727Winson Chung * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1397a60d9d00240949b9642c28a34be118469eb727Winson Chung * See the License for the specific language governing permissions and 1497a60d9d00240949b9642c28a34be118469eb727Winson Chung * limitations under the License. 1597a60d9d00240949b9642c28a34be118469eb727Winson Chung */ 1697a60d9d00240949b9642c28a34be118469eb727Winson Chung 1715504af3f75037b9b94846e55bf706369531d786Winson Chungpackage com.android.systemui.pip.phone; 1815504af3f75037b9b94846e55bf706369531d786Winson Chung 1915504af3f75037b9b94846e55bf706369531d786Winson Chungimport static android.app.ActivityManager.StackId.PINNED_STACK_ID; 2015504af3f75037b9b94846e55bf706369531d786Winson Chung 2115504af3f75037b9b94846e55bf706369531d786Winson Chungimport android.app.ActivityManager.StackInfo; 2215504af3f75037b9b94846e55bf706369531d786Winson Chungimport android.app.ActivityOptions; 2315504af3f75037b9b94846e55bf706369531d786Winson Chungimport android.app.IActivityManager; 2497a60d9d00240949b9642c28a34be118469eb727Winson Chungimport android.app.RemoteAction; 2515504af3f75037b9b94846e55bf706369531d786Winson Chungimport android.content.Context; 2615504af3f75037b9b94846e55bf706369531d786Winson Chungimport android.content.Intent; 27a29eb98d9fba99528f0809c448daf2ddae37de7eWinson Chungimport android.content.pm.ParceledListSlice; 28e7a3d2225c3fcfcac4f7d1055e6ddbcbd55b52a4Winson Chungimport android.graphics.Rect; 29853c99a083dc6a96694373c48f427e4d3466d4a9Winson Chungimport android.os.Bundle; 30bb23376439a369d2a4f94abcda6a46dea673a74cWinson Chungimport android.os.Debug; 3115504af3f75037b9b94846e55bf706369531d786Winson Chungimport android.os.Handler; 3215504af3f75037b9b94846e55bf706369531d786Winson Chungimport android.os.Message; 3315504af3f75037b9b94846e55bf706369531d786Winson Chungimport android.os.Messenger; 3415504af3f75037b9b94846e55bf706369531d786Winson Chungimport android.os.RemoteException; 3515504af3f75037b9b94846e55bf706369531d786Winson Chungimport android.os.UserHandle; 3615504af3f75037b9b94846e55bf706369531d786Winson Chungimport android.util.Log; 3715504af3f75037b9b94846e55bf706369531d786Winson Chungimport android.view.IWindowManager; 3815504af3f75037b9b94846e55bf706369531d786Winson Chung 3997a60d9d00240949b9642c28a34be118469eb727Winson Chungimport com.android.systemui.pip.phone.PipMediaController.ActionListener; 40b502690e2d0a120993279a6fe800ad07dccc8872Winson Chungimport com.android.systemui.recents.events.EventBus; 41b502690e2d0a120993279a6fe800ad07dccc8872Winson Chungimport com.android.systemui.recents.events.component.HidePipMenuEvent; 42b502690e2d0a120993279a6fe800ad07dccc8872Winson Chungimport com.android.systemui.recents.misc.ReferenceCountedTrigger; 4397a60d9d00240949b9642c28a34be118469eb727Winson Chung 4429a786590f273b123efa4bb669c4ae51dd055a00Winson Chungimport java.io.PrintWriter; 4515504af3f75037b9b94846e55bf706369531d786Winson Chungimport java.util.ArrayList; 4697a60d9d00240949b9642c28a34be118469eb727Winson Chungimport java.util.List; 4715504af3f75037b9b94846e55bf706369531d786Winson Chung 4897a60d9d00240949b9642c28a34be118469eb727Winson Chung/** 4981d406104a1661658eba8755de59bf1df575e4c7Mady Mellor * Manages the PiP menu activity which can show menu options or a scrim. 5097a60d9d00240949b9642c28a34be118469eb727Winson Chung * 5197a60d9d00240949b9642c28a34be118469eb727Winson Chung * The current media session provides actions whenever there are no valid actions provided by the 5297a60d9d00240949b9642c28a34be118469eb727Winson Chung * current PiP activity. Otherwise, those actions always take precedence. 5397a60d9d00240949b9642c28a34be118469eb727Winson Chung */ 5415504af3f75037b9b94846e55bf706369531d786Winson Chungpublic class PipMenuActivityController { 5515504af3f75037b9b94846e55bf706369531d786Winson Chung 5697a60d9d00240949b9642c28a34be118469eb727Winson Chung private static final String TAG = "PipMenuActController"; 5787e5d55e98857bd43984c2395660d88ae20efcfcWinson Chung private static final boolean DEBUG = false; 5815504af3f75037b9b94846e55bf706369531d786Winson Chung 5915504af3f75037b9b94846e55bf706369531d786Winson Chung public static final String EXTRA_CONTROLLER_MESSENGER = "messenger"; 60a29eb98d9fba99528f0809c448daf2ddae37de7eWinson Chung public static final String EXTRA_ACTIONS = "actions"; 61e7a3d2225c3fcfcac4f7d1055e6ddbcbd55b52a4Winson Chung public static final String EXTRA_STACK_BOUNDS = "stack_bounds"; 62e7a3d2225c3fcfcac4f7d1055e6ddbcbd55b52a4Winson Chung public static final String EXTRA_MOVEMENT_BOUNDS = "movement_bounds"; 630f873de5ff40f4cf0be65267cf4fc2af2844bf39Winson Chung public static final String EXTRA_ALLOW_TIMEOUT = "allow_timeout"; 64853c99a083dc6a96694373c48f427e4d3466d4a9Winson Chung public static final String EXTRA_DISMISS_FRACTION = "dismiss_fraction"; 65637cd4892213b820c00a2a09959c84c49c50a15eMady Mellor public static final String EXTRA_MENU_STATE = "menu_state"; 66a29eb98d9fba99528f0809c448daf2ddae37de7eWinson Chung 67637cd4892213b820c00a2a09959c84c49c50a15eMady Mellor public static final int MESSAGE_MENU_STATE_CHANGED = 100; 68a29eb98d9fba99528f0809c448daf2ddae37de7eWinson Chung public static final int MESSAGE_EXPAND_PIP = 101; 69a29eb98d9fba99528f0809c448daf2ddae37de7eWinson Chung public static final int MESSAGE_MINIMIZE_PIP = 102; 70a29eb98d9fba99528f0809c448daf2ddae37de7eWinson Chung public static final int MESSAGE_DISMISS_PIP = 103; 71c75ffe8ccb58966753654c5b817507ad11168bcaWinson Chung public static final int MESSAGE_UPDATE_ACTIVITY_CALLBACK = 104; 72d2d909778c3dd67ccbccd5134ef7624059994ca9Winson Chung public static final int MESSAGE_REGISTER_INPUT_CONSUMER = 105; 732824d7c1b32675233221bd30d24b60f2dac2bdd5Winson Chung public static final int MESSAGE_UNREGISTER_INPUT_CONSUMER = 106; 74637cd4892213b820c00a2a09959c84c49c50a15eMady Mellor public static final int MESSAGE_SHOW_MENU = 107; 75637cd4892213b820c00a2a09959c84c49c50a15eMady Mellor 76637cd4892213b820c00a2a09959c84c49c50a15eMady Mellor public static final int MENU_STATE_NONE = 0; 77637cd4892213b820c00a2a09959c84c49c50a15eMady Mellor public static final int MENU_STATE_CLOSE = 1; 78637cd4892213b820c00a2a09959c84c49c50a15eMady Mellor public static final int MENU_STATE_FULL = 2; 7915504af3f75037b9b94846e55bf706369531d786Winson Chung 8015504af3f75037b9b94846e55bf706369531d786Winson Chung /** 8115504af3f75037b9b94846e55bf706369531d786Winson Chung * A listener interface to receive notification on changes in PIP. 8215504af3f75037b9b94846e55bf706369531d786Winson Chung */ 8315504af3f75037b9b94846e55bf706369531d786Winson Chung public interface Listener { 8415504af3f75037b9b94846e55bf706369531d786Winson Chung /** 8515504af3f75037b9b94846e55bf706369531d786Winson Chung * Called when the PIP menu visibility changes. 86d2d909778c3dd67ccbccd5134ef7624059994ca9Winson Chung * 87637cd4892213b820c00a2a09959c84c49c50a15eMady Mellor * @param menuState the current state of the menu 88637cd4892213b820c00a2a09959c84c49c50a15eMady Mellor * @param resize whether or not to resize the PiP with the state change 8915504af3f75037b9b94846e55bf706369531d786Winson Chung */ 90637cd4892213b820c00a2a09959c84c49c50a15eMady Mellor void onPipMenuStateChanged(int menuState, boolean resize); 91a29eb98d9fba99528f0809c448daf2ddae37de7eWinson Chung 92a29eb98d9fba99528f0809c448daf2ddae37de7eWinson Chung /** 93a29eb98d9fba99528f0809c448daf2ddae37de7eWinson Chung * Called when the PIP requested to be expanded. 94a29eb98d9fba99528f0809c448daf2ddae37de7eWinson Chung */ 95a29eb98d9fba99528f0809c448daf2ddae37de7eWinson Chung void onPipExpand(); 96a29eb98d9fba99528f0809c448daf2ddae37de7eWinson Chung 97a29eb98d9fba99528f0809c448daf2ddae37de7eWinson Chung /** 98a29eb98d9fba99528f0809c448daf2ddae37de7eWinson Chung * Called when the PIP requested to be minimized. 99a29eb98d9fba99528f0809c448daf2ddae37de7eWinson Chung */ 100a29eb98d9fba99528f0809c448daf2ddae37de7eWinson Chung void onPipMinimize(); 101a29eb98d9fba99528f0809c448daf2ddae37de7eWinson Chung 102a29eb98d9fba99528f0809c448daf2ddae37de7eWinson Chung /** 10314fbe141e0990d423b8564c0fc3a786ed26232c0Winson Chung * Called when the PIP requested to be dismissed. 104a29eb98d9fba99528f0809c448daf2ddae37de7eWinson Chung */ 105a29eb98d9fba99528f0809c448daf2ddae37de7eWinson Chung void onPipDismiss(); 106637cd4892213b820c00a2a09959c84c49c50a15eMady Mellor 107637cd4892213b820c00a2a09959c84c49c50a15eMady Mellor /** 108637cd4892213b820c00a2a09959c84c49c50a15eMady Mellor * Called when the PIP requested to show the menu. 109637cd4892213b820c00a2a09959c84c49c50a15eMady Mellor */ 110637cd4892213b820c00a2a09959c84c49c50a15eMady Mellor void onPipShowMenu(); 11115504af3f75037b9b94846e55bf706369531d786Winson Chung } 11215504af3f75037b9b94846e55bf706369531d786Winson Chung 11315504af3f75037b9b94846e55bf706369531d786Winson Chung private Context mContext; 11415504af3f75037b9b94846e55bf706369531d786Winson Chung private IActivityManager mActivityManager; 11597a60d9d00240949b9642c28a34be118469eb727Winson Chung private PipMediaController mMediaController; 116d2d909778c3dd67ccbccd5134ef7624059994ca9Winson Chung private InputConsumerController mInputConsumerController; 117a29eb98d9fba99528f0809c448daf2ddae37de7eWinson Chung 11815504af3f75037b9b94846e55bf706369531d786Winson Chung private ArrayList<Listener> mListeners = new ArrayList<>(); 11997a60d9d00240949b9642c28a34be118469eb727Winson Chung private ParceledListSlice mAppActions; 12097a60d9d00240949b9642c28a34be118469eb727Winson Chung private ParceledListSlice mMediaActions; 121637cd4892213b820c00a2a09959c84c49c50a15eMady Mellor private int mMenuState; 12215504af3f75037b9b94846e55bf706369531d786Winson Chung 1230f873de5ff40f4cf0be65267cf4fc2af2844bf39Winson Chung // The dismiss fraction update is sent frequently, so use a temporary bundle for the message 1240f873de5ff40f4cf0be65267cf4fc2af2844bf39Winson Chung private Bundle mTmpDismissFractionData = new Bundle(); 125853c99a083dc6a96694373c48f427e4d3466d4a9Winson Chung 126b502690e2d0a120993279a6fe800ad07dccc8872Winson Chung private ReferenceCountedTrigger mOnAttachDecrementTrigger; 12781d406104a1661658eba8755de59bf1df575e4c7Mady Mellor private boolean mStartActivityRequested; 12815504af3f75037b9b94846e55bf706369531d786Winson Chung private Messenger mToActivityMessenger; 12915504af3f75037b9b94846e55bf706369531d786Winson Chung private Messenger mMessenger = new Messenger(new Handler() { 13015504af3f75037b9b94846e55bf706369531d786Winson Chung @Override 13115504af3f75037b9b94846e55bf706369531d786Winson Chung public void handleMessage(Message msg) { 13215504af3f75037b9b94846e55bf706369531d786Winson Chung switch (msg.what) { 133637cd4892213b820c00a2a09959c84c49c50a15eMady Mellor case MESSAGE_MENU_STATE_CHANGED: { 134637cd4892213b820c00a2a09959c84c49c50a15eMady Mellor int menuState = msg.arg1; 135637cd4892213b820c00a2a09959c84c49c50a15eMady Mellor onMenuStateChanged(menuState, true /* resize */); 13615504af3f75037b9b94846e55bf706369531d786Winson Chung break; 13715504af3f75037b9b94846e55bf706369531d786Winson Chung } 13815504af3f75037b9b94846e55bf706369531d786Winson Chung case MESSAGE_EXPAND_PIP: { 139c75ffe8ccb58966753654c5b817507ad11168bcaWinson Chung mListeners.forEach(l -> l.onPipExpand()); 140a29eb98d9fba99528f0809c448daf2ddae37de7eWinson Chung break; 141a29eb98d9fba99528f0809c448daf2ddae37de7eWinson Chung } 142a29eb98d9fba99528f0809c448daf2ddae37de7eWinson Chung case MESSAGE_MINIMIZE_PIP: { 143c75ffe8ccb58966753654c5b817507ad11168bcaWinson Chung mListeners.forEach(l -> l.onPipMinimize()); 144a29eb98d9fba99528f0809c448daf2ddae37de7eWinson Chung break; 145a29eb98d9fba99528f0809c448daf2ddae37de7eWinson Chung } 146a29eb98d9fba99528f0809c448daf2ddae37de7eWinson Chung case MESSAGE_DISMISS_PIP: { 147c75ffe8ccb58966753654c5b817507ad11168bcaWinson Chung mListeners.forEach(l -> l.onPipDismiss()); 148637cd4892213b820c00a2a09959c84c49c50a15eMady Mellor break; 149637cd4892213b820c00a2a09959c84c49c50a15eMady Mellor } 150637cd4892213b820c00a2a09959c84c49c50a15eMady Mellor case MESSAGE_SHOW_MENU: { 151637cd4892213b820c00a2a09959c84c49c50a15eMady Mellor mListeners.forEach(l -> l.onPipShowMenu()); 152d2d909778c3dd67ccbccd5134ef7624059994ca9Winson Chung break; 153d2d909778c3dd67ccbccd5134ef7624059994ca9Winson Chung } 154d2d909778c3dd67ccbccd5134ef7624059994ca9Winson Chung case MESSAGE_REGISTER_INPUT_CONSUMER: { 155d2d909778c3dd67ccbccd5134ef7624059994ca9Winson Chung mInputConsumerController.registerInputConsumer(); 156c75ffe8ccb58966753654c5b817507ad11168bcaWinson Chung break; 157c75ffe8ccb58966753654c5b817507ad11168bcaWinson Chung } 1582824d7c1b32675233221bd30d24b60f2dac2bdd5Winson Chung case MESSAGE_UNREGISTER_INPUT_CONSUMER: { 1592824d7c1b32675233221bd30d24b60f2dac2bdd5Winson Chung mInputConsumerController.unregisterInputConsumer(); 1602824d7c1b32675233221bd30d24b60f2dac2bdd5Winson Chung break; 1612824d7c1b32675233221bd30d24b60f2dac2bdd5Winson Chung } 162c75ffe8ccb58966753654c5b817507ad11168bcaWinson Chung case MESSAGE_UPDATE_ACTIVITY_CALLBACK: { 163c75ffe8ccb58966753654c5b817507ad11168bcaWinson Chung mToActivityMessenger = msg.replyTo; 16481d406104a1661658eba8755de59bf1df575e4c7Mady Mellor mStartActivityRequested = false; 165b502690e2d0a120993279a6fe800ad07dccc8872Winson Chung if (mOnAttachDecrementTrigger != null) { 166b502690e2d0a120993279a6fe800ad07dccc8872Winson Chung mOnAttachDecrementTrigger.decrement(); 167b502690e2d0a120993279a6fe800ad07dccc8872Winson Chung mOnAttachDecrementTrigger = null; 168b502690e2d0a120993279a6fe800ad07dccc8872Winson Chung } 169929d4f722533fef8d8dc498b2ecf6ac3d0cb66d5Winson Chung // Mark the menu as invisible once the activity finishes as well 170929d4f722533fef8d8dc498b2ecf6ac3d0cb66d5Winson Chung if (mToActivityMessenger == null) { 171637cd4892213b820c00a2a09959c84c49c50a15eMady Mellor onMenuStateChanged(MENU_STATE_NONE, true /* resize */); 172929d4f722533fef8d8dc498b2ecf6ac3d0cb66d5Winson Chung } 17315504af3f75037b9b94846e55bf706369531d786Winson Chung break; 17415504af3f75037b9b94846e55bf706369531d786Winson Chung } 17515504af3f75037b9b94846e55bf706369531d786Winson Chung } 17615504af3f75037b9b94846e55bf706369531d786Winson Chung } 17715504af3f75037b9b94846e55bf706369531d786Winson Chung }); 17815504af3f75037b9b94846e55bf706369531d786Winson Chung 17997a60d9d00240949b9642c28a34be118469eb727Winson Chung private ActionListener mMediaActionListener = new ActionListener() { 18097a60d9d00240949b9642c28a34be118469eb727Winson Chung @Override 18197a60d9d00240949b9642c28a34be118469eb727Winson Chung public void onMediaActionsChanged(List<RemoteAction> mediaActions) { 18297a60d9d00240949b9642c28a34be118469eb727Winson Chung mMediaActions = new ParceledListSlice<>(mediaActions); 18397a60d9d00240949b9642c28a34be118469eb727Winson Chung updateMenuActions(); 18497a60d9d00240949b9642c28a34be118469eb727Winson Chung } 18597a60d9d00240949b9642c28a34be118469eb727Winson Chung }; 18697a60d9d00240949b9642c28a34be118469eb727Winson Chung 18715504af3f75037b9b94846e55bf706369531d786Winson Chung public PipMenuActivityController(Context context, IActivityManager activityManager, 188d2d909778c3dd67ccbccd5134ef7624059994ca9Winson Chung PipMediaController mediaController, InputConsumerController inputConsumerController) { 18915504af3f75037b9b94846e55bf706369531d786Winson Chung mContext = context; 19015504af3f75037b9b94846e55bf706369531d786Winson Chung mActivityManager = activityManager; 19197a60d9d00240949b9642c28a34be118469eb727Winson Chung mMediaController = mediaController; 192d2d909778c3dd67ccbccd5134ef7624059994ca9Winson Chung mInputConsumerController = inputConsumerController; 193b502690e2d0a120993279a6fe800ad07dccc8872Winson Chung 194b502690e2d0a120993279a6fe800ad07dccc8872Winson Chung EventBus.getDefault().register(this); 195d2d909778c3dd67ccbccd5134ef7624059994ca9Winson Chung } 196d2d909778c3dd67ccbccd5134ef7624059994ca9Winson Chung 197d2d909778c3dd67ccbccd5134ef7624059994ca9Winson Chung public void onActivityPinned() { 198637cd4892213b820c00a2a09959c84c49c50a15eMady Mellor if (mMenuState == MENU_STATE_NONE) { 199d2d909778c3dd67ccbccd5134ef7624059994ca9Winson Chung // If the menu is not visible, then re-register the input consumer if it is not already 200d2d909778c3dd67ccbccd5134ef7624059994ca9Winson Chung // registered 201d2d909778c3dd67ccbccd5134ef7624059994ca9Winson Chung mInputConsumerController.registerInputConsumer(); 202d2d909778c3dd67ccbccd5134ef7624059994ca9Winson Chung } 20315504af3f75037b9b94846e55bf706369531d786Winson Chung } 20415504af3f75037b9b94846e55bf706369531d786Winson Chung 20534488242f889d4d5889a38f796633b0d1c8b5541Winson Chung public void onPinnedStackAnimationEnded() { 20634488242f889d4d5889a38f796633b0d1c8b5541Winson Chung // Note: Only active menu activities care about this event 20734488242f889d4d5889a38f796633b0d1c8b5541Winson Chung if (mToActivityMessenger != null) { 20834488242f889d4d5889a38f796633b0d1c8b5541Winson Chung Message m = Message.obtain(); 20934488242f889d4d5889a38f796633b0d1c8b5541Winson Chung m.what = PipMenuActivity.MESSAGE_ANIMATION_ENDED; 21034488242f889d4d5889a38f796633b0d1c8b5541Winson Chung try { 21134488242f889d4d5889a38f796633b0d1c8b5541Winson Chung mToActivityMessenger.send(m); 21234488242f889d4d5889a38f796633b0d1c8b5541Winson Chung } catch (RemoteException e) { 21334488242f889d4d5889a38f796633b0d1c8b5541Winson Chung Log.e(TAG, "Could not notify menu pinned animation ended", e); 21434488242f889d4d5889a38f796633b0d1c8b5541Winson Chung } 21534488242f889d4d5889a38f796633b0d1c8b5541Winson Chung } 21634488242f889d4d5889a38f796633b0d1c8b5541Winson Chung } 21734488242f889d4d5889a38f796633b0d1c8b5541Winson Chung 21815504af3f75037b9b94846e55bf706369531d786Winson Chung /** 21915504af3f75037b9b94846e55bf706369531d786Winson Chung * Adds a new menu activity listener. 22015504af3f75037b9b94846e55bf706369531d786Winson Chung */ 22115504af3f75037b9b94846e55bf706369531d786Winson Chung public void addListener(Listener listener) { 22215504af3f75037b9b94846e55bf706369531d786Winson Chung if (!mListeners.contains(listener)) { 22315504af3f75037b9b94846e55bf706369531d786Winson Chung mListeners.add(listener); 22415504af3f75037b9b94846e55bf706369531d786Winson Chung } 22515504af3f75037b9b94846e55bf706369531d786Winson Chung } 22615504af3f75037b9b94846e55bf706369531d786Winson Chung 22715504af3f75037b9b94846e55bf706369531d786Winson Chung /** 22881d406104a1661658eba8755de59bf1df575e4c7Mady Mellor * Updates the appearance of the menu and scrim on top of the PiP while dismissing. 22981d406104a1661658eba8755de59bf1df575e4c7Mady Mellor */ 23081d406104a1661658eba8755de59bf1df575e4c7Mady Mellor public void setDismissFraction(float fraction) { 23187e5d55e98857bd43984c2395660d88ae20efcfcWinson Chung if (DEBUG) { 23287e5d55e98857bd43984c2395660d88ae20efcfcWinson Chung Log.d(TAG, "setDismissFraction() hasActivity=" + (mToActivityMessenger != null) 23387e5d55e98857bd43984c2395660d88ae20efcfcWinson Chung + " fraction=" + fraction); 23487e5d55e98857bd43984c2395660d88ae20efcfcWinson Chung } 23581d406104a1661658eba8755de59bf1df575e4c7Mady Mellor if (mToActivityMessenger != null) { 2360f873de5ff40f4cf0be65267cf4fc2af2844bf39Winson Chung mTmpDismissFractionData.clear(); 2370f873de5ff40f4cf0be65267cf4fc2af2844bf39Winson Chung mTmpDismissFractionData.putFloat(EXTRA_DISMISS_FRACTION, fraction); 23881d406104a1661658eba8755de59bf1df575e4c7Mady Mellor Message m = Message.obtain(); 23981d406104a1661658eba8755de59bf1df575e4c7Mady Mellor m.what = PipMenuActivity.MESSAGE_UPDATE_DISMISS_FRACTION; 2400f873de5ff40f4cf0be65267cf4fc2af2844bf39Winson Chung m.obj = mTmpDismissFractionData; 24181d406104a1661658eba8755de59bf1df575e4c7Mady Mellor try { 24281d406104a1661658eba8755de59bf1df575e4c7Mady Mellor mToActivityMessenger.send(m); 24381d406104a1661658eba8755de59bf1df575e4c7Mady Mellor } catch (RemoteException e) { 244637cd4892213b820c00a2a09959c84c49c50a15eMady Mellor Log.e(TAG, "Could not notify menu to update dismiss fraction", e); 24581d406104a1661658eba8755de59bf1df575e4c7Mady Mellor } 24681d406104a1661658eba8755de59bf1df575e4c7Mady Mellor } else if (!mStartActivityRequested) { 247637cd4892213b820c00a2a09959c84c49c50a15eMady Mellor startMenuActivity(MENU_STATE_NONE, null /* stackBounds */, 248637cd4892213b820c00a2a09959c84c49c50a15eMady Mellor null /* movementBounds */, false /* allowMenuTimeout */); 24981d406104a1661658eba8755de59bf1df575e4c7Mady Mellor } 25081d406104a1661658eba8755de59bf1df575e4c7Mady Mellor } 25181d406104a1661658eba8755de59bf1df575e4c7Mady Mellor 25281d406104a1661658eba8755de59bf1df575e4c7Mady Mellor /** 25315504af3f75037b9b94846e55bf706369531d786Winson Chung * Shows the menu activity. 25415504af3f75037b9b94846e55bf706369531d786Winson Chung */ 255637cd4892213b820c00a2a09959c84c49c50a15eMady Mellor public void showMenu(int menuState, Rect stackBounds, Rect movementBounds, 256637cd4892213b820c00a2a09959c84c49c50a15eMady Mellor boolean allowMenuTimeout) { 25787e5d55e98857bd43984c2395660d88ae20efcfcWinson Chung if (DEBUG) { 258bb23376439a369d2a4f94abcda6a46dea673a74cWinson Chung Log.d(TAG, "showMenu() state=" + menuState 259bb23376439a369d2a4f94abcda6a46dea673a74cWinson Chung + " hasActivity=" + (mToActivityMessenger != null) 260bb23376439a369d2a4f94abcda6a46dea673a74cWinson Chung + " callers=\n" + Debug.getCallers(5, " ")); 26187e5d55e98857bd43984c2395660d88ae20efcfcWinson Chung } 262c75ffe8ccb58966753654c5b817507ad11168bcaWinson Chung if (mToActivityMessenger != null) { 2630f873de5ff40f4cf0be65267cf4fc2af2844bf39Winson Chung Bundle data = new Bundle(); 264637cd4892213b820c00a2a09959c84c49c50a15eMady Mellor data.putInt(EXTRA_MENU_STATE, menuState); 2650f873de5ff40f4cf0be65267cf4fc2af2844bf39Winson Chung data.putParcelable(EXTRA_STACK_BOUNDS, stackBounds); 2660f873de5ff40f4cf0be65267cf4fc2af2844bf39Winson Chung data.putParcelable(EXTRA_MOVEMENT_BOUNDS, movementBounds); 2670f873de5ff40f4cf0be65267cf4fc2af2844bf39Winson Chung data.putBoolean(EXTRA_ALLOW_TIMEOUT, allowMenuTimeout); 268c75ffe8ccb58966753654c5b817507ad11168bcaWinson Chung Message m = Message.obtain(); 269c75ffe8ccb58966753654c5b817507ad11168bcaWinson Chung m.what = PipMenuActivity.MESSAGE_SHOW_MENU; 2700f873de5ff40f4cf0be65267cf4fc2af2844bf39Winson Chung m.obj = data; 271c75ffe8ccb58966753654c5b817507ad11168bcaWinson Chung try { 272c75ffe8ccb58966753654c5b817507ad11168bcaWinson Chung mToActivityMessenger.send(m); 273c75ffe8ccb58966753654c5b817507ad11168bcaWinson Chung } catch (RemoteException e) { 274c75ffe8ccb58966753654c5b817507ad11168bcaWinson Chung Log.e(TAG, "Could not notify menu to show", e); 275c75ffe8ccb58966753654c5b817507ad11168bcaWinson Chung } 27681d406104a1661658eba8755de59bf1df575e4c7Mady Mellor } else if (!mStartActivityRequested) { 277637cd4892213b820c00a2a09959c84c49c50a15eMady Mellor startMenuActivity(menuState, stackBounds, movementBounds, allowMenuTimeout); 27815504af3f75037b9b94846e55bf706369531d786Winson Chung } 27915504af3f75037b9b94846e55bf706369531d786Winson Chung } 280a7f69740b5b4d74cd0736b05220d2c8633b07a63Mady Mellor 281a7f69740b5b4d74cd0736b05220d2c8633b07a63Mady Mellor /** 282a7f69740b5b4d74cd0736b05220d2c8633b07a63Mady Mellor * Pokes the menu, indicating that the user is interacting with it. 283a7f69740b5b4d74cd0736b05220d2c8633b07a63Mady Mellor */ 284a7f69740b5b4d74cd0736b05220d2c8633b07a63Mady Mellor public void pokeMenu() { 28587e5d55e98857bd43984c2395660d88ae20efcfcWinson Chung if (DEBUG) { 28687e5d55e98857bd43984c2395660d88ae20efcfcWinson Chung Log.d(TAG, "pokeMenu() hasActivity=" + (mToActivityMessenger != null)); 28787e5d55e98857bd43984c2395660d88ae20efcfcWinson Chung } 288a7f69740b5b4d74cd0736b05220d2c8633b07a63Mady Mellor if (mToActivityMessenger != null) { 289a7f69740b5b4d74cd0736b05220d2c8633b07a63Mady Mellor Message m = Message.obtain(); 290a7f69740b5b4d74cd0736b05220d2c8633b07a63Mady Mellor m.what = PipMenuActivity.MESSAGE_POKE_MENU; 291a7f69740b5b4d74cd0736b05220d2c8633b07a63Mady Mellor try { 292a7f69740b5b4d74cd0736b05220d2c8633b07a63Mady Mellor mToActivityMessenger.send(m); 293a7f69740b5b4d74cd0736b05220d2c8633b07a63Mady Mellor } catch (RemoteException e) { 294a7f69740b5b4d74cd0736b05220d2c8633b07a63Mady Mellor Log.e(TAG, "Could not notify poke menu", e); 295a7f69740b5b4d74cd0736b05220d2c8633b07a63Mady Mellor } 296a7f69740b5b4d74cd0736b05220d2c8633b07a63Mady Mellor } 297a7f69740b5b4d74cd0736b05220d2c8633b07a63Mady Mellor } 29815504af3f75037b9b94846e55bf706369531d786Winson Chung 29915504af3f75037b9b94846e55bf706369531d786Winson Chung /** 30015504af3f75037b9b94846e55bf706369531d786Winson Chung * Hides the menu activity. 30115504af3f75037b9b94846e55bf706369531d786Winson Chung */ 30215504af3f75037b9b94846e55bf706369531d786Winson Chung public void hideMenu() { 30387e5d55e98857bd43984c2395660d88ae20efcfcWinson Chung if (DEBUG) { 304bb23376439a369d2a4f94abcda6a46dea673a74cWinson Chung Log.d(TAG, "hideMenu() state=" + mMenuState 305bb23376439a369d2a4f94abcda6a46dea673a74cWinson Chung + " hasActivity=" + (mToActivityMessenger != null) 306bb23376439a369d2a4f94abcda6a46dea673a74cWinson Chung + " callers=\n" + Debug.getCallers(5, " ")); 30787e5d55e98857bd43984c2395660d88ae20efcfcWinson Chung } 30815504af3f75037b9b94846e55bf706369531d786Winson Chung if (mToActivityMessenger != null) { 30915504af3f75037b9b94846e55bf706369531d786Winson Chung Message m = Message.obtain(); 310c75ffe8ccb58966753654c5b817507ad11168bcaWinson Chung m.what = PipMenuActivity.MESSAGE_HIDE_MENU; 31115504af3f75037b9b94846e55bf706369531d786Winson Chung try { 31215504af3f75037b9b94846e55bf706369531d786Winson Chung mToActivityMessenger.send(m); 31315504af3f75037b9b94846e55bf706369531d786Winson Chung } catch (RemoteException e) { 314c75ffe8ccb58966753654c5b817507ad11168bcaWinson Chung Log.e(TAG, "Could not notify menu to hide", e); 31515504af3f75037b9b94846e55bf706369531d786Winson Chung } 31615504af3f75037b9b94846e55bf706369531d786Winson Chung } 31715504af3f75037b9b94846e55bf706369531d786Winson Chung } 318a29eb98d9fba99528f0809c448daf2ddae37de7eWinson Chung 319a29eb98d9fba99528f0809c448daf2ddae37de7eWinson Chung /** 32079f852e7a784a6c1721fcea0936d98098f9359b9Winson Chung * Preemptively mark the menu as invisible, used when we are directly manipulating the pinned 32179f852e7a784a6c1721fcea0936d98098f9359b9Winson Chung * stack and don't want to trigger a resize which can animate the stack in a conflicting way 32279f852e7a784a6c1721fcea0936d98098f9359b9Winson Chung * (ie. when manually expanding or dismissing). 32379f852e7a784a6c1721fcea0936d98098f9359b9Winson Chung */ 32479f852e7a784a6c1721fcea0936d98098f9359b9Winson Chung public void hideMenuWithoutResize() { 32579f852e7a784a6c1721fcea0936d98098f9359b9Winson Chung onMenuStateChanged(MENU_STATE_NONE, false /* resize */); 32679f852e7a784a6c1721fcea0936d98098f9359b9Winson Chung } 32779f852e7a784a6c1721fcea0936d98098f9359b9Winson Chung 32879f852e7a784a6c1721fcea0936d98098f9359b9Winson Chung /** 32997a60d9d00240949b9642c28a34be118469eb727Winson Chung * Sets the menu actions to the actions provided by the current PiP activity. 33097a60d9d00240949b9642c28a34be118469eb727Winson Chung */ 33197a60d9d00240949b9642c28a34be118469eb727Winson Chung public void setAppActions(ParceledListSlice appActions) { 33297a60d9d00240949b9642c28a34be118469eb727Winson Chung mAppActions = appActions; 33397a60d9d00240949b9642c28a34be118469eb727Winson Chung updateMenuActions(); 33497a60d9d00240949b9642c28a34be118469eb727Winson Chung } 33597a60d9d00240949b9642c28a34be118469eb727Winson Chung 33697a60d9d00240949b9642c28a34be118469eb727Winson Chung /** 33797a60d9d00240949b9642c28a34be118469eb727Winson Chung * @return the best set of actions to show in the PiP menu. 338a29eb98d9fba99528f0809c448daf2ddae37de7eWinson Chung */ 33997a60d9d00240949b9642c28a34be118469eb727Winson Chung private ParceledListSlice resolveMenuActions() { 34097a60d9d00240949b9642c28a34be118469eb727Winson Chung if (isValidActions(mAppActions)) { 34197a60d9d00240949b9642c28a34be118469eb727Winson Chung return mAppActions; 34297a60d9d00240949b9642c28a34be118469eb727Winson Chung } 34397a60d9d00240949b9642c28a34be118469eb727Winson Chung return mMediaActions; 34497a60d9d00240949b9642c28a34be118469eb727Winson Chung } 345a29eb98d9fba99528f0809c448daf2ddae37de7eWinson Chung 34697a60d9d00240949b9642c28a34be118469eb727Winson Chung /** 34781d406104a1661658eba8755de59bf1df575e4c7Mady Mellor * Starts the menu activity on the top task of the pinned stack. 34881d406104a1661658eba8755de59bf1df575e4c7Mady Mellor */ 349637cd4892213b820c00a2a09959c84c49c50a15eMady Mellor private void startMenuActivity(int menuState, Rect stackBounds, Rect movementBounds, 3500f873de5ff40f4cf0be65267cf4fc2af2844bf39Winson Chung boolean allowMenuTimeout) { 35181d406104a1661658eba8755de59bf1df575e4c7Mady Mellor try { 35281d406104a1661658eba8755de59bf1df575e4c7Mady Mellor StackInfo pinnedStackInfo = mActivityManager.getStackInfo(PINNED_STACK_ID); 35381d406104a1661658eba8755de59bf1df575e4c7Mady Mellor if (pinnedStackInfo != null && pinnedStackInfo.taskIds != null && 35481d406104a1661658eba8755de59bf1df575e4c7Mady Mellor pinnedStackInfo.taskIds.length > 0) { 35581d406104a1661658eba8755de59bf1df575e4c7Mady Mellor Intent intent = new Intent(mContext, PipMenuActivity.class); 35681d406104a1661658eba8755de59bf1df575e4c7Mady Mellor intent.putExtra(EXTRA_CONTROLLER_MESSENGER, mMessenger); 35781d406104a1661658eba8755de59bf1df575e4c7Mady Mellor intent.putExtra(EXTRA_ACTIONS, resolveMenuActions()); 35881d406104a1661658eba8755de59bf1df575e4c7Mady Mellor if (stackBounds != null) { 359853c99a083dc6a96694373c48f427e4d3466d4a9Winson Chung intent.putExtra(EXTRA_STACK_BOUNDS, stackBounds); 36081d406104a1661658eba8755de59bf1df575e4c7Mady Mellor } 36181d406104a1661658eba8755de59bf1df575e4c7Mady Mellor if (movementBounds != null) { 362853c99a083dc6a96694373c48f427e4d3466d4a9Winson Chung intent.putExtra(EXTRA_MOVEMENT_BOUNDS, movementBounds); 36381d406104a1661658eba8755de59bf1df575e4c7Mady Mellor } 364637cd4892213b820c00a2a09959c84c49c50a15eMady Mellor intent.putExtra(EXTRA_MENU_STATE, menuState); 3650f873de5ff40f4cf0be65267cf4fc2af2844bf39Winson Chung intent.putExtra(EXTRA_ALLOW_TIMEOUT, allowMenuTimeout); 36681d406104a1661658eba8755de59bf1df575e4c7Mady Mellor ActivityOptions options = ActivityOptions.makeCustomAnimation(mContext, 0, 0); 36781d406104a1661658eba8755de59bf1df575e4c7Mady Mellor options.setLaunchTaskId( 36881d406104a1661658eba8755de59bf1df575e4c7Mady Mellor pinnedStackInfo.taskIds[pinnedStackInfo.taskIds.length - 1]); 36981d406104a1661658eba8755de59bf1df575e4c7Mady Mellor options.setTaskOverlay(true, true /* canResume */); 37081d406104a1661658eba8755de59bf1df575e4c7Mady Mellor mContext.startActivityAsUser(intent, options.toBundle(), UserHandle.CURRENT); 37181d406104a1661658eba8755de59bf1df575e4c7Mady Mellor mStartActivityRequested = true; 37281d406104a1661658eba8755de59bf1df575e4c7Mady Mellor } else { 37381d406104a1661658eba8755de59bf1df575e4c7Mady Mellor Log.e(TAG, "No PIP tasks found"); 37481d406104a1661658eba8755de59bf1df575e4c7Mady Mellor } 37581d406104a1661658eba8755de59bf1df575e4c7Mady Mellor } catch (RemoteException e) { 37681d406104a1661658eba8755de59bf1df575e4c7Mady Mellor mStartActivityRequested = false; 37781d406104a1661658eba8755de59bf1df575e4c7Mady Mellor Log.e(TAG, "Error showing PIP menu activity", e); 37881d406104a1661658eba8755de59bf1df575e4c7Mady Mellor } 37981d406104a1661658eba8755de59bf1df575e4c7Mady Mellor } 38081d406104a1661658eba8755de59bf1df575e4c7Mady Mellor 38181d406104a1661658eba8755de59bf1df575e4c7Mady Mellor /** 38297a60d9d00240949b9642c28a34be118469eb727Winson Chung * Updates the PiP menu activity with the best set of actions provided. 38397a60d9d00240949b9642c28a34be118469eb727Winson Chung */ 38497a60d9d00240949b9642c28a34be118469eb727Winson Chung private void updateMenuActions() { 385a29eb98d9fba99528f0809c448daf2ddae37de7eWinson Chung if (mToActivityMessenger != null) { 386e7a3d2225c3fcfcac4f7d1055e6ddbcbd55b52a4Winson Chung // Fetch the pinned stack bounds 387e7a3d2225c3fcfcac4f7d1055e6ddbcbd55b52a4Winson Chung Rect stackBounds = null; 388e7a3d2225c3fcfcac4f7d1055e6ddbcbd55b52a4Winson Chung try { 389e7a3d2225c3fcfcac4f7d1055e6ddbcbd55b52a4Winson Chung StackInfo pinnedStackInfo = mActivityManager.getStackInfo(PINNED_STACK_ID); 390e7a3d2225c3fcfcac4f7d1055e6ddbcbd55b52a4Winson Chung if (pinnedStackInfo != null) { 391e7a3d2225c3fcfcac4f7d1055e6ddbcbd55b52a4Winson Chung stackBounds = pinnedStackInfo.bounds; 392e7a3d2225c3fcfcac4f7d1055e6ddbcbd55b52a4Winson Chung } 393e7a3d2225c3fcfcac4f7d1055e6ddbcbd55b52a4Winson Chung } catch (RemoteException e) { 394e7a3d2225c3fcfcac4f7d1055e6ddbcbd55b52a4Winson Chung Log.e(TAG, "Error showing PIP menu activity", e); 395e7a3d2225c3fcfcac4f7d1055e6ddbcbd55b52a4Winson Chung } 396e7a3d2225c3fcfcac4f7d1055e6ddbcbd55b52a4Winson Chung 3970f873de5ff40f4cf0be65267cf4fc2af2844bf39Winson Chung Bundle data = new Bundle(); 3980f873de5ff40f4cf0be65267cf4fc2af2844bf39Winson Chung data.putParcelable(EXTRA_STACK_BOUNDS, stackBounds); 3990f873de5ff40f4cf0be65267cf4fc2af2844bf39Winson Chung data.putParcelable(EXTRA_ACTIONS, resolveMenuActions()); 400a29eb98d9fba99528f0809c448daf2ddae37de7eWinson Chung Message m = Message.obtain(); 401a29eb98d9fba99528f0809c448daf2ddae37de7eWinson Chung m.what = PipMenuActivity.MESSAGE_UPDATE_ACTIONS; 4020f873de5ff40f4cf0be65267cf4fc2af2844bf39Winson Chung m.obj = data; 403a29eb98d9fba99528f0809c448daf2ddae37de7eWinson Chung try { 404a29eb98d9fba99528f0809c448daf2ddae37de7eWinson Chung mToActivityMessenger.send(m); 405a29eb98d9fba99528f0809c448daf2ddae37de7eWinson Chung } catch (RemoteException e) { 406a29eb98d9fba99528f0809c448daf2ddae37de7eWinson Chung Log.e(TAG, "Could not notify menu activity to update actions", e); 407a29eb98d9fba99528f0809c448daf2ddae37de7eWinson Chung } 408a29eb98d9fba99528f0809c448daf2ddae37de7eWinson Chung } 409a29eb98d9fba99528f0809c448daf2ddae37de7eWinson Chung } 41097a60d9d00240949b9642c28a34be118469eb727Winson Chung 41197a60d9d00240949b9642c28a34be118469eb727Winson Chung /** 41297a60d9d00240949b9642c28a34be118469eb727Winson Chung * Returns whether the set of actions are valid. 41397a60d9d00240949b9642c28a34be118469eb727Winson Chung */ 41497a60d9d00240949b9642c28a34be118469eb727Winson Chung private boolean isValidActions(ParceledListSlice actions) { 41597a60d9d00240949b9642c28a34be118469eb727Winson Chung return actions != null && actions.getList().size() > 0; 41697a60d9d00240949b9642c28a34be118469eb727Winson Chung } 41797a60d9d00240949b9642c28a34be118469eb727Winson Chung 41897a60d9d00240949b9642c28a34be118469eb727Winson Chung /** 41997a60d9d00240949b9642c28a34be118469eb727Winson Chung * Handles changes in menu visibility. 42097a60d9d00240949b9642c28a34be118469eb727Winson Chung */ 421637cd4892213b820c00a2a09959c84c49c50a15eMady Mellor private void onMenuStateChanged(int menuState, boolean resize) { 42287e5d55e98857bd43984c2395660d88ae20efcfcWinson Chung if (DEBUG) { 423637cd4892213b820c00a2a09959c84c49c50a15eMady Mellor Log.d(TAG, "onMenuStateChanged() mMenuState=" + mMenuState 424637cd4892213b820c00a2a09959c84c49c50a15eMady Mellor + " menuState=" + menuState + " resize=" + resize); 42587e5d55e98857bd43984c2395660d88ae20efcfcWinson Chung } 426637cd4892213b820c00a2a09959c84c49c50a15eMady Mellor if (menuState == MENU_STATE_NONE) { 427d2d909778c3dd67ccbccd5134ef7624059994ca9Winson Chung mInputConsumerController.registerInputConsumer(); 428637cd4892213b820c00a2a09959c84c49c50a15eMady Mellor } else { 429637cd4892213b820c00a2a09959c84c49c50a15eMady Mellor mInputConsumerController.unregisterInputConsumer(); 430d2d909778c3dd67ccbccd5134ef7624059994ca9Winson Chung } 431637cd4892213b820c00a2a09959c84c49c50a15eMady Mellor if (menuState != mMenuState) { 432637cd4892213b820c00a2a09959c84c49c50a15eMady Mellor mListeners.forEach(l -> l.onPipMenuStateChanged(menuState, resize)); 433637cd4892213b820c00a2a09959c84c49c50a15eMady Mellor if (menuState == MENU_STATE_FULL) { 43497a60d9d00240949b9642c28a34be118469eb727Winson Chung // Once visible, start listening for media action changes. This call will trigger 43597a60d9d00240949b9642c28a34be118469eb727Winson Chung // the menu actions to be updated again. 43697a60d9d00240949b9642c28a34be118469eb727Winson Chung mMediaController.addListener(mMediaActionListener); 43797a60d9d00240949b9642c28a34be118469eb727Winson Chung } else { 43897a60d9d00240949b9642c28a34be118469eb727Winson Chung // Once hidden, stop listening for media action changes. This call will trigger 43997a60d9d00240949b9642c28a34be118469eb727Winson Chung // the menu actions to be updated again. 44097a60d9d00240949b9642c28a34be118469eb727Winson Chung mMediaController.removeListener(mMediaActionListener); 44197a60d9d00240949b9642c28a34be118469eb727Winson Chung } 44297a60d9d00240949b9642c28a34be118469eb727Winson Chung } 443637cd4892213b820c00a2a09959c84c49c50a15eMady Mellor mMenuState = menuState; 44497a60d9d00240949b9642c28a34be118469eb727Winson Chung } 44529a786590f273b123efa4bb669c4ae51dd055a00Winson Chung 446b502690e2d0a120993279a6fe800ad07dccc8872Winson Chung public final void onBusEvent(HidePipMenuEvent event) { 447b502690e2d0a120993279a6fe800ad07dccc8872Winson Chung if (mStartActivityRequested) { 448b502690e2d0a120993279a6fe800ad07dccc8872Winson Chung // If the menu has been start-requested, but not actually started, then we defer the 449b502690e2d0a120993279a6fe800ad07dccc8872Winson Chung // trigger callback until the menu has started and called back to the controller 450b502690e2d0a120993279a6fe800ad07dccc8872Winson Chung mOnAttachDecrementTrigger = event.getAnimationTrigger(); 451b502690e2d0a120993279a6fe800ad07dccc8872Winson Chung mOnAttachDecrementTrigger.increment(); 452b502690e2d0a120993279a6fe800ad07dccc8872Winson Chung } 453b502690e2d0a120993279a6fe800ad07dccc8872Winson Chung } 454b502690e2d0a120993279a6fe800ad07dccc8872Winson Chung 45529a786590f273b123efa4bb669c4ae51dd055a00Winson Chung public void dump(PrintWriter pw, String prefix) { 45629a786590f273b123efa4bb669c4ae51dd055a00Winson Chung final String innerPrefix = prefix + " "; 45729a786590f273b123efa4bb669c4ae51dd055a00Winson Chung pw.println(prefix + TAG); 458637cd4892213b820c00a2a09959c84c49c50a15eMady Mellor pw.println(innerPrefix + "mMenuState=" + mMenuState); 45987e5d55e98857bd43984c2395660d88ae20efcfcWinson Chung pw.println(innerPrefix + "mToActivityMessenger=" + mToActivityMessenger); 46029a786590f273b123efa4bb669c4ae51dd055a00Winson Chung pw.println(innerPrefix + "mListeners=" + mListeners.size()); 46129a786590f273b123efa4bb669c4ae51dd055a00Winson Chung } 46215504af3f75037b9b94846e55bf706369531d786Winson Chung} 463