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