16386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes/*
26386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes * Copyright (C) 2013 The Android Open Source Project
36386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes *
46386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes * Licensed under the Apache License, Version 2.0 (the "License");
56386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes * you may not use this file except in compliance with the License.
66386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes * You may obtain a copy of the License at
76386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes *
86386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes *      http://www.apache.org/licenses/LICENSE-2.0
96386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes *
106386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes * Unless required by applicable law or agreed to in writing, software
116386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes * distributed under the License is distributed on an "AS IS" BASIS,
126386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes * See the License for the specific language governing permissions and
146386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes * limitations under the License.
156386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes */
166386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes
176386aac7ea9be44d23dcea28d9a02110c174e988Chris Banespackage android.support.v7.app;
186386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes
19f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banesimport android.app.Activity;
2016e8d4dd91083260223c007c797e46bc8f631055Chris Banesimport android.app.Dialog;
216386aac7ea9be44d23dcea28d9a02110c174e988Chris Banesimport android.content.Context;
226386aac7ea9be44d23dcea28d9a02110c174e988Chris Banesimport android.content.res.Configuration;
2361c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banesimport android.content.res.Resources;
246386aac7ea9be44d23dcea28d9a02110c174e988Chris Banesimport android.content.res.TypedArray;
2546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banesimport android.graphics.PixelFormat;
26ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banesimport android.graphics.Rect;
2746dfe0c53492ef0cb59873123ca141906fbb7dccChris Banesimport android.media.AudioManager;
28469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banesimport android.os.Build;
298902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banesimport android.os.Bundle;
3000d183885b54de433e43118d3032340f40cac8c0Chris Banesimport android.os.Parcel;
3100d183885b54de433e43118d3032340f40cac8c0Chris Banesimport android.os.Parcelable;
328c3845ebb7e8198950510cd7a08bc8e66e2195feChris Banesimport android.support.annotation.IdRes;
33469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banesimport android.support.annotation.NonNull;
348c3845ebb7e8198950510cd7a08bc8e66e2195feChris Banesimport android.support.annotation.Nullable;
3549c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.support.v4.app.NavUtils;
3662ab25d71ccfa775a8bd2add7b41277bc4e14bbcChris Banesimport android.support.v4.os.ParcelableCompat;
3762ab25d71ccfa775a8bd2add7b41277bc4e14bbcChris Banesimport android.support.v4.os.ParcelableCompatCreatorCallbacks;
38f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banesimport android.support.v4.view.LayoutInflaterCompat;
39f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banesimport android.support.v4.view.LayoutInflaterFactory;
40ea4f700ac38424954c56df5138ff794def50b019Chris Banesimport android.support.v4.view.OnApplyWindowInsetsListener;
4103fc11b659da1645507062bddda450136e13af35Chris Banesimport android.support.v4.view.ViewCompat;
4249c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.support.v4.view.ViewConfigurationCompat;
43c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liuimport android.support.v4.view.ViewPropertyAnimatorCompat;
44c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liuimport android.support.v4.view.ViewPropertyAnimatorListenerAdapter;
45d25af35061a9f20d59b25329d613c62c20184dadChris Banesimport android.support.v4.view.WindowCompat;
46ea4f700ac38424954c56df5138ff794def50b019Chris Banesimport android.support.v4.view.WindowInsetsCompat;
47f5829201b976fc650789accc22f325a2541ed478Chris Banesimport android.support.v4.widget.PopupWindowCompat;
486386aac7ea9be44d23dcea28d9a02110c174e988Chris Banesimport android.support.v7.appcompat.R;
49d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banesimport android.support.v7.view.ActionMode;
5066698bb15ba0f873aa1c2290cc50d6bb839a474aChris Banesimport android.support.v7.view.ContextThemeWrapper;
5166698bb15ba0f873aa1c2290cc50d6bb839a474aChris Banesimport android.support.v7.view.StandaloneActionMode;
5266698bb15ba0f873aa1c2290cc50d6bb839a474aChris Banesimport android.support.v7.view.menu.ListMenuPresenter;
5366698bb15ba0f873aa1c2290cc50d6bb839a474aChris Banesimport android.support.v7.view.menu.MenuBuilder;
5466698bb15ba0f873aa1c2290cc50d6bb839a474aChris Banesimport android.support.v7.view.menu.MenuPresenter;
5566698bb15ba0f873aa1c2290cc50d6bb839a474aChris Banesimport android.support.v7.view.menu.MenuView;
5666698bb15ba0f873aa1c2290cc50d6bb839a474aChris Banesimport android.support.v7.widget.ActionBarContextView;
5766698bb15ba0f873aa1c2290cc50d6bb839a474aChris Banesimport android.support.v7.widget.AppCompatDrawableManager;
5866698bb15ba0f873aa1c2290cc50d6bb839a474aChris Banesimport android.support.v7.widget.ContentFrameLayout;
5966698bb15ba0f873aa1c2290cc50d6bb839a474aChris Banesimport android.support.v7.widget.DecorContentParent;
6066698bb15ba0f873aa1c2290cc50d6bb839a474aChris Banesimport android.support.v7.widget.FitWindowsViewGroup;
6149c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.support.v7.widget.Toolbar;
625fa121a1f51114f3a2f6d705139e83c0e0aea610Chris Banesimport android.support.v7.widget.VectorEnabledTintResources;
6366698bb15ba0f873aa1c2290cc50d6bb839a474aChris Banesimport android.support.v7.widget.ViewStubCompat;
6466698bb15ba0f873aa1c2290cc50d6bb839a474aChris Banesimport android.support.v7.widget.ViewUtils;
6516e8d4dd91083260223c007c797e46bc8f631055Chris Banesimport android.text.TextUtils;
66cc7aada3ee922cfb38eeb36ee696cc73dcbae0a4Chris Banesimport android.util.AndroidRuntimeException;
67469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banesimport android.util.AttributeSet;
6846dfe0c53492ef0cb59873123ca141906fbb7dccChris Banesimport android.util.Log;
6956fd50144df518461398a9b3397ee4842b346708Chris Banesimport android.util.TypedValue;
704c2a95906254748cb9a843b061288265d6e185a9Chris Banesimport android.view.Gravity;
7100d183885b54de433e43118d3032340f40cac8c0Chris Banesimport android.view.KeyCharacterMap;
72dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banesimport android.view.KeyEvent;
73dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banesimport android.view.LayoutInflater;
7430837f1095c803f332f4a1c3f0917c8afdd50156Adam Powellimport android.view.Menu;
7530837f1095c803f332f4a1c3f0917c8afdd50156Adam Powellimport android.view.MenuItem;
7646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banesimport android.view.MotionEvent;
776386aac7ea9be44d23dcea28d9a02110c174e988Chris Banesimport android.view.View;
7849c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.view.ViewConfiguration;
796386aac7ea9be44d23dcea28d9a02110c174e988Chris Banesimport android.view.ViewGroup;
8046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banesimport android.view.ViewParent;
816386aac7ea9be44d23dcea28d9a02110c174e988Chris Banesimport android.view.Window;
8246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banesimport android.view.WindowManager;
834c2a95906254748cb9a843b061288265d6e185a9Chris Banesimport android.view.accessibility.AccessibilityEvent;
8430837f1095c803f332f4a1c3f0917c8afdd50156Adam Powellimport android.widget.FrameLayout;
854c2a95906254748cb9a843b061288265d6e185a9Chris Banesimport android.widget.PopupWindow;
8616e8d4dd91083260223c007c797e46bc8f631055Chris Banesimport android.widget.TextView;
876386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes
8846dfe0c53492ef0cb59873123ca141906fbb7dccChris Banesimport static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
8946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banesimport static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
9000d183885b54de433e43118d3032340f40cac8c0Chris Banesimport static android.view.Window.FEATURE_OPTIONS_PANEL;
9100d183885b54de433e43118d3032340f40cac8c0Chris Banes
92f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banesclass AppCompatDelegateImplV7 extends AppCompatDelegateImplBase
93f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes        implements MenuBuilder.Callback, LayoutInflaterFactory {
946386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes
9549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    private DecorContentParent mDecorContentParent;
9603fc11b659da1645507062bddda450136e13af35Chris Banes    private ActionMenuPresenterCallback mActionMenuPresenterCallback;
9703fc11b659da1645507062bddda450136e13af35Chris Banes    private PanelMenuPresenterCallback mPanelMenuPresenterCallback;
9803fc11b659da1645507062bddda450136e13af35Chris Banes
994c2a95906254748cb9a843b061288265d6e185a9Chris Banes    ActionMode mActionMode;
1004c2a95906254748cb9a843b061288265d6e185a9Chris Banes    ActionBarContextView mActionModeView;
1014c2a95906254748cb9a843b061288265d6e185a9Chris Banes    PopupWindow mActionModePopup;
1024c2a95906254748cb9a843b061288265d6e185a9Chris Banes    Runnable mShowActionModePopup;
103c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu    ViewPropertyAnimatorCompat mFadeAnim = null;
1045a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes
1055a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes    // true if we have installed a window sub-decor layout.
1065a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes    private boolean mSubDecorInstalled;
107ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes    private ViewGroup mSubDecor;
108ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes
10916e8d4dd91083260223c007c797e46bc8f631055Chris Banes    private TextView mTitleView;
110ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes    private View mStatusGuard;
111d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes
112ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes    // Used to keep track of Progress Bar Window features
113ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes    private boolean mFeatureProgress, mFeatureIndeterminateProgress;
114ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes
1158902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes    // Used for emulating PanelFeatureState
1168902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes    private boolean mClosingActionMenu;
11700d183885b54de433e43118d3032340f40cac8c0Chris Banes    private PanelFeatureState[] mPanels;
11800d183885b54de433e43118d3032340f40cac8c0Chris Banes    private PanelFeatureState mPreparedPanel;
119556ac47ce764a4a9320b5ac914536e9da2524176Chris Banes
120625c9c3db9bb6f6b92ca35b74f26a61a04ec8cd7Chris Banes    private boolean mLongPressBackDown;
121625c9c3db9bb6f6b92ca35b74f26a61a04ec8cd7Chris Banes
12203fc11b659da1645507062bddda450136e13af35Chris Banes    private boolean mInvalidatePanelMenuPosted;
12300d183885b54de433e43118d3032340f40cac8c0Chris Banes    private int mInvalidatePanelMenuFeatures;
12403fc11b659da1645507062bddda450136e13af35Chris Banes    private final Runnable mInvalidatePanelMenuRunnable = new Runnable() {
12503fc11b659da1645507062bddda450136e13af35Chris Banes        @Override
12603fc11b659da1645507062bddda450136e13af35Chris Banes        public void run() {
12700d183885b54de433e43118d3032340f40cac8c0Chris Banes            if ((mInvalidatePanelMenuFeatures & 1 << FEATURE_OPTIONS_PANEL) != 0) {
12800d183885b54de433e43118d3032340f40cac8c0Chris Banes                doInvalidatePanelMenu(FEATURE_OPTIONS_PANEL);
12900d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
130d25af35061a9f20d59b25329d613c62c20184dadChris Banes            if ((mInvalidatePanelMenuFeatures & 1 << FEATURE_SUPPORT_ACTION_BAR) != 0) {
131d25af35061a9f20d59b25329d613c62c20184dadChris Banes                doInvalidatePanelMenu(FEATURE_SUPPORT_ACTION_BAR);
13200d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
13300d183885b54de433e43118d3032340f40cac8c0Chris Banes            mInvalidatePanelMenuPosted = false;
13400d183885b54de433e43118d3032340f40cac8c0Chris Banes            mInvalidatePanelMenuFeatures = 0;
13503fc11b659da1645507062bddda450136e13af35Chris Banes        }
13603fc11b659da1645507062bddda450136e13af35Chris Banes    };
13703fc11b659da1645507062bddda450136e13af35Chris Banes
13849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    private boolean mEnableDefaultActionBarUp;
13949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
1407efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell    private Rect mTempRect1;
1417efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell    private Rect mTempRect2;
1427efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell
1432cccf609662389d6a23dbc0711d5fb2e826e8c63Chris Banes    private AppCompatViewInflater mAppCompatViewInflater;
144fd1eb27a3700de31507de34fd1bcc51830fe876cChris Banes
14516e8d4dd91083260223c007c797e46bc8f631055Chris Banes    AppCompatDelegateImplV7(Context context, Window window, AppCompatCallback callback) {
14616e8d4dd91083260223c007c797e46bc8f631055Chris Banes        super(context, window, callback);
1476386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    }
1486386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes
1496386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    @Override
150f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes    public void onCreate(Bundle savedInstanceState) {
15116e8d4dd91083260223c007c797e46bc8f631055Chris Banes        if (mOriginalWindowCallback instanceof Activity) {
15216e8d4dd91083260223c007c797e46bc8f631055Chris Banes            if (NavUtils.getParentActivityName((Activity) mOriginalWindowCallback) != null) {
15316e8d4dd91083260223c007c797e46bc8f631055Chris Banes                // Peek at the Action Bar and update it if it already exists
15416e8d4dd91083260223c007c797e46bc8f631055Chris Banes                ActionBar ab = peekSupportActionBar();
15516e8d4dd91083260223c007c797e46bc8f631055Chris Banes                if (ab == null) {
15616e8d4dd91083260223c007c797e46bc8f631055Chris Banes                    mEnableDefaultActionBarUp = true;
15716e8d4dd91083260223c007c797e46bc8f631055Chris Banes                } else {
15816e8d4dd91083260223c007c797e46bc8f631055Chris Banes                    ab.setDefaultDisplayHomeAsUpEnabled(true);
15916e8d4dd91083260223c007c797e46bc8f631055Chris Banes                }
16049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            }
16149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        }
16249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
16349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
16449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    @Override
165f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes    public void onPostCreate(Bundle savedInstanceState) {
166c826d759805928c84b20e646e442d55483e003c8Chris Banes        // Make sure that the sub decor is installed
167c826d759805928c84b20e646e442d55483e003c8Chris Banes        ensureSubDecor();
168c826d759805928c84b20e646e442d55483e003c8Chris Banes    }
169c826d759805928c84b20e646e442d55483e003c8Chris Banes
170c826d759805928c84b20e646e442d55483e003c8Chris Banes    @Override
1718122ad54f129c2214631fad86cabda82815cc0d8Chris Banes    public void initWindowDecorActionBar() {
17230837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        ensureSubDecor();
17388c0ac5649d6b82c882e2de4bc4f043b107a4428Chris Banes
1748122ad54f129c2214631fad86cabda82815cc0d8Chris Banes        if (!mHasActionBar || mActionBar != null) {
1758122ad54f129c2214631fad86cabda82815cc0d8Chris Banes            return;
17688c0ac5649d6b82c882e2de4bc4f043b107a4428Chris Banes        }
17788c0ac5649d6b82c882e2de4bc4f043b107a4428Chris Banes
17816e8d4dd91083260223c007c797e46bc8f631055Chris Banes        if (mOriginalWindowCallback instanceof Activity) {
1798122ad54f129c2214631fad86cabda82815cc0d8Chris Banes            mActionBar = new WindowDecorActionBar((Activity) mOriginalWindowCallback,
1808122ad54f129c2214631fad86cabda82815cc0d8Chris Banes                    mOverlayActionBar);
18116e8d4dd91083260223c007c797e46bc8f631055Chris Banes        } else if (mOriginalWindowCallback instanceof Dialog) {
1828122ad54f129c2214631fad86cabda82815cc0d8Chris Banes            mActionBar = new WindowDecorActionBar((Dialog) mOriginalWindowCallback);
18316e8d4dd91083260223c007c797e46bc8f631055Chris Banes        }
1848122ad54f129c2214631fad86cabda82815cc0d8Chris Banes        if (mActionBar != null) {
1858122ad54f129c2214631fad86cabda82815cc0d8Chris Banes            mActionBar.setDefaultDisplayHomeAsUpEnabled(mEnableDefaultActionBarUp);
18616e8d4dd91083260223c007c797e46bc8f631055Chris Banes        }
18749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
18849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
18949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    @Override
190f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes    public void setSupportActionBar(Toolbar toolbar) {
19116e8d4dd91083260223c007c797e46bc8f631055Chris Banes        if (!(mOriginalWindowCallback instanceof Activity)) {
19216e8d4dd91083260223c007c797e46bc8f631055Chris Banes            // Only Activities support custom Action Bars
19316e8d4dd91083260223c007c797e46bc8f631055Chris Banes            return;
19416e8d4dd91083260223c007c797e46bc8f631055Chris Banes        }
19516e8d4dd91083260223c007c797e46bc8f631055Chris Banes
196da0b9d63d6f940cbfd5b526c3f81858aeadcb7e8Chris Banes        final ActionBar ab = getSupportActionBar();
197da0b9d63d6f940cbfd5b526c3f81858aeadcb7e8Chris Banes        if (ab instanceof WindowDecorActionBar) {
19849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            throw new IllegalStateException("This Activity already has an action bar supplied " +
199d25af35061a9f20d59b25329d613c62c20184dadChris Banes                    "by the window decor. Do not request Window.FEATURE_SUPPORT_ACTION_BAR and set " +
20049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                    "windowActionBar to false in your theme to use a Toolbar instead.");
20149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        }
202733d0b2acb07ede7455b9d020901a10586053923Chris Banes
203733d0b2acb07ede7455b9d020901a10586053923Chris Banes        // If we reach here then we're setting a new action bar
204733d0b2acb07ede7455b9d020901a10586053923Chris Banes        // First clear out the MenuInflater to make sure that it is valid for the new Action Bar
2055ecdb2c5042da49d36d7cda3fa08f1d9151a1fbdChris Banes        mMenuInflater = null;
206da0b9d63d6f940cbfd5b526c3f81858aeadcb7e8Chris Banes
207733d0b2acb07ede7455b9d020901a10586053923Chris Banes        // If we have an action bar currently, destroy it
208733d0b2acb07ede7455b9d020901a10586053923Chris Banes        if (ab != null) {
209733d0b2acb07ede7455b9d020901a10586053923Chris Banes            ab.onDestroy();
210733d0b2acb07ede7455b9d020901a10586053923Chris Banes        }
211733d0b2acb07ede7455b9d020901a10586053923Chris Banes
212740e50456ff7aa7b93d40e7bdc59f8a619197ed5Chris Banes        if (toolbar != null) {
213740e50456ff7aa7b93d40e7bdc59f8a619197ed5Chris Banes            final ToolbarActionBar tbab = new ToolbarActionBar(toolbar,
214740e50456ff7aa7b93d40e7bdc59f8a619197ed5Chris Banes                    ((Activity) mContext).getTitle(), mAppCompatWindowCallback);
215740e50456ff7aa7b93d40e7bdc59f8a619197ed5Chris Banes            mActionBar = tbab;
216740e50456ff7aa7b93d40e7bdc59f8a619197ed5Chris Banes            mWindow.setCallback(tbab.getWrappedWindowCallback());
217740e50456ff7aa7b93d40e7bdc59f8a619197ed5Chris Banes        } else {
218740e50456ff7aa7b93d40e7bdc59f8a619197ed5Chris Banes            mActionBar = null;
219740e50456ff7aa7b93d40e7bdc59f8a619197ed5Chris Banes            // Re-set the original window callback since we may have already set a Toolbar wrapper
220740e50456ff7aa7b93d40e7bdc59f8a619197ed5Chris Banes            mWindow.setCallback(mAppCompatWindowCallback);
221740e50456ff7aa7b93d40e7bdc59f8a619197ed5Chris Banes        }
222740e50456ff7aa7b93d40e7bdc59f8a619197ed5Chris Banes
223740e50456ff7aa7b93d40e7bdc59f8a619197ed5Chris Banes        invalidateOptionsMenu();
2246386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    }
2256386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes
2268c3845ebb7e8198950510cd7a08bc8e66e2195feChris Banes    @Nullable
2278c3845ebb7e8198950510cd7a08bc8e66e2195feChris Banes    @Override
2288c3845ebb7e8198950510cd7a08bc8e66e2195feChris Banes    public View findViewById(@IdRes int id) {
2298c3845ebb7e8198950510cd7a08bc8e66e2195feChris Banes        ensureSubDecor();
2308c3845ebb7e8198950510cd7a08bc8e66e2195feChris Banes        return mWindow.findViewById(id);
2318c3845ebb7e8198950510cd7a08bc8e66e2195feChris Banes    }
2328c3845ebb7e8198950510cd7a08bc8e66e2195feChris Banes
2336386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    @Override
2346386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    public void onConfigurationChanged(Configuration newConfig) {
2356386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes        // If this is called before sub-decor is installed, ActionBar will not
2366386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes        // be properly initialized.
2375a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes        if (mHasActionBar && mSubDecorInstalled) {
2386386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes            // Note: The action bar will need to access
2396386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes            // view changes from superclass.
24049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            ActionBar ab = getSupportActionBar();
24149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            if (ab != null) {
24249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                ab.onConfigurationChanged(newConfig);
24349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            }
2446386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes        }
245862ce3b5a8789281e0510da9195bc8ea22581706Chris Banes
246862ce3b5a8789281e0510da9195bc8ea22581706Chris Banes        // Re-apply Day/Night to the new configuration
247862ce3b5a8789281e0510da9195bc8ea22581706Chris Banes        applyDayNight();
2486386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    }
2496386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes
2506386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    @Override
251a1fae63dbeeef71c2daa25bfcaa2348bffc369aaChris Banes    public void onStop() {
25249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        ActionBar ab = getSupportActionBar();
253a1fae63dbeeef71c2daa25bfcaa2348bffc369aaChris Banes        if (ab != null) {
254a1fae63dbeeef71c2daa25bfcaa2348bffc369aaChris Banes            ab.setShowHideAnimationEnabled(false);
255a1fae63dbeeef71c2daa25bfcaa2348bffc369aaChris Banes        }
256a1fae63dbeeef71c2daa25bfcaa2348bffc369aaChris Banes    }
257a1fae63dbeeef71c2daa25bfcaa2348bffc369aaChris Banes
258a1fae63dbeeef71c2daa25bfcaa2348bffc369aaChris Banes    @Override
259a1fae63dbeeef71c2daa25bfcaa2348bffc369aaChris Banes    public void onPostResume() {
26049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        ActionBar ab = getSupportActionBar();
261a1fae63dbeeef71c2daa25bfcaa2348bffc369aaChris Banes        if (ab != null) {
262a1fae63dbeeef71c2daa25bfcaa2348bffc369aaChris Banes            ab.setShowHideAnimationEnabled(true);
263a1fae63dbeeef71c2daa25bfcaa2348bffc369aaChris Banes        }
264a1fae63dbeeef71c2daa25bfcaa2348bffc369aaChris Banes    }
265a1fae63dbeeef71c2daa25bfcaa2348bffc369aaChris Banes
266a1fae63dbeeef71c2daa25bfcaa2348bffc369aaChris Banes    @Override
2676386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    public void setContentView(View v) {
2686386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes        ensureSubDecor();
26916e8d4dd91083260223c007c797e46bc8f631055Chris Banes        ViewGroup contentParent = (ViewGroup) mSubDecor.findViewById(android.R.id.content);
27056fd50144df518461398a9b3397ee4842b346708Chris Banes        contentParent.removeAllViews();
27156fd50144df518461398a9b3397ee4842b346708Chris Banes        contentParent.addView(v);
27216e8d4dd91083260223c007c797e46bc8f631055Chris Banes        mOriginalWindowCallback.onContentChanged();
2736386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    }
2746386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes
2756386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    @Override
2766386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    public void setContentView(int resId) {
2776386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes        ensureSubDecor();
27816e8d4dd91083260223c007c797e46bc8f631055Chris Banes        ViewGroup contentParent = (ViewGroup) mSubDecor.findViewById(android.R.id.content);
27956fd50144df518461398a9b3397ee4842b346708Chris Banes        contentParent.removeAllViews();
28016e8d4dd91083260223c007c797e46bc8f631055Chris Banes        LayoutInflater.from(mContext).inflate(resId, contentParent);
28116e8d4dd91083260223c007c797e46bc8f631055Chris Banes        mOriginalWindowCallback.onContentChanged();
2826386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    }
2836386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes
2846386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    @Override
2856386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    public void setContentView(View v, ViewGroup.LayoutParams lp) {
2866386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes        ensureSubDecor();
28716e8d4dd91083260223c007c797e46bc8f631055Chris Banes        ViewGroup contentParent = (ViewGroup) mSubDecor.findViewById(android.R.id.content);
28856fd50144df518461398a9b3397ee4842b346708Chris Banes        contentParent.removeAllViews();
28956fd50144df518461398a9b3397ee4842b346708Chris Banes        contentParent.addView(v, lp);
29016e8d4dd91083260223c007c797e46bc8f631055Chris Banes        mOriginalWindowCallback.onContentChanged();
2916386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    }
2926386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes
2936386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    @Override
2946386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    public void addContentView(View v, ViewGroup.LayoutParams lp) {
2956386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes        ensureSubDecor();
29616e8d4dd91083260223c007c797e46bc8f631055Chris Banes        ViewGroup contentParent = (ViewGroup) mSubDecor.findViewById(android.R.id.content);
29756fd50144df518461398a9b3397ee4842b346708Chris Banes        contentParent.addView(v, lp);
29816e8d4dd91083260223c007c797e46bc8f631055Chris Banes        mOriginalWindowCallback.onContentChanged();
299d64322f4b9686fabfd5a03f402d50a8e3fe5adedChris Banes    }
300d64322f4b9686fabfd5a03f402d50a8e3fe5adedChris Banes
301733d0b2acb07ede7455b9d020901a10586053923Chris Banes    @Override
302733d0b2acb07ede7455b9d020901a10586053923Chris Banes    public void onDestroy() {
303733d0b2acb07ede7455b9d020901a10586053923Chris Banes        super.onDestroy();
304733d0b2acb07ede7455b9d020901a10586053923Chris Banes
305733d0b2acb07ede7455b9d020901a10586053923Chris Banes        if (mActionBar != null) {
306733d0b2acb07ede7455b9d020901a10586053923Chris Banes            mActionBar.onDestroy();
307733d0b2acb07ede7455b9d020901a10586053923Chris Banes        }
308733d0b2acb07ede7455b9d020901a10586053923Chris Banes    }
309733d0b2acb07ede7455b9d020901a10586053923Chris Banes
310f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes    private void ensureSubDecor() {
31156fd50144df518461398a9b3397ee4842b346708Chris Banes        if (!mSubDecorInstalled) {
312a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes            mSubDecor = createSubDecor();
31391a95c4599d0d5fa936b81396c71210ae7e68e54Chris Banes
31416e8d4dd91083260223c007c797e46bc8f631055Chris Banes            // If a title was set before we installed the decor, propogate it now
31516e8d4dd91083260223c007c797e46bc8f631055Chris Banes            CharSequence title = getTitle();
31616e8d4dd91083260223c007c797e46bc8f631055Chris Banes            if (!TextUtils.isEmpty(title)) {
31716e8d4dd91083260223c007c797e46bc8f631055Chris Banes                onTitleChanged(title);
318f53c7bf3146bf9bcba46324f9f06449df475be36Chris Banes            }
3194b217eaec19887b37d6d124df5ba04c5bb8b8141Chris Banes
320a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes            applyFixedSizeWindow();
3210f58401dc72db8ea2a201e3c0220f6529f2a7b33Chris Banes
32216e8d4dd91083260223c007c797e46bc8f631055Chris Banes            onSubDecorInstalled(mSubDecor);
3230f58401dc72db8ea2a201e3c0220f6529f2a7b33Chris Banes
324f53c7bf3146bf9bcba46324f9f06449df475be36Chris Banes            mSubDecorInstalled = true;
3250f58401dc72db8ea2a201e3c0220f6529f2a7b33Chris Banes
32600d183885b54de433e43118d3032340f40cac8c0Chris Banes            // Invalidate if the panel menu hasn't been created before this.
32700d183885b54de433e43118d3032340f40cac8c0Chris Banes            // Panel menu invalidation is deferred avoiding application onCreateOptionsMenu
32800d183885b54de433e43118d3032340f40cac8c0Chris Banes            // being called in the middle of onCreate or similar.
32900d183885b54de433e43118d3032340f40cac8c0Chris Banes            // A pending invalidation will typically be resolved before the posted message
33000d183885b54de433e43118d3032340f40cac8c0Chris Banes            // would run normally in order to satisfy instance state restoration.
33100d183885b54de433e43118d3032340f40cac8c0Chris Banes            PanelFeatureState st = getPanelState(FEATURE_OPTIONS_PANEL, false);
3329b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes            if (!isDestroyed() && (st == null || st.menu == null)) {
333d25af35061a9f20d59b25329d613c62c20184dadChris Banes                invalidatePanelMenu(FEATURE_SUPPORT_ACTION_BAR);
33400d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
3356386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes        }
3366386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    }
337ea4f700ac38424954c56df5138ff794def50b019Chris Banes
338a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes    private ViewGroup createSubDecor() {
339a777694569b333a4459606db6bc94a9e80fd25f3Chris Banes        TypedArray a = mContext.obtainStyledAttributes(R.styleable.AppCompatTheme);
340a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes
341a777694569b333a4459606db6bc94a9e80fd25f3Chris Banes        if (!a.hasValue(R.styleable.AppCompatTheme_windowActionBar)) {
342a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes            a.recycle();
343a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes            throw new IllegalStateException(
344a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes                    "You need to use a Theme.AppCompat theme (or descendant) with this activity.");
345a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes        }
346a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes
347a777694569b333a4459606db6bc94a9e80fd25f3Chris Banes        if (a.getBoolean(R.styleable.AppCompatTheme_windowNoTitle, false)) {
348a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes            requestWindowFeature(Window.FEATURE_NO_TITLE);
349a777694569b333a4459606db6bc94a9e80fd25f3Chris Banes        } else if (a.getBoolean(R.styleable.AppCompatTheme_windowActionBar, false)) {
350a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes            // Don't allow an action bar if there is no title.
351a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes            requestWindowFeature(FEATURE_SUPPORT_ACTION_BAR);
352a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes        }
353a777694569b333a4459606db6bc94a9e80fd25f3Chris Banes        if (a.getBoolean(R.styleable.AppCompatTheme_windowActionBarOverlay, false)) {
354a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes            requestWindowFeature(FEATURE_SUPPORT_ACTION_BAR_OVERLAY);
355a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes        }
356a777694569b333a4459606db6bc94a9e80fd25f3Chris Banes        if (a.getBoolean(R.styleable.AppCompatTheme_windowActionModeOverlay, false)) {
357a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes            requestWindowFeature(FEATURE_ACTION_MODE_OVERLAY);
358a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes        }
359a777694569b333a4459606db6bc94a9e80fd25f3Chris Banes        mIsFloating = a.getBoolean(R.styleable.AppCompatTheme_android_windowIsFloating, false);
360a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes        a.recycle();
361a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes
362d3c6a162266698b98df2fa7793d9fe4d8ee8935bChris Banes        // Now let's make sure that the Window has installed its decor by retrieving it
363d3c6a162266698b98df2fa7793d9fe4d8ee8935bChris Banes        mWindow.getDecorView();
364d3c6a162266698b98df2fa7793d9fe4d8ee8935bChris Banes
365a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes        final LayoutInflater inflater = LayoutInflater.from(mContext);
366a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes        ViewGroup subDecor = null;
367a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes
368a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes
369a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes        if (!mWindowNoTitle) {
370a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes            if (mIsFloating) {
371a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes                // If we're floating, inflate the dialog title decor
372a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes                subDecor = (ViewGroup) inflater.inflate(
373a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes                        R.layout.abc_dialog_title_material, null);
374a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes
375a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes                // Floating windows can never have an action bar, reset the flags
376a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes                mHasActionBar = mOverlayActionBar = false;
377a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes            } else if (mHasActionBar) {
378a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes                /**
379a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes                 * This needs some explanation. As we can not use the android:theme attribute
380a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes                 * pre-L, we emulate it by manually creating a LayoutInflater using a
381a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes                 * ContextThemeWrapper pointing to actionBarTheme.
382a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes                 */
383a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes                TypedValue outValue = new TypedValue();
384a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes                mContext.getTheme().resolveAttribute(R.attr.actionBarTheme, outValue, true);
385a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes
386a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes                Context themedContext;
387a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes                if (outValue.resourceId != 0) {
388a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes                    themedContext = new ContextThemeWrapper(mContext, outValue.resourceId);
389ea4f700ac38424954c56df5138ff794def50b019Chris Banes                } else {
390a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes                    themedContext = mContext;
391ea4f700ac38424954c56df5138ff794def50b019Chris Banes                }
3923954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes
393a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes                // Now inflate the view using the themed context and set it as the content view
394a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes                subDecor = (ViewGroup) LayoutInflater.from(themedContext)
395a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes                        .inflate(R.layout.abc_screen_toolbar, null);
3960f58401dc72db8ea2a201e3c0220f6529f2a7b33Chris Banes
397a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes                mDecorContentParent = (DecorContentParent) subDecor
398a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes                        .findViewById(R.id.decor_content_parent);
399a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes                mDecorContentParent.setWindowCallback(getWindowCallback());
40016e8d4dd91083260223c007c797e46bc8f631055Chris Banes
401a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes                /**
402a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes                 * Propagate features to DecorContentParent
403a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes                 */
404a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes                if (mOverlayActionBar) {
405a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes                    mDecorContentParent.initFeature(FEATURE_SUPPORT_ACTION_BAR_OVERLAY);
406a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes                }
407a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes                if (mFeatureProgress) {
408a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes                    mDecorContentParent.initFeature(Window.FEATURE_PROGRESS);
409a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes                }
410a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes                if (mFeatureIndeterminateProgress) {
411a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes                    mDecorContentParent.initFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
412a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes                }
413a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes            }
414a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes        } else {
415a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes            if (mOverlayActionMode) {
416a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes                subDecor = (ViewGroup) inflater.inflate(
417a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes                        R.layout.abc_screen_simple_overlay_action_mode, null);
418a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes            } else {
419a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes                subDecor = (ViewGroup) inflater.inflate(R.layout.abc_screen_simple, null);
420a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes            }
4211f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes
422a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes            if (Build.VERSION.SDK_INT >= 21) {
423a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes                // If we're running on L or above, we can rely on ViewCompat's
424a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes                // setOnApplyWindowInsetsListener
425a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes                ViewCompat.setOnApplyWindowInsetsListener(subDecor,
426a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes                        new OnApplyWindowInsetsListener() {
427a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes                            @Override
428a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes                            public WindowInsetsCompat onApplyWindowInsets(View v,
429a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes                                    WindowInsetsCompat insets) {
430a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes                                final int top = insets.getSystemWindowInsetTop();
431a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes                                final int newTop = updateStatusGuard(top);
432a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes
433a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes                                if (top != newTop) {
434a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes                                    insets = insets.replaceSystemWindowInsets(
435a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes                                            insets.getSystemWindowInsetLeft(),
436a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes                                            newTop,
437a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes                                            insets.getSystemWindowInsetRight(),
438a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes                                            insets.getSystemWindowInsetBottom());
439a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes                                }
440c826d759805928c84b20e646e442d55483e003c8Chris Banes
441a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes                                // Now apply the insets on our view
442a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes                                return ViewCompat.onApplyWindowInsets(v, insets);
443a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes                            }
444a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes                        });
445a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes            } else {
446a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes                // Else, we need to use our own FitWindowsViewGroup handling
447a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes                ((FitWindowsViewGroup) subDecor).setOnFitSystemWindowsListener(
448a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes                        new FitWindowsViewGroup.OnFitSystemWindowsListener() {
449a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes                            @Override
450a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes                            public void onFitSystemWindows(Rect insets) {
451a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes                                insets.top = updateStatusGuard(insets.top);
452a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes                            }
453a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes                        });
454c826d759805928c84b20e646e442d55483e003c8Chris Banes            }
455a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes        }
456c826d759805928c84b20e646e442d55483e003c8Chris Banes
457a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes        if (subDecor == null) {
458a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes            throw new IllegalArgumentException(
459a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes                    "AppCompat does not support the current theme features: { "
460a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes                            + "windowActionBar: " + mHasActionBar
461a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes                            + ", windowActionBarOverlay: "+ mOverlayActionBar
462a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes                            + ", android:windowIsFloating: " + mIsFloating
463a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes                            + ", windowActionModeOverlay: " + mOverlayActionMode
464a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes                            + ", windowNoTitle: " + mWindowNoTitle
465a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes                            + " }");
466a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes        }
4671f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes
468a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes        if (mDecorContentParent == null) {
469a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes            mTitleView = (TextView) subDecor.findViewById(R.id.title);
470a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes        }
47192b18eb0263ef2421fda5bf977fea3bf044bf941Chris Banes
472a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes        // Make the decor optionally fit system windows, like the window's decor
473a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes        ViewUtils.makeOptionalFitsSystemWindows(subDecor);
4744b217eaec19887b37d6d124df5ba04c5bb8b8141Chris Banes
475d3c6a162266698b98df2fa7793d9fe4d8ee8935bChris Banes        final ContentFrameLayout contentView = (ContentFrameLayout) subDecor.findViewById(
476a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes                R.id.action_bar_activity_content);
477556ac47ce764a4a9320b5ac914536e9da2524176Chris Banes
478d3c6a162266698b98df2fa7793d9fe4d8ee8935bChris Banes        final ViewGroup windowContentView = (ViewGroup) mWindow.findViewById(android.R.id.content);
479d3c6a162266698b98df2fa7793d9fe4d8ee8935bChris Banes        if (windowContentView != null) {
480d3c6a162266698b98df2fa7793d9fe4d8ee8935bChris Banes            // There might be Views already added to the Window's content view so we need to
481d3c6a162266698b98df2fa7793d9fe4d8ee8935bChris Banes            // migrate them to our content view
482d3c6a162266698b98df2fa7793d9fe4d8ee8935bChris Banes            while (windowContentView.getChildCount() > 0) {
483d3c6a162266698b98df2fa7793d9fe4d8ee8935bChris Banes                final View child = windowContentView.getChildAt(0);
484d3c6a162266698b98df2fa7793d9fe4d8ee8935bChris Banes                windowContentView.removeViewAt(0);
485d3c6a162266698b98df2fa7793d9fe4d8ee8935bChris Banes                contentView.addView(child);
486d3c6a162266698b98df2fa7793d9fe4d8ee8935bChris Banes            }
487d3c6a162266698b98df2fa7793d9fe4d8ee8935bChris Banes
488d3c6a162266698b98df2fa7793d9fe4d8ee8935bChris Banes            // Change our content FrameLayout to use the android.R.id.content id.
489d3c6a162266698b98df2fa7793d9fe4d8ee8935bChris Banes            // Useful for fragments.
490d3c6a162266698b98df2fa7793d9fe4d8ee8935bChris Banes            windowContentView.setId(View.NO_ID);
491d3c6a162266698b98df2fa7793d9fe4d8ee8935bChris Banes            contentView.setId(android.R.id.content);
492d3c6a162266698b98df2fa7793d9fe4d8ee8935bChris Banes
493d3c6a162266698b98df2fa7793d9fe4d8ee8935bChris Banes            // The decorContent may have a foreground drawable set (windowContentOverlay).
494d3c6a162266698b98df2fa7793d9fe4d8ee8935bChris Banes            // Remove this as we handle it ourselves
495d3c6a162266698b98df2fa7793d9fe4d8ee8935bChris Banes            if (windowContentView instanceof FrameLayout) {
496d3c6a162266698b98df2fa7793d9fe4d8ee8935bChris Banes                ((FrameLayout) windowContentView).setForeground(null);
497d3c6a162266698b98df2fa7793d9fe4d8ee8935bChris Banes            }
498a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes        }
49956fd50144df518461398a9b3397ee4842b346708Chris Banes
500a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes        // Now set the Window's content view with the decor
501a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes        mWindow.setContentView(subDecor);
50249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
503d3c6a162266698b98df2fa7793d9fe4d8ee8935bChris Banes        contentView.setAttachListener(new ContentFrameLayout.OnAttachListener() {
504b034e4ad40bff78a848d9ed91754e3f9f3492f11Chris Banes            @Override
505b034e4ad40bff78a848d9ed91754e3f9f3492f11Chris Banes            public void onAttachedFromWindow() {}
506b034e4ad40bff78a848d9ed91754e3f9f3492f11Chris Banes
507b034e4ad40bff78a848d9ed91754e3f9f3492f11Chris Banes            @Override
508b034e4ad40bff78a848d9ed91754e3f9f3492f11Chris Banes            public void onDetachedFromWindow() {
509b034e4ad40bff78a848d9ed91754e3f9f3492f11Chris Banes                dismissPopups();
510b034e4ad40bff78a848d9ed91754e3f9f3492f11Chris Banes            }
511b034e4ad40bff78a848d9ed91754e3f9f3492f11Chris Banes        });
512b034e4ad40bff78a848d9ed91754e3f9f3492f11Chris Banes
513a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes        return subDecor;
5146386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    }
5156386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes
51616e8d4dd91083260223c007c797e46bc8f631055Chris Banes    void onSubDecorInstalled(ViewGroup subDecor) {}
51749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
518a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes    private void applyFixedSizeWindow() {
519a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes        ContentFrameLayout cfl = (ContentFrameLayout) mSubDecor.findViewById(android.R.id.content);
520a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes
521d8b7157eae680353a2821dca3c9e52b3aaf737a5Chris Banes        // This is a bit weird. In the framework, the window sizing attributes control
522d8b7157eae680353a2821dca3c9e52b3aaf737a5Chris Banes        // the decor view's size, meaning that any padding is inset for the min/max widths below.
523d8b7157eae680353a2821dca3c9e52b3aaf737a5Chris Banes        // We don't control measurement at that level, so we need to workaround it by making sure
524d8b7157eae680353a2821dca3c9e52b3aaf737a5Chris Banes        // that the decor view's padding is taken into account.
525ff7f258a9b0781de5c6325358c7075128bf05a91Chris Banes        final View windowDecor = mWindow.getDecorView();
526ff7f258a9b0781de5c6325358c7075128bf05a91Chris Banes        cfl.setDecorPadding(windowDecor.getPaddingLeft(),
527ff7f258a9b0781de5c6325358c7075128bf05a91Chris Banes                windowDecor.getPaddingTop(), windowDecor.getPaddingRight(),
528ff7f258a9b0781de5c6325358c7075128bf05a91Chris Banes                windowDecor.getPaddingBottom());
529d8b7157eae680353a2821dca3c9e52b3aaf737a5Chris Banes
530a777694569b333a4459606db6bc94a9e80fd25f3Chris Banes        TypedArray a = mContext.obtainStyledAttributes(R.styleable.AppCompatTheme);
531a777694569b333a4459606db6bc94a9e80fd25f3Chris Banes        a.getValue(R.styleable.AppCompatTheme_windowMinWidthMajor, cfl.getMinWidthMajor());
532a777694569b333a4459606db6bc94a9e80fd25f3Chris Banes        a.getValue(R.styleable.AppCompatTheme_windowMinWidthMinor, cfl.getMinWidthMinor());
53356fd50144df518461398a9b3397ee4842b346708Chris Banes
534a777694569b333a4459606db6bc94a9e80fd25f3Chris Banes        if (a.hasValue(R.styleable.AppCompatTheme_windowFixedWidthMajor)) {
535a777694569b333a4459606db6bc94a9e80fd25f3Chris Banes            a.getValue(R.styleable.AppCompatTheme_windowFixedWidthMajor,
536a777694569b333a4459606db6bc94a9e80fd25f3Chris Banes                    cfl.getFixedWidthMajor());
53756fd50144df518461398a9b3397ee4842b346708Chris Banes        }
538a777694569b333a4459606db6bc94a9e80fd25f3Chris Banes        if (a.hasValue(R.styleable.AppCompatTheme_windowFixedWidthMinor)) {
539a777694569b333a4459606db6bc94a9e80fd25f3Chris Banes            a.getValue(R.styleable.AppCompatTheme_windowFixedWidthMinor,
540a777694569b333a4459606db6bc94a9e80fd25f3Chris Banes                    cfl.getFixedWidthMinor());
54156fd50144df518461398a9b3397ee4842b346708Chris Banes        }
542a777694569b333a4459606db6bc94a9e80fd25f3Chris Banes        if (a.hasValue(R.styleable.AppCompatTheme_windowFixedHeightMajor)) {
543a777694569b333a4459606db6bc94a9e80fd25f3Chris Banes            a.getValue(R.styleable.AppCompatTheme_windowFixedHeightMajor,
544a777694569b333a4459606db6bc94a9e80fd25f3Chris Banes                    cfl.getFixedHeightMajor());
54556fd50144df518461398a9b3397ee4842b346708Chris Banes        }
546a777694569b333a4459606db6bc94a9e80fd25f3Chris Banes        if (a.hasValue(R.styleable.AppCompatTheme_windowFixedHeightMinor)) {
547a777694569b333a4459606db6bc94a9e80fd25f3Chris Banes            a.getValue(R.styleable.AppCompatTheme_windowFixedHeightMinor,
548a777694569b333a4459606db6bc94a9e80fd25f3Chris Banes                    cfl.getFixedHeightMinor());
54956fd50144df518461398a9b3397ee4842b346708Chris Banes        }
55056fd50144df518461398a9b3397ee4842b346708Chris Banes        a.recycle();
55119eaf14cb3cca613f984a32be2fab2534427fb29Chris Banes
552a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes        cfl.requestLayout();
55356fd50144df518461398a9b3397ee4842b346708Chris Banes    }
55456fd50144df518461398a9b3397ee4842b346708Chris Banes
5556386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    @Override
556f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes    public boolean requestWindowFeature(int featureId) {
5578122ad54f129c2214631fad86cabda82815cc0d8Chris Banes        featureId = sanitizeWindowFeatureId(featureId);
5588122ad54f129c2214631fad86cabda82815cc0d8Chris Banes
55988c0ac5649d6b82c882e2de4bc4f043b107a4428Chris Banes        if (mWindowNoTitle && featureId == FEATURE_SUPPORT_ACTION_BAR) {
56088c0ac5649d6b82c882e2de4bc4f043b107a4428Chris Banes            return false; // Ignore. No title dominates.
56188c0ac5649d6b82c882e2de4bc4f043b107a4428Chris Banes        }
56288c0ac5649d6b82c882e2de4bc4f043b107a4428Chris Banes        if (mHasActionBar && featureId == Window.FEATURE_NO_TITLE) {
56388c0ac5649d6b82c882e2de4bc4f043b107a4428Chris Banes            // Remove the action bar feature if we have no title. No title dominates.
56488c0ac5649d6b82c882e2de4bc4f043b107a4428Chris Banes            mHasActionBar = false;
56588c0ac5649d6b82c882e2de4bc4f043b107a4428Chris Banes        }
56688c0ac5649d6b82c882e2de4bc4f043b107a4428Chris Banes
5676386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes        switch (featureId) {
568d25af35061a9f20d59b25329d613c62c20184dadChris Banes            case FEATURE_SUPPORT_ACTION_BAR:
569cc7aada3ee922cfb38eeb36ee696cc73dcbae0a4Chris Banes                throwFeatureRequestIfSubDecorInstalled();
5705a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes                mHasActionBar = true;
5716386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes                return true;
572d25af35061a9f20d59b25329d613c62c20184dadChris Banes            case FEATURE_SUPPORT_ACTION_BAR_OVERLAY:
573cc7aada3ee922cfb38eeb36ee696cc73dcbae0a4Chris Banes                throwFeatureRequestIfSubDecorInstalled();
5745a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes                mOverlayActionBar = true;
5756386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes                return true;
57600d183885b54de433e43118d3032340f40cac8c0Chris Banes            case FEATURE_ACTION_MODE_OVERLAY:
577cc7aada3ee922cfb38eeb36ee696cc73dcbae0a4Chris Banes                throwFeatureRequestIfSubDecorInstalled();
578de9f38cc4a30b33ac46b105edf470fbc4a044e99Chris Banes                mOverlayActionMode = true;
579de9f38cc4a30b33ac46b105edf470fbc4a044e99Chris Banes                return true;
580ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes            case Window.FEATURE_PROGRESS:
581cc7aada3ee922cfb38eeb36ee696cc73dcbae0a4Chris Banes                throwFeatureRequestIfSubDecorInstalled();
582ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes                mFeatureProgress = true;
583ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes                return true;
584ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes            case Window.FEATURE_INDETERMINATE_PROGRESS:
585cc7aada3ee922cfb38eeb36ee696cc73dcbae0a4Chris Banes                throwFeatureRequestIfSubDecorInstalled();
586ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes                mFeatureIndeterminateProgress = true;
587ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes                return true;
58819eaf14cb3cca613f984a32be2fab2534427fb29Chris Banes            case Window.FEATURE_NO_TITLE:
58919eaf14cb3cca613f984a32be2fab2534427fb29Chris Banes                throwFeatureRequestIfSubDecorInstalled();
59019eaf14cb3cca613f984a32be2fab2534427fb29Chris Banes                mWindowNoTitle = true;
59119eaf14cb3cca613f984a32be2fab2534427fb29Chris Banes                return true;
5926386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes        }
593cc7aada3ee922cfb38eeb36ee696cc73dcbae0a4Chris Banes
59416e8d4dd91083260223c007c797e46bc8f631055Chris Banes        return mWindow.requestFeature(featureId);
5956386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    }
5966386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes
5976386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    @Override
598eba6361c28fad482737765413aed1290da67f2daChris Banes    public boolean hasWindowFeature(int featureId) {
599eba6361c28fad482737765413aed1290da67f2daChris Banes        featureId = sanitizeWindowFeatureId(featureId);
600eba6361c28fad482737765413aed1290da67f2daChris Banes        switch (featureId) {
601eba6361c28fad482737765413aed1290da67f2daChris Banes            case FEATURE_SUPPORT_ACTION_BAR:
602eba6361c28fad482737765413aed1290da67f2daChris Banes                return mHasActionBar;
603eba6361c28fad482737765413aed1290da67f2daChris Banes            case FEATURE_SUPPORT_ACTION_BAR_OVERLAY:
604eba6361c28fad482737765413aed1290da67f2daChris Banes                return mOverlayActionBar;
605eba6361c28fad482737765413aed1290da67f2daChris Banes            case FEATURE_ACTION_MODE_OVERLAY:
606eba6361c28fad482737765413aed1290da67f2daChris Banes                return mOverlayActionMode;
607eba6361c28fad482737765413aed1290da67f2daChris Banes            case Window.FEATURE_PROGRESS:
608eba6361c28fad482737765413aed1290da67f2daChris Banes                return mFeatureProgress;
609eba6361c28fad482737765413aed1290da67f2daChris Banes            case Window.FEATURE_INDETERMINATE_PROGRESS:
610eba6361c28fad482737765413aed1290da67f2daChris Banes                return mFeatureIndeterminateProgress;
611eba6361c28fad482737765413aed1290da67f2daChris Banes            case Window.FEATURE_NO_TITLE:
612eba6361c28fad482737765413aed1290da67f2daChris Banes                return mWindowNoTitle;
613eba6361c28fad482737765413aed1290da67f2daChris Banes        }
614eba6361c28fad482737765413aed1290da67f2daChris Banes        return mWindow.hasFeature(featureId);
615eba6361c28fad482737765413aed1290da67f2daChris Banes    }
616eba6361c28fad482737765413aed1290da67f2daChris Banes
617eba6361c28fad482737765413aed1290da67f2daChris Banes    @Override
61816e8d4dd91083260223c007c797e46bc8f631055Chris Banes    void onTitleChanged(CharSequence title) {
61949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        if (mDecorContentParent != null) {
62049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            mDecorContentParent.setWindowTitle(title);
621535c5737ba868a622d7783d57f7078ab285717c0Chris Banes        } else if (peekSupportActionBar() != null) {
622535c5737ba868a622d7783d57f7078ab285717c0Chris Banes            peekSupportActionBar().setWindowTitle(title);
62316e8d4dd91083260223c007c797e46bc8f631055Chris Banes        } else if (mTitleView != null) {
62416e8d4dd91083260223c007c797e46bc8f631055Chris Banes            mTitleView.setText(title);
6256386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes        }
6266386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    }
6276386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes
6286386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    @Override
629d25af35061a9f20d59b25329d613c62c20184dadChris Banes    void onPanelClosed(final int featureId, Menu menu) {
630d25af35061a9f20d59b25329d613c62c20184dadChris Banes        if (featureId == FEATURE_SUPPORT_ACTION_BAR) {
63100d183885b54de433e43118d3032340f40cac8c0Chris Banes            ActionBar ab = getSupportActionBar();
63200d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (ab != null) {
63300d183885b54de433e43118d3032340f40cac8c0Chris Banes                ab.dispatchMenuVisibilityChanged(false);
63400d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
635436e191f80e197712dd1a7f1f7c61acfff8b1f04Chris Banes        } else if (featureId == FEATURE_OPTIONS_PANEL) {
636436e191f80e197712dd1a7f1f7c61acfff8b1f04Chris Banes            // Make sure that the options panel is closed. This is mainly used when we're using a
637436e191f80e197712dd1a7f1f7c61acfff8b1f04Chris Banes            // ToolbarActionBar
638436e191f80e197712dd1a7f1f7c61acfff8b1f04Chris Banes            PanelFeatureState st = getPanelState(featureId, true);
639436e191f80e197712dd1a7f1f7c61acfff8b1f04Chris Banes            if (st.isOpen) {
640436e191f80e197712dd1a7f1f7c61acfff8b1f04Chris Banes                closePanel(st, false);
641436e191f80e197712dd1a7f1f7c61acfff8b1f04Chris Banes            }
642c4b9e0cb716a4caff218b27d86f37ef8117d257bChris Banes        }
643c4b9e0cb716a4caff218b27d86f37ef8117d257bChris Banes    }
644c4b9e0cb716a4caff218b27d86f37ef8117d257bChris Banes
645c4b9e0cb716a4caff218b27d86f37ef8117d257bChris Banes    @Override
64600d183885b54de433e43118d3032340f40cac8c0Chris Banes    boolean onMenuOpened(final int featureId, Menu menu) {
647d25af35061a9f20d59b25329d613c62c20184dadChris Banes        if (featureId == FEATURE_SUPPORT_ACTION_BAR) {
64800d183885b54de433e43118d3032340f40cac8c0Chris Banes            ActionBar ab = getSupportActionBar();
64900d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (ab != null) {
65000d183885b54de433e43118d3032340f40cac8c0Chris Banes                ab.dispatchMenuVisibilityChanged(true);
65100d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
65200d183885b54de433e43118d3032340f40cac8c0Chris Banes            return true;
653c4b9e0cb716a4caff218b27d86f37ef8117d257bChris Banes        }
654f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes        return false;
65503fc11b659da1645507062bddda450136e13af35Chris Banes    }
65603fc11b659da1645507062bddda450136e13af35Chris Banes
65703fc11b659da1645507062bddda450136e13af35Chris Banes    @Override
6586386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    public boolean onMenuItemSelected(MenuBuilder menu, MenuItem item) {
659f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes        final Window.Callback cb = getWindowCallback();
6609b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes        if (cb != null && !isDestroyed()) {
6619b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes            final PanelFeatureState panel = findMenuPanel(menu.getRootMenu());
6629b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes            if (panel != null) {
6639b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes                return cb.onMenuItemSelected(panel.featureId, item);
6649b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes            }
6659b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes        }
6669b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes        return false;
6676386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    }
6686386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes
6696386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    @Override
6706386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    public void onMenuModeChange(MenuBuilder menu) {
6716386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes        reopenMenu(menu, true);
6726386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    }
6736386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes
6746386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    @Override
675bfc9bd50c5c7e6874dc6f32a5d81620398a5c1e5Chris Banes    public ActionMode startSupportActionMode(@NonNull final ActionMode.Callback callback) {
676d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        if (callback == null) {
677d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes            throw new IllegalArgumentException("ActionMode callback can not be null.");
678d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        }
679d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes
680d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        if (mActionMode != null) {
681d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes            mActionMode.finish();
682d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        }
683d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes
684547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes        final ActionMode.Callback wrappedCallback = new ActionModeCallbackWrapperV7(callback);
685d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes
68649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        ActionBar ab = getSupportActionBar();
687d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        if (ab != null) {
6885a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes            mActionMode = ab.startActionMode(wrappedCallback);
689f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes            if (mActionMode != null && mAppCompatCallback != null) {
690f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes                mAppCompatCallback.onSupportActionModeStarted(mActionMode);
6910bf48858279237f95d6aad565a074490745491cdChris Banes            }
692d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        }
693d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes
6940bf48858279237f95d6aad565a074490745491cdChris Banes        if (mActionMode == null) {
6950bf48858279237f95d6aad565a074490745491cdChris Banes            // If the action bar didn't provide an action mode, start the emulated window one
6960bf48858279237f95d6aad565a074490745491cdChris Banes            mActionMode = startSupportActionModeFromWindow(wrappedCallback);
697d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        }
6980bf48858279237f95d6aad565a074490745491cdChris Banes
699d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        return mActionMode;
700d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes    }
701d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes
702d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes    @Override
703f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes    public void invalidateOptionsMenu() {
704f2045f06bdfc9e2cc40a734e41e45d11adf2bc23Chris Banes        final ActionBar ab = getSupportActionBar();
705f2045f06bdfc9e2cc40a734e41e45d11adf2bc23Chris Banes        if (ab != null && ab.invalidateOptionsMenu()) return;
706f2045f06bdfc9e2cc40a734e41e45d11adf2bc23Chris Banes
70700d183885b54de433e43118d3032340f40cac8c0Chris Banes        invalidatePanelMenu(FEATURE_OPTIONS_PANEL);
7086386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    }
7096386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes
7104c2a95906254748cb9a843b061288265d6e185a9Chris Banes    @Override
711bfc9bd50c5c7e6874dc6f32a5d81620398a5c1e5Chris Banes    ActionMode startSupportActionModeFromWindow(@NonNull ActionMode.Callback callback) {
712c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu        endOnGoingFadeAnimation();
7134c2a95906254748cb9a843b061288265d6e185a9Chris Banes        if (mActionMode != null) {
7144c2a95906254748cb9a843b061288265d6e185a9Chris Banes            mActionMode.finish();
7154c2a95906254748cb9a843b061288265d6e185a9Chris Banes        }
7164c2a95906254748cb9a843b061288265d6e185a9Chris Banes
717bfc9bd50c5c7e6874dc6f32a5d81620398a5c1e5Chris Banes        if (!(callback instanceof ActionModeCallbackWrapperV7)) {
718bfc9bd50c5c7e6874dc6f32a5d81620398a5c1e5Chris Banes            // If the callback hasn't been wrapped yet, wrap it
719bfc9bd50c5c7e6874dc6f32a5d81620398a5c1e5Chris Banes            callback = new ActionModeCallbackWrapperV7(callback);
720bfc9bd50c5c7e6874dc6f32a5d81620398a5c1e5Chris Banes        }
721bfc9bd50c5c7e6874dc6f32a5d81620398a5c1e5Chris Banes
722547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes        ActionMode mode = null;
723547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes        if (mAppCompatCallback != null && !isDestroyed()) {
724547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes            try {
725bfc9bd50c5c7e6874dc6f32a5d81620398a5c1e5Chris Banes                mode = mAppCompatCallback.onWindowStartingSupportActionMode(callback);
726547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes            } catch (AbstractMethodError ame) {
727547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes                // Older apps might not implement this callback method.
7284c2a95906254748cb9a843b061288265d6e185a9Chris Banes            }
7294c2a95906254748cb9a843b061288265d6e185a9Chris Banes        }
7304c2a95906254748cb9a843b061288265d6e185a9Chris Banes
731547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes        if (mode != null) {
732547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes            mActionMode = mode;
733547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes        } else {
734547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes            if (mActionModeView == null) {
735547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes                if (mIsFloating) {
736547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes                    // Use the action bar theme.
737547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes                    final TypedValue outValue = new TypedValue();
738547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes                    final Resources.Theme baseTheme = mContext.getTheme();
739547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes                    baseTheme.resolveAttribute(R.attr.actionBarTheme, outValue, true);
740547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes
741547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes                    final Context actionBarContext;
742547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes                    if (outValue.resourceId != 0) {
743547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes                        final Resources.Theme actionBarTheme = mContext.getResources().newTheme();
744547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes                        actionBarTheme.setTo(baseTheme);
745547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes                        actionBarTheme.applyStyle(outValue.resourceId, true);
746547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes
747547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes                        actionBarContext = new ContextThemeWrapper(mContext, 0);
748547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes                        actionBarContext.getTheme().setTo(actionBarTheme);
749547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes                    } else {
750547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes                        actionBarContext = mContext;
751547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes                    }
752547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes
753547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes                    mActionModeView = new ActionBarContextView(actionBarContext);
754547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes                    mActionModePopup = new PopupWindow(actionBarContext, null,
755547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes                            R.attr.actionModePopupWindowStyle);
756f5829201b976fc650789accc22f325a2541ed478Chris Banes                    PopupWindowCompat.setWindowLayoutType(mActionModePopup,
757f5829201b976fc650789accc22f325a2541ed478Chris Banes                            WindowManager.LayoutParams.TYPE_APPLICATION);
758547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes                    mActionModePopup.setContentView(mActionModeView);
759547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes                    mActionModePopup.setWidth(ViewGroup.LayoutParams.MATCH_PARENT);
760547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes
761547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes                    actionBarContext.getTheme().resolveAttribute(
762547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes                            R.attr.actionBarSize, outValue, true);
763547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes                    final int height = TypedValue.complexToDimensionPixelSize(outValue.data,
764547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes                            actionBarContext.getResources().getDisplayMetrics());
765547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes                    mActionModeView.setContentHeight(height);
766547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes                    mActionModePopup.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
767547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes                    mShowActionModePopup = new Runnable() {
768547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes                        public void run() {
769547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes                            mActionModePopup.showAtLocation(
770547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes                                    mActionModeView,
771547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes                                    Gravity.TOP | Gravity.FILL_HORIZONTAL, 0, 0);
772c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu                            endOnGoingFadeAnimation();
773c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu
77445b0ea2a10e79b580aabb411126d8d6b79c9da95Chris Banes                            if (shouldAnimateActionModeView()) {
77545b0ea2a10e79b580aabb411126d8d6b79c9da95Chris Banes                                ViewCompat.setAlpha(mActionModeView, 0f);
77645b0ea2a10e79b580aabb411126d8d6b79c9da95Chris Banes                                mFadeAnim = ViewCompat.animate(mActionModeView).alpha(1f);
77745b0ea2a10e79b580aabb411126d8d6b79c9da95Chris Banes                                mFadeAnim.setListener(new ViewPropertyAnimatorListenerAdapter() {
77845b0ea2a10e79b580aabb411126d8d6b79c9da95Chris Banes                                    @Override
77945b0ea2a10e79b580aabb411126d8d6b79c9da95Chris Banes                                    public void onAnimationStart(View view) {
78045b0ea2a10e79b580aabb411126d8d6b79c9da95Chris Banes                                        mActionModeView.setVisibility(View.VISIBLE);
78145b0ea2a10e79b580aabb411126d8d6b79c9da95Chris Banes                                    }
78245b0ea2a10e79b580aabb411126d8d6b79c9da95Chris Banes
78345b0ea2a10e79b580aabb411126d8d6b79c9da95Chris Banes                                    @Override
78445b0ea2a10e79b580aabb411126d8d6b79c9da95Chris Banes                                    public void onAnimationEnd(View view) {
78545b0ea2a10e79b580aabb411126d8d6b79c9da95Chris Banes                                        ViewCompat.setAlpha(mActionModeView, 1f);
78645b0ea2a10e79b580aabb411126d8d6b79c9da95Chris Banes                                        mFadeAnim.setListener(null);
78745b0ea2a10e79b580aabb411126d8d6b79c9da95Chris Banes                                        mFadeAnim = null;
78845b0ea2a10e79b580aabb411126d8d6b79c9da95Chris Banes                                    }
78945b0ea2a10e79b580aabb411126d8d6b79c9da95Chris Banes                                });
79045b0ea2a10e79b580aabb411126d8d6b79c9da95Chris Banes                            } else {
79145b0ea2a10e79b580aabb411126d8d6b79c9da95Chris Banes                                ViewCompat.setAlpha(mActionModeView, 1f);
79245b0ea2a10e79b580aabb411126d8d6b79c9da95Chris Banes                                mActionModeView.setVisibility(View.VISIBLE);
79345b0ea2a10e79b580aabb411126d8d6b79c9da95Chris Banes                            }
794547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes                        }
795547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes                    };
796547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes                } else {
797547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes                    ViewStubCompat stub = (ViewStubCompat) mSubDecor
798547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes                            .findViewById(R.id.action_mode_bar_stub);
799547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes                    if (stub != null) {
800547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes                        // Set the layout inflater so that it is inflated with the action bar's context
801547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes                        stub.setLayoutInflater(LayoutInflater.from(getActionBarThemedContext()));
802547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes                        mActionModeView = (ActionBarContextView) stub.inflate();
803547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes                    }
8044c2a95906254748cb9a843b061288265d6e185a9Chris Banes                }
805547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes            }
806ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes
807547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes            if (mActionModeView != null) {
808c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu                endOnGoingFadeAnimation();
809547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes                mActionModeView.killMode();
810547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes                mode = new StandaloneActionMode(mActionModeView.getContext(), mActionModeView,
811bfc9bd50c5c7e6874dc6f32a5d81620398a5c1e5Chris Banes                        callback, mActionModePopup == null);
812547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes                if (callback.onCreateActionMode(mode, mode.getMenu())) {
813547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes                    mode.invalidate();
814547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes                    mActionModeView.initForMode(mode);
815547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes                    mActionMode = mode;
816c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu
81745b0ea2a10e79b580aabb411126d8d6b79c9da95Chris Banes                    if (shouldAnimateActionModeView()) {
81845b0ea2a10e79b580aabb411126d8d6b79c9da95Chris Banes                        ViewCompat.setAlpha(mActionModeView, 0f);
81945b0ea2a10e79b580aabb411126d8d6b79c9da95Chris Banes                        mFadeAnim = ViewCompat.animate(mActionModeView).alpha(1f);
82045b0ea2a10e79b580aabb411126d8d6b79c9da95Chris Banes                        mFadeAnim.setListener(new ViewPropertyAnimatorListenerAdapter() {
82145b0ea2a10e79b580aabb411126d8d6b79c9da95Chris Banes                            @Override
82245b0ea2a10e79b580aabb411126d8d6b79c9da95Chris Banes                            public void onAnimationStart(View view) {
82345b0ea2a10e79b580aabb411126d8d6b79c9da95Chris Banes                                mActionModeView.setVisibility(View.VISIBLE);
82445b0ea2a10e79b580aabb411126d8d6b79c9da95Chris Banes                                mActionModeView.sendAccessibilityEvent(
82545b0ea2a10e79b580aabb411126d8d6b79c9da95Chris Banes                                        AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
82645b0ea2a10e79b580aabb411126d8d6b79c9da95Chris Banes                                if (mActionModeView.getParent() != null) {
82745b0ea2a10e79b580aabb411126d8d6b79c9da95Chris Banes                                    ViewCompat.requestApplyInsets((View) mActionModeView.getParent());
82845b0ea2a10e79b580aabb411126d8d6b79c9da95Chris Banes                                }
8298ba0fdde8e91fd59808ce3453eef079e54915ce8Chris Banes                            }
83045b0ea2a10e79b580aabb411126d8d6b79c9da95Chris Banes
83145b0ea2a10e79b580aabb411126d8d6b79c9da95Chris Banes                            @Override
83245b0ea2a10e79b580aabb411126d8d6b79c9da95Chris Banes                            public void onAnimationEnd(View view) {
83345b0ea2a10e79b580aabb411126d8d6b79c9da95Chris Banes                                ViewCompat.setAlpha(mActionModeView, 1f);
83445b0ea2a10e79b580aabb411126d8d6b79c9da95Chris Banes                                mFadeAnim.setListener(null);
83545b0ea2a10e79b580aabb411126d8d6b79c9da95Chris Banes                                mFadeAnim = null;
83645b0ea2a10e79b580aabb411126d8d6b79c9da95Chris Banes                            }
83745b0ea2a10e79b580aabb411126d8d6b79c9da95Chris Banes                        });
83845b0ea2a10e79b580aabb411126d8d6b79c9da95Chris Banes                    } else {
83945b0ea2a10e79b580aabb411126d8d6b79c9da95Chris Banes                        ViewCompat.setAlpha(mActionModeView, 1f);
84045b0ea2a10e79b580aabb411126d8d6b79c9da95Chris Banes                        mActionModeView.setVisibility(View.VISIBLE);
84145b0ea2a10e79b580aabb411126d8d6b79c9da95Chris Banes                        mActionModeView.sendAccessibilityEvent(
84245b0ea2a10e79b580aabb411126d8d6b79c9da95Chris Banes                                AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
84345b0ea2a10e79b580aabb411126d8d6b79c9da95Chris Banes                        if (mActionModeView.getParent() != null) {
84445b0ea2a10e79b580aabb411126d8d6b79c9da95Chris Banes                            ViewCompat.requestApplyInsets((View) mActionModeView.getParent());
845c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu                        }
84645b0ea2a10e79b580aabb411126d8d6b79c9da95Chris Banes                    }
84745b0ea2a10e79b580aabb411126d8d6b79c9da95Chris Banes
848547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes                    if (mActionModePopup != null) {
849547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes                        mWindow.getDecorView().post(mShowActionModePopup);
850547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes                    }
851547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes                } else {
852547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes                    mActionMode = null;
853ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                }
8544c2a95906254748cb9a843b061288265d6e185a9Chris Banes            }
8554c2a95906254748cb9a843b061288265d6e185a9Chris Banes        }
856f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes        if (mActionMode != null && mAppCompatCallback != null) {
857f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes            mAppCompatCallback.onSupportActionModeStarted(mActionMode);
8584c2a95906254748cb9a843b061288265d6e185a9Chris Banes        }
8594c2a95906254748cb9a843b061288265d6e185a9Chris Banes        return mActionMode;
8604c2a95906254748cb9a843b061288265d6e185a9Chris Banes    }
8614c2a95906254748cb9a843b061288265d6e185a9Chris Banes
86245b0ea2a10e79b580aabb411126d8d6b79c9da95Chris Banes    final boolean shouldAnimateActionModeView() {
86345b0ea2a10e79b580aabb411126d8d6b79c9da95Chris Banes        // We only to animate the action mode in if the sub decor has already been laid out.
86445b0ea2a10e79b580aabb411126d8d6b79c9da95Chris Banes        // If it hasn't been laid out, it hasn't been drawn to screen yet.
86545b0ea2a10e79b580aabb411126d8d6b79c9da95Chris Banes        return mSubDecorInstalled && mSubDecor != null && ViewCompat.isLaidOut(mSubDecor);
86645b0ea2a10e79b580aabb411126d8d6b79c9da95Chris Banes    }
86745b0ea2a10e79b580aabb411126d8d6b79c9da95Chris Banes
868c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu    private void endOnGoingFadeAnimation() {
869c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu        if (mFadeAnim != null) {
870c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu            mFadeAnim.cancel();
871c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu        }
872c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu    }
873c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu
874f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes    boolean onBackPressed() {
875d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        // Back cancels action modes first.
876d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        if (mActionMode != null) {
877d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes            mActionMode.finish();
878d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes            return true;
879d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        }
880d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes
881d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        // Next collapse any expanded action views.
88249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        ActionBar ab = getSupportActionBar();
88349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        if (ab != null && ab.collapseActionView()) {
884d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes            return true;
885d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        }
886d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes
887f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes        // Let the call through...
888d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        return false;
889d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes    }
890d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes
891d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes    @Override
89200d183885b54de433e43118d3032340f40cac8c0Chris Banes    boolean onKeyShortcut(int keyCode, KeyEvent ev) {
893d15ee7df01f2f48b536a610c4739f33b226d3f81Chris Banes        // Let the Action Bar have a chance at handling the shortcut
894d15ee7df01f2f48b536a610c4739f33b226d3f81Chris Banes        ActionBar ab = getSupportActionBar();
895d15ee7df01f2f48b536a610c4739f33b226d3f81Chris Banes        if (ab != null && ab.onKeyShortcut(keyCode, ev)) {
896d15ee7df01f2f48b536a610c4739f33b226d3f81Chris Banes            return true;
897d15ee7df01f2f48b536a610c4739f33b226d3f81Chris Banes        }
898d15ee7df01f2f48b536a610c4739f33b226d3f81Chris Banes
899dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes        // If the panel is already prepared, then perform the shortcut using it.
90000d183885b54de433e43118d3032340f40cac8c0Chris Banes        boolean handled;
90100d183885b54de433e43118d3032340f40cac8c0Chris Banes        if (mPreparedPanel != null) {
90200d183885b54de433e43118d3032340f40cac8c0Chris Banes            handled = performPanelShortcut(mPreparedPanel, ev.getKeyCode(), ev,
90300d183885b54de433e43118d3032340f40cac8c0Chris Banes                    Menu.FLAG_PERFORM_NO_CLOSE);
90400d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (handled) {
90500d183885b54de433e43118d3032340f40cac8c0Chris Banes                if (mPreparedPanel != null) {
90600d183885b54de433e43118d3032340f40cac8c0Chris Banes                    mPreparedPanel.isHandled = true;
90700d183885b54de433e43118d3032340f40cac8c0Chris Banes                }
90800d183885b54de433e43118d3032340f40cac8c0Chris Banes                return true;
90900d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
91000d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
91100d183885b54de433e43118d3032340f40cac8c0Chris Banes
91200d183885b54de433e43118d3032340f40cac8c0Chris Banes        // If the panel is not prepared, then we may be trying to handle a shortcut key
91300d183885b54de433e43118d3032340f40cac8c0Chris Banes        // combination such as Control+C.  Temporarily prepare the panel then mark it
91400d183885b54de433e43118d3032340f40cac8c0Chris Banes        // unprepared again when finished to ensure that the panel will again be prepared
91500d183885b54de433e43118d3032340f40cac8c0Chris Banes        // the next time it is shown for real.
91600d183885b54de433e43118d3032340f40cac8c0Chris Banes        if (mPreparedPanel == null) {
91700d183885b54de433e43118d3032340f40cac8c0Chris Banes            PanelFeatureState st = getPanelState(FEATURE_OPTIONS_PANEL, true);
91800d183885b54de433e43118d3032340f40cac8c0Chris Banes            preparePanel(st, ev);
91900d183885b54de433e43118d3032340f40cac8c0Chris Banes            handled = performPanelShortcut(st, ev.getKeyCode(), ev, Menu.FLAG_PERFORM_NO_CLOSE);
92000d183885b54de433e43118d3032340f40cac8c0Chris Banes            st.isPrepared = false;
92100d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (handled) {
92200d183885b54de433e43118d3032340f40cac8c0Chris Banes                return true;
92300d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
92400d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
92500d183885b54de433e43118d3032340f40cac8c0Chris Banes        return false;
926dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes    }
927dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes
928dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes    @Override
92946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes    boolean dispatchKeyEvent(KeyEvent event) {
9304d95686e7ade79bfb1081047e90de4bf2affbbcaChris Banes        if (event.getKeyCode() == KeyEvent.KEYCODE_MENU) {
9314d95686e7ade79bfb1081047e90de4bf2affbbcaChris Banes            // If this is a MENU event, let the Activity have a go.
9324d95686e7ade79bfb1081047e90de4bf2affbbcaChris Banes            if (mOriginalWindowCallback.dispatchKeyEvent(event)) {
9334d95686e7ade79bfb1081047e90de4bf2affbbcaChris Banes                return true;
9344d95686e7ade79bfb1081047e90de4bf2affbbcaChris Banes            }
9354d95686e7ade79bfb1081047e90de4bf2affbbcaChris Banes        }
9364d95686e7ade79bfb1081047e90de4bf2affbbcaChris Banes
93746dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes        final int keyCode = event.getKeyCode();
93846dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes        final int action = event.getAction();
93946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes        final boolean isDown = action == KeyEvent.ACTION_DOWN;
94046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes
94146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes        return isDown ? onKeyDown(keyCode, event) : onKeyUp(keyCode, event);
94246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes    }
94346dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes
944f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes    boolean onKeyUp(int keyCode, KeyEvent event) {
94546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes        switch (keyCode) {
94646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes            case KeyEvent.KEYCODE_MENU:
9474d95686e7ade79bfb1081047e90de4bf2affbbcaChris Banes                onKeyUpPanel(Window.FEATURE_OPTIONS_PANEL, event);
9484d95686e7ade79bfb1081047e90de4bf2affbbcaChris Banes                return true;
94946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes            case KeyEvent.KEYCODE_BACK:
950625c9c3db9bb6f6b92ca35b74f26a61a04ec8cd7Chris Banes                final boolean wasLongPressBackDown = mLongPressBackDown;
951625c9c3db9bb6f6b92ca35b74f26a61a04ec8cd7Chris Banes                mLongPressBackDown = false;
952625c9c3db9bb6f6b92ca35b74f26a61a04ec8cd7Chris Banes
95346dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                PanelFeatureState st = getPanelState(Window.FEATURE_OPTIONS_PANEL, false);
95446dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                if (st != null && st.isOpen) {
955625c9c3db9bb6f6b92ca35b74f26a61a04ec8cd7Chris Banes                    if (!wasLongPressBackDown) {
956625c9c3db9bb6f6b92ca35b74f26a61a04ec8cd7Chris Banes                        // Certain devices allow opening the options menu via a long press of the
957625c9c3db9bb6f6b92ca35b74f26a61a04ec8cd7Chris Banes                        // back button. We should only close the open options menu if it wasn't
958625c9c3db9bb6f6b92ca35b74f26a61a04ec8cd7Chris Banes                        // opened via a long press gesture.
959625c9c3db9bb6f6b92ca35b74f26a61a04ec8cd7Chris Banes                        closePanel(st, true);
960625c9c3db9bb6f6b92ca35b74f26a61a04ec8cd7Chris Banes                    }
96146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                    return true;
96246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                }
963f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes                if (onBackPressed()) {
964f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes                    return true;
965f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes                }
96646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                break;
96746dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes        }
96846dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes        return false;
96946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes    }
97046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes
971f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes    boolean onKeyDown(int keyCode, KeyEvent event) {
972f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes        switch (keyCode) {
973f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes            case KeyEvent.KEYCODE_MENU:
9744d95686e7ade79bfb1081047e90de4bf2affbbcaChris Banes                onKeyDownPanel(Window.FEATURE_OPTIONS_PANEL, event);
9752f769dc974bd526d945efe8a644f3f89112e08feChris Banes                // We need to return true here and not let it bubble up to the Window.
9762f769dc974bd526d945efe8a644f3f89112e08feChris Banes                // For empty menus, PhoneWindow's KEYCODE_BACK handling will steals all events,
9772f769dc974bd526d945efe8a644f3f89112e08feChris Banes                // not allowing the Activity to call onBackPressed().
9782f769dc974bd526d945efe8a644f3f89112e08feChris Banes                return true;
979625c9c3db9bb6f6b92ca35b74f26a61a04ec8cd7Chris Banes            case KeyEvent.KEYCODE_BACK:
980625c9c3db9bb6f6b92ca35b74f26a61a04ec8cd7Chris Banes                // Certain devices allow opening the options menu via a long press of the back
981625c9c3db9bb6f6b92ca35b74f26a61a04ec8cd7Chris Banes                // button. We keep a record of whether the last event is from a long press.
982625c9c3db9bb6f6b92ca35b74f26a61a04ec8cd7Chris Banes                mLongPressBackDown = (event.getFlags() & KeyEvent.FLAG_LONG_PRESS) != 0;
983625c9c3db9bb6f6b92ca35b74f26a61a04ec8cd7Chris Banes                break;
98446dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes        }
98546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes
986dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes        // On API v7-10 we need to manually call onKeyShortcut() as this is not called
987dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes        // from the Activity
98846dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
989a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes            // We do not return true here otherwise dispatchKeyEvent will not reach the Activity
990a4b5c35036e68c7551dd77641ceec17b92c6368dChris Banes            // (which results in the back button not working)
991c9b517a68ed7070d4edcdd5be818540d81b43db0Chris Banes            onKeyShortcut(keyCode, event);
99246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes        }
99346dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes        return false;
994dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes    }
995dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes
996469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banes    @Override
997f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes    public View createView(View parent, final String name, @NonNull Context context,
998fd1eb27a3700de31507de34fd1bcc51830fe876cChris Banes            @NonNull AttributeSet attrs) {
999a73cf65dff6d7fa58907e614f95e1d3679de0a79Chris Banes        final boolean isPre21 = Build.VERSION.SDK_INT < 21;
1000878ed08a784cafb112a5d350573b0d1e81c554dbChris Banes
10012cccf609662389d6a23dbc0711d5fb2e826e8c63Chris Banes        if (mAppCompatViewInflater == null) {
1002e183f2600fb31c69eceacc1c263cd56f12489a65Chris Banes            mAppCompatViewInflater = new AppCompatViewInflater();
1003469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banes        }
1004fd1eb27a3700de31507de34fd1bcc51830fe876cChris Banes
1005481ff5b456cc4ce7c75f03808ed344de4bdbf5ceChris Banes        // We only want the View to inherit its context if we're running pre-v21
1006481ff5b456cc4ce7c75f03808ed344de4bdbf5ceChris Banes        final boolean inheritContext = isPre21 && shouldInheritContext((ViewParent) parent);
1007a73cf65dff6d7fa58907e614f95e1d3679de0a79Chris Banes
1008484705a5e6fdc1f6ef746b822716a45f82652ab9Chris Banes        return mAppCompatViewInflater.createView(parent, name, context, attrs, inheritContext,
1009484705a5e6fdc1f6ef746b822716a45f82652ab9Chris Banes                isPre21, /* Only read android:theme pre-L (L+ handles this anyway) */
10105fa121a1f51114f3a2f6d705139e83c0e0aea610Chris Banes                true, /* Read read app:theme as a fallback at all times for legacy reasons */
10115fa121a1f51114f3a2f6d705139e83c0e0aea610Chris Banes                VectorEnabledTintResources.shouldBeUsed() /* Only tint wrap the context if enabled */
1012484705a5e6fdc1f6ef746b822716a45f82652ab9Chris Banes        );
1013469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banes    }
1014469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banes
1015d95c99933cb57a5678afeff01d91269be61e2502Chris Banes    private boolean shouldInheritContext(ViewParent parent) {
1016d95c99933cb57a5678afeff01d91269be61e2502Chris Banes        if (parent == null) {
1017d95c99933cb57a5678afeff01d91269be61e2502Chris Banes            // The initial parent is null so just return false
1018d95c99933cb57a5678afeff01d91269be61e2502Chris Banes            return false;
1019d95c99933cb57a5678afeff01d91269be61e2502Chris Banes        }
1020ff7f258a9b0781de5c6325358c7075128bf05a91Chris Banes        final View windowDecor = mWindow.getDecorView();
1021d95c99933cb57a5678afeff01d91269be61e2502Chris Banes        while (true) {
1022d95c99933cb57a5678afeff01d91269be61e2502Chris Banes            if (parent == null) {
1023d95c99933cb57a5678afeff01d91269be61e2502Chris Banes                // Bingo. We've hit a view which has a null parent before being terminated from
1024d95c99933cb57a5678afeff01d91269be61e2502Chris Banes                // the loop. This is (most probably) because it's the root view in an inflation
1025d95c99933cb57a5678afeff01d91269be61e2502Chris Banes                // call, therefore we should inherit. This works as the inflated layout is only
1026d95c99933cb57a5678afeff01d91269be61e2502Chris Banes                // added to the hierarchy at the end of the inflate() call.
1027d95c99933cb57a5678afeff01d91269be61e2502Chris Banes                return true;
1028ff7f258a9b0781de5c6325358c7075128bf05a91Chris Banes            } else if (parent == windowDecor || !(parent instanceof View)
1029d95c99933cb57a5678afeff01d91269be61e2502Chris Banes                    || ViewCompat.isAttachedToWindow((View) parent)) {
1030d95c99933cb57a5678afeff01d91269be61e2502Chris Banes                // We have either hit the window's decor view, a parent which isn't a View
1031d95c99933cb57a5678afeff01d91269be61e2502Chris Banes                // (i.e. ViewRootImpl), or an attached view, so we know that the original parent
1032d95c99933cb57a5678afeff01d91269be61e2502Chris Banes                // is currently added to the view hierarchy. This means that it has not be
1033d95c99933cb57a5678afeff01d91269be61e2502Chris Banes                // inflated in the current inflate() call and we should not inherit the context.
1034d95c99933cb57a5678afeff01d91269be61e2502Chris Banes                return false;
1035d95c99933cb57a5678afeff01d91269be61e2502Chris Banes            }
1036d95c99933cb57a5678afeff01d91269be61e2502Chris Banes            parent = parent.getParent();
1037d95c99933cb57a5678afeff01d91269be61e2502Chris Banes        }
1038d95c99933cb57a5678afeff01d91269be61e2502Chris Banes    }
1039d95c99933cb57a5678afeff01d91269be61e2502Chris Banes
1040f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes    @Override
1041f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes    public void installViewFactory() {
104216e8d4dd91083260223c007c797e46bc8f631055Chris Banes        LayoutInflater layoutInflater = LayoutInflater.from(mContext);
1043f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes        if (layoutInflater.getFactory() == null) {
1044f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes            LayoutInflaterCompat.setFactory(layoutInflater, this);
1045f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes        } else {
104656594b0cf74a9f71c52980044283ddb0e9e6f47cYuichi Araki            if (!(LayoutInflaterCompat.getFactory(layoutInflater)
104756594b0cf74a9f71c52980044283ddb0e9e6f47cYuichi Araki                    instanceof AppCompatDelegateImplV7)) {
104856594b0cf74a9f71c52980044283ddb0e9e6f47cYuichi Araki                Log.i(TAG, "The Activity's LayoutInflater already has a Factory installed"
104956594b0cf74a9f71c52980044283ddb0e9e6f47cYuichi Araki                        + " so we can not install AppCompat's");
105056594b0cf74a9f71c52980044283ddb0e9e6f47cYuichi Araki            }
1051f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes        }
1052f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes    }
1053f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes
1054f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes    /**
1055f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes     * From {@link android.support.v4.view.LayoutInflaterFactory}
1056f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes     */
1057f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes    @Override
1058498356fea126122c3e3720a419969055cb889428Chris Banes    public final View onCreateView(View parent, String name,
1059f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes            Context context, AttributeSet attrs) {
1060498356fea126122c3e3720a419969055cb889428Chris Banes        // First let the Activity's Factory try and inflate the view
1061498356fea126122c3e3720a419969055cb889428Chris Banes        final View view = callActivityOnCreateView(parent, name, context, attrs);
1062498356fea126122c3e3720a419969055cb889428Chris Banes        if (view != null) {
1063498356fea126122c3e3720a419969055cb889428Chris Banes            return view;
1064498356fea126122c3e3720a419969055cb889428Chris Banes        }
1065498356fea126122c3e3720a419969055cb889428Chris Banes
1066498356fea126122c3e3720a419969055cb889428Chris Banes        // If the Factory didn't handle it, let our createView() method try
1067498356fea126122c3e3720a419969055cb889428Chris Banes        return createView(parent, name, context, attrs);
1068498356fea126122c3e3720a419969055cb889428Chris Banes    }
106916e8d4dd91083260223c007c797e46bc8f631055Chris Banes
1070498356fea126122c3e3720a419969055cb889428Chris Banes    View callActivityOnCreateView(View parent, String name, Context context, AttributeSet attrs) {
1071498356fea126122c3e3720a419969055cb889428Chris Banes        // Let the Activity's LayoutInflater.Factory try and handle it
107216e8d4dd91083260223c007c797e46bc8f631055Chris Banes        if (mOriginalWindowCallback instanceof LayoutInflater.Factory) {
1073498356fea126122c3e3720a419969055cb889428Chris Banes            final View result = ((LayoutInflater.Factory) mOriginalWindowCallback)
107416e8d4dd91083260223c007c797e46bc8f631055Chris Banes                    .onCreateView(name, context, attrs);
107516e8d4dd91083260223c007c797e46bc8f631055Chris Banes            if (result != null) {
107616e8d4dd91083260223c007c797e46bc8f631055Chris Banes                return result;
107716e8d4dd91083260223c007c797e46bc8f631055Chris Banes            }
1078f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes        }
1079498356fea126122c3e3720a419969055cb889428Chris Banes        return null;
1080f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes    }
1081f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes
108200d183885b54de433e43118d3032340f40cac8c0Chris Banes    private void openPanel(final PanelFeatureState st, KeyEvent event) {
108300d183885b54de433e43118d3032340f40cac8c0Chris Banes        // Already open, return
10849b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes        if (st.isOpen || isDestroyed()) {
108500d183885b54de433e43118d3032340f40cac8c0Chris Banes            return;
108600d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
108700d183885b54de433e43118d3032340f40cac8c0Chris Banes
108800d183885b54de433e43118d3032340f40cac8c0Chris Banes        // Don't open an options panel for honeycomb apps on xlarge devices.
108900d183885b54de433e43118d3032340f40cac8c0Chris Banes        // (The app should be using an action bar for menu items.)
109000d183885b54de433e43118d3032340f40cac8c0Chris Banes        if (st.featureId == FEATURE_OPTIONS_PANEL) {
109116e8d4dd91083260223c007c797e46bc8f631055Chris Banes            Context context = mContext;
109200d183885b54de433e43118d3032340f40cac8c0Chris Banes            Configuration config = context.getResources().getConfiguration();
109300d183885b54de433e43118d3032340f40cac8c0Chris Banes            boolean isXLarge = (config.screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) ==
109400d183885b54de433e43118d3032340f40cac8c0Chris Banes                    Configuration.SCREENLAYOUT_SIZE_XLARGE;
109500d183885b54de433e43118d3032340f40cac8c0Chris Banes            boolean isHoneycombApp = context.getApplicationInfo().targetSdkVersion >=
109600d183885b54de433e43118d3032340f40cac8c0Chris Banes                    android.os.Build.VERSION_CODES.HONEYCOMB;
109700d183885b54de433e43118d3032340f40cac8c0Chris Banes
109800d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (isXLarge && isHoneycombApp) {
109900d183885b54de433e43118d3032340f40cac8c0Chris Banes                return;
110000d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
110100d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
110200d183885b54de433e43118d3032340f40cac8c0Chris Banes
1103f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes        Window.Callback cb = getWindowCallback();
110400d183885b54de433e43118d3032340f40cac8c0Chris Banes        if ((cb != null) && (!cb.onMenuOpened(st.featureId, st.menu))) {
110500d183885b54de433e43118d3032340f40cac8c0Chris Banes            // Callback doesn't want the menu to open, reset any state
110600d183885b54de433e43118d3032340f40cac8c0Chris Banes            closePanel(st, true);
110700d183885b54de433e43118d3032340f40cac8c0Chris Banes            return;
110800d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
110900d183885b54de433e43118d3032340f40cac8c0Chris Banes
111016e8d4dd91083260223c007c797e46bc8f631055Chris Banes        final WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
111146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes        if (wm == null) {
111246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes            return;
111346dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes        }
111446dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes
111500d183885b54de433e43118d3032340f40cac8c0Chris Banes        // Prepare panel (should have been done before, but just in case)
111600d183885b54de433e43118d3032340f40cac8c0Chris Banes        if (!preparePanel(st, event)) {
111700d183885b54de433e43118d3032340f40cac8c0Chris Banes            return;
111800d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
111900d183885b54de433e43118d3032340f40cac8c0Chris Banes
112046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes        int width = WRAP_CONTENT;
112100d183885b54de433e43118d3032340f40cac8c0Chris Banes        if (st.decorView == null || st.refreshDecorView) {
112246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes            if (st.decorView == null) {
112346dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                // Initialize the panel decor, this will populate st.decorView
112446dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                if (!initializePanelDecor(st) || (st.decorView == null))
112546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                    return;
112646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes            } else if (st.refreshDecorView && (st.decorView.getChildCount() > 0)) {
112746dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                // Decor needs refreshing, so remove its views
112846dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                st.decorView.removeAllViews();
112946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes            }
113000d183885b54de433e43118d3032340f40cac8c0Chris Banes
113146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes            // This will populate st.shownPanelView
113246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes            if (!initializePanelContent(st) || !st.hasPanelItems()) {
113346dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                return;
113446dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes            }
113546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes
113646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes            ViewGroup.LayoutParams lp = st.shownPanelView.getLayoutParams();
113746dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes            if (lp == null) {
113846dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                lp = new ViewGroup.LayoutParams(WRAP_CONTENT, WRAP_CONTENT);
113946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes            }
114046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes
114146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes            int backgroundResId = st.background;
114246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes            st.decorView.setBackgroundResource(backgroundResId);
114346dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes
114446dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes            ViewParent shownPanelParent = st.shownPanelView.getParent();
114546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes            if (shownPanelParent != null && shownPanelParent instanceof ViewGroup) {
114646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                ((ViewGroup) shownPanelParent).removeView(st.shownPanelView);
114746dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes            }
114846dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes            st.decorView.addView(st.shownPanelView, lp);
114946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes
115046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes            /*
115146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes             * Give focus to the view, if it or one of its children does not
115246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes             * already have it.
115346dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes             */
115446dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes            if (!st.shownPanelView.hasFocus()) {
115546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                st.shownPanelView.requestFocus();
115646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes            }
115746dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes        } else if (st.createdPanelView != null) {
115846dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes            // If we already had a panel view, carry width=MATCH_PARENT through
115946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes            // as we did above when it was created.
116046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes            ViewGroup.LayoutParams lp = st.createdPanelView.getLayoutParams();
116146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes            if (lp != null && lp.width == ViewGroup.LayoutParams.MATCH_PARENT) {
116246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                width = MATCH_PARENT;
116346dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes            }
116400d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
116500d183885b54de433e43118d3032340f40cac8c0Chris Banes
116600d183885b54de433e43118d3032340f40cac8c0Chris Banes        st.isHandled = false;
116746dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes
116846dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes        WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
116946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                width, WRAP_CONTENT,
117046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                st.x, st.y, WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL,
117146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
117246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                        | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
117346dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                PixelFormat.TRANSLUCENT);
117446dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes
117546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes        lp.gravity = st.gravity;
117646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes        lp.windowAnimations = st.windowAnimations;
117746dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes
117846dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes        wm.addView(st.decorView, lp);
117900d183885b54de433e43118d3032340f40cac8c0Chris Banes        st.isOpen = true;
118000d183885b54de433e43118d3032340f40cac8c0Chris Banes    }
118100d183885b54de433e43118d3032340f40cac8c0Chris Banes
118246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes    private boolean initializePanelDecor(PanelFeatureState st) {
118357c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes        st.setStyle(getActionBarThemedContext());
118446dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes        st.decorView = new ListMenuDecorView(st.listPresenterContext);
118546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes        st.gravity = Gravity.CENTER | Gravity.BOTTOM;
118646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes        return true;
118700d183885b54de433e43118d3032340f40cac8c0Chris Banes    }
118800d183885b54de433e43118d3032340f40cac8c0Chris Banes
118900d183885b54de433e43118d3032340f40cac8c0Chris Banes    private void reopenMenu(MenuBuilder menu, boolean toggleMenuMode) {
119000d183885b54de433e43118d3032340f40cac8c0Chris Banes        if (mDecorContentParent != null && mDecorContentParent.canShowOverflowMenu() &&
119116e8d4dd91083260223c007c797e46bc8f631055Chris Banes                (!ViewConfigurationCompat.hasPermanentMenuKey(ViewConfiguration.get(mContext)) ||
119200d183885b54de433e43118d3032340f40cac8c0Chris Banes                        mDecorContentParent.isOverflowMenuShowPending())) {
11939b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes
1194f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes            final Window.Callback cb = getWindowCallback();
11959b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes
119600d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (!mDecorContentParent.isOverflowMenuShowing() || !toggleMenuMode) {
11979b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes                if (cb != null && !isDestroyed()) {
11989b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes                    // If we have a menu invalidation pending, do it now.
11999b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes                    if (mInvalidatePanelMenuPosted &&
12009b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes                            (mInvalidatePanelMenuFeatures & (1 << FEATURE_OPTIONS_PANEL)) != 0) {
1201ff7f258a9b0781de5c6325358c7075128bf05a91Chris Banes                        mWindow.getDecorView().removeCallbacks(mInvalidatePanelMenuRunnable);
12029b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes                        mInvalidatePanelMenuRunnable.run();
12039b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes                    }
120400d183885b54de433e43118d3032340f40cac8c0Chris Banes
12059b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes                    final PanelFeatureState st = getPanelState(FEATURE_OPTIONS_PANEL, true);
120600d183885b54de433e43118d3032340f40cac8c0Chris Banes
12079b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes                    // If we don't have a menu or we're waiting for a full content refresh,
12089b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes                    // forget it. This is a lingering event that no longer matters.
12099b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes                    if (st.menu != null && !st.refreshMenuContent &&
121046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                            cb.onPreparePanel(FEATURE_OPTIONS_PANEL, st.createdPanelView, st.menu)) {
1211d25af35061a9f20d59b25329d613c62c20184dadChris Banes                        cb.onMenuOpened(FEATURE_SUPPORT_ACTION_BAR, st.menu);
12129b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes                        mDecorContentParent.showOverflowMenu();
12139b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes                    }
121400d183885b54de433e43118d3032340f40cac8c0Chris Banes                }
121500d183885b54de433e43118d3032340f40cac8c0Chris Banes            } else {
121600d183885b54de433e43118d3032340f40cac8c0Chris Banes                mDecorContentParent.hideOverflowMenu();
12179b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes                if (!isDestroyed()) {
12189b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes                    final PanelFeatureState st = getPanelState(FEATURE_OPTIONS_PANEL, true);
1219d25af35061a9f20d59b25329d613c62c20184dadChris Banes                    cb.onPanelClosed(FEATURE_SUPPORT_ACTION_BAR, st.menu);
12209b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes                }
122100d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
122200d183885b54de433e43118d3032340f40cac8c0Chris Banes            return;
122300d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
122400d183885b54de433e43118d3032340f40cac8c0Chris Banes
122500d183885b54de433e43118d3032340f40cac8c0Chris Banes        PanelFeatureState st = getPanelState(FEATURE_OPTIONS_PANEL, true);
122600d183885b54de433e43118d3032340f40cac8c0Chris Banes
122700d183885b54de433e43118d3032340f40cac8c0Chris Banes        st.refreshDecorView = true;
122800d183885b54de433e43118d3032340f40cac8c0Chris Banes        closePanel(st, false);
122900d183885b54de433e43118d3032340f40cac8c0Chris Banes
123000d183885b54de433e43118d3032340f40cac8c0Chris Banes        openPanel(st, null);
123100d183885b54de433e43118d3032340f40cac8c0Chris Banes    }
123200d183885b54de433e43118d3032340f40cac8c0Chris Banes
123300d183885b54de433e43118d3032340f40cac8c0Chris Banes    private boolean initializePanelMenu(final PanelFeatureState st) {
123416e8d4dd91083260223c007c797e46bc8f631055Chris Banes        Context context = mContext;
123561c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes
123600d183885b54de433e43118d3032340f40cac8c0Chris Banes        // If we have an action bar, initialize the menu with the right theme.
1237d25af35061a9f20d59b25329d613c62c20184dadChris Banes        if ((st.featureId == FEATURE_OPTIONS_PANEL || st.featureId == FEATURE_SUPPORT_ACTION_BAR) &&
123800d183885b54de433e43118d3032340f40cac8c0Chris Banes                mDecorContentParent != null) {
123961c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes            final TypedValue outValue = new TypedValue();
124061c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes            final Resources.Theme baseTheme = context.getTheme();
124161c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes            baseTheme.resolveAttribute(R.attr.actionBarTheme, outValue, true);
124261c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes
124361c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes            Resources.Theme widgetTheme = null;
124461c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes            if (outValue.resourceId != 0) {
124561c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes                widgetTheme = context.getResources().newTheme();
124661c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes                widgetTheme.setTo(baseTheme);
124761c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes                widgetTheme.applyStyle(outValue.resourceId, true);
124861c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes                widgetTheme.resolveAttribute(
124961c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes                        R.attr.actionBarWidgetTheme, outValue, true);
125061c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes            } else {
125161c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes                baseTheme.resolveAttribute(
125261c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes                        R.attr.actionBarWidgetTheme, outValue, true);
125361c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes            }
125461c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes
125561c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes            if (outValue.resourceId != 0) {
125661c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes                if (widgetTheme == null) {
125761c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes                    widgetTheme = context.getResources().newTheme();
125861c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes                    widgetTheme.setTo(baseTheme);
125961c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes                }
126061c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes                widgetTheme.applyStyle(outValue.resourceId, true);
126161c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes            }
126261c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes
126361c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes            if (widgetTheme != null) {
126461c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes                context = new ContextThemeWrapper(context, 0);
126561c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes                context.getTheme().setTo(widgetTheme);
126661c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes            }
126761c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes        }
126861c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes
126900d183885b54de433e43118d3032340f40cac8c0Chris Banes        final MenuBuilder menu = new MenuBuilder(context);
127000d183885b54de433e43118d3032340f40cac8c0Chris Banes        menu.setCallback(this);
127100d183885b54de433e43118d3032340f40cac8c0Chris Banes        st.setMenu(menu);
127261c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes
12738902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes        return true;
12748902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes    }
12758902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes
127600d183885b54de433e43118d3032340f40cac8c0Chris Banes    private boolean initializePanelContent(PanelFeatureState st) {
127746dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes        if (st.createdPanelView != null) {
127846dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes            st.shownPanelView = st.createdPanelView;
127946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes            return true;
128046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes        }
128146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes
128200d183885b54de433e43118d3032340f40cac8c0Chris Banes        if (st.menu == null) {
128300d183885b54de433e43118d3032340f40cac8c0Chris Banes            return false;
128400d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
128500d183885b54de433e43118d3032340f40cac8c0Chris Banes
128600d183885b54de433e43118d3032340f40cac8c0Chris Banes        if (mPanelMenuPresenterCallback == null) {
128700d183885b54de433e43118d3032340f40cac8c0Chris Banes            mPanelMenuPresenterCallback = new PanelMenuPresenterCallback();
128800d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
128900d183885b54de433e43118d3032340f40cac8c0Chris Banes
129057c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes        MenuView menuView = st.getListMenuView(mPanelMenuPresenterCallback);
129100d183885b54de433e43118d3032340f40cac8c0Chris Banes
129200d183885b54de433e43118d3032340f40cac8c0Chris Banes        st.shownPanelView = (View) menuView;
129300d183885b54de433e43118d3032340f40cac8c0Chris Banes
129400d183885b54de433e43118d3032340f40cac8c0Chris Banes        return st.shownPanelView != null;
129500d183885b54de433e43118d3032340f40cac8c0Chris Banes    }
129600d183885b54de433e43118d3032340f40cac8c0Chris Banes
129700d183885b54de433e43118d3032340f40cac8c0Chris Banes    private boolean preparePanel(PanelFeatureState st, KeyEvent event) {
12989b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes        if (isDestroyed()) {
12999b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes            return false;
13009b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes        }
13019b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes
13028902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes        // Already prepared (isPrepared will be reset to false later)
130300d183885b54de433e43118d3032340f40cac8c0Chris Banes        if (st.isPrepared) {
13048902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes            return true;
13058902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes        }
13068902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes
130700d183885b54de433e43118d3032340f40cac8c0Chris Banes        if ((mPreparedPanel != null) && (mPreparedPanel != st)) {
130800d183885b54de433e43118d3032340f40cac8c0Chris Banes            // Another Panel is prepared and possibly open, so close it
130900d183885b54de433e43118d3032340f40cac8c0Chris Banes            closePanel(mPreparedPanel, false);
131000d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
131100d183885b54de433e43118d3032340f40cac8c0Chris Banes
1312f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes        final Window.Callback cb = getWindowCallback();
131346dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes
131446dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes        if (cb != null) {
131546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes            st.createdPanelView = cb.onCreatePanelView(st.featureId);
131646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes        }
131746dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes
131800d183885b54de433e43118d3032340f40cac8c0Chris Banes        final boolean isActionBarMenu =
1319d25af35061a9f20d59b25329d613c62c20184dadChris Banes                (st.featureId == FEATURE_OPTIONS_PANEL || st.featureId == FEATURE_SUPPORT_ACTION_BAR);
132000d183885b54de433e43118d3032340f40cac8c0Chris Banes
132100d183885b54de433e43118d3032340f40cac8c0Chris Banes        if (isActionBarMenu && mDecorContentParent != null) {
13228088261dec5dd277ccace13fe00f280ffa80098cChris Banes            // Enforce ordering guarantees around events so that the action bar never
13238088261dec5dd277ccace13fe00f280ffa80098cChris Banes            // dispatches menu-related events before the panel is prepared.
13248088261dec5dd277ccace13fe00f280ffa80098cChris Banes            mDecorContentParent.setMenuPrepared();
13258088261dec5dd277ccace13fe00f280ffa80098cChris Banes        }
13268088261dec5dd277ccace13fe00f280ffa80098cChris Banes
13276094d733a9bcc923491937532255f79eb23fab90Chris Banes        if (st.createdPanelView == null &&
13286094d733a9bcc923491937532255f79eb23fab90Chris Banes                (!isActionBarMenu || !(peekSupportActionBar() instanceof ToolbarActionBar))) {
13296094d733a9bcc923491937532255f79eb23fab90Chris Banes            // Since ToolbarActionBar handles the list options menu itself, we only want to
13306094d733a9bcc923491937532255f79eb23fab90Chris Banes            // init this menu panel if we're not using a TAB.
133146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes            if (st.menu == null || st.refreshMenuContent) {
133246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                if (st.menu == null) {
133346dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                    if (!initializePanelMenu(st) || (st.menu == null)) {
133446dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                        return false;
133546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                    }
13368902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes                }
13378902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes
133846dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                if (isActionBarMenu && mDecorContentParent != null) {
133946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                    if (mActionMenuPresenterCallback == null) {
134046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                        mActionMenuPresenterCallback = new ActionMenuPresenterCallback();
134146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                    }
134246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                    mDecorContentParent.setMenu(st.menu, mActionMenuPresenterCallback);
134346dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                }
134446dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes
134546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                // Creating the panel menu will involve a lot of manipulation;
134646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                // don't dispatch change events to presenters until we're done.
134746dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                st.menu.stopDispatchingItemsChanged();
1348f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes                if (!cb.onCreatePanelMenu(st.featureId, st.menu)) {
134946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                    // Ditch the menu created above
135046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                    st.setMenu(null);
135146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes
135246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                    if (isActionBarMenu && mDecorContentParent != null) {
135346dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                        // Don't show it in the action bar either
135446dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                        mDecorContentParent.setMenu(null, mActionMenuPresenterCallback);
135546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                    }
135646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes
135746dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                    return false;
135803fc11b659da1645507062bddda450136e13af35Chris Banes                }
135946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes
136046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                st.refreshMenuContent = false;
13618902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes            }
13628902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes
136346dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes            // Preparing the panel menu can involve a lot of manipulation;
13648902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes            // don't dispatch change events to presenters until we're done.
136500d183885b54de433e43118d3032340f40cac8c0Chris Banes            st.menu.stopDispatchingItemsChanged();
13668902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes
136746dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes            // Restore action view state before we prepare. This gives apps
136846dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes            // an opportunity to override frozen/restored state in onPrepare.
136946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes            if (st.frozenActionViewState != null) {
137046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                st.menu.restoreActionViewStates(st.frozenActionViewState);
137146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                st.frozenActionViewState = null;
137246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes            }
137346dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes
137446dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes            // Callback and return if the callback does not want to show the menu
137546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes            if (!cb.onPreparePanel(FEATURE_OPTIONS_PANEL, st.createdPanelView, st.menu)) {
137600d183885b54de433e43118d3032340f40cac8c0Chris Banes                if (isActionBarMenu && mDecorContentParent != null) {
137746dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                    // The app didn't want to show the menu for now but it still exists.
137846dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                    // Clear it out of the action bar.
137903fc11b659da1645507062bddda450136e13af35Chris Banes                    mDecorContentParent.setMenu(null, mActionMenuPresenterCallback);
13808902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes                }
138146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                st.menu.startDispatchingItemsChanged();
13828902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes                return false;
13838902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes            }
13848902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes
138546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes            // Set the proper keymap
138646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes            KeyCharacterMap kmap = KeyCharacterMap.load(
138746dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                    event != null ? event.getDeviceId() : KeyCharacterMap.VIRTUAL_KEYBOARD);
138846dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes            st.qwertyMode = kmap.getKeyboardType() != KeyCharacterMap.NUMERIC;
138946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes            st.menu.setQwertyMode(st.qwertyMode);
139000d183885b54de433e43118d3032340f40cac8c0Chris Banes            st.menu.startDispatchingItemsChanged();
13918902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes        }
13928902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes
13938902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes        // Set other state
139400d183885b54de433e43118d3032340f40cac8c0Chris Banes        st.isPrepared = true;
139500d183885b54de433e43118d3032340f40cac8c0Chris Banes        st.isHandled = false;
139600d183885b54de433e43118d3032340f40cac8c0Chris Banes        mPreparedPanel = st;
13978902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes
13988902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes        return true;
13998902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes    }
14008902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes
140100d183885b54de433e43118d3032340f40cac8c0Chris Banes    private void checkCloseActionMenu(MenuBuilder menu) {
140203fc11b659da1645507062bddda450136e13af35Chris Banes        if (mClosingActionMenu) {
140303fc11b659da1645507062bddda450136e13af35Chris Banes            return;
140403fc11b659da1645507062bddda450136e13af35Chris Banes        }
140503fc11b659da1645507062bddda450136e13af35Chris Banes
140603fc11b659da1645507062bddda450136e13af35Chris Banes        mClosingActionMenu = true;
140703fc11b659da1645507062bddda450136e13af35Chris Banes        mDecorContentParent.dismissPopups();
1408f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes        Window.Callback cb = getWindowCallback();
14099b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes        if (cb != null && !isDestroyed()) {
1410d25af35061a9f20d59b25329d613c62c20184dadChris Banes            cb.onPanelClosed(FEATURE_SUPPORT_ACTION_BAR, menu);
141100d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
141203fc11b659da1645507062bddda450136e13af35Chris Banes        mClosingActionMenu = false;
141303fc11b659da1645507062bddda450136e13af35Chris Banes    }
141403fc11b659da1645507062bddda450136e13af35Chris Banes
141546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes    private void closePanel(int featureId) {
141646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes        closePanel(getPanelState(featureId, true), true);
141746dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes    }
141846dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes
141900d183885b54de433e43118d3032340f40cac8c0Chris Banes    private void closePanel(PanelFeatureState st, boolean doCallback) {
142000d183885b54de433e43118d3032340f40cac8c0Chris Banes        if (doCallback && st.featureId == FEATURE_OPTIONS_PANEL &&
142100d183885b54de433e43118d3032340f40cac8c0Chris Banes                mDecorContentParent != null && mDecorContentParent.isOverflowMenuShowing()) {
142200d183885b54de433e43118d3032340f40cac8c0Chris Banes            checkCloseActionMenu(st.menu);
142300d183885b54de433e43118d3032340f40cac8c0Chris Banes            return;
142400d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
142500d183885b54de433e43118d3032340f40cac8c0Chris Banes
1426436e191f80e197712dd1a7f1f7c61acfff8b1f04Chris Banes        final WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
14274d95686e7ade79bfb1081047e90de4bf2affbbcaChris Banes        if (wm != null && st.isOpen && st.decorView != null) {
1428436e191f80e197712dd1a7f1f7c61acfff8b1f04Chris Banes            wm.removeView(st.decorView);
14294d95686e7ade79bfb1081047e90de4bf2affbbcaChris Banes
14304d95686e7ade79bfb1081047e90de4bf2affbbcaChris Banes            if (doCallback) {
14314d95686e7ade79bfb1081047e90de4bf2affbbcaChris Banes                callOnPanelClosed(st.featureId, st, null);
14324d95686e7ade79bfb1081047e90de4bf2affbbcaChris Banes            }
143300d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
143400d183885b54de433e43118d3032340f40cac8c0Chris Banes
143500d183885b54de433e43118d3032340f40cac8c0Chris Banes        st.isPrepared = false;
143600d183885b54de433e43118d3032340f40cac8c0Chris Banes        st.isHandled = false;
143700d183885b54de433e43118d3032340f40cac8c0Chris Banes        st.isOpen = false;
143800d183885b54de433e43118d3032340f40cac8c0Chris Banes
143900d183885b54de433e43118d3032340f40cac8c0Chris Banes        // This view is no longer shown, so null it out
144000d183885b54de433e43118d3032340f40cac8c0Chris Banes        st.shownPanelView = null;
144100d183885b54de433e43118d3032340f40cac8c0Chris Banes
144200d183885b54de433e43118d3032340f40cac8c0Chris Banes        // Next time the menu opens, it should not be in expanded mode, so
144300d183885b54de433e43118d3032340f40cac8c0Chris Banes        // force a refresh of the decor
144400d183885b54de433e43118d3032340f40cac8c0Chris Banes        st.refreshDecorView = true;
144500d183885b54de433e43118d3032340f40cac8c0Chris Banes
144600d183885b54de433e43118d3032340f40cac8c0Chris Banes        if (mPreparedPanel == st) {
144700d183885b54de433e43118d3032340f40cac8c0Chris Banes            mPreparedPanel = null;
144803fc11b659da1645507062bddda450136e13af35Chris Banes        }
144903fc11b659da1645507062bddda450136e13af35Chris Banes    }
145003fc11b659da1645507062bddda450136e13af35Chris Banes
145146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes    private boolean onKeyDownPanel(int featureId, KeyEvent event) {
145246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes        if (event.getRepeatCount() == 0) {
145346dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes            PanelFeatureState st = getPanelState(featureId, true);
145446dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes            if (!st.isOpen) {
145546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                return preparePanel(st, event);
145646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes            }
145746dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes        }
145846dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes
145946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes        return false;
146046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes    }
146146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes
1462559fa14454cc053127b3b96c0e63c48c06937e38Chris Banes    private boolean onKeyUpPanel(int featureId, KeyEvent event) {
146346dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes        if (mActionMode != null) {
1464559fa14454cc053127b3b96c0e63c48c06937e38Chris Banes            return false;
146546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes        }
146646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes
1467559fa14454cc053127b3b96c0e63c48c06937e38Chris Banes        boolean handled = false;
146846dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes        final PanelFeatureState st = getPanelState(featureId, true);
146946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes        if (featureId == FEATURE_OPTIONS_PANEL && mDecorContentParent != null &&
147046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                mDecorContentParent.canShowOverflowMenu() &&
147116e8d4dd91083260223c007c797e46bc8f631055Chris Banes                !ViewConfigurationCompat.hasPermanentMenuKey(ViewConfiguration.get(mContext))) {
147246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes            if (!mDecorContentParent.isOverflowMenuShowing()) {
147346dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                if (!isDestroyed() && preparePanel(st, event)) {
1474559fa14454cc053127b3b96c0e63c48c06937e38Chris Banes                    handled = mDecorContentParent.showOverflowMenu();
147546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                }
147646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes            } else {
1477559fa14454cc053127b3b96c0e63c48c06937e38Chris Banes                handled = mDecorContentParent.hideOverflowMenu();
147846dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes            }
147946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes        } else {
148046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes            if (st.isOpen || st.isHandled) {
148146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                // Play the sound effect if the user closed an open menu (and not if
148246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                // they just released a menu shortcut)
1483559fa14454cc053127b3b96c0e63c48c06937e38Chris Banes                handled = st.isOpen;
148446dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                // Close menu
148546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                closePanel(st, true);
148646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes            } else if (st.isPrepared) {
148746dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                boolean show = true;
148846dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                if (st.refreshMenuContent) {
148946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                    // Something may have invalidated the menu since we prepared it.
149046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                    // Re-prepare it to refresh.
149146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                    st.isPrepared = false;
149246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                    show = preparePanel(st, event);
149346dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                }
149446dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes
149546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                if (show) {
149646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                    // Show menu
149746dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                    openPanel(st, event);
1498559fa14454cc053127b3b96c0e63c48c06937e38Chris Banes                    handled = true;
149946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                }
150046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes            }
150146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes        }
150246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes
1503559fa14454cc053127b3b96c0e63c48c06937e38Chris Banes        if (handled) {
150416e8d4dd91083260223c007c797e46bc8f631055Chris Banes            AudioManager audioManager = (AudioManager) mContext.getSystemService(
150546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                    Context.AUDIO_SERVICE);
150646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes            if (audioManager != null) {
150746dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                audioManager.playSoundEffect(AudioManager.FX_KEY_CLICK);
150846dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes            } else {
150946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                Log.w(TAG, "Couldn't get audio manager");
151046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes            }
151146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes        }
1512559fa14454cc053127b3b96c0e63c48c06937e38Chris Banes        return handled;
151346dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes    }
151446dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes
151500d183885b54de433e43118d3032340f40cac8c0Chris Banes    private void callOnPanelClosed(int featureId, PanelFeatureState panel, Menu menu) {
151600d183885b54de433e43118d3032340f40cac8c0Chris Banes        // Try to get a menu
151700d183885b54de433e43118d3032340f40cac8c0Chris Banes        if (menu == null) {
151800d183885b54de433e43118d3032340f40cac8c0Chris Banes            // Need a panel to grab the menu, so try to get that
151900d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (panel == null) {
152000d183885b54de433e43118d3032340f40cac8c0Chris Banes                if ((featureId >= 0) && (featureId < mPanels.length)) {
152100d183885b54de433e43118d3032340f40cac8c0Chris Banes                    panel = mPanels[featureId];
152200d183885b54de433e43118d3032340f40cac8c0Chris Banes                }
152300d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
152400d183885b54de433e43118d3032340f40cac8c0Chris Banes
152500d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (panel != null) {
152600d183885b54de433e43118d3032340f40cac8c0Chris Banes                // menu still may be null, which is okay--we tried our best
152700d183885b54de433e43118d3032340f40cac8c0Chris Banes                menu = panel.menu;
152800d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
152900d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
153000d183885b54de433e43118d3032340f40cac8c0Chris Banes
153100d183885b54de433e43118d3032340f40cac8c0Chris Banes        // If the panel is not open, do not callback
153200d183885b54de433e43118d3032340f40cac8c0Chris Banes        if ((panel != null) && (!panel.isOpen))
153300d183885b54de433e43118d3032340f40cac8c0Chris Banes            return;
153400d183885b54de433e43118d3032340f40cac8c0Chris Banes
1535d2f8851a0a27ea6a2ddf5a88097f3d10eed38485Chris Banes        if (!isDestroyed()) {
1536d2f8851a0a27ea6a2ddf5a88097f3d10eed38485Chris Banes            // We need to be careful which callback we dispatch the call to. We can not dispatch
1537d2f8851a0a27ea6a2ddf5a88097f3d10eed38485Chris Banes            // this to the Window's callback since that will call back into this method and cause a
1538d2f8851a0a27ea6a2ddf5a88097f3d10eed38485Chris Banes            // crash. Instead we need to dispatch down to the original Activity/Dialog/etc.
1539d2f8851a0a27ea6a2ddf5a88097f3d10eed38485Chris Banes            mOriginalWindowCallback.onPanelClosed(featureId, menu);
1540f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes        }
154100d183885b54de433e43118d3032340f40cac8c0Chris Banes    }
154200d183885b54de433e43118d3032340f40cac8c0Chris Banes
154300d183885b54de433e43118d3032340f40cac8c0Chris Banes    private PanelFeatureState findMenuPanel(Menu menu) {
154400d183885b54de433e43118d3032340f40cac8c0Chris Banes        final PanelFeatureState[] panels = mPanels;
154500d183885b54de433e43118d3032340f40cac8c0Chris Banes        final int N = panels != null ? panels.length : 0;
154600d183885b54de433e43118d3032340f40cac8c0Chris Banes        for (int i = 0; i < N; i++) {
154700d183885b54de433e43118d3032340f40cac8c0Chris Banes            final PanelFeatureState panel = panels[i];
154800d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (panel != null && panel.menu == menu) {
154900d183885b54de433e43118d3032340f40cac8c0Chris Banes                return panel;
155000d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
155100d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
155200d183885b54de433e43118d3032340f40cac8c0Chris Banes        return null;
155300d183885b54de433e43118d3032340f40cac8c0Chris Banes    }
155400d183885b54de433e43118d3032340f40cac8c0Chris Banes
155585035fae2e7f292a529dc70e8d41cebc799e7d4fChris Banes    protected PanelFeatureState getPanelState(int featureId, boolean required) {
155600d183885b54de433e43118d3032340f40cac8c0Chris Banes        PanelFeatureState[] ar;
155700d183885b54de433e43118d3032340f40cac8c0Chris Banes        if ((ar = mPanels) == null || ar.length <= featureId) {
155800d183885b54de433e43118d3032340f40cac8c0Chris Banes            PanelFeatureState[] nar = new PanelFeatureState[featureId + 1];
155900d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (ar != null) {
156000d183885b54de433e43118d3032340f40cac8c0Chris Banes                System.arraycopy(ar, 0, nar, 0, ar.length);
156100d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
156200d183885b54de433e43118d3032340f40cac8c0Chris Banes            mPanels = ar = nar;
156303fc11b659da1645507062bddda450136e13af35Chris Banes        }
156400d183885b54de433e43118d3032340f40cac8c0Chris Banes
156500d183885b54de433e43118d3032340f40cac8c0Chris Banes        PanelFeatureState st = ar[featureId];
156600d183885b54de433e43118d3032340f40cac8c0Chris Banes        if (st == null) {
156700d183885b54de433e43118d3032340f40cac8c0Chris Banes            ar[featureId] = st = new PanelFeatureState(featureId);
156800d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
156900d183885b54de433e43118d3032340f40cac8c0Chris Banes        return st;
157003fc11b659da1645507062bddda450136e13af35Chris Banes    }
157103fc11b659da1645507062bddda450136e13af35Chris Banes
1572f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes    private boolean performPanelShortcut(PanelFeatureState st, int keyCode, KeyEvent event,
157300d183885b54de433e43118d3032340f40cac8c0Chris Banes            int flags) {
1574dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes        if (event.isSystem()) {
1575dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes            return false;
1576dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes        }
1577dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes
1578dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes        boolean handled = false;
1579dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes
1580dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes        // Only try to perform menu shortcuts if preparePanel returned true (possible false
1581dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes        // return value from application not wanting to show the menu).
158200d183885b54de433e43118d3032340f40cac8c0Chris Banes        if ((st.isPrepared || preparePanel(st, event)) && st.menu != null) {
1583dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes            // The menu is prepared now, perform the shortcut on it
158400d183885b54de433e43118d3032340f40cac8c0Chris Banes            handled = st.menu.performShortcut(keyCode, event, flags);
1585dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes        }
1586dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes
1587dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes        if (handled) {
1588dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes            // Only close down the menu if we don't have an action bar keeping it open.
1589dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes            if ((flags & Menu.FLAG_PERFORM_NO_CLOSE) == 0 && mDecorContentParent == null) {
159000d183885b54de433e43118d3032340f40cac8c0Chris Banes                closePanel(st, true);
1591dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes            }
1592dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes        }
1593dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes
1594dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes        return handled;
1595dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes    }
1596dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes
159700d183885b54de433e43118d3032340f40cac8c0Chris Banes    private void invalidatePanelMenu(int featureId) {
159800d183885b54de433e43118d3032340f40cac8c0Chris Banes        mInvalidatePanelMenuFeatures |= 1 << featureId;
159900d183885b54de433e43118d3032340f40cac8c0Chris Banes
1600ff7f258a9b0781de5c6325358c7075128bf05a91Chris Banes        if (!mInvalidatePanelMenuPosted) {
1601ff7f258a9b0781de5c6325358c7075128bf05a91Chris Banes            ViewCompat.postOnAnimation(mWindow.getDecorView(), mInvalidatePanelMenuRunnable);
160200d183885b54de433e43118d3032340f40cac8c0Chris Banes            mInvalidatePanelMenuPosted = true;
160300d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
160400d183885b54de433e43118d3032340f40cac8c0Chris Banes    }
160500d183885b54de433e43118d3032340f40cac8c0Chris Banes
160600d183885b54de433e43118d3032340f40cac8c0Chris Banes    private void doInvalidatePanelMenu(int featureId) {
160700d183885b54de433e43118d3032340f40cac8c0Chris Banes        PanelFeatureState st = getPanelState(featureId, true);
160800d183885b54de433e43118d3032340f40cac8c0Chris Banes        Bundle savedActionViewStates = null;
160900d183885b54de433e43118d3032340f40cac8c0Chris Banes        if (st.menu != null) {
161000d183885b54de433e43118d3032340f40cac8c0Chris Banes            savedActionViewStates = new Bundle();
161100d183885b54de433e43118d3032340f40cac8c0Chris Banes            st.menu.saveActionViewStates(savedActionViewStates);
161200d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (savedActionViewStates.size() > 0) {
161300d183885b54de433e43118d3032340f40cac8c0Chris Banes                st.frozenActionViewState = savedActionViewStates;
161400d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
161500d183885b54de433e43118d3032340f40cac8c0Chris Banes            // This will be started again when the panel is prepared.
161600d183885b54de433e43118d3032340f40cac8c0Chris Banes            st.menu.stopDispatchingItemsChanged();
161700d183885b54de433e43118d3032340f40cac8c0Chris Banes            st.menu.clear();
161800d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
161900d183885b54de433e43118d3032340f40cac8c0Chris Banes        st.refreshMenuContent = true;
162000d183885b54de433e43118d3032340f40cac8c0Chris Banes        st.refreshDecorView = true;
162100d183885b54de433e43118d3032340f40cac8c0Chris Banes
162200d183885b54de433e43118d3032340f40cac8c0Chris Banes        // Prepare the options panel if we have an action bar
1623d25af35061a9f20d59b25329d613c62c20184dadChris Banes        if ((featureId == FEATURE_SUPPORT_ACTION_BAR || featureId == FEATURE_OPTIONS_PANEL)
162400d183885b54de433e43118d3032340f40cac8c0Chris Banes                && mDecorContentParent != null) {
162500d183885b54de433e43118d3032340f40cac8c0Chris Banes            st = getPanelState(Window.FEATURE_OPTIONS_PANEL, false);
162600d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (st != null) {
162700d183885b54de433e43118d3032340f40cac8c0Chris Banes                st.isPrepared = false;
162800d183885b54de433e43118d3032340f40cac8c0Chris Banes                preparePanel(st, null);
162900d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
163000d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
163100d183885b54de433e43118d3032340f40cac8c0Chris Banes    }
163200d183885b54de433e43118d3032340f40cac8c0Chris Banes
1633ea4f700ac38424954c56df5138ff794def50b019Chris Banes    /**
1634ea4f700ac38424954c56df5138ff794def50b019Chris Banes     * Updates the status bar guard
1635ea4f700ac38424954c56df5138ff794def50b019Chris Banes     *
1636ea4f700ac38424954c56df5138ff794def50b019Chris Banes     * @param insetTop the current top system window inset
1637ea4f700ac38424954c56df5138ff794def50b019Chris Banes     * @return the new top system window inset
1638ea4f700ac38424954c56df5138ff794def50b019Chris Banes     */
1639ea4f700ac38424954c56df5138ff794def50b019Chris Banes    private int updateStatusGuard(int insetTop) {
1640ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes        boolean showStatusGuard = false;
1641ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes        // Show the status guard when the non-overlay contextual action bar is showing
1642ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes        if (mActionModeView != null) {
1643ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes            if (mActionModeView.getLayoutParams() instanceof ViewGroup.MarginLayoutParams) {
1644ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                ViewGroup.MarginLayoutParams mlp = (ViewGroup.MarginLayoutParams)
1645ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                        mActionModeView.getLayoutParams();
1646ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                boolean mlpChanged = false;
1647ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes
1648ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                if (mActionModeView.isShown()) {
16497efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell                    if (mTempRect1 == null) {
16507efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell                        mTempRect1 = new Rect();
16517efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell                        mTempRect2 = new Rect();
16527efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell                    }
16537efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell                    final Rect insets = mTempRect1;
16547efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell                    final Rect localInsets = mTempRect2;
16557efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell                    insets.set(0, insetTop, 0, 0);
16567efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell
16577efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell                    ViewUtils.computeFitSystemWindows(mSubDecor, insets, localInsets);
16587efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell                    final int newMargin = localInsets.top == 0 ? insetTop : 0;
16597efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell                    if (mlp.topMargin != newMargin) {
16607efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell                        mlpChanged = true;
16617efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell                        mlp.topMargin = insetTop;
16627efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell
1663ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                        if (mStatusGuard == null) {
166416e8d4dd91083260223c007c797e46bc8f631055Chris Banes                            mStatusGuard = new View(mContext);
166516e8d4dd91083260223c007c797e46bc8f631055Chris Banes                            mStatusGuard.setBackgroundColor(mContext.getResources()
1666ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                                    .getColor(R.color.abc_input_method_navigation_guard));
16677efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell                            mSubDecor.addView(mStatusGuard, -1,
1668ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                                    new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
1669ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                                            insetTop));
1670ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                        } else {
1671ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                            ViewGroup.LayoutParams lp = mStatusGuard.getLayoutParams();
1672ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                            if (lp.height != insetTop) {
1673ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                                lp.height = insetTop;
1674ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                                mStatusGuard.setLayoutParams(lp);
1675ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                            }
1676ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                        }
1677ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                    }
1678ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes
1679bbb50c78cc6ee24677c79bd4548fa38fcdc41d92Adam Powell                    // The action mode's theme may differ from the app, so
1680bbb50c78cc6ee24677c79bd4548fa38fcdc41d92Adam Powell                    // always show the status guard above it.
1681bbb50c78cc6ee24677c79bd4548fa38fcdc41d92Adam Powell                    showStatusGuard = mStatusGuard != null;
1682bbb50c78cc6ee24677c79bd4548fa38fcdc41d92Adam Powell
16837efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell                    // We only need to consume the insets if the action
16847efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell                    // mode is overlaid on the app content (e.g. it's
16857efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell                    // sitting in a FrameLayout, see
16867efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell                    // screen_simple_overlay_action_mode.xml).
1687bbb50c78cc6ee24677c79bd4548fa38fcdc41d92Adam Powell                    if (!mOverlayActionMode && showStatusGuard) {
16887efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell                        insetTop = 0;
16897efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell                    }
1690ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                } else {
1691ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                    // reset top margin
1692ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                    if (mlp.topMargin != 0) {
1693ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                        mlpChanged = true;
1694ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                        mlp.topMargin = 0;
1695ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                    }
1696ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                }
1697ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                if (mlpChanged) {
1698ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                    mActionModeView.setLayoutParams(mlp);
1699ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                }
1700ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes            }
1701ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes        }
1702ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes        if (mStatusGuard != null) {
1703ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes            mStatusGuard.setVisibility(showStatusGuard ? View.VISIBLE : View.GONE);
1704ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes        }
1705ea4f700ac38424954c56df5138ff794def50b019Chris Banes
1706ea4f700ac38424954c56df5138ff794def50b019Chris Banes        return insetTop;
1707ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes    }
1708ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes
1709cc7aada3ee922cfb38eeb36ee696cc73dcbae0a4Chris Banes    private void throwFeatureRequestIfSubDecorInstalled() {
1710cc7aada3ee922cfb38eeb36ee696cc73dcbae0a4Chris Banes        if (mSubDecorInstalled) {
1711cc7aada3ee922cfb38eeb36ee696cc73dcbae0a4Chris Banes            throw new AndroidRuntimeException(
1712f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes                    "Window feature must be requested before adding content");
1713cc7aada3ee922cfb38eeb36ee696cc73dcbae0a4Chris Banes        }
1714cc7aada3ee922cfb38eeb36ee696cc73dcbae0a4Chris Banes    }
1715cc7aada3ee922cfb38eeb36ee696cc73dcbae0a4Chris Banes
17168122ad54f129c2214631fad86cabda82815cc0d8Chris Banes    private int sanitizeWindowFeatureId(int featureId) {
17178122ad54f129c2214631fad86cabda82815cc0d8Chris Banes        if (featureId == WindowCompat.FEATURE_ACTION_BAR) {
17188122ad54f129c2214631fad86cabda82815cc0d8Chris Banes            Log.i(TAG, "You should now use the AppCompatDelegate.FEATURE_SUPPORT_ACTION_BAR"
17198122ad54f129c2214631fad86cabda82815cc0d8Chris Banes                    + " id when requesting this feature.");
17208122ad54f129c2214631fad86cabda82815cc0d8Chris Banes            return FEATURE_SUPPORT_ACTION_BAR;
17218122ad54f129c2214631fad86cabda82815cc0d8Chris Banes        } else if (featureId == WindowCompat.FEATURE_ACTION_BAR_OVERLAY) {
17228122ad54f129c2214631fad86cabda82815cc0d8Chris Banes            Log.i(TAG, "You should now use the AppCompatDelegate.FEATURE_SUPPORT_ACTION_BAR_OVERLAY"
17238122ad54f129c2214631fad86cabda82815cc0d8Chris Banes                    + " id when requesting this feature.");
17248122ad54f129c2214631fad86cabda82815cc0d8Chris Banes            return FEATURE_SUPPORT_ACTION_BAR_OVERLAY;
17258122ad54f129c2214631fad86cabda82815cc0d8Chris Banes        }
17268122ad54f129c2214631fad86cabda82815cc0d8Chris Banes        // Else we'll just return the original id
17278122ad54f129c2214631fad86cabda82815cc0d8Chris Banes        return featureId;
17288122ad54f129c2214631fad86cabda82815cc0d8Chris Banes    }
17298122ad54f129c2214631fad86cabda82815cc0d8Chris Banes
173016e8d4dd91083260223c007c797e46bc8f631055Chris Banes    ViewGroup getSubDecor() {
173116e8d4dd91083260223c007c797e46bc8f631055Chris Banes        return mSubDecor;
173216e8d4dd91083260223c007c797e46bc8f631055Chris Banes    }
173316e8d4dd91083260223c007c797e46bc8f631055Chris Banes
1734b034e4ad40bff78a848d9ed91754e3f9f3492f11Chris Banes    private void dismissPopups() {
1735b034e4ad40bff78a848d9ed91754e3f9f3492f11Chris Banes        if (mDecorContentParent != null) {
1736b034e4ad40bff78a848d9ed91754e3f9f3492f11Chris Banes            mDecorContentParent.dismissPopups();
1737b034e4ad40bff78a848d9ed91754e3f9f3492f11Chris Banes        }
1738b034e4ad40bff78a848d9ed91754e3f9f3492f11Chris Banes
1739b034e4ad40bff78a848d9ed91754e3f9f3492f11Chris Banes        if (mActionModePopup != null) {
1740ff7f258a9b0781de5c6325358c7075128bf05a91Chris Banes            mWindow.getDecorView().removeCallbacks(mShowActionModePopup);
1741b034e4ad40bff78a848d9ed91754e3f9f3492f11Chris Banes            if (mActionModePopup.isShowing()) {
1742d3a70c7dfb3292c72f9bee4cd47a632fc01d5231Chris Banes                try {
1743d3a70c7dfb3292c72f9bee4cd47a632fc01d5231Chris Banes                    mActionModePopup.dismiss();
1744d3a70c7dfb3292c72f9bee4cd47a632fc01d5231Chris Banes                } catch (IllegalArgumentException e) {
1745d3a70c7dfb3292c72f9bee4cd47a632fc01d5231Chris Banes                    // Pre-v18, there are times when the Window will remove the popup before us.
1746d3a70c7dfb3292c72f9bee4cd47a632fc01d5231Chris Banes                    // In these cases we need to swallow the resulting exception.
1747d3a70c7dfb3292c72f9bee4cd47a632fc01d5231Chris Banes                }
1748b034e4ad40bff78a848d9ed91754e3f9f3492f11Chris Banes            }
1749b034e4ad40bff78a848d9ed91754e3f9f3492f11Chris Banes            mActionModePopup = null;
1750b034e4ad40bff78a848d9ed91754e3f9f3492f11Chris Banes        }
1751b034e4ad40bff78a848d9ed91754e3f9f3492f11Chris Banes        endOnGoingFadeAnimation();
1752b034e4ad40bff78a848d9ed91754e3f9f3492f11Chris Banes
1753b034e4ad40bff78a848d9ed91754e3f9f3492f11Chris Banes        PanelFeatureState st = getPanelState(FEATURE_OPTIONS_PANEL, false);
1754b034e4ad40bff78a848d9ed91754e3f9f3492f11Chris Banes        if (st != null && st.menu != null) {
1755b034e4ad40bff78a848d9ed91754e3f9f3492f11Chris Banes            st.menu.close();
1756b034e4ad40bff78a848d9ed91754e3f9f3492f11Chris Banes        }
1757b034e4ad40bff78a848d9ed91754e3f9f3492f11Chris Banes    }
1758b034e4ad40bff78a848d9ed91754e3f9f3492f11Chris Banes
1759ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes    /**
1760d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes     * Clears out internal reference when the action mode is destroyed.
1761d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes     */
1762547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes    class ActionModeCallbackWrapperV7 implements ActionMode.Callback {
1763d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        private ActionMode.Callback mWrapped;
1764d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes
1765547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes        public ActionModeCallbackWrapperV7(ActionMode.Callback wrapped) {
1766d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes            mWrapped = wrapped;
1767d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        }
1768d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes
1769d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        public boolean onCreateActionMode(ActionMode mode, Menu menu) {
1770d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes            return mWrapped.onCreateActionMode(mode, menu);
1771d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        }
1772d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes
1773d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
17749addcff1698f71fb4145f39dacaf33a9c1fef24fChris Banes            return mWrapped.onPrepareActionMode(mode, menu);
1775d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        }
1776d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes
1777d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
1778d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes            return mWrapped.onActionItemClicked(mode, item);
1779d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        }
1780d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes
1781d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        public void onDestroyActionMode(ActionMode mode) {
1782d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes            mWrapped.onDestroyActionMode(mode);
17834c2a95906254748cb9a843b061288265d6e185a9Chris Banes            if (mActionModePopup != null) {
178416e8d4dd91083260223c007c797e46bc8f631055Chris Banes                mWindow.getDecorView().removeCallbacks(mShowActionModePopup);
17854c2a95906254748cb9a843b061288265d6e185a9Chris Banes            }
1786c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu
17874c2a95906254748cb9a843b061288265d6e185a9Chris Banes            if (mActionModeView != null) {
1788c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu                endOnGoingFadeAnimation();
1789c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu                mFadeAnim = ViewCompat.animate(mActionModeView).alpha(0f);
1790c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu                mFadeAnim.setListener(new ViewPropertyAnimatorListenerAdapter() {
1791c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu                    @Override
1792c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu                    public void onAnimationEnd(View view) {
1793c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu                        mActionModeView.setVisibility(View.GONE);
1794c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu                        if (mActionModePopup != null) {
1795c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu                            mActionModePopup.dismiss();
1796c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu                        } else if (mActionModeView.getParent() instanceof View) {
1797c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu                            ViewCompat.requestApplyInsets((View) mActionModeView.getParent());
1798c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu                        }
1799c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu                        mActionModeView.removeAllViews();
1800c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu                        mFadeAnim.setListener(null);
1801c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu                        mFadeAnim = null;
1802c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu                    }
1803c04ae73a9793cdad7784fd543f3b7ad32cc8dbedDoris Liu                });
18044c2a95906254748cb9a843b061288265d6e185a9Chris Banes            }
1805f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes            if (mAppCompatCallback != null) {
1806f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes                mAppCompatCallback.onSupportActionModeFinished(mActionMode);
18074c2a95906254748cb9a843b061288265d6e185a9Chris Banes            }
1808d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes            mActionMode = null;
1809d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        }
1810d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes    }
1811d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes
181203fc11b659da1645507062bddda450136e13af35Chris Banes    private final class PanelMenuPresenterCallback implements MenuPresenter.Callback {
181303fc11b659da1645507062bddda450136e13af35Chris Banes        @Override
181400d183885b54de433e43118d3032340f40cac8c0Chris Banes        public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) {
181500d183885b54de433e43118d3032340f40cac8c0Chris Banes            final Menu parentMenu = menu.getRootMenu();
181600d183885b54de433e43118d3032340f40cac8c0Chris Banes            final boolean isSubMenu = parentMenu != menu;
181700d183885b54de433e43118d3032340f40cac8c0Chris Banes            final PanelFeatureState panel = findMenuPanel(isSubMenu ? parentMenu : menu);
181800d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (panel != null) {
181900d183885b54de433e43118d3032340f40cac8c0Chris Banes                if (isSubMenu) {
182000d183885b54de433e43118d3032340f40cac8c0Chris Banes                    callOnPanelClosed(panel.featureId, panel, parentMenu);
182100d183885b54de433e43118d3032340f40cac8c0Chris Banes                    closePanel(panel, true);
182200d183885b54de433e43118d3032340f40cac8c0Chris Banes                } else {
182300d183885b54de433e43118d3032340f40cac8c0Chris Banes                    // Close the panel and only do the callback if the menu is being
182400d183885b54de433e43118d3032340f40cac8c0Chris Banes                    // closed completely, not if opening a sub menu
182500d183885b54de433e43118d3032340f40cac8c0Chris Banes                    closePanel(panel, allMenusAreClosing);
182600d183885b54de433e43118d3032340f40cac8c0Chris Banes                }
182700d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
182803fc11b659da1645507062bddda450136e13af35Chris Banes        }
182903fc11b659da1645507062bddda450136e13af35Chris Banes
183003fc11b659da1645507062bddda450136e13af35Chris Banes        @Override
183100d183885b54de433e43118d3032340f40cac8c0Chris Banes        public boolean onOpenSubMenu(MenuBuilder subMenu) {
183200d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (subMenu == null && mHasActionBar) {
1833f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes                Window.Callback cb = getWindowCallback();
18349b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes                if (cb != null && !isDestroyed()) {
1835d25af35061a9f20d59b25329d613c62c20184dadChris Banes                    cb.onMenuOpened(FEATURE_SUPPORT_ACTION_BAR, subMenu);
183600d183885b54de433e43118d3032340f40cac8c0Chris Banes                }
183700d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
183800d183885b54de433e43118d3032340f40cac8c0Chris Banes            return true;
183903fc11b659da1645507062bddda450136e13af35Chris Banes        }
184003fc11b659da1645507062bddda450136e13af35Chris Banes    }
184103fc11b659da1645507062bddda450136e13af35Chris Banes
184203fc11b659da1645507062bddda450136e13af35Chris Banes    private final class ActionMenuPresenterCallback implements MenuPresenter.Callback {
184303fc11b659da1645507062bddda450136e13af35Chris Banes        @Override
184403fc11b659da1645507062bddda450136e13af35Chris Banes        public boolean onOpenSubMenu(MenuBuilder subMenu) {
1845f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes            Window.Callback cb = getWindowCallback();
184600d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (cb != null) {
1847d25af35061a9f20d59b25329d613c62c20184dadChris Banes                cb.onMenuOpened(FEATURE_SUPPORT_ACTION_BAR, subMenu);
184800d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
184900d183885b54de433e43118d3032340f40cac8c0Chris Banes            return true;
185003fc11b659da1645507062bddda450136e13af35Chris Banes        }
185103fc11b659da1645507062bddda450136e13af35Chris Banes
185203fc11b659da1645507062bddda450136e13af35Chris Banes        @Override
185303fc11b659da1645507062bddda450136e13af35Chris Banes        public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) {
185400d183885b54de433e43118d3032340f40cac8c0Chris Banes            checkCloseActionMenu(menu);
185500d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
185600d183885b54de433e43118d3032340f40cac8c0Chris Banes    }
185700d183885b54de433e43118d3032340f40cac8c0Chris Banes
185885035fae2e7f292a529dc70e8d41cebc799e7d4fChris Banes    protected static final class PanelFeatureState {
18599b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes
186000d183885b54de433e43118d3032340f40cac8c0Chris Banes        /** Feature ID for this panel. */
186100d183885b54de433e43118d3032340f40cac8c0Chris Banes        int featureId;
186200d183885b54de433e43118d3032340f40cac8c0Chris Banes
186346dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes        int background;
186446dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes
186546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes        int gravity;
186646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes
186746dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes        int x;
186846dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes
186946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes        int y;
187046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes
187146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes        int windowAnimations;
187246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes
187300d183885b54de433e43118d3032340f40cac8c0Chris Banes        /** Dynamic state of the panel. */
187400d183885b54de433e43118d3032340f40cac8c0Chris Banes        ViewGroup decorView;
187500d183885b54de433e43118d3032340f40cac8c0Chris Banes
187600d183885b54de433e43118d3032340f40cac8c0Chris Banes        /** The panel that we are actually showing. */
187700d183885b54de433e43118d3032340f40cac8c0Chris Banes        View shownPanelView;
187800d183885b54de433e43118d3032340f40cac8c0Chris Banes
187946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes        /** The panel that was returned by onCreatePanelView(). */
188046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes        View createdPanelView;
188146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes
188200d183885b54de433e43118d3032340f40cac8c0Chris Banes        /** Use {@link #setMenu} to set this. */
188300d183885b54de433e43118d3032340f40cac8c0Chris Banes        MenuBuilder menu;
188400d183885b54de433e43118d3032340f40cac8c0Chris Banes
188500d183885b54de433e43118d3032340f40cac8c0Chris Banes        ListMenuPresenter listMenuPresenter;
188600d183885b54de433e43118d3032340f40cac8c0Chris Banes
188757c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes        Context listPresenterContext;
188800d183885b54de433e43118d3032340f40cac8c0Chris Banes
188900d183885b54de433e43118d3032340f40cac8c0Chris Banes        /**
189000d183885b54de433e43118d3032340f40cac8c0Chris Banes         * Whether the panel has been prepared (see
18919b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes         * {@link #preparePanel}).
189200d183885b54de433e43118d3032340f40cac8c0Chris Banes         */
189300d183885b54de433e43118d3032340f40cac8c0Chris Banes        boolean isPrepared;
189400d183885b54de433e43118d3032340f40cac8c0Chris Banes
189500d183885b54de433e43118d3032340f40cac8c0Chris Banes        /**
189600d183885b54de433e43118d3032340f40cac8c0Chris Banes         * Whether an item's action has been performed. This happens in obvious
189700d183885b54de433e43118d3032340f40cac8c0Chris Banes         * scenarios (user clicks on menu item), but can also happen with
189800d183885b54de433e43118d3032340f40cac8c0Chris Banes         * chording menu+(shortcut key).
189900d183885b54de433e43118d3032340f40cac8c0Chris Banes         */
190000d183885b54de433e43118d3032340f40cac8c0Chris Banes        boolean isHandled;
190100d183885b54de433e43118d3032340f40cac8c0Chris Banes
190200d183885b54de433e43118d3032340f40cac8c0Chris Banes        boolean isOpen;
190300d183885b54de433e43118d3032340f40cac8c0Chris Banes
190400d183885b54de433e43118d3032340f40cac8c0Chris Banes        public boolean qwertyMode;
190500d183885b54de433e43118d3032340f40cac8c0Chris Banes
190600d183885b54de433e43118d3032340f40cac8c0Chris Banes        boolean refreshDecorView;
190700d183885b54de433e43118d3032340f40cac8c0Chris Banes
190800d183885b54de433e43118d3032340f40cac8c0Chris Banes        boolean refreshMenuContent;
190900d183885b54de433e43118d3032340f40cac8c0Chris Banes
191000d183885b54de433e43118d3032340f40cac8c0Chris Banes        boolean wasLastOpen;
191100d183885b54de433e43118d3032340f40cac8c0Chris Banes
191200d183885b54de433e43118d3032340f40cac8c0Chris Banes        /**
191300d183885b54de433e43118d3032340f40cac8c0Chris Banes         * Contains the state of the menu when told to freeze.
191400d183885b54de433e43118d3032340f40cac8c0Chris Banes         */
191500d183885b54de433e43118d3032340f40cac8c0Chris Banes        Bundle frozenMenuState;
191600d183885b54de433e43118d3032340f40cac8c0Chris Banes
191700d183885b54de433e43118d3032340f40cac8c0Chris Banes        /**
191800d183885b54de433e43118d3032340f40cac8c0Chris Banes         * Contains the state of associated action views when told to freeze.
191900d183885b54de433e43118d3032340f40cac8c0Chris Banes         * These are saved across invalidations.
192000d183885b54de433e43118d3032340f40cac8c0Chris Banes         */
192100d183885b54de433e43118d3032340f40cac8c0Chris Banes        Bundle frozenActionViewState;
192200d183885b54de433e43118d3032340f40cac8c0Chris Banes
192300d183885b54de433e43118d3032340f40cac8c0Chris Banes        PanelFeatureState(int featureId) {
192400d183885b54de433e43118d3032340f40cac8c0Chris Banes            this.featureId = featureId;
192500d183885b54de433e43118d3032340f40cac8c0Chris Banes
192600d183885b54de433e43118d3032340f40cac8c0Chris Banes            refreshDecorView = false;
192700d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
192800d183885b54de433e43118d3032340f40cac8c0Chris Banes
192900d183885b54de433e43118d3032340f40cac8c0Chris Banes        public boolean hasPanelItems() {
193000d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (shownPanelView == null) return false;
193146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes            if (createdPanelView != null) return true;
193200d183885b54de433e43118d3032340f40cac8c0Chris Banes
193300d183885b54de433e43118d3032340f40cac8c0Chris Banes            return listMenuPresenter.getAdapter().getCount() > 0;
193400d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
193500d183885b54de433e43118d3032340f40cac8c0Chris Banes
193600d183885b54de433e43118d3032340f40cac8c0Chris Banes        /**
193700d183885b54de433e43118d3032340f40cac8c0Chris Banes         * Unregister and free attached MenuPresenters. They will be recreated as needed.
193800d183885b54de433e43118d3032340f40cac8c0Chris Banes         */
193900d183885b54de433e43118d3032340f40cac8c0Chris Banes        public void clearMenuPresenters() {
194000d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (menu != null) {
194100d183885b54de433e43118d3032340f40cac8c0Chris Banes                menu.removeMenuPresenter(listMenuPresenter);
194200d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
194300d183885b54de433e43118d3032340f40cac8c0Chris Banes            listMenuPresenter = null;
194400d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
194500d183885b54de433e43118d3032340f40cac8c0Chris Banes
194600d183885b54de433e43118d3032340f40cac8c0Chris Banes        void setStyle(Context context) {
194757c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes            final TypedValue outValue = new TypedValue();
194857c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes            final Resources.Theme widgetTheme = context.getResources().newTheme();
194957c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes            widgetTheme.setTo(context.getTheme());
195057c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes
195157c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes            // First apply the actionBarPopupTheme
195257c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes            widgetTheme.resolveAttribute(R.attr.actionBarPopupTheme, outValue, true);
195357c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes            if (outValue.resourceId != 0) {
195457c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes                widgetTheme.applyStyle(outValue.resourceId, true);
195557c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes            }
195657c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes
195757c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes            // Now apply the panelMenuListTheme
195857c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes            widgetTheme.resolveAttribute(R.attr.panelMenuListTheme, outValue, true);
195957c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes            if (outValue.resourceId != 0) {
196057c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes                widgetTheme.applyStyle(outValue.resourceId, true);
196157c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes            } else {
196257c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes                widgetTheme.applyStyle(R.style.Theme_AppCompat_CompactMenu, true);
196357c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes            }
196457c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes
196557c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes            context = new ContextThemeWrapper(context, 0);
196657c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes            context.getTheme().setTo(widgetTheme);
196757c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes
196857c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes            listPresenterContext = context;
196946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes
1970a777694569b333a4459606db6bc94a9e80fd25f3Chris Banes            TypedArray a = context.obtainStyledAttributes(R.styleable.AppCompatTheme);
197146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes            background = a.getResourceId(
1972a777694569b333a4459606db6bc94a9e80fd25f3Chris Banes                    R.styleable.AppCompatTheme_panelBackground, 0);
197346dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes            windowAnimations = a.getResourceId(
1974a777694569b333a4459606db6bc94a9e80fd25f3Chris Banes                    R.styleable.AppCompatTheme_android_windowAnimationStyle, 0);
197546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes            a.recycle();
197600d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
197700d183885b54de433e43118d3032340f40cac8c0Chris Banes
197800d183885b54de433e43118d3032340f40cac8c0Chris Banes        void setMenu(MenuBuilder menu) {
197900d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (menu == this.menu) return;
198000d183885b54de433e43118d3032340f40cac8c0Chris Banes
198100d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (this.menu != null) {
198200d183885b54de433e43118d3032340f40cac8c0Chris Banes                this.menu.removeMenuPresenter(listMenuPresenter);
198300d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
198400d183885b54de433e43118d3032340f40cac8c0Chris Banes            this.menu = menu;
198500d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (menu != null) {
198600d183885b54de433e43118d3032340f40cac8c0Chris Banes                if (listMenuPresenter != null) menu.addMenuPresenter(listMenuPresenter);
198700d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
198800d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
198900d183885b54de433e43118d3032340f40cac8c0Chris Banes
199057c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes        MenuView getListMenuView(MenuPresenter.Callback cb) {
199100d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (menu == null) return null;
199200d183885b54de433e43118d3032340f40cac8c0Chris Banes
199300d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (listMenuPresenter == null) {
199457c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes                listMenuPresenter = new ListMenuPresenter(listPresenterContext,
199557c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes                        R.layout.abc_list_menu_item_layout);
199600d183885b54de433e43118d3032340f40cac8c0Chris Banes                listMenuPresenter.setCallback(cb);
199700d183885b54de433e43118d3032340f40cac8c0Chris Banes                menu.addMenuPresenter(listMenuPresenter);
199800d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
199900d183885b54de433e43118d3032340f40cac8c0Chris Banes
200000d183885b54de433e43118d3032340f40cac8c0Chris Banes            MenuView result = listMenuPresenter.getMenuView(decorView);
200100d183885b54de433e43118d3032340f40cac8c0Chris Banes
200200d183885b54de433e43118d3032340f40cac8c0Chris Banes            return result;
200300d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
200400d183885b54de433e43118d3032340f40cac8c0Chris Banes
200500d183885b54de433e43118d3032340f40cac8c0Chris Banes        Parcelable onSaveInstanceState() {
200600d183885b54de433e43118d3032340f40cac8c0Chris Banes            SavedState savedState = new SavedState();
200700d183885b54de433e43118d3032340f40cac8c0Chris Banes            savedState.featureId = featureId;
200800d183885b54de433e43118d3032340f40cac8c0Chris Banes            savedState.isOpen = isOpen;
200900d183885b54de433e43118d3032340f40cac8c0Chris Banes
201000d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (menu != null) {
201100d183885b54de433e43118d3032340f40cac8c0Chris Banes                savedState.menuState = new Bundle();
201200d183885b54de433e43118d3032340f40cac8c0Chris Banes                menu.savePresenterStates(savedState.menuState);
201300d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
201400d183885b54de433e43118d3032340f40cac8c0Chris Banes
201500d183885b54de433e43118d3032340f40cac8c0Chris Banes            return savedState;
201600d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
201700d183885b54de433e43118d3032340f40cac8c0Chris Banes
201800d183885b54de433e43118d3032340f40cac8c0Chris Banes        void onRestoreInstanceState(Parcelable state) {
201900d183885b54de433e43118d3032340f40cac8c0Chris Banes            SavedState savedState = (SavedState) state;
202000d183885b54de433e43118d3032340f40cac8c0Chris Banes            featureId = savedState.featureId;
202100d183885b54de433e43118d3032340f40cac8c0Chris Banes            wasLastOpen = savedState.isOpen;
202200d183885b54de433e43118d3032340f40cac8c0Chris Banes            frozenMenuState = savedState.menuState;
202300d183885b54de433e43118d3032340f40cac8c0Chris Banes
202400d183885b54de433e43118d3032340f40cac8c0Chris Banes            shownPanelView = null;
202500d183885b54de433e43118d3032340f40cac8c0Chris Banes            decorView = null;
202600d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
202700d183885b54de433e43118d3032340f40cac8c0Chris Banes
202800d183885b54de433e43118d3032340f40cac8c0Chris Banes        void applyFrozenState() {
202900d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (menu != null && frozenMenuState != null) {
203000d183885b54de433e43118d3032340f40cac8c0Chris Banes                menu.restorePresenterStates(frozenMenuState);
203100d183885b54de433e43118d3032340f40cac8c0Chris Banes                frozenMenuState = null;
203200d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
203300d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
203400d183885b54de433e43118d3032340f40cac8c0Chris Banes
203500d183885b54de433e43118d3032340f40cac8c0Chris Banes        private static class SavedState implements Parcelable {
203600d183885b54de433e43118d3032340f40cac8c0Chris Banes            int featureId;
203700d183885b54de433e43118d3032340f40cac8c0Chris Banes            boolean isOpen;
203800d183885b54de433e43118d3032340f40cac8c0Chris Banes            Bundle menuState;
203900d183885b54de433e43118d3032340f40cac8c0Chris Banes
204000d183885b54de433e43118d3032340f40cac8c0Chris Banes            public int describeContents() {
204100d183885b54de433e43118d3032340f40cac8c0Chris Banes                return 0;
204200d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
204300d183885b54de433e43118d3032340f40cac8c0Chris Banes
204400d183885b54de433e43118d3032340f40cac8c0Chris Banes            public void writeToParcel(Parcel dest, int flags) {
204500d183885b54de433e43118d3032340f40cac8c0Chris Banes                dest.writeInt(featureId);
204600d183885b54de433e43118d3032340f40cac8c0Chris Banes                dest.writeInt(isOpen ? 1 : 0);
204700d183885b54de433e43118d3032340f40cac8c0Chris Banes
204800d183885b54de433e43118d3032340f40cac8c0Chris Banes                if (isOpen) {
204900d183885b54de433e43118d3032340f40cac8c0Chris Banes                    dest.writeBundle(menuState);
205000d183885b54de433e43118d3032340f40cac8c0Chris Banes                }
205100d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
205200d183885b54de433e43118d3032340f40cac8c0Chris Banes
205362ab25d71ccfa775a8bd2add7b41277bc4e14bbcChris Banes            private static SavedState readFromParcel(Parcel source, ClassLoader loader) {
205400d183885b54de433e43118d3032340f40cac8c0Chris Banes                SavedState savedState = new SavedState();
205500d183885b54de433e43118d3032340f40cac8c0Chris Banes                savedState.featureId = source.readInt();
205600d183885b54de433e43118d3032340f40cac8c0Chris Banes                savedState.isOpen = source.readInt() == 1;
205700d183885b54de433e43118d3032340f40cac8c0Chris Banes
205800d183885b54de433e43118d3032340f40cac8c0Chris Banes                if (savedState.isOpen) {
205962ab25d71ccfa775a8bd2add7b41277bc4e14bbcChris Banes                    savedState.menuState = source.readBundle(loader);
206000d183885b54de433e43118d3032340f40cac8c0Chris Banes                }
206100d183885b54de433e43118d3032340f40cac8c0Chris Banes
206200d183885b54de433e43118d3032340f40cac8c0Chris Banes                return savedState;
206300d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
206400d183885b54de433e43118d3032340f40cac8c0Chris Banes
206500d183885b54de433e43118d3032340f40cac8c0Chris Banes            public static final Parcelable.Creator<SavedState> CREATOR
206662ab25d71ccfa775a8bd2add7b41277bc4e14bbcChris Banes                    = ParcelableCompat.newCreator(
206762ab25d71ccfa775a8bd2add7b41277bc4e14bbcChris Banes                    new ParcelableCompatCreatorCallbacks<SavedState>() {
206862ab25d71ccfa775a8bd2add7b41277bc4e14bbcChris Banes                        @Override
206962ab25d71ccfa775a8bd2add7b41277bc4e14bbcChris Banes                        public SavedState createFromParcel(Parcel in, ClassLoader loader) {
207062ab25d71ccfa775a8bd2add7b41277bc4e14bbcChris Banes                            return readFromParcel(in, loader);
207162ab25d71ccfa775a8bd2add7b41277bc4e14bbcChris Banes                        }
207200d183885b54de433e43118d3032340f40cac8c0Chris Banes
207362ab25d71ccfa775a8bd2add7b41277bc4e14bbcChris Banes                        @Override
207462ab25d71ccfa775a8bd2add7b41277bc4e14bbcChris Banes                        public SavedState[] newArray(int size) {
207562ab25d71ccfa775a8bd2add7b41277bc4e14bbcChris Banes                            return new SavedState[size];
207662ab25d71ccfa775a8bd2add7b41277bc4e14bbcChris Banes                        }
207762ab25d71ccfa775a8bd2add7b41277bc4e14bbcChris Banes                    });
207803fc11b659da1645507062bddda450136e13af35Chris Banes        }
207903fc11b659da1645507062bddda450136e13af35Chris Banes    }
208003fc11b659da1645507062bddda450136e13af35Chris Banes
2081b034e4ad40bff78a848d9ed91754e3f9f3492f11Chris Banes    private class ListMenuDecorView extends ContentFrameLayout {
208246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes        public ListMenuDecorView(Context context) {
208346dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes            super(context);
208446dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes        }
208546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes
208646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes        @Override
208746dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes        public boolean dispatchKeyEvent(KeyEvent event) {
20881d0e76a0ba8bfc5e280203a56e10be95dd959a51Chris Banes            return AppCompatDelegateImplV7.this.dispatchKeyEvent(event)
20891d0e76a0ba8bfc5e280203a56e10be95dd959a51Chris Banes                    || super.dispatchKeyEvent(event);
209046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes        }
209146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes
209246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes        @Override
209346dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes        public boolean onInterceptTouchEvent(MotionEvent event) {
209446dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes            int action = event.getAction();
209546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes            if (action == MotionEvent.ACTION_DOWN) {
209646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                int x = (int) event.getX();
209746dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                int y = (int) event.getY();
209846dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                if (isOutOfBounds(x, y)) {
209946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                    closePanel(Window.FEATURE_OPTIONS_PANEL);
210046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                    return true;
210146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                }
210246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes            }
210346dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes            return super.onInterceptTouchEvent(event);
210446dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes        }
210546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes
210646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes        @Override
210746dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes        public void setBackgroundResource(int resid) {
21087e4e8b664820f773bc96e37ee1d2bbf500d64e69Chris Banes            setBackgroundDrawable(AppCompatDrawableManager.get().getDrawable(getContext(), resid));
210946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes        }
211046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes
211146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes        private boolean isOutOfBounds(int x, int y) {
211246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes            return x < -5 || y < -5 || x > (getWidth() + 5) || y > (getHeight() + 5);
211346dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes        }
211446dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes    }
21156386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes}
2116