AppCompatDelegateImplV7.java revision d15ee7df01f2f48b536a610c4739f33b226d3f81
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
196386aac7ea9be44d23dcea28d9a02110c174e988Chris Banesimport android.content.Context;
206386aac7ea9be44d23dcea28d9a02110c174e988Chris Banesimport android.content.res.Configuration;
2161c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banesimport android.content.res.Resources;
226386aac7ea9be44d23dcea28d9a02110c174e988Chris Banesimport android.content.res.TypedArray;
23ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banesimport android.graphics.Rect;
24469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banesimport android.os.Build;
258902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banesimport android.os.Bundle;
2600d183885b54de433e43118d3032340f40cac8c0Chris Banesimport android.os.Parcel;
2700d183885b54de433e43118d3032340f40cac8c0Chris Banesimport android.os.Parcelable;
28469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banesimport android.support.annotation.NonNull;
2949c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.support.v4.app.NavUtils;
30ea4f700ac38424954c56df5138ff794def50b019Chris Banesimport android.support.v4.view.OnApplyWindowInsetsListener;
3103fc11b659da1645507062bddda450136e13af35Chris Banesimport android.support.v4.view.ViewCompat;
3249c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.support.v4.view.ViewConfigurationCompat;
33ea4f700ac38424954c56df5138ff794def50b019Chris Banesimport android.support.v4.view.WindowInsetsCompat;
346386aac7ea9be44d23dcea28d9a02110c174e988Chris Banesimport android.support.v7.appcompat.R;
35b73824b81c57b0a6821be9296a053ce4e516e583Chris Banesimport android.support.v7.internal.VersionUtils;
3649c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.support.v7.internal.app.ToolbarActionBar;
3700d183885b54de433e43118d3032340f40cac8c0Chris Banesimport android.support.v7.internal.app.WindowCallback;
3849c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.support.v7.internal.app.WindowDecorActionBar;
394c2a95906254748cb9a843b061288265d6e185a9Chris Banesimport android.support.v7.internal.view.StandaloneActionMode;
406386aac7ea9be44d23dcea28d9a02110c174e988Chris Banesimport android.support.v7.internal.view.menu.ListMenuPresenter;
416386aac7ea9be44d23dcea28d9a02110c174e988Chris Banesimport android.support.v7.internal.view.menu.MenuBuilder;
426386aac7ea9be44d23dcea28d9a02110c174e988Chris Banesimport android.support.v7.internal.view.menu.MenuPresenter;
436386aac7ea9be44d23dcea28d9a02110c174e988Chris Banesimport android.support.v7.internal.view.menu.MenuView;
444c2a95906254748cb9a843b061288265d6e185a9Chris Banesimport android.support.v7.internal.widget.ActionBarContextView;
4549c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.support.v7.internal.widget.DecorContentParent;
46ea4f700ac38424954c56df5138ff794def50b019Chris Banesimport android.support.v7.internal.widget.FitWindowsViewGroup;
47012047c60d03e61498955b7fa3e9cb9b409fbad8Chris Banesimport android.support.v7.internal.widget.TintAutoCompleteTextView;
48a9585dae398a69dd67797e7ca86f44ffcabd9e86Chris Banesimport android.support.v7.internal.widget.TintButton;
49415f740df4981ef2f5fb462a50c7cf095cc21128Chris Banesimport android.support.v7.internal.widget.TintCheckBox;
50415f740df4981ef2f5fb462a50c7cf095cc21128Chris Banesimport android.support.v7.internal.widget.TintCheckedTextView;
51469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banesimport android.support.v7.internal.widget.TintEditText;
52012047c60d03e61498955b7fa3e9cb9b409fbad8Chris Banesimport android.support.v7.internal.widget.TintMultiAutoCompleteTextView;
53415f740df4981ef2f5fb462a50c7cf095cc21128Chris Banesimport android.support.v7.internal.widget.TintRadioButton;
54a9585dae398a69dd67797e7ca86f44ffcabd9e86Chris Banesimport android.support.v7.internal.widget.TintRatingBar;
55415f740df4981ef2f5fb462a50c7cf095cc21128Chris Banesimport android.support.v7.internal.widget.TintSpinner;
564bd5cbd6ca4f1e5ed43217b808068a48f937feabChris Banesimport android.support.v7.internal.widget.ViewStubCompat;
57ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banesimport android.support.v7.internal.widget.ViewUtils;
58d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banesimport android.support.v7.view.ActionMode;
5949c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.support.v7.widget.Toolbar;
60cc7aada3ee922cfb38eeb36ee696cc73dcbae0a4Chris Banesimport android.util.AndroidRuntimeException;
61469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banesimport android.util.AttributeSet;
6256fd50144df518461398a9b3397ee4842b346708Chris Banesimport android.util.DisplayMetrics;
6356fd50144df518461398a9b3397ee4842b346708Chris Banesimport android.util.TypedValue;
6461c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banesimport android.view.ContextThemeWrapper;
654c2a95906254748cb9a843b061288265d6e185a9Chris Banesimport android.view.Gravity;
6600d183885b54de433e43118d3032340f40cac8c0Chris Banesimport android.view.KeyCharacterMap;
67dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banesimport android.view.KeyEvent;
68dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banesimport android.view.LayoutInflater;
6930837f1095c803f332f4a1c3f0917c8afdd50156Adam Powellimport android.view.Menu;
7030837f1095c803f332f4a1c3f0917c8afdd50156Adam Powellimport android.view.MenuItem;
716386aac7ea9be44d23dcea28d9a02110c174e988Chris Banesimport android.view.View;
7249c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.view.ViewConfiguration;
736386aac7ea9be44d23dcea28d9a02110c174e988Chris Banesimport android.view.ViewGroup;
746386aac7ea9be44d23dcea28d9a02110c174e988Chris Banesimport android.view.Window;
754c2a95906254748cb9a843b061288265d6e185a9Chris Banesimport android.view.accessibility.AccessibilityEvent;
7630837f1095c803f332f4a1c3f0917c8afdd50156Adam Powellimport android.widget.FrameLayout;
774c2a95906254748cb9a843b061288265d6e185a9Chris Banesimport android.widget.PopupWindow;
786386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes
79469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banesimport static android.support.v4.view.WindowCompat.FEATURE_ACTION_BAR;
80469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banesimport static android.support.v4.view.WindowCompat.FEATURE_ACTION_BAR_OVERLAY;
81469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banesimport static android.support.v4.view.WindowCompat.FEATURE_ACTION_MODE_OVERLAY;
8200d183885b54de433e43118d3032340f40cac8c0Chris Banesimport static android.view.Window.FEATURE_OPTIONS_PANEL;
8300d183885b54de433e43118d3032340f40cac8c0Chris Banes
8403fc11b659da1645507062bddda450136e13af35Chris Banesclass ActionBarActivityDelegateBase extends ActionBarActivityDelegate
8503fc11b659da1645507062bddda450136e13af35Chris Banes        implements MenuBuilder.Callback {
8630837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell    private static final String TAG = "ActionBarActivityDelegateBase";
876386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes
8849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    private DecorContentParent mDecorContentParent;
8903fc11b659da1645507062bddda450136e13af35Chris Banes    private ActionMenuPresenterCallback mActionMenuPresenterCallback;
9003fc11b659da1645507062bddda450136e13af35Chris Banes    private PanelMenuPresenterCallback mPanelMenuPresenterCallback;
9103fc11b659da1645507062bddda450136e13af35Chris Banes
924c2a95906254748cb9a843b061288265d6e185a9Chris Banes    ActionMode mActionMode;
934c2a95906254748cb9a843b061288265d6e185a9Chris Banes    ActionBarContextView mActionModeView;
944c2a95906254748cb9a843b061288265d6e185a9Chris Banes    PopupWindow mActionModePopup;
954c2a95906254748cb9a843b061288265d6e185a9Chris Banes    Runnable mShowActionModePopup;
965a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes
975a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes    // true if we have installed a window sub-decor layout.
985a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes    private boolean mSubDecorInstalled;
9903fc11b659da1645507062bddda450136e13af35Chris Banes    private ViewGroup mWindowDecor;
100ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes    private ViewGroup mSubDecor;
101ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes
102ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes    private View mStatusGuard;
103d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes
104f53c7bf3146bf9bcba46324f9f06449df475be36Chris Banes    private CharSequence mTitleToSet;
105f53c7bf3146bf9bcba46324f9f06449df475be36Chris Banes
106ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes    // Used to keep track of Progress Bar Window features
107ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes    private boolean mFeatureProgress, mFeatureIndeterminateProgress;
108ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes
1098902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes    // Used for emulating PanelFeatureState
1108902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes    private boolean mClosingActionMenu;
11100d183885b54de433e43118d3032340f40cac8c0Chris Banes    private PanelFeatureState[] mPanels;
11200d183885b54de433e43118d3032340f40cac8c0Chris Banes    private PanelFeatureState mPreparedPanel;
113556ac47ce764a4a9320b5ac914536e9da2524176Chris Banes
11403fc11b659da1645507062bddda450136e13af35Chris Banes    private boolean mInvalidatePanelMenuPosted;
11500d183885b54de433e43118d3032340f40cac8c0Chris Banes    private int mInvalidatePanelMenuFeatures;
11603fc11b659da1645507062bddda450136e13af35Chris Banes    private final Runnable mInvalidatePanelMenuRunnable = new Runnable() {
11703fc11b659da1645507062bddda450136e13af35Chris Banes        @Override
11803fc11b659da1645507062bddda450136e13af35Chris Banes        public void run() {
11900d183885b54de433e43118d3032340f40cac8c0Chris Banes            if ((mInvalidatePanelMenuFeatures & 1 << FEATURE_OPTIONS_PANEL) != 0) {
12000d183885b54de433e43118d3032340f40cac8c0Chris Banes                doInvalidatePanelMenu(FEATURE_OPTIONS_PANEL);
12100d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
12200d183885b54de433e43118d3032340f40cac8c0Chris Banes            if ((mInvalidatePanelMenuFeatures & 1 << FEATURE_ACTION_BAR) != 0) {
12300d183885b54de433e43118d3032340f40cac8c0Chris Banes                doInvalidatePanelMenu(FEATURE_ACTION_BAR);
12400d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
12500d183885b54de433e43118d3032340f40cac8c0Chris Banes            mInvalidatePanelMenuPosted = false;
12600d183885b54de433e43118d3032340f40cac8c0Chris Banes            mInvalidatePanelMenuFeatures = 0;
12703fc11b659da1645507062bddda450136e13af35Chris Banes        }
12803fc11b659da1645507062bddda450136e13af35Chris Banes    };
12903fc11b659da1645507062bddda450136e13af35Chris Banes
13049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    private boolean mEnableDefaultActionBarUp;
13149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
132da0b9d63d6f940cbfd5b526c3f81858aeadcb7e8Chris Banes    private ListMenuPresenter mToolbarListMenuPresenter;
133da0b9d63d6f940cbfd5b526c3f81858aeadcb7e8Chris Banes
1347efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell    private Rect mTempRect1;
1357efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell    private Rect mTempRect2;
1367efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell
137f2b7cd67036d78fd5b487b0a2dab28aee11d9c88Adam Powell    ActionBarActivityDelegateBase(ActionBarActivity activity) {
1383954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes        super(activity);
1396386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    }
1406386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes
1416386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    @Override
14249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    void onCreate(Bundle savedInstanceState) {
14349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        super.onCreate(savedInstanceState);
14449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
14503fc11b659da1645507062bddda450136e13af35Chris Banes        mWindowDecor = (ViewGroup) mActivity.getWindow().getDecorView();
14603fc11b659da1645507062bddda450136e13af35Chris Banes
14749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        if (NavUtils.getParentActivityName(mActivity) != null) {
148cc7aada3ee922cfb38eeb36ee696cc73dcbae0a4Chris Banes            // Peek at the Action Bar and update it if it already exists
149cc7aada3ee922cfb38eeb36ee696cc73dcbae0a4Chris Banes            ActionBar ab = peekSupportActionBar();
15049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            if (ab == null) {
15149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                mEnableDefaultActionBarUp = true;
15249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            } else {
15349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                ab.setDefaultDisplayHomeAsUpEnabled(true);
15449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            }
15549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        }
15649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
15749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
15849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    @Override
1596386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    public ActionBar createSupportActionBar() {
16030837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        ensureSubDecor();
16149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        ActionBar ab = new WindowDecorActionBar(mActivity, mOverlayActionBar);
16249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        ab.setDefaultDisplayHomeAsUpEnabled(mEnableDefaultActionBarUp);
16349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        return ab;
16449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
16549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
16649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    @Override
16749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    void setSupportActionBar(Toolbar toolbar) {
168da0b9d63d6f940cbfd5b526c3f81858aeadcb7e8Chris Banes        final ActionBar ab = getSupportActionBar();
169da0b9d63d6f940cbfd5b526c3f81858aeadcb7e8Chris Banes        if (ab instanceof WindowDecorActionBar) {
17049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            throw new IllegalStateException("This Activity already has an action bar supplied " +
17149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                    "by the window decor. Do not request Window.FEATURE_ACTION_BAR and set " +
17249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                    "windowActionBar to false in your theme to use a Toolbar instead.");
173da0b9d63d6f940cbfd5b526c3f81858aeadcb7e8Chris Banes        } else if (ab instanceof ToolbarActionBar) {
174da0b9d63d6f940cbfd5b526c3f81858aeadcb7e8Chris Banes            // Make sure we reset the old toolbar AB's list menu presenter
175da0b9d63d6f940cbfd5b526c3f81858aeadcb7e8Chris Banes            ((ToolbarActionBar) ab).setListMenuPresenter(null);
17649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        }
177da0b9d63d6f940cbfd5b526c3f81858aeadcb7e8Chris Banes
178a6e86333cb4de18fc9b86746a49643e213db7c18Chris Banes        // Need to make sure we give the action bar the default window callback. Otherwise multiple
179a6e86333cb4de18fc9b86746a49643e213db7c18Chris Banes        // setSupportActionBar() calls lead to memory leaks
1800b216f2263135782c361e122892a12156d5d2ce1Chris Banes        ToolbarActionBar tbab = new ToolbarActionBar(toolbar, mActivity.getTitle(),
181da0b9d63d6f940cbfd5b526c3f81858aeadcb7e8Chris Banes                mActivity.getWindow(), mDefaultWindowCallback);
182da0b9d63d6f940cbfd5b526c3f81858aeadcb7e8Chris Banes        ensureToolbarListMenuPresenter();
183da0b9d63d6f940cbfd5b526c3f81858aeadcb7e8Chris Banes        tbab.setListMenuPresenter(mToolbarListMenuPresenter);
1840b216f2263135782c361e122892a12156d5d2ce1Chris Banes        setSupportActionBar(tbab);
1850b216f2263135782c361e122892a12156d5d2ce1Chris Banes        setWindowCallback(tbab.getWrappedWindowCallback());
1860b216f2263135782c361e122892a12156d5d2ce1Chris Banes        tbab.invalidateOptionsMenu();
1876386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    }
1886386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes
1896386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    @Override
1906386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    public void onConfigurationChanged(Configuration newConfig) {
1916386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes        // If this is called before sub-decor is installed, ActionBar will not
1926386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes        // be properly initialized.
1935a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes        if (mHasActionBar && mSubDecorInstalled) {
1946386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes            // Note: The action bar will need to access
1956386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes            // view changes from superclass.
19649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            ActionBar ab = getSupportActionBar();
19749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            if (ab != null) {
19849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                ab.onConfigurationChanged(newConfig);
19949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            }
2006386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes        }
2016386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    }
2026386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes
2036386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    @Override
204a1fae63dbeeef71c2daa25bfcaa2348bffc369aaChris Banes    public void onStop() {
20549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        ActionBar ab = getSupportActionBar();
206a1fae63dbeeef71c2daa25bfcaa2348bffc369aaChris Banes        if (ab != null) {
207a1fae63dbeeef71c2daa25bfcaa2348bffc369aaChris Banes            ab.setShowHideAnimationEnabled(false);
208a1fae63dbeeef71c2daa25bfcaa2348bffc369aaChris Banes        }
209a1fae63dbeeef71c2daa25bfcaa2348bffc369aaChris Banes    }
210a1fae63dbeeef71c2daa25bfcaa2348bffc369aaChris Banes
211a1fae63dbeeef71c2daa25bfcaa2348bffc369aaChris Banes    @Override
212a1fae63dbeeef71c2daa25bfcaa2348bffc369aaChris Banes    public void onPostResume() {
21349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        ActionBar ab = getSupportActionBar();
214a1fae63dbeeef71c2daa25bfcaa2348bffc369aaChris Banes        if (ab != null) {
215a1fae63dbeeef71c2daa25bfcaa2348bffc369aaChris Banes            ab.setShowHideAnimationEnabled(true);
216a1fae63dbeeef71c2daa25bfcaa2348bffc369aaChris Banes        }
217a1fae63dbeeef71c2daa25bfcaa2348bffc369aaChris Banes    }
218a1fae63dbeeef71c2daa25bfcaa2348bffc369aaChris Banes
219a1fae63dbeeef71c2daa25bfcaa2348bffc369aaChris Banes    @Override
2206386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    public void setContentView(View v) {
2216386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes        ensureSubDecor();
22256fd50144df518461398a9b3397ee4842b346708Chris Banes        ViewGroup contentParent = (ViewGroup) mActivity.findViewById(android.R.id.content);
22356fd50144df518461398a9b3397ee4842b346708Chris Banes        contentParent.removeAllViews();
22456fd50144df518461398a9b3397ee4842b346708Chris Banes        contentParent.addView(v);
225d64322f4b9686fabfd5a03f402d50a8e3fe5adedChris Banes        mActivity.onSupportContentChanged();
2266386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    }
2276386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes
2286386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    @Override
2296386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    public void setContentView(int resId) {
2306386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes        ensureSubDecor();
23156fd50144df518461398a9b3397ee4842b346708Chris Banes        ViewGroup contentParent = (ViewGroup) mActivity.findViewById(android.R.id.content);
23256fd50144df518461398a9b3397ee4842b346708Chris Banes        contentParent.removeAllViews();
23356fd50144df518461398a9b3397ee4842b346708Chris Banes        mActivity.getLayoutInflater().inflate(resId, contentParent);
234d64322f4b9686fabfd5a03f402d50a8e3fe5adedChris Banes        mActivity.onSupportContentChanged();
2356386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    }
2366386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes
2376386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    @Override
2386386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    public void setContentView(View v, ViewGroup.LayoutParams lp) {
2396386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes        ensureSubDecor();
24056fd50144df518461398a9b3397ee4842b346708Chris Banes        ViewGroup contentParent = (ViewGroup) mActivity.findViewById(android.R.id.content);
24156fd50144df518461398a9b3397ee4842b346708Chris Banes        contentParent.removeAllViews();
24256fd50144df518461398a9b3397ee4842b346708Chris Banes        contentParent.addView(v, lp);
243d64322f4b9686fabfd5a03f402d50a8e3fe5adedChris Banes        mActivity.onSupportContentChanged();
2446386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    }
2456386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes
2466386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    @Override
2476386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    public void addContentView(View v, ViewGroup.LayoutParams lp) {
2486386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes        ensureSubDecor();
24956fd50144df518461398a9b3397ee4842b346708Chris Banes        ViewGroup contentParent = (ViewGroup) mActivity.findViewById(android.R.id.content);
25056fd50144df518461398a9b3397ee4842b346708Chris Banes        contentParent.addView(v, lp);
251d64322f4b9686fabfd5a03f402d50a8e3fe5adedChris Banes        mActivity.onSupportContentChanged();
252d64322f4b9686fabfd5a03f402d50a8e3fe5adedChris Banes    }
253d64322f4b9686fabfd5a03f402d50a8e3fe5adedChris Banes
254d64322f4b9686fabfd5a03f402d50a8e3fe5adedChris Banes    @Override
255d64322f4b9686fabfd5a03f402d50a8e3fe5adedChris Banes    public void onContentChanged() {
256d64322f4b9686fabfd5a03f402d50a8e3fe5adedChris Banes        // Ignore all calls to this method as we call onSupportContentChanged manually above
2576386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    }
2586386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes
2598123e4b3d19031e34a60c0db202f0b3d100eb9d8Chris Banes    final void ensureSubDecor() {
26056fd50144df518461398a9b3397ee4842b346708Chris Banes        if (!mSubDecorInstalled) {
26156fd50144df518461398a9b3397ee4842b346708Chris Banes            if (mHasActionBar) {
2624b217eaec19887b37d6d124df5ba04c5bb8b8141Chris Banes                /**
2634b217eaec19887b37d6d124df5ba04c5bb8b8141Chris Banes                 * This needs some explanation. As we can not use the android:theme attribute
2644b217eaec19887b37d6d124df5ba04c5bb8b8141Chris Banes                 * pre-L, we emulate it by manually creating a LayoutInflater using a
2654b217eaec19887b37d6d124df5ba04c5bb8b8141Chris Banes                 * ContextThemeWrapper pointing to actionBarTheme.
2664b217eaec19887b37d6d124df5ba04c5bb8b8141Chris Banes                 */
2674b217eaec19887b37d6d124df5ba04c5bb8b8141Chris Banes                TypedValue outValue = new TypedValue();
2684b217eaec19887b37d6d124df5ba04c5bb8b8141Chris Banes                mActivity.getTheme().resolveAttribute(R.attr.actionBarTheme, outValue, true);
2694b217eaec19887b37d6d124df5ba04c5bb8b8141Chris Banes
2704b217eaec19887b37d6d124df5ba04c5bb8b8141Chris Banes                Context themedContext;
2714b217eaec19887b37d6d124df5ba04c5bb8b8141Chris Banes                if (outValue.resourceId != 0) {
2724b217eaec19887b37d6d124df5ba04c5bb8b8141Chris Banes                    themedContext = new ContextThemeWrapper(mActivity, outValue.resourceId);
2734b217eaec19887b37d6d124df5ba04c5bb8b8141Chris Banes                } else {
2744b217eaec19887b37d6d124df5ba04c5bb8b8141Chris Banes                    themedContext = mActivity;
27561c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes                }
27661c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes
2774b217eaec19887b37d6d124df5ba04c5bb8b8141Chris Banes                // Now inflate the view using the themed context and set it as the content view
278ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                mSubDecor = (ViewGroup) LayoutInflater.from(themedContext)
2794b217eaec19887b37d6d124df5ba04c5bb8b8141Chris Banes                        .inflate(R.layout.abc_screen_toolbar, null);
2804b217eaec19887b37d6d124df5ba04c5bb8b8141Chris Banes
281ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                mDecorContentParent = (DecorContentParent) mSubDecor
28203fc11b659da1645507062bddda450136e13af35Chris Banes                        .findViewById(R.id.decor_content_parent);
283a6e86333cb4de18fc9b86746a49643e213db7c18Chris Banes                mDecorContentParent.setWindowCallback(getWindowCallback());
284ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes
28556fd50144df518461398a9b3397ee4842b346708Chris Banes                /**
28649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                 * Propagate features to DecorContentParent
28756fd50144df518461398a9b3397ee4842b346708Chris Banes                 */
28849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                if (mOverlayActionBar) {
289469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banes                    mDecorContentParent.initFeature(FEATURE_ACTION_BAR_OVERLAY);
29049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                }
29156fd50144df518461398a9b3397ee4842b346708Chris Banes                if (mFeatureProgress) {
29249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                    mDecorContentParent.initFeature(Window.FEATURE_PROGRESS);
29356fd50144df518461398a9b3397ee4842b346708Chris Banes                }
29456fd50144df518461398a9b3397ee4842b346708Chris Banes                if (mFeatureIndeterminateProgress) {
29549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                    mDecorContentParent.initFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
29656fd50144df518461398a9b3397ee4842b346708Chris Banes                }
29756fd50144df518461398a9b3397ee4842b346708Chris Banes            } else {
298ea4f700ac38424954c56df5138ff794def50b019Chris Banes                if (mOverlayActionMode) {
299ea4f700ac38424954c56df5138ff794def50b019Chris Banes                    mSubDecor = (ViewGroup) LayoutInflater.from(mActivity)
300ea4f700ac38424954c56df5138ff794def50b019Chris Banes                            .inflate(R.layout.abc_screen_simple_overlay_action_mode, null);
301ea4f700ac38424954c56df5138ff794def50b019Chris Banes                } else {
302ea4f700ac38424954c56df5138ff794def50b019Chris Banes                    mSubDecor = (ViewGroup) LayoutInflater.from(mActivity)
303ea4f700ac38424954c56df5138ff794def50b019Chris Banes                            .inflate(R.layout.abc_screen_simple, null);
304ea4f700ac38424954c56df5138ff794def50b019Chris Banes                }
305ea4f700ac38424954c56df5138ff794def50b019Chris Banes
306ea4f700ac38424954c56df5138ff794def50b019Chris Banes                if (Build.VERSION.SDK_INT >= 21) {
307ea4f700ac38424954c56df5138ff794def50b019Chris Banes                    // If we're running on L or above, we can rely on ViewCompat's
308ea4f700ac38424954c56df5138ff794def50b019Chris Banes                    // setOnApplyWindowInsetsListener
309ea4f700ac38424954c56df5138ff794def50b019Chris Banes                    ViewCompat.setOnApplyWindowInsetsListener(mSubDecor,
310ea4f700ac38424954c56df5138ff794def50b019Chris Banes                            new OnApplyWindowInsetsListener() {
311ea4f700ac38424954c56df5138ff794def50b019Chris Banes                                @Override
312ea4f700ac38424954c56df5138ff794def50b019Chris Banes                                public WindowInsetsCompat onApplyWindowInsets(View v,
313ea4f700ac38424954c56df5138ff794def50b019Chris Banes                                        WindowInsetsCompat insets) {
314ea4f700ac38424954c56df5138ff794def50b019Chris Banes                                    final int top = insets.getSystemWindowInsetTop();
315ea4f700ac38424954c56df5138ff794def50b019Chris Banes                                    final int newTop = updateStatusGuard(top);
316ea4f700ac38424954c56df5138ff794def50b019Chris Banes
317ea4f700ac38424954c56df5138ff794def50b019Chris Banes                                    if (top != newTop) {
318ea4f700ac38424954c56df5138ff794def50b019Chris Banes                                        return insets.replaceSystemWindowInsets(
319ea4f700ac38424954c56df5138ff794def50b019Chris Banes                                                insets.getSystemWindowInsetLeft(),
320ea4f700ac38424954c56df5138ff794def50b019Chris Banes                                                newTop,
321ea4f700ac38424954c56df5138ff794def50b019Chris Banes                                                insets.getSystemWindowInsetRight(),
322ea4f700ac38424954c56df5138ff794def50b019Chris Banes                                                insets.getSystemWindowInsetBottom());
323ea4f700ac38424954c56df5138ff794def50b019Chris Banes                                    } else {
324ea4f700ac38424954c56df5138ff794def50b019Chris Banes                                        return insets;
325ea4f700ac38424954c56df5138ff794def50b019Chris Banes                                    }
326ea4f700ac38424954c56df5138ff794def50b019Chris Banes                                }
327ea4f700ac38424954c56df5138ff794def50b019Chris Banes                            });
328ea4f700ac38424954c56df5138ff794def50b019Chris Banes                } else {
329ea4f700ac38424954c56df5138ff794def50b019Chris Banes                    // Else, we need to use our own FitWindowsViewGroup handling
330ea4f700ac38424954c56df5138ff794def50b019Chris Banes                    ((FitWindowsViewGroup) mSubDecor).setOnFitSystemWindowsListener(
331ea4f700ac38424954c56df5138ff794def50b019Chris Banes                            new FitWindowsViewGroup.OnFitSystemWindowsListener() {
332ea4f700ac38424954c56df5138ff794def50b019Chris Banes                                @Override
333ea4f700ac38424954c56df5138ff794def50b019Chris Banes                                public void onFitSystemWindows(Rect insets) {
334ea4f700ac38424954c56df5138ff794def50b019Chris Banes                                    insets.top = updateStatusGuard(insets.top);
335ea4f700ac38424954c56df5138ff794def50b019Chris Banes                                }
336ea4f700ac38424954c56df5138ff794def50b019Chris Banes                            });
337ea4f700ac38424954c56df5138ff794def50b019Chris Banes                }
3383954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes            }
3393954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes
3408c9ce11dec24a32f438406286404be7ac294011dChris Banes            // The DecorView's original content view
3418c9ce11dec24a32f438406286404be7ac294011dChris Banes            final View decorContent = mActivity.findViewById(android.R.id.content);
3428c9ce11dec24a32f438406286404be7ac294011dChris Banes
3438c9ce11dec24a32f438406286404be7ac294011dChris Banes            // Traverse up the hierarchy from the original content view, making each view
3448c9ce11dec24a32f438406286404be7ac294011dChris Banes            // ignore system window insets so that our sub-decor handles it
3458c9ce11dec24a32f438406286404be7ac294011dChris Banes            View view = decorContent;
3468c9ce11dec24a32f438406286404be7ac294011dChris Banes            while (view != mWindowDecor) {
3478c9ce11dec24a32f438406286404be7ac294011dChris Banes                ViewCompat.setFitsSystemWindows(view, false);
3488c9ce11dec24a32f438406286404be7ac294011dChris Banes                view = (View) view.getParent();
3498c9ce11dec24a32f438406286404be7ac294011dChris Banes            }
3508c9ce11dec24a32f438406286404be7ac294011dChris Banes
3511f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes            // Make the decor optionally fit system windows, like the window's decor
352ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes            ViewUtils.makeOptionalFitsSystemWindows(mSubDecor);
3531f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes
354ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes            // Now set the Activity's content view with the decor
355ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes            mActivity.superSetContentView(mSubDecor);
3561f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes
35792b18eb0263ef2421fda5bf977fea3bf044bf941Chris Banes            // Change our content FrameLayout to use the android.R.id.content id.
35892b18eb0263ef2421fda5bf977fea3bf044bf941Chris Banes            // Useful for fragments.
3594b217eaec19887b37d6d124df5ba04c5bb8b8141Chris Banes            decorContent.setId(View.NO_ID);
36092b18eb0263ef2421fda5bf977fea3bf044bf941Chris Banes            View abcContent = mActivity.findViewById(R.id.action_bar_activity_content);
36192b18eb0263ef2421fda5bf977fea3bf044bf941Chris Banes            abcContent.setId(android.R.id.content);
36292b18eb0263ef2421fda5bf977fea3bf044bf941Chris Banes
3634b217eaec19887b37d6d124df5ba04c5bb8b8141Chris Banes            // The decorContent may have a foreground drawable set (windowContentOverlay).
3644b217eaec19887b37d6d124df5ba04c5bb8b8141Chris Banes            // Remove this as we handle it ourselves
3654b217eaec19887b37d6d124df5ba04c5bb8b8141Chris Banes            if (decorContent instanceof FrameLayout) {
3664b217eaec19887b37d6d124df5ba04c5bb8b8141Chris Banes                ((FrameLayout) decorContent).setForeground(null);
3674b217eaec19887b37d6d124df5ba04c5bb8b8141Chris Banes            }
3684b217eaec19887b37d6d124df5ba04c5bb8b8141Chris Banes
369f53c7bf3146bf9bcba46324f9f06449df475be36Chris Banes            // A title was set before we've install the decor so set it now.
37049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            if (mTitleToSet != null && mDecorContentParent != null) {
37149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                mDecorContentParent.setWindowTitle(mTitleToSet);
37256fd50144df518461398a9b3397ee4842b346708Chris Banes                mTitleToSet = null;
373f53c7bf3146bf9bcba46324f9f06449df475be36Chris Banes            }
374556ac47ce764a4a9320b5ac914536e9da2524176Chris Banes
37556fd50144df518461398a9b3397ee4842b346708Chris Banes            applyFixedSizeWindow();
37656fd50144df518461398a9b3397ee4842b346708Chris Banes
37749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            onSubDecorInstalled();
37849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
379f53c7bf3146bf9bcba46324f9f06449df475be36Chris Banes            mSubDecorInstalled = true;
3808902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes
38100d183885b54de433e43118d3032340f40cac8c0Chris Banes            // Invalidate if the panel menu hasn't been created before this.
38200d183885b54de433e43118d3032340f40cac8c0Chris Banes            // Panel menu invalidation is deferred avoiding application onCreateOptionsMenu
38300d183885b54de433e43118d3032340f40cac8c0Chris Banes            // being called in the middle of onCreate or similar.
38400d183885b54de433e43118d3032340f40cac8c0Chris Banes            // A pending invalidation will typically be resolved before the posted message
38500d183885b54de433e43118d3032340f40cac8c0Chris Banes            // would run normally in order to satisfy instance state restoration.
38600d183885b54de433e43118d3032340f40cac8c0Chris Banes            PanelFeatureState st = getPanelState(FEATURE_OPTIONS_PANEL, false);
3879b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes            if (!isDestroyed() && (st == null || st.menu == null)) {
38800d183885b54de433e43118d3032340f40cac8c0Chris Banes                invalidatePanelMenu(FEATURE_ACTION_BAR);
38900d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
3906386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes        }
3916386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    }
3926386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes
39349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    void onSubDecorInstalled() {}
39449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
39556fd50144df518461398a9b3397ee4842b346708Chris Banes    private void applyFixedSizeWindow() {
39649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        TypedArray a = mActivity.obtainStyledAttributes(R.styleable.Theme);
39756fd50144df518461398a9b3397ee4842b346708Chris Banes
39856fd50144df518461398a9b3397ee4842b346708Chris Banes        TypedValue mFixedWidthMajor = null;
39956fd50144df518461398a9b3397ee4842b346708Chris Banes        TypedValue mFixedWidthMinor = null;
40056fd50144df518461398a9b3397ee4842b346708Chris Banes        TypedValue mFixedHeightMajor = null;
40156fd50144df518461398a9b3397ee4842b346708Chris Banes        TypedValue mFixedHeightMinor = null;
40256fd50144df518461398a9b3397ee4842b346708Chris Banes
40349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        if (a.hasValue(R.styleable.Theme_windowFixedWidthMajor)) {
40456fd50144df518461398a9b3397ee4842b346708Chris Banes            if (mFixedWidthMajor == null) mFixedWidthMajor = new TypedValue();
40549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            a.getValue(R.styleable.Theme_windowFixedWidthMajor, mFixedWidthMajor);
40656fd50144df518461398a9b3397ee4842b346708Chris Banes        }
40749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        if (a.hasValue(R.styleable.Theme_windowFixedWidthMinor)) {
40856fd50144df518461398a9b3397ee4842b346708Chris Banes            if (mFixedWidthMinor == null) mFixedWidthMinor = new TypedValue();
40949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            a.getValue(R.styleable.Theme_windowFixedWidthMinor, mFixedWidthMinor);
41056fd50144df518461398a9b3397ee4842b346708Chris Banes        }
41149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        if (a.hasValue(R.styleable.Theme_windowFixedHeightMajor)) {
41256fd50144df518461398a9b3397ee4842b346708Chris Banes            if (mFixedHeightMajor == null) mFixedHeightMajor = new TypedValue();
41349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            a.getValue(R.styleable.Theme_windowFixedHeightMajor, mFixedHeightMajor);
41456fd50144df518461398a9b3397ee4842b346708Chris Banes        }
41549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        if (a.hasValue(R.styleable.Theme_windowFixedHeightMinor)) {
41656fd50144df518461398a9b3397ee4842b346708Chris Banes            if (mFixedHeightMinor == null) mFixedHeightMinor = new TypedValue();
41749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            a.getValue(R.styleable.Theme_windowFixedHeightMinor, mFixedHeightMinor);
41856fd50144df518461398a9b3397ee4842b346708Chris Banes        }
41956fd50144df518461398a9b3397ee4842b346708Chris Banes
42056fd50144df518461398a9b3397ee4842b346708Chris Banes        final DisplayMetrics metrics = mActivity.getResources().getDisplayMetrics();
42156fd50144df518461398a9b3397ee4842b346708Chris Banes        final boolean isPortrait = metrics.widthPixels < metrics.heightPixels;
42256fd50144df518461398a9b3397ee4842b346708Chris Banes        int w = ViewGroup.LayoutParams.MATCH_PARENT;
42356fd50144df518461398a9b3397ee4842b346708Chris Banes        int h = ViewGroup.LayoutParams.MATCH_PARENT;
42456fd50144df518461398a9b3397ee4842b346708Chris Banes
42556fd50144df518461398a9b3397ee4842b346708Chris Banes        final TypedValue tvw = isPortrait ? mFixedWidthMinor : mFixedWidthMajor;
42656fd50144df518461398a9b3397ee4842b346708Chris Banes        if (tvw != null && tvw.type != TypedValue.TYPE_NULL) {
42756fd50144df518461398a9b3397ee4842b346708Chris Banes            if (tvw.type == TypedValue.TYPE_DIMENSION) {
42856fd50144df518461398a9b3397ee4842b346708Chris Banes                w = (int) tvw.getDimension(metrics);
42956fd50144df518461398a9b3397ee4842b346708Chris Banes            } else if (tvw.type == TypedValue.TYPE_FRACTION) {
43056fd50144df518461398a9b3397ee4842b346708Chris Banes                w = (int) tvw.getFraction(metrics.widthPixels, metrics.widthPixels);
43156fd50144df518461398a9b3397ee4842b346708Chris Banes            }
43256fd50144df518461398a9b3397ee4842b346708Chris Banes        }
43356fd50144df518461398a9b3397ee4842b346708Chris Banes
43456fd50144df518461398a9b3397ee4842b346708Chris Banes        final TypedValue tvh = isPortrait ? mFixedHeightMajor : mFixedHeightMinor;
43556fd50144df518461398a9b3397ee4842b346708Chris Banes        if (tvh != null && tvh.type != TypedValue.TYPE_NULL) {
43656fd50144df518461398a9b3397ee4842b346708Chris Banes            if (tvh.type == TypedValue.TYPE_DIMENSION) {
43756fd50144df518461398a9b3397ee4842b346708Chris Banes                h = (int) tvh.getDimension(metrics);
43856fd50144df518461398a9b3397ee4842b346708Chris Banes            } else if (tvh.type == TypedValue.TYPE_FRACTION) {
43956fd50144df518461398a9b3397ee4842b346708Chris Banes                h = (int) tvh.getFraction(metrics.heightPixels, metrics.heightPixels);
44056fd50144df518461398a9b3397ee4842b346708Chris Banes            }
44156fd50144df518461398a9b3397ee4842b346708Chris Banes        }
44256fd50144df518461398a9b3397ee4842b346708Chris Banes
44356fd50144df518461398a9b3397ee4842b346708Chris Banes        if (w != ViewGroup.LayoutParams.MATCH_PARENT || h != ViewGroup.LayoutParams.MATCH_PARENT) {
44456fd50144df518461398a9b3397ee4842b346708Chris Banes            mActivity.getWindow().setLayout(w, h);
44556fd50144df518461398a9b3397ee4842b346708Chris Banes        }
44656fd50144df518461398a9b3397ee4842b346708Chris Banes
44756fd50144df518461398a9b3397ee4842b346708Chris Banes        a.recycle();
44856fd50144df518461398a9b3397ee4842b346708Chris Banes    }
44956fd50144df518461398a9b3397ee4842b346708Chris Banes
4506386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    @Override
451ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes    public boolean supportRequestWindowFeature(int featureId) {
4526386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes        switch (featureId) {
45300d183885b54de433e43118d3032340f40cac8c0Chris Banes            case FEATURE_ACTION_BAR:
454cc7aada3ee922cfb38eeb36ee696cc73dcbae0a4Chris Banes                throwFeatureRequestIfSubDecorInstalled();
4555a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes                mHasActionBar = true;
4566386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes                return true;
45700d183885b54de433e43118d3032340f40cac8c0Chris Banes            case FEATURE_ACTION_BAR_OVERLAY:
458cc7aada3ee922cfb38eeb36ee696cc73dcbae0a4Chris Banes                throwFeatureRequestIfSubDecorInstalled();
4595a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes                mOverlayActionBar = true;
4606386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes                return true;
46100d183885b54de433e43118d3032340f40cac8c0Chris Banes            case FEATURE_ACTION_MODE_OVERLAY:
462cc7aada3ee922cfb38eeb36ee696cc73dcbae0a4Chris Banes                throwFeatureRequestIfSubDecorInstalled();
463de9f38cc4a30b33ac46b105edf470fbc4a044e99Chris Banes                mOverlayActionMode = true;
464de9f38cc4a30b33ac46b105edf470fbc4a044e99Chris Banes                return true;
465ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes            case Window.FEATURE_PROGRESS:
466cc7aada3ee922cfb38eeb36ee696cc73dcbae0a4Chris Banes                throwFeatureRequestIfSubDecorInstalled();
467ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes                mFeatureProgress = true;
468ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes                return true;
469ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes            case Window.FEATURE_INDETERMINATE_PROGRESS:
470cc7aada3ee922cfb38eeb36ee696cc73dcbae0a4Chris Banes                throwFeatureRequestIfSubDecorInstalled();
471ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes                mFeatureIndeterminateProgress = true;
472ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes                return true;
4736386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes        }
474cc7aada3ee922cfb38eeb36ee696cc73dcbae0a4Chris Banes
475cc7aada3ee922cfb38eeb36ee696cc73dcbae0a4Chris Banes        return mActivity.requestWindowFeature(featureId);
4766386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    }
4776386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes
4786386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    @Override
479904507029cd8ea2d070b6df0911b2dd36b7075a6Chris Banes    public void onTitleChanged(CharSequence title) {
48049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        if (mDecorContentParent != null) {
48149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            mDecorContentParent.setWindowTitle(title);
48249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        } else if (getSupportActionBar() != null) {
483ca58f2ce7cd9f0e0f2c4a46c3bcc98013209f6b3Chris Banes            getSupportActionBar().setWindowTitle(title);
484f53c7bf3146bf9bcba46324f9f06449df475be36Chris Banes        } else {
485f53c7bf3146bf9bcba46324f9f06449df475be36Chris Banes            mTitleToSet = title;
4866386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes        }
4876386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    }
4886386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes
4896386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    @Override
4906386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    public View onCreatePanelView(int featureId) {
49157c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes        View panelView = null;
49257c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes
49357c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes        // If there isn't an action mode currently being displayed
49400d183885b54de433e43118d3032340f40cac8c0Chris Banes        if (mActionMode == null) {
49557c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes            // Let our window callback try first
49657c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes            WindowCallback callback = getWindowCallback();
49757c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes            if (callback != null) {
49857c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes                panelView = callback.onCreatePanelView(featureId);
49957c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes            }
50057c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes
5010b7aedbbe43b9d4af60cc4ebd4994c74ebe6bc5fChris Banes            if (panelView == null && mToolbarListMenuPresenter == null) {
5020b7aedbbe43b9d4af60cc4ebd4994c74ebe6bc5fChris Banes                // Only check our panels if the callback didn't return a view and we do not have
5030b7aedbbe43b9d4af60cc4ebd4994c74ebe6bc5fChris Banes                // a ListMenuPresenter for Toolbars. We check for the ListMenuPresenter because
5040b7aedbbe43b9d4af60cc4ebd4994c74ebe6bc5fChris Banes                // once created, Toolbar needs to control the panel view regardless of whether it
5050b7aedbbe43b9d4af60cc4ebd4994c74ebe6bc5fChris Banes                // has any non-action items to display.
50657c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes                PanelFeatureState st = getPanelState(featureId, true);
50757c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes                openPanel(st, null);
50857c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes                if (st.isOpen) {
50957c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes                    panelView = st.shownPanelView;
51057c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes                }
51157c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes            }
5126386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes        }
51357c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes        return panelView;
5146386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    }
5156386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes
5166386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    @Override
51730837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell    public boolean onCreatePanelMenu(int featureId, Menu menu) {
51830837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        if (featureId != Window.FEATURE_OPTIONS_PANEL) {
519a6e86333cb4de18fc9b86746a49643e213db7c18Chris Banes            return getWindowCallback().onCreatePanelMenu(featureId, menu);
5206386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes        }
5216386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes        return false;
5226386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    }
5236386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes
5246386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    @Override
52530837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell    public boolean onPreparePanel(int featureId, View view, Menu menu) {
52630837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell        if (featureId != Window.FEATURE_OPTIONS_PANEL) {
527a6e86333cb4de18fc9b86746a49643e213db7c18Chris Banes            return getWindowCallback().onPreparePanel(featureId, view, menu);
5286386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes        }
5296386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes        return false;
5306386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    }
5316386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes
5326386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    @Override
53300d183885b54de433e43118d3032340f40cac8c0Chris Banes    public void onPanelClosed(final int featureId, Menu menu) {
53400d183885b54de433e43118d3032340f40cac8c0Chris Banes        PanelFeatureState st = getPanelState(featureId, false);
53500d183885b54de433e43118d3032340f40cac8c0Chris Banes        if (st != null) {
53600d183885b54de433e43118d3032340f40cac8c0Chris Banes            // If we know about the feature id, update it's state
53700d183885b54de433e43118d3032340f40cac8c0Chris Banes            closePanel(st, false);
53803fc11b659da1645507062bddda450136e13af35Chris Banes        }
53900d183885b54de433e43118d3032340f40cac8c0Chris Banes
54000d183885b54de433e43118d3032340f40cac8c0Chris Banes        if (featureId == FEATURE_ACTION_BAR) {
54100d183885b54de433e43118d3032340f40cac8c0Chris Banes            ActionBar ab = getSupportActionBar();
54200d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (ab != null) {
54300d183885b54de433e43118d3032340f40cac8c0Chris Banes                ab.dispatchMenuVisibilityChanged(false);
54400d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
5459b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes        } else if (!isDestroyed()) {
54600d183885b54de433e43118d3032340f40cac8c0Chris Banes            // Only pass it through to the Activity's super impl if it's not ACTION_BAR. This is
54700d183885b54de433e43118d3032340f40cac8c0Chris Banes            // because ICS+ will try and create a framework action bar due to this call
548c4b9e0cb716a4caff218b27d86f37ef8117d257bChris Banes            mActivity.superOnPanelClosed(featureId, menu);
549c4b9e0cb716a4caff218b27d86f37ef8117d257bChris Banes        }
550c4b9e0cb716a4caff218b27d86f37ef8117d257bChris Banes    }
551c4b9e0cb716a4caff218b27d86f37ef8117d257bChris Banes
552c4b9e0cb716a4caff218b27d86f37ef8117d257bChris Banes    @Override
55300d183885b54de433e43118d3032340f40cac8c0Chris Banes    boolean onMenuOpened(final int featureId, Menu menu) {
55400d183885b54de433e43118d3032340f40cac8c0Chris Banes        if (featureId == FEATURE_ACTION_BAR) {
55500d183885b54de433e43118d3032340f40cac8c0Chris Banes            ActionBar ab = getSupportActionBar();
55600d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (ab != null) {
55700d183885b54de433e43118d3032340f40cac8c0Chris Banes                ab.dispatchMenuVisibilityChanged(true);
55800d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
55900d183885b54de433e43118d3032340f40cac8c0Chris Banes            return true;
56000d183885b54de433e43118d3032340f40cac8c0Chris Banes        } else {
561c4b9e0cb716a4caff218b27d86f37ef8117d257bChris Banes            return mActivity.superOnMenuOpened(featureId, menu);
562c4b9e0cb716a4caff218b27d86f37ef8117d257bChris Banes        }
56303fc11b659da1645507062bddda450136e13af35Chris Banes    }
56403fc11b659da1645507062bddda450136e13af35Chris Banes
56503fc11b659da1645507062bddda450136e13af35Chris Banes    @Override
5666386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    public boolean onMenuItemSelected(MenuBuilder menu, MenuItem item) {
5679b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes        final WindowCallback cb = getWindowCallback();
5689b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes        if (cb != null && !isDestroyed()) {
5699b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes            final PanelFeatureState panel = findMenuPanel(menu.getRootMenu());
5709b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes            if (panel != null) {
5719b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes                return cb.onMenuItemSelected(panel.featureId, item);
5729b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes            }
5739b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes        }
5749b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes        return false;
5756386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    }
5766386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes
5776386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    @Override
5786386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    public void onMenuModeChange(MenuBuilder menu) {
5796386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes        reopenMenu(menu, true);
5806386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    }
5816386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes
5826386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    @Override
583d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes    public ActionMode startSupportActionMode(ActionMode.Callback callback) {
584d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        if (callback == null) {
585d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes            throw new IllegalArgumentException("ActionMode callback can not be null.");
586d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        }
587d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes
588d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        if (mActionMode != null) {
589d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes            mActionMode.finish();
590d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        }
591d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes
592d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        final ActionMode.Callback wrappedCallback = new ActionModeCallbackWrapper(callback);
593d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes
59449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        ActionBar ab = getSupportActionBar();
595d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        if (ab != null) {
5965a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes            mActionMode = ab.startActionMode(wrappedCallback);
5970bf48858279237f95d6aad565a074490745491cdChris Banes            if (mActionMode != null) {
5980bf48858279237f95d6aad565a074490745491cdChris Banes                mActivity.onSupportActionModeStarted(mActionMode);
5990bf48858279237f95d6aad565a074490745491cdChris Banes            }
600d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        }
601d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes
6020bf48858279237f95d6aad565a074490745491cdChris Banes        if (mActionMode == null) {
6030bf48858279237f95d6aad565a074490745491cdChris Banes            // If the action bar didn't provide an action mode, start the emulated window one
6040bf48858279237f95d6aad565a074490745491cdChris Banes            mActionMode = startSupportActionModeFromWindow(wrappedCallback);
605d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        }
6060bf48858279237f95d6aad565a074490745491cdChris Banes
607d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        return mActionMode;
608d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes    }
609d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes
610d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes    @Override
6116386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    public void supportInvalidateOptionsMenu() {
612f2045f06bdfc9e2cc40a734e41e45d11adf2bc23Chris Banes        final ActionBar ab = getSupportActionBar();
613f2045f06bdfc9e2cc40a734e41e45d11adf2bc23Chris Banes        if (ab != null && ab.invalidateOptionsMenu()) return;
614f2045f06bdfc9e2cc40a734e41e45d11adf2bc23Chris Banes
61500d183885b54de433e43118d3032340f40cac8c0Chris Banes        invalidatePanelMenu(FEATURE_OPTIONS_PANEL);
6166386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes    }
6176386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes
6184c2a95906254748cb9a843b061288265d6e185a9Chris Banes    @Override
6194c2a95906254748cb9a843b061288265d6e185a9Chris Banes    ActionMode startSupportActionModeFromWindow(ActionMode.Callback callback) {
6204c2a95906254748cb9a843b061288265d6e185a9Chris Banes        if (mActionMode != null) {
6214c2a95906254748cb9a843b061288265d6e185a9Chris Banes            mActionMode.finish();
6224c2a95906254748cb9a843b061288265d6e185a9Chris Banes        }
6234c2a95906254748cb9a843b061288265d6e185a9Chris Banes
6244c2a95906254748cb9a843b061288265d6e185a9Chris Banes        final ActionMode.Callback wrappedCallback = new ActionModeCallbackWrapper(callback);
6254bd5cbd6ca4f1e5ed43217b808068a48f937feabChris Banes        final Context context = getActionBarThemedContext();
6264c2a95906254748cb9a843b061288265d6e185a9Chris Banes
6274c2a95906254748cb9a843b061288265d6e185a9Chris Banes        if (mActionModeView == null) {
6284c2a95906254748cb9a843b061288265d6e185a9Chris Banes            if (mIsFloating) {
6294bd5cbd6ca4f1e5ed43217b808068a48f937feabChris Banes                mActionModeView = new ActionBarContextView(context);
6304bd5cbd6ca4f1e5ed43217b808068a48f937feabChris Banes                mActionModePopup = new PopupWindow(context, null,
6314c2a95906254748cb9a843b061288265d6e185a9Chris Banes                        R.attr.actionModePopupWindowStyle);
6324c2a95906254748cb9a843b061288265d6e185a9Chris Banes                mActionModePopup.setContentView(mActionModeView);
6334c2a95906254748cb9a843b061288265d6e185a9Chris Banes                mActionModePopup.setWidth(ViewGroup.LayoutParams.MATCH_PARENT);
6344c2a95906254748cb9a843b061288265d6e185a9Chris Banes
6354c2a95906254748cb9a843b061288265d6e185a9Chris Banes                TypedValue heightValue = new TypedValue();
6364c2a95906254748cb9a843b061288265d6e185a9Chris Banes                mActivity.getTheme().resolveAttribute(R.attr.actionBarSize, heightValue, true);
6374c2a95906254748cb9a843b061288265d6e185a9Chris Banes                final int height = TypedValue.complexToDimensionPixelSize(heightValue.data,
6384c2a95906254748cb9a843b061288265d6e185a9Chris Banes                        mActivity.getResources().getDisplayMetrics());
6394c2a95906254748cb9a843b061288265d6e185a9Chris Banes                mActionModeView.setContentHeight(height);
6404c2a95906254748cb9a843b061288265d6e185a9Chris Banes                mActionModePopup.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
6414c2a95906254748cb9a843b061288265d6e185a9Chris Banes                mShowActionModePopup = new Runnable() {
6424c2a95906254748cb9a843b061288265d6e185a9Chris Banes                    public void run() {
6434c2a95906254748cb9a843b061288265d6e185a9Chris Banes                        mActionModePopup.showAtLocation(
6444c2a95906254748cb9a843b061288265d6e185a9Chris Banes                                mActionModeView,
6454c2a95906254748cb9a843b061288265d6e185a9Chris Banes                                Gravity.TOP | Gravity.FILL_HORIZONTAL, 0, 0);
6464c2a95906254748cb9a843b061288265d6e185a9Chris Banes                    }
6474c2a95906254748cb9a843b061288265d6e185a9Chris Banes                };
6484c2a95906254748cb9a843b061288265d6e185a9Chris Banes            } else {
6494bd5cbd6ca4f1e5ed43217b808068a48f937feabChris Banes                ViewStubCompat stub = (ViewStubCompat) mActivity
6504bd5cbd6ca4f1e5ed43217b808068a48f937feabChris Banes                        .findViewById(R.id.action_mode_bar_stub);
6514c2a95906254748cb9a843b061288265d6e185a9Chris Banes                if (stub != null) {
6524bd5cbd6ca4f1e5ed43217b808068a48f937feabChris Banes                    // Set the layout inflater so that it is inflated with the action bar's context
6534bd5cbd6ca4f1e5ed43217b808068a48f937feabChris Banes                    stub.setLayoutInflater(LayoutInflater.from(context));
6544c2a95906254748cb9a843b061288265d6e185a9Chris Banes                    mActionModeView = (ActionBarContextView) stub.inflate();
6554c2a95906254748cb9a843b061288265d6e185a9Chris Banes                }
6564c2a95906254748cb9a843b061288265d6e185a9Chris Banes            }
6574c2a95906254748cb9a843b061288265d6e185a9Chris Banes        }
6584c2a95906254748cb9a843b061288265d6e185a9Chris Banes
6594c2a95906254748cb9a843b061288265d6e185a9Chris Banes        if (mActionModeView != null) {
6604c2a95906254748cb9a843b061288265d6e185a9Chris Banes            mActionModeView.killMode();
6614bd5cbd6ca4f1e5ed43217b808068a48f937feabChris Banes            ActionMode mode = new StandaloneActionMode(context, mActionModeView, wrappedCallback,
6624c2a95906254748cb9a843b061288265d6e185a9Chris Banes                    mActionModePopup == null);
6634c2a95906254748cb9a843b061288265d6e185a9Chris Banes            if (callback.onCreateActionMode(mode, mode.getMenu())) {
6644c2a95906254748cb9a843b061288265d6e185a9Chris Banes                mode.invalidate();
6654c2a95906254748cb9a843b061288265d6e185a9Chris Banes                mActionModeView.initForMode(mode);
6664c2a95906254748cb9a843b061288265d6e185a9Chris Banes                mActionModeView.setVisibility(View.VISIBLE);
6674c2a95906254748cb9a843b061288265d6e185a9Chris Banes                mActionMode = mode;
6684c2a95906254748cb9a843b061288265d6e185a9Chris Banes                if (mActionModePopup != null) {
6694c2a95906254748cb9a843b061288265d6e185a9Chris Banes                    mActivity.getWindow().getDecorView().post(mShowActionModePopup);
6704c2a95906254748cb9a843b061288265d6e185a9Chris Banes                }
6714c2a95906254748cb9a843b061288265d6e185a9Chris Banes                mActionModeView.sendAccessibilityEvent(
6724c2a95906254748cb9a843b061288265d6e185a9Chris Banes                        AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
673ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes
674ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                if (mActionModeView.getParent() != null) {
675ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                    ViewCompat.requestApplyInsets((View) mActionModeView.getParent());
676ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                }
6774c2a95906254748cb9a843b061288265d6e185a9Chris Banes            } else {
6784c2a95906254748cb9a843b061288265d6e185a9Chris Banes                mActionMode = null;
6794c2a95906254748cb9a843b061288265d6e185a9Chris Banes            }
6804c2a95906254748cb9a843b061288265d6e185a9Chris Banes        }
6814c2a95906254748cb9a843b061288265d6e185a9Chris Banes        if (mActionMode != null && mActivity != null) {
6824c2a95906254748cb9a843b061288265d6e185a9Chris Banes            mActivity.onSupportActionModeStarted(mActionMode);
6834c2a95906254748cb9a843b061288265d6e185a9Chris Banes        }
6844c2a95906254748cb9a843b061288265d6e185a9Chris Banes        return mActionMode;
6854c2a95906254748cb9a843b061288265d6e185a9Chris Banes    }
6864c2a95906254748cb9a843b061288265d6e185a9Chris Banes
687d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes    @Override
688d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes    public boolean onBackPressed() {
689d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        // Back cancels action modes first.
690d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        if (mActionMode != null) {
691d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes            mActionMode.finish();
692d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes            return true;
693d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        }
694d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes
695d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        // Next collapse any expanded action views.
69649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        ActionBar ab = getSupportActionBar();
69749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        if (ab != null && ab.collapseActionView()) {
698d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes            return true;
699d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        }
700d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes
701d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        return false;
702d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes    }
703d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes
704d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes    @Override
705ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes    void setSupportProgressBarVisibility(boolean visible) {
706c132781c9ed6354e451c647737013600b0da2425Chris Banes        // noop
707ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes    }
708ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes
709ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes    @Override
710ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes    void setSupportProgressBarIndeterminateVisibility(boolean visible) {
711c132781c9ed6354e451c647737013600b0da2425Chris Banes        // noop
712ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes    }
713ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes
714ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes    @Override
715ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes    void setSupportProgressBarIndeterminate(boolean indeterminate) {
716c132781c9ed6354e451c647737013600b0da2425Chris Banes        // noop
717ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes    }
718ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes
719ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes    @Override
720ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes    void setSupportProgress(int progress) {
721c132781c9ed6354e451c647737013600b0da2425Chris Banes        // noop
722ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes    }
723ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes
72445d973fcc4c43f5ea00cddd3d9b947d9e8d8fc4eChris Banes    @Override
725f4a93d160fc696de65e103e7e078106ea8f818faChris Banes    int getHomeAsUpIndicatorAttrId() {
726f4a93d160fc696de65e103e7e078106ea8f818faChris Banes        return R.attr.homeAsUpIndicator;
72745d973fcc4c43f5ea00cddd3d9b947d9e8d8fc4eChris Banes    }
72845d973fcc4c43f5ea00cddd3d9b947d9e8d8fc4eChris Banes
729dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes    @Override
73000d183885b54de433e43118d3032340f40cac8c0Chris Banes    boolean onKeyShortcut(int keyCode, KeyEvent ev) {
731d15ee7df01f2f48b536a610c4739f33b226d3f81Chris Banes        // Let the Action Bar have a chance at handling the shortcut
732d15ee7df01f2f48b536a610c4739f33b226d3f81Chris Banes        ActionBar ab = getSupportActionBar();
733d15ee7df01f2f48b536a610c4739f33b226d3f81Chris Banes        if (ab != null && ab.onKeyShortcut(keyCode, ev)) {
734d15ee7df01f2f48b536a610c4739f33b226d3f81Chris Banes            return true;
735d15ee7df01f2f48b536a610c4739f33b226d3f81Chris Banes        }
736d15ee7df01f2f48b536a610c4739f33b226d3f81Chris Banes
737dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes        // If the panel is already prepared, then perform the shortcut using it.
73800d183885b54de433e43118d3032340f40cac8c0Chris Banes        boolean handled;
73900d183885b54de433e43118d3032340f40cac8c0Chris Banes        if (mPreparedPanel != null) {
74000d183885b54de433e43118d3032340f40cac8c0Chris Banes            handled = performPanelShortcut(mPreparedPanel, ev.getKeyCode(), ev,
74100d183885b54de433e43118d3032340f40cac8c0Chris Banes                    Menu.FLAG_PERFORM_NO_CLOSE);
74200d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (handled) {
74300d183885b54de433e43118d3032340f40cac8c0Chris Banes                if (mPreparedPanel != null) {
74400d183885b54de433e43118d3032340f40cac8c0Chris Banes                    mPreparedPanel.isHandled = true;
74500d183885b54de433e43118d3032340f40cac8c0Chris Banes                }
74600d183885b54de433e43118d3032340f40cac8c0Chris Banes                return true;
74700d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
74800d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
74900d183885b54de433e43118d3032340f40cac8c0Chris Banes
75000d183885b54de433e43118d3032340f40cac8c0Chris Banes        // If the panel is not prepared, then we may be trying to handle a shortcut key
75100d183885b54de433e43118d3032340f40cac8c0Chris Banes        // combination such as Control+C.  Temporarily prepare the panel then mark it
75200d183885b54de433e43118d3032340f40cac8c0Chris Banes        // unprepared again when finished to ensure that the panel will again be prepared
75300d183885b54de433e43118d3032340f40cac8c0Chris Banes        // the next time it is shown for real.
75400d183885b54de433e43118d3032340f40cac8c0Chris Banes        if (mPreparedPanel == null) {
75500d183885b54de433e43118d3032340f40cac8c0Chris Banes            PanelFeatureState st = getPanelState(FEATURE_OPTIONS_PANEL, true);
75600d183885b54de433e43118d3032340f40cac8c0Chris Banes            preparePanel(st, ev);
75700d183885b54de433e43118d3032340f40cac8c0Chris Banes            handled = performPanelShortcut(st, ev.getKeyCode(), ev, Menu.FLAG_PERFORM_NO_CLOSE);
75800d183885b54de433e43118d3032340f40cac8c0Chris Banes            st.isPrepared = false;
75900d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (handled) {
76000d183885b54de433e43118d3032340f40cac8c0Chris Banes                return true;
76100d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
76200d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
76300d183885b54de433e43118d3032340f40cac8c0Chris Banes        return false;
764dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes    }
765dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes
766dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes    @Override
767dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes    boolean onKeyDown(int keyCode, KeyEvent event) {
768dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes        // On API v7-10 we need to manually call onKeyShortcut() as this is not called
769dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes        // from the Activity
770dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes        return onKeyShortcut(keyCode, event);
771dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes    }
772dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes
773469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banes    @Override
7741c7a431337d8794b8c72291a281d7ebed0d2b397Chris Banes    View createView(final String name, @NonNull Context context, @NonNull AttributeSet attrs) {
775469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banes        if (Build.VERSION.SDK_INT < 21) {
776469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banes            // If we're running pre-L, we need to 'inject' our tint aware Views in place of the
777469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banes            // standard framework versions
778469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banes            switch (name) {
779469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banes                case "EditText":
7801c7a431337d8794b8c72291a281d7ebed0d2b397Chris Banes                    return new TintEditText(context, attrs);
781415f740df4981ef2f5fb462a50c7cf095cc21128Chris Banes                case "Spinner":
7821c7a431337d8794b8c72291a281d7ebed0d2b397Chris Banes                    return new TintSpinner(context, attrs);
783415f740df4981ef2f5fb462a50c7cf095cc21128Chris Banes                case "CheckBox":
7841c7a431337d8794b8c72291a281d7ebed0d2b397Chris Banes                    return new TintCheckBox(context, attrs);
785415f740df4981ef2f5fb462a50c7cf095cc21128Chris Banes                case "RadioButton":
7861c7a431337d8794b8c72291a281d7ebed0d2b397Chris Banes                    return new TintRadioButton(context, attrs);
787415f740df4981ef2f5fb462a50c7cf095cc21128Chris Banes                case "CheckedTextView":
7881c7a431337d8794b8c72291a281d7ebed0d2b397Chris Banes                    return new TintCheckedTextView(context, attrs);
789012047c60d03e61498955b7fa3e9cb9b409fbad8Chris Banes                case "AutoCompleteTextView":
7901c7a431337d8794b8c72291a281d7ebed0d2b397Chris Banes                    return new TintAutoCompleteTextView(context, attrs);
791012047c60d03e61498955b7fa3e9cb9b409fbad8Chris Banes                case "MultiAutoCompleteTextView":
7921c7a431337d8794b8c72291a281d7ebed0d2b397Chris Banes                    return new TintMultiAutoCompleteTextView(context, attrs);
793a9585dae398a69dd67797e7ca86f44ffcabd9e86Chris Banes                case "RatingBar":
794a9585dae398a69dd67797e7ca86f44ffcabd9e86Chris Banes                    return new TintRatingBar(context, attrs);
795a9585dae398a69dd67797e7ca86f44ffcabd9e86Chris Banes                case "Button":
796a9585dae398a69dd67797e7ca86f44ffcabd9e86Chris Banes                    return new TintButton(context, attrs);
797469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banes            }
798469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banes        }
799469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banes        return null;
800469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banes    }
801469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banes
80200d183885b54de433e43118d3032340f40cac8c0Chris Banes    private void openPanel(int featureId, KeyEvent event) {
80300d183885b54de433e43118d3032340f40cac8c0Chris Banes        if (featureId == FEATURE_OPTIONS_PANEL && mDecorContentParent != null &&
80400d183885b54de433e43118d3032340f40cac8c0Chris Banes                mDecorContentParent.canShowOverflowMenu() &&
80500d183885b54de433e43118d3032340f40cac8c0Chris Banes                !ViewConfigurationCompat.hasPermanentMenuKey(ViewConfiguration.get(mActivity))) {
80600d183885b54de433e43118d3032340f40cac8c0Chris Banes            mDecorContentParent.showOverflowMenu();
80700d183885b54de433e43118d3032340f40cac8c0Chris Banes        } else {
80800d183885b54de433e43118d3032340f40cac8c0Chris Banes            openPanel(getPanelState(featureId, true), event);
80900d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
81000d183885b54de433e43118d3032340f40cac8c0Chris Banes    }
81100d183885b54de433e43118d3032340f40cac8c0Chris Banes
81200d183885b54de433e43118d3032340f40cac8c0Chris Banes    private void openPanel(final PanelFeatureState st, KeyEvent event) {
81300d183885b54de433e43118d3032340f40cac8c0Chris Banes        // Already open, return
8149b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes        if (st.isOpen || isDestroyed()) {
81500d183885b54de433e43118d3032340f40cac8c0Chris Banes            return;
81600d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
81700d183885b54de433e43118d3032340f40cac8c0Chris Banes
81800d183885b54de433e43118d3032340f40cac8c0Chris Banes        // Don't open an options panel for honeycomb apps on xlarge devices.
81900d183885b54de433e43118d3032340f40cac8c0Chris Banes        // (The app should be using an action bar for menu items.)
82000d183885b54de433e43118d3032340f40cac8c0Chris Banes        if (st.featureId == FEATURE_OPTIONS_PANEL) {
82100d183885b54de433e43118d3032340f40cac8c0Chris Banes            Context context = mActivity;
82200d183885b54de433e43118d3032340f40cac8c0Chris Banes            Configuration config = context.getResources().getConfiguration();
82300d183885b54de433e43118d3032340f40cac8c0Chris Banes            boolean isXLarge = (config.screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) ==
82400d183885b54de433e43118d3032340f40cac8c0Chris Banes                    Configuration.SCREENLAYOUT_SIZE_XLARGE;
82500d183885b54de433e43118d3032340f40cac8c0Chris Banes            boolean isHoneycombApp = context.getApplicationInfo().targetSdkVersion >=
82600d183885b54de433e43118d3032340f40cac8c0Chris Banes                    android.os.Build.VERSION_CODES.HONEYCOMB;
82700d183885b54de433e43118d3032340f40cac8c0Chris Banes
82800d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (isXLarge && isHoneycombApp) {
82900d183885b54de433e43118d3032340f40cac8c0Chris Banes                return;
83000d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
83100d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
83200d183885b54de433e43118d3032340f40cac8c0Chris Banes
83300d183885b54de433e43118d3032340f40cac8c0Chris Banes        WindowCallback cb = getWindowCallback();
83400d183885b54de433e43118d3032340f40cac8c0Chris Banes        if ((cb != null) && (!cb.onMenuOpened(st.featureId, st.menu))) {
83500d183885b54de433e43118d3032340f40cac8c0Chris Banes            // Callback doesn't want the menu to open, reset any state
83600d183885b54de433e43118d3032340f40cac8c0Chris Banes            closePanel(st, true);
83700d183885b54de433e43118d3032340f40cac8c0Chris Banes            return;
83800d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
83900d183885b54de433e43118d3032340f40cac8c0Chris Banes
84000d183885b54de433e43118d3032340f40cac8c0Chris Banes        // Prepare panel (should have been done before, but just in case)
84100d183885b54de433e43118d3032340f40cac8c0Chris Banes        if (!preparePanel(st, event)) {
84200d183885b54de433e43118d3032340f40cac8c0Chris Banes            return;
84300d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
84400d183885b54de433e43118d3032340f40cac8c0Chris Banes
84500d183885b54de433e43118d3032340f40cac8c0Chris Banes        if (st.decorView == null || st.refreshDecorView) {
84600d183885b54de433e43118d3032340f40cac8c0Chris Banes            initializePanelDecor(st);
84700d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
84800d183885b54de433e43118d3032340f40cac8c0Chris Banes
84900d183885b54de433e43118d3032340f40cac8c0Chris Banes        // This will populate st.shownPanelView
85000d183885b54de433e43118d3032340f40cac8c0Chris Banes        if (!initializePanelContent(st) || !st.hasPanelItems()) {
85100d183885b54de433e43118d3032340f40cac8c0Chris Banes            return;
85200d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
85300d183885b54de433e43118d3032340f40cac8c0Chris Banes
85400d183885b54de433e43118d3032340f40cac8c0Chris Banes        st.isHandled = false;
85500d183885b54de433e43118d3032340f40cac8c0Chris Banes        st.isOpen = true;
85600d183885b54de433e43118d3032340f40cac8c0Chris Banes    }
85700d183885b54de433e43118d3032340f40cac8c0Chris Banes
85800d183885b54de433e43118d3032340f40cac8c0Chris Banes    private void initializePanelDecor(PanelFeatureState st) {
85900d183885b54de433e43118d3032340f40cac8c0Chris Banes        st.decorView = mWindowDecor;
86057c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes        st.setStyle(getActionBarThemedContext());
86100d183885b54de433e43118d3032340f40cac8c0Chris Banes    }
86200d183885b54de433e43118d3032340f40cac8c0Chris Banes
86300d183885b54de433e43118d3032340f40cac8c0Chris Banes    private void reopenMenu(MenuBuilder menu, boolean toggleMenuMode) {
86400d183885b54de433e43118d3032340f40cac8c0Chris Banes        if (mDecorContentParent != null && mDecorContentParent.canShowOverflowMenu() &&
86500d183885b54de433e43118d3032340f40cac8c0Chris Banes                (!ViewConfigurationCompat.hasPermanentMenuKey(ViewConfiguration.get(mActivity)) ||
86600d183885b54de433e43118d3032340f40cac8c0Chris Banes                        mDecorContentParent.isOverflowMenuShowPending())) {
8679b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes
8689b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes            WindowCallback cb = getWindowCallback();
8699b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes
87000d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (!mDecorContentParent.isOverflowMenuShowing() || !toggleMenuMode) {
8719b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes                if (cb != null && !isDestroyed()) {
8729b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes                    // If we have a menu invalidation pending, do it now.
8739b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes                    if (mInvalidatePanelMenuPosted &&
8749b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes                            (mInvalidatePanelMenuFeatures & (1 << FEATURE_OPTIONS_PANEL)) != 0) {
8759b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes                        mWindowDecor.removeCallbacks(mInvalidatePanelMenuRunnable);
8769b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes                        mInvalidatePanelMenuRunnable.run();
8779b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes                    }
87800d183885b54de433e43118d3032340f40cac8c0Chris Banes
8799b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes                    final PanelFeatureState st = getPanelState(FEATURE_OPTIONS_PANEL, true);
88000d183885b54de433e43118d3032340f40cac8c0Chris Banes
8819b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes                    // If we don't have a menu or we're waiting for a full content refresh,
8829b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes                    // forget it. This is a lingering event that no longer matters.
8839b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes                    if (st.menu != null && !st.refreshMenuContent &&
8849b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes                            cb.onPreparePanel(FEATURE_OPTIONS_PANEL, null, st.menu)) {
8859b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes                        cb.onMenuOpened(FEATURE_ACTION_BAR, st.menu);
8869b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes                        mDecorContentParent.showOverflowMenu();
8879b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes                    }
88800d183885b54de433e43118d3032340f40cac8c0Chris Banes                }
88900d183885b54de433e43118d3032340f40cac8c0Chris Banes            } else {
89000d183885b54de433e43118d3032340f40cac8c0Chris Banes                mDecorContentParent.hideOverflowMenu();
8919b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes                if (!isDestroyed()) {
8929b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes                    final PanelFeatureState st = getPanelState(FEATURE_OPTIONS_PANEL, true);
8939b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes                    mActivity.onPanelClosed(FEATURE_ACTION_BAR, st.menu);
8949b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes                }
89500d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
89600d183885b54de433e43118d3032340f40cac8c0Chris Banes            return;
89700d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
89800d183885b54de433e43118d3032340f40cac8c0Chris Banes
89900d183885b54de433e43118d3032340f40cac8c0Chris Banes        PanelFeatureState st = getPanelState(FEATURE_OPTIONS_PANEL, true);
90000d183885b54de433e43118d3032340f40cac8c0Chris Banes
90100d183885b54de433e43118d3032340f40cac8c0Chris Banes        st.refreshDecorView = true;
90200d183885b54de433e43118d3032340f40cac8c0Chris Banes        closePanel(st, false);
90300d183885b54de433e43118d3032340f40cac8c0Chris Banes
90400d183885b54de433e43118d3032340f40cac8c0Chris Banes        openPanel(st, null);
90500d183885b54de433e43118d3032340f40cac8c0Chris Banes    }
90600d183885b54de433e43118d3032340f40cac8c0Chris Banes
90700d183885b54de433e43118d3032340f40cac8c0Chris Banes    private boolean initializePanelMenu(final PanelFeatureState st) {
90861c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes        Context context = mActivity;
90961c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes
91000d183885b54de433e43118d3032340f40cac8c0Chris Banes        // If we have an action bar, initialize the menu with the right theme.
91100d183885b54de433e43118d3032340f40cac8c0Chris Banes        if ((st.featureId == FEATURE_OPTIONS_PANEL || st.featureId == FEATURE_ACTION_BAR) &&
91200d183885b54de433e43118d3032340f40cac8c0Chris Banes                mDecorContentParent != null) {
91361c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes            final TypedValue outValue = new TypedValue();
91461c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes            final Resources.Theme baseTheme = context.getTheme();
91561c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes            baseTheme.resolveAttribute(R.attr.actionBarTheme, outValue, true);
91661c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes
91761c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes            Resources.Theme widgetTheme = null;
91861c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes            if (outValue.resourceId != 0) {
91961c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes                widgetTheme = context.getResources().newTheme();
92061c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes                widgetTheme.setTo(baseTheme);
92161c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes                widgetTheme.applyStyle(outValue.resourceId, true);
92261c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes                widgetTheme.resolveAttribute(
92361c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes                        R.attr.actionBarWidgetTheme, outValue, true);
92461c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes            } else {
92561c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes                baseTheme.resolveAttribute(
92661c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes                        R.attr.actionBarWidgetTheme, outValue, true);
92761c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes            }
92861c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes
92961c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes            if (outValue.resourceId != 0) {
93061c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes                if (widgetTheme == null) {
93161c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes                    widgetTheme = context.getResources().newTheme();
93261c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes                    widgetTheme.setTo(baseTheme);
93361c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes                }
93461c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes                widgetTheme.applyStyle(outValue.resourceId, true);
93561c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes            }
93661c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes
93761c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes            if (widgetTheme != null) {
93861c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes                context = new ContextThemeWrapper(context, 0);
93961c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes                context.getTheme().setTo(widgetTheme);
94061c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes            }
94161c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes        }
94261c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes
94300d183885b54de433e43118d3032340f40cac8c0Chris Banes        final MenuBuilder menu = new MenuBuilder(context);
94400d183885b54de433e43118d3032340f40cac8c0Chris Banes        menu.setCallback(this);
94500d183885b54de433e43118d3032340f40cac8c0Chris Banes        st.setMenu(menu);
94661c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes
9478902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes        return true;
9488902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes    }
9498902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes
95000d183885b54de433e43118d3032340f40cac8c0Chris Banes    private boolean initializePanelContent(PanelFeatureState st) {
95100d183885b54de433e43118d3032340f40cac8c0Chris Banes        if (st.menu == null) {
95200d183885b54de433e43118d3032340f40cac8c0Chris Banes            return false;
95300d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
95400d183885b54de433e43118d3032340f40cac8c0Chris Banes
95500d183885b54de433e43118d3032340f40cac8c0Chris Banes        if (mPanelMenuPresenterCallback == null) {
95600d183885b54de433e43118d3032340f40cac8c0Chris Banes            mPanelMenuPresenterCallback = new PanelMenuPresenterCallback();
95700d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
95800d183885b54de433e43118d3032340f40cac8c0Chris Banes
95957c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes        MenuView menuView = st.getListMenuView(mPanelMenuPresenterCallback);
96000d183885b54de433e43118d3032340f40cac8c0Chris Banes
96100d183885b54de433e43118d3032340f40cac8c0Chris Banes        st.shownPanelView = (View) menuView;
96200d183885b54de433e43118d3032340f40cac8c0Chris Banes
96300d183885b54de433e43118d3032340f40cac8c0Chris Banes        return st.shownPanelView != null;
96400d183885b54de433e43118d3032340f40cac8c0Chris Banes    }
96500d183885b54de433e43118d3032340f40cac8c0Chris Banes
96600d183885b54de433e43118d3032340f40cac8c0Chris Banes    private boolean preparePanel(PanelFeatureState st, KeyEvent event) {
9679b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes        if (isDestroyed()) {
9689b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes            return false;
9699b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes        }
9709b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes
9718902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes        // Already prepared (isPrepared will be reset to false later)
97200d183885b54de433e43118d3032340f40cac8c0Chris Banes        if (st.isPrepared) {
9738902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes            return true;
9748902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes        }
9758902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes
97600d183885b54de433e43118d3032340f40cac8c0Chris Banes        if ((mPreparedPanel != null) && (mPreparedPanel != st)) {
97700d183885b54de433e43118d3032340f40cac8c0Chris Banes            // Another Panel is prepared and possibly open, so close it
97800d183885b54de433e43118d3032340f40cac8c0Chris Banes            closePanel(mPreparedPanel, false);
97900d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
98000d183885b54de433e43118d3032340f40cac8c0Chris Banes
98100d183885b54de433e43118d3032340f40cac8c0Chris Banes        final boolean isActionBarMenu =
98200d183885b54de433e43118d3032340f40cac8c0Chris Banes                (st.featureId == FEATURE_OPTIONS_PANEL || st.featureId == FEATURE_ACTION_BAR);
98300d183885b54de433e43118d3032340f40cac8c0Chris Banes
98400d183885b54de433e43118d3032340f40cac8c0Chris Banes        if (isActionBarMenu && mDecorContentParent != null) {
9858088261dec5dd277ccace13fe00f280ffa80098cChris Banes            // Enforce ordering guarantees around events so that the action bar never
9868088261dec5dd277ccace13fe00f280ffa80098cChris Banes            // dispatches menu-related events before the panel is prepared.
9878088261dec5dd277ccace13fe00f280ffa80098cChris Banes            mDecorContentParent.setMenuPrepared();
9888088261dec5dd277ccace13fe00f280ffa80098cChris Banes        }
9898088261dec5dd277ccace13fe00f280ffa80098cChris Banes
9908902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes        // Init the panel state's menu--return false if init failed
99100d183885b54de433e43118d3032340f40cac8c0Chris Banes        if (st.menu == null || st.refreshMenuContent) {
99200d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (st.menu == null) {
99300d183885b54de433e43118d3032340f40cac8c0Chris Banes                if (!initializePanelMenu(st) || (st.menu == null)) {
9948902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes                    return false;
9958902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes                }
9968902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes            }
9978902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes
99800d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (isActionBarMenu && mDecorContentParent != null) {
99903fc11b659da1645507062bddda450136e13af35Chris Banes                if (mActionMenuPresenterCallback == null) {
100003fc11b659da1645507062bddda450136e13af35Chris Banes                    mActionMenuPresenterCallback = new ActionMenuPresenterCallback();
100103fc11b659da1645507062bddda450136e13af35Chris Banes                }
100200d183885b54de433e43118d3032340f40cac8c0Chris Banes                mDecorContentParent.setMenu(st.menu, mActionMenuPresenterCallback);
10038902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes            }
10048902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes
10058902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes            // Creating the panel menu will involve a lot of manipulation;
10068902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes            // don't dispatch change events to presenters until we're done.
100700d183885b54de433e43118d3032340f40cac8c0Chris Banes            st.menu.stopDispatchingItemsChanged();
100800d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (!getWindowCallback().onCreatePanelMenu(st.featureId, st.menu)) {
10098902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes                // Ditch the menu created above
101000d183885b54de433e43118d3032340f40cac8c0Chris Banes                st.setMenu(null);
10118902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes
101200d183885b54de433e43118d3032340f40cac8c0Chris Banes                if (isActionBarMenu && mDecorContentParent != null) {
10138902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes                    // Don't show it in the action bar either
101403fc11b659da1645507062bddda450136e13af35Chris Banes                    mDecorContentParent.setMenu(null, mActionMenuPresenterCallback);
10158902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes                }
10168902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes
10178902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes                return false;
10188902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes            }
10198902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes
102000d183885b54de433e43118d3032340f40cac8c0Chris Banes            st.refreshMenuContent = false;
10218902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes        }
10228902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes
10238902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes        // Preparing the panel menu can involve a lot of manipulation;
10248902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes        // don't dispatch change events to presenters until we're done.
102500d183885b54de433e43118d3032340f40cac8c0Chris Banes        st.menu.stopDispatchingItemsChanged();
10268902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes
10278902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes        // Restore action view state before we prepare. This gives apps
10288902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes        // an opportunity to override frozen/restored state in onPrepare.
102900d183885b54de433e43118d3032340f40cac8c0Chris Banes        if (st.frozenActionViewState != null) {
103000d183885b54de433e43118d3032340f40cac8c0Chris Banes            st.menu.restoreActionViewStates(st.frozenActionViewState);
103100d183885b54de433e43118d3032340f40cac8c0Chris Banes            st.frozenActionViewState = null;
10328902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes        }
10338902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes
10348902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes        // Callback and return if the callback does not want to show the menu
103500d183885b54de433e43118d3032340f40cac8c0Chris Banes        if (!getWindowCallback().onPreparePanel(FEATURE_OPTIONS_PANEL, null, st.menu)) {
103600d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (isActionBarMenu && mDecorContentParent != null) {
10378902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes                // The app didn't want to show the menu for now but it still exists.
10388902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes                // Clear it out of the action bar.
103903fc11b659da1645507062bddda450136e13af35Chris Banes                mDecorContentParent.setMenu(null, mActionMenuPresenterCallback);
10408902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes            }
104100d183885b54de433e43118d3032340f40cac8c0Chris Banes            st.menu.startDispatchingItemsChanged();
10428902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes            return false;
10438902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes        }
10448902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes
104500d183885b54de433e43118d3032340f40cac8c0Chris Banes        // Set the proper keymap
104600d183885b54de433e43118d3032340f40cac8c0Chris Banes        KeyCharacterMap kmap = KeyCharacterMap.load(
104700d183885b54de433e43118d3032340f40cac8c0Chris Banes                event != null ? event.getDeviceId() : KeyCharacterMap.VIRTUAL_KEYBOARD);
104800d183885b54de433e43118d3032340f40cac8c0Chris Banes        st.qwertyMode = kmap.getKeyboardType() != KeyCharacterMap.NUMERIC;
104900d183885b54de433e43118d3032340f40cac8c0Chris Banes        st.menu.setQwertyMode(st.qwertyMode);
105000d183885b54de433e43118d3032340f40cac8c0Chris Banes        st.menu.startDispatchingItemsChanged();
10518902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes
10528902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes        // Set other state
105300d183885b54de433e43118d3032340f40cac8c0Chris Banes        st.isPrepared = true;
105400d183885b54de433e43118d3032340f40cac8c0Chris Banes        st.isHandled = false;
105500d183885b54de433e43118d3032340f40cac8c0Chris Banes        mPreparedPanel = st;
10568902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes
10578902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes        return true;
10588902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes    }
10598902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes
106000d183885b54de433e43118d3032340f40cac8c0Chris Banes    private void checkCloseActionMenu(MenuBuilder menu) {
106103fc11b659da1645507062bddda450136e13af35Chris Banes        if (mClosingActionMenu) {
106203fc11b659da1645507062bddda450136e13af35Chris Banes            return;
106303fc11b659da1645507062bddda450136e13af35Chris Banes        }
106403fc11b659da1645507062bddda450136e13af35Chris Banes
106503fc11b659da1645507062bddda450136e13af35Chris Banes        mClosingActionMenu = true;
106603fc11b659da1645507062bddda450136e13af35Chris Banes        mDecorContentParent.dismissPopups();
106700d183885b54de433e43118d3032340f40cac8c0Chris Banes        WindowCallback cb = getWindowCallback();
10689b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes        if (cb != null && !isDestroyed()) {
106900d183885b54de433e43118d3032340f40cac8c0Chris Banes            cb.onPanelClosed(FEATURE_ACTION_BAR, menu);
107000d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
107103fc11b659da1645507062bddda450136e13af35Chris Banes        mClosingActionMenu = false;
107203fc11b659da1645507062bddda450136e13af35Chris Banes    }
107303fc11b659da1645507062bddda450136e13af35Chris Banes
107400d183885b54de433e43118d3032340f40cac8c0Chris Banes    private void closePanel(PanelFeatureState st, boolean doCallback) {
107500d183885b54de433e43118d3032340f40cac8c0Chris Banes        if (doCallback && st.featureId == FEATURE_OPTIONS_PANEL &&
107600d183885b54de433e43118d3032340f40cac8c0Chris Banes                mDecorContentParent != null && mDecorContentParent.isOverflowMenuShowing()) {
107700d183885b54de433e43118d3032340f40cac8c0Chris Banes            checkCloseActionMenu(st.menu);
107800d183885b54de433e43118d3032340f40cac8c0Chris Banes            return;
107900d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
108000d183885b54de433e43118d3032340f40cac8c0Chris Banes
108100d183885b54de433e43118d3032340f40cac8c0Chris Banes        if (st.isOpen) {
108200d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (doCallback) {
108300d183885b54de433e43118d3032340f40cac8c0Chris Banes                callOnPanelClosed(st.featureId, st, null);
108400d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
108500d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
108600d183885b54de433e43118d3032340f40cac8c0Chris Banes
108700d183885b54de433e43118d3032340f40cac8c0Chris Banes        st.isPrepared = false;
108800d183885b54de433e43118d3032340f40cac8c0Chris Banes        st.isHandled = false;
108900d183885b54de433e43118d3032340f40cac8c0Chris Banes        st.isOpen = false;
109000d183885b54de433e43118d3032340f40cac8c0Chris Banes
109100d183885b54de433e43118d3032340f40cac8c0Chris Banes        // This view is no longer shown, so null it out
109200d183885b54de433e43118d3032340f40cac8c0Chris Banes        st.shownPanelView = null;
109300d183885b54de433e43118d3032340f40cac8c0Chris Banes
109400d183885b54de433e43118d3032340f40cac8c0Chris Banes        // Next time the menu opens, it should not be in expanded mode, so
109500d183885b54de433e43118d3032340f40cac8c0Chris Banes        // force a refresh of the decor
109600d183885b54de433e43118d3032340f40cac8c0Chris Banes        st.refreshDecorView = true;
109700d183885b54de433e43118d3032340f40cac8c0Chris Banes
109800d183885b54de433e43118d3032340f40cac8c0Chris Banes        if (mPreparedPanel == st) {
109900d183885b54de433e43118d3032340f40cac8c0Chris Banes            mPreparedPanel = null;
110003fc11b659da1645507062bddda450136e13af35Chris Banes        }
110103fc11b659da1645507062bddda450136e13af35Chris Banes    }
110203fc11b659da1645507062bddda450136e13af35Chris Banes
110300d183885b54de433e43118d3032340f40cac8c0Chris Banes    private void callOnPanelClosed(int featureId, PanelFeatureState panel, Menu menu) {
110400d183885b54de433e43118d3032340f40cac8c0Chris Banes        // Try to get a menu
110500d183885b54de433e43118d3032340f40cac8c0Chris Banes        if (menu == null) {
110600d183885b54de433e43118d3032340f40cac8c0Chris Banes            // Need a panel to grab the menu, so try to get that
110700d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (panel == null) {
110800d183885b54de433e43118d3032340f40cac8c0Chris Banes                if ((featureId >= 0) && (featureId < mPanels.length)) {
110900d183885b54de433e43118d3032340f40cac8c0Chris Banes                    panel = mPanels[featureId];
111000d183885b54de433e43118d3032340f40cac8c0Chris Banes                }
111100d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
111200d183885b54de433e43118d3032340f40cac8c0Chris Banes
111300d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (panel != null) {
111400d183885b54de433e43118d3032340f40cac8c0Chris Banes                // menu still may be null, which is okay--we tried our best
111500d183885b54de433e43118d3032340f40cac8c0Chris Banes                menu = panel.menu;
111600d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
111700d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
111800d183885b54de433e43118d3032340f40cac8c0Chris Banes
111900d183885b54de433e43118d3032340f40cac8c0Chris Banes        // If the panel is not open, do not callback
112000d183885b54de433e43118d3032340f40cac8c0Chris Banes        if ((panel != null) && (!panel.isOpen))
112100d183885b54de433e43118d3032340f40cac8c0Chris Banes            return;
112200d183885b54de433e43118d3032340f40cac8c0Chris Banes
112300d183885b54de433e43118d3032340f40cac8c0Chris Banes        getWindowCallback().onPanelClosed(featureId, menu);
112400d183885b54de433e43118d3032340f40cac8c0Chris Banes    }
112500d183885b54de433e43118d3032340f40cac8c0Chris Banes
112600d183885b54de433e43118d3032340f40cac8c0Chris Banes    private PanelFeatureState findMenuPanel(Menu menu) {
112700d183885b54de433e43118d3032340f40cac8c0Chris Banes        final PanelFeatureState[] panels = mPanels;
112800d183885b54de433e43118d3032340f40cac8c0Chris Banes        final int N = panels != null ? panels.length : 0;
112900d183885b54de433e43118d3032340f40cac8c0Chris Banes        for (int i = 0; i < N; i++) {
113000d183885b54de433e43118d3032340f40cac8c0Chris Banes            final PanelFeatureState panel = panels[i];
113100d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (panel != null && panel.menu == menu) {
113200d183885b54de433e43118d3032340f40cac8c0Chris Banes                return panel;
113300d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
113400d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
113500d183885b54de433e43118d3032340f40cac8c0Chris Banes        return null;
113600d183885b54de433e43118d3032340f40cac8c0Chris Banes    }
113700d183885b54de433e43118d3032340f40cac8c0Chris Banes
113800d183885b54de433e43118d3032340f40cac8c0Chris Banes    private PanelFeatureState getPanelState(int featureId, boolean required) {
113900d183885b54de433e43118d3032340f40cac8c0Chris Banes        PanelFeatureState[] ar;
114000d183885b54de433e43118d3032340f40cac8c0Chris Banes        if ((ar = mPanels) == null || ar.length <= featureId) {
114100d183885b54de433e43118d3032340f40cac8c0Chris Banes            PanelFeatureState[] nar = new PanelFeatureState[featureId + 1];
114200d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (ar != null) {
114300d183885b54de433e43118d3032340f40cac8c0Chris Banes                System.arraycopy(ar, 0, nar, 0, ar.length);
114400d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
114500d183885b54de433e43118d3032340f40cac8c0Chris Banes            mPanels = ar = nar;
114603fc11b659da1645507062bddda450136e13af35Chris Banes        }
114700d183885b54de433e43118d3032340f40cac8c0Chris Banes
114800d183885b54de433e43118d3032340f40cac8c0Chris Banes        PanelFeatureState st = ar[featureId];
114900d183885b54de433e43118d3032340f40cac8c0Chris Banes        if (st == null) {
115000d183885b54de433e43118d3032340f40cac8c0Chris Banes            ar[featureId] = st = new PanelFeatureState(featureId);
115100d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
115200d183885b54de433e43118d3032340f40cac8c0Chris Banes        return st;
115303fc11b659da1645507062bddda450136e13af35Chris Banes    }
115403fc11b659da1645507062bddda450136e13af35Chris Banes
115500d183885b54de433e43118d3032340f40cac8c0Chris Banes    final boolean performPanelShortcut(PanelFeatureState st, int keyCode, KeyEvent event,
115600d183885b54de433e43118d3032340f40cac8c0Chris Banes            int flags) {
1157dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes        if (event.isSystem()) {
1158dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes            return false;
1159dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes        }
1160dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes
1161dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes        boolean handled = false;
1162dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes
1163dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes        // Only try to perform menu shortcuts if preparePanel returned true (possible false
1164dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes        // return value from application not wanting to show the menu).
116500d183885b54de433e43118d3032340f40cac8c0Chris Banes        if ((st.isPrepared || preparePanel(st, event)) && st.menu != null) {
1166dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes            // The menu is prepared now, perform the shortcut on it
116700d183885b54de433e43118d3032340f40cac8c0Chris Banes            handled = st.menu.performShortcut(keyCode, event, flags);
1168dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes        }
1169dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes
1170dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes        if (handled) {
1171dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes            // Only close down the menu if we don't have an action bar keeping it open.
1172dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes            if ((flags & Menu.FLAG_PERFORM_NO_CLOSE) == 0 && mDecorContentParent == null) {
117300d183885b54de433e43118d3032340f40cac8c0Chris Banes                closePanel(st, true);
1174dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes            }
1175dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes        }
1176dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes
1177dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes        return handled;
1178dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes    }
1179dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes
118000d183885b54de433e43118d3032340f40cac8c0Chris Banes    private void invalidatePanelMenu(int featureId) {
118100d183885b54de433e43118d3032340f40cac8c0Chris Banes        mInvalidatePanelMenuFeatures |= 1 << featureId;
118200d183885b54de433e43118d3032340f40cac8c0Chris Banes
118300d183885b54de433e43118d3032340f40cac8c0Chris Banes        if (!mInvalidatePanelMenuPosted && mWindowDecor != null) {
118400d183885b54de433e43118d3032340f40cac8c0Chris Banes            ViewCompat.postOnAnimation(mWindowDecor, mInvalidatePanelMenuRunnable);
118500d183885b54de433e43118d3032340f40cac8c0Chris Banes            mInvalidatePanelMenuPosted = true;
118600d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
118700d183885b54de433e43118d3032340f40cac8c0Chris Banes    }
118800d183885b54de433e43118d3032340f40cac8c0Chris Banes
118900d183885b54de433e43118d3032340f40cac8c0Chris Banes    private void doInvalidatePanelMenu(int featureId) {
119000d183885b54de433e43118d3032340f40cac8c0Chris Banes        PanelFeatureState st = getPanelState(featureId, true);
119100d183885b54de433e43118d3032340f40cac8c0Chris Banes        Bundle savedActionViewStates = null;
119200d183885b54de433e43118d3032340f40cac8c0Chris Banes        if (st.menu != null) {
119300d183885b54de433e43118d3032340f40cac8c0Chris Banes            savedActionViewStates = new Bundle();
119400d183885b54de433e43118d3032340f40cac8c0Chris Banes            st.menu.saveActionViewStates(savedActionViewStates);
119500d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (savedActionViewStates.size() > 0) {
119600d183885b54de433e43118d3032340f40cac8c0Chris Banes                st.frozenActionViewState = savedActionViewStates;
119700d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
119800d183885b54de433e43118d3032340f40cac8c0Chris Banes            // This will be started again when the panel is prepared.
119900d183885b54de433e43118d3032340f40cac8c0Chris Banes            st.menu.stopDispatchingItemsChanged();
120000d183885b54de433e43118d3032340f40cac8c0Chris Banes            st.menu.clear();
120100d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
120200d183885b54de433e43118d3032340f40cac8c0Chris Banes        st.refreshMenuContent = true;
120300d183885b54de433e43118d3032340f40cac8c0Chris Banes        st.refreshDecorView = true;
120400d183885b54de433e43118d3032340f40cac8c0Chris Banes
120500d183885b54de433e43118d3032340f40cac8c0Chris Banes        // Prepare the options panel if we have an action bar
120600d183885b54de433e43118d3032340f40cac8c0Chris Banes        if ((featureId == FEATURE_ACTION_BAR || featureId == FEATURE_OPTIONS_PANEL)
120700d183885b54de433e43118d3032340f40cac8c0Chris Banes                && mDecorContentParent != null) {
120800d183885b54de433e43118d3032340f40cac8c0Chris Banes            st = getPanelState(Window.FEATURE_OPTIONS_PANEL, false);
120900d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (st != null) {
121000d183885b54de433e43118d3032340f40cac8c0Chris Banes                st.isPrepared = false;
121100d183885b54de433e43118d3032340f40cac8c0Chris Banes                preparePanel(st, null);
121200d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
121300d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
121400d183885b54de433e43118d3032340f40cac8c0Chris Banes    }
121500d183885b54de433e43118d3032340f40cac8c0Chris Banes
1216ea4f700ac38424954c56df5138ff794def50b019Chris Banes    /**
1217ea4f700ac38424954c56df5138ff794def50b019Chris Banes     * Updates the status bar guard
1218ea4f700ac38424954c56df5138ff794def50b019Chris Banes     *
1219ea4f700ac38424954c56df5138ff794def50b019Chris Banes     * @param insetTop the current top system window inset
1220ea4f700ac38424954c56df5138ff794def50b019Chris Banes     * @return the new top system window inset
1221ea4f700ac38424954c56df5138ff794def50b019Chris Banes     */
1222ea4f700ac38424954c56df5138ff794def50b019Chris Banes    private int updateStatusGuard(int insetTop) {
1223ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes        boolean showStatusGuard = false;
1224ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes        // Show the status guard when the non-overlay contextual action bar is showing
1225ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes        if (mActionModeView != null) {
1226ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes            if (mActionModeView.getLayoutParams() instanceof ViewGroup.MarginLayoutParams) {
1227ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                ViewGroup.MarginLayoutParams mlp = (ViewGroup.MarginLayoutParams)
1228ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                        mActionModeView.getLayoutParams();
1229ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                boolean mlpChanged = false;
1230ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes
1231ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                if (mActionModeView.isShown()) {
12327efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell                    if (mTempRect1 == null) {
12337efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell                        mTempRect1 = new Rect();
12347efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell                        mTempRect2 = new Rect();
12357efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell                    }
12367efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell                    final Rect insets = mTempRect1;
12377efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell                    final Rect localInsets = mTempRect2;
12387efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell                    insets.set(0, insetTop, 0, 0);
12397efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell
12407efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell                    ViewUtils.computeFitSystemWindows(mSubDecor, insets, localInsets);
12417efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell                    final int newMargin = localInsets.top == 0 ? insetTop : 0;
12427efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell                    if (mlp.topMargin != newMargin) {
12437efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell                        mlpChanged = true;
12447efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell                        mlp.topMargin = insetTop;
12457efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell
1246ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                        if (mStatusGuard == null) {
1247ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                            mStatusGuard = new View(mActivity);
1248ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                            mStatusGuard.setBackgroundColor(mActivity.getResources()
1249ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                                    .getColor(R.color.abc_input_method_navigation_guard));
12507efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell                            mSubDecor.addView(mStatusGuard, -1,
1251ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                                    new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
1252ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                                            insetTop));
1253ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                        } else {
1254ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                            ViewGroup.LayoutParams lp = mStatusGuard.getLayoutParams();
1255ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                            if (lp.height != insetTop) {
1256ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                                lp.height = insetTop;
1257ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                                mStatusGuard.setLayoutParams(lp);
1258ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                            }
1259ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                        }
1260ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                    }
1261ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes
1262bbb50c78cc6ee24677c79bd4548fa38fcdc41d92Adam Powell                    // The action mode's theme may differ from the app, so
1263bbb50c78cc6ee24677c79bd4548fa38fcdc41d92Adam Powell                    // always show the status guard above it.
1264bbb50c78cc6ee24677c79bd4548fa38fcdc41d92Adam Powell                    showStatusGuard = mStatusGuard != null;
1265bbb50c78cc6ee24677c79bd4548fa38fcdc41d92Adam Powell
12667efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell                    // We only need to consume the insets if the action
12677efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell                    // mode is overlaid on the app content (e.g. it's
12687efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell                    // sitting in a FrameLayout, see
12697efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell                    // screen_simple_overlay_action_mode.xml).
1270bbb50c78cc6ee24677c79bd4548fa38fcdc41d92Adam Powell                    if (!mOverlayActionMode && showStatusGuard) {
12717efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell                        insetTop = 0;
12727efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell                    }
1273ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                } else {
1274ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                    // reset top margin
1275ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                    if (mlp.topMargin != 0) {
1276ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                        mlpChanged = true;
1277ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                        mlp.topMargin = 0;
1278ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                    }
1279ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                }
1280ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                if (mlpChanged) {
1281ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                    mActionModeView.setLayoutParams(mlp);
1282ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                }
1283ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes            }
1284ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes        }
1285ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes        if (mStatusGuard != null) {
1286ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes            mStatusGuard.setVisibility(showStatusGuard ? View.VISIBLE : View.GONE);
1287ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes        }
1288ea4f700ac38424954c56df5138ff794def50b019Chris Banes
1289ea4f700ac38424954c56df5138ff794def50b019Chris Banes        return insetTop;
1290ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes    }
1291ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes
1292da0b9d63d6f940cbfd5b526c3f81858aeadcb7e8Chris Banes    private void ensureToolbarListMenuPresenter() {
1293da0b9d63d6f940cbfd5b526c3f81858aeadcb7e8Chris Banes        if (mToolbarListMenuPresenter == null) {
1294da0b9d63d6f940cbfd5b526c3f81858aeadcb7e8Chris Banes            // First resolve panelMenuListTheme
1295da0b9d63d6f940cbfd5b526c3f81858aeadcb7e8Chris Banes            TypedValue outValue = new TypedValue();
1296da0b9d63d6f940cbfd5b526c3f81858aeadcb7e8Chris Banes            mActivity.getTheme().resolveAttribute(R.attr.panelMenuListTheme, outValue, true);
1297da0b9d63d6f940cbfd5b526c3f81858aeadcb7e8Chris Banes
1298da0b9d63d6f940cbfd5b526c3f81858aeadcb7e8Chris Banes            Context context = new ContextThemeWrapper(mActivity,
1299da0b9d63d6f940cbfd5b526c3f81858aeadcb7e8Chris Banes                    outValue.resourceId != 0
1300da0b9d63d6f940cbfd5b526c3f81858aeadcb7e8Chris Banes                            ? outValue.resourceId
1301da0b9d63d6f940cbfd5b526c3f81858aeadcb7e8Chris Banes                            : R.style.Theme_AppCompat_CompactMenu);
1302da0b9d63d6f940cbfd5b526c3f81858aeadcb7e8Chris Banes
1303da0b9d63d6f940cbfd5b526c3f81858aeadcb7e8Chris Banes            mToolbarListMenuPresenter = new ListMenuPresenter(context,
1304da0b9d63d6f940cbfd5b526c3f81858aeadcb7e8Chris Banes                    R.layout.abc_list_menu_item_layout);
1305da0b9d63d6f940cbfd5b526c3f81858aeadcb7e8Chris Banes        }
1306da0b9d63d6f940cbfd5b526c3f81858aeadcb7e8Chris Banes    }
1307da0b9d63d6f940cbfd5b526c3f81858aeadcb7e8Chris Banes
1308cc7aada3ee922cfb38eeb36ee696cc73dcbae0a4Chris Banes    private void throwFeatureRequestIfSubDecorInstalled() {
1309cc7aada3ee922cfb38eeb36ee696cc73dcbae0a4Chris Banes        if (mSubDecorInstalled) {
1310cc7aada3ee922cfb38eeb36ee696cc73dcbae0a4Chris Banes            throw new AndroidRuntimeException(
1311cc7aada3ee922cfb38eeb36ee696cc73dcbae0a4Chris Banes                    "supportRequestWindowFeature() must be called before adding content");
1312cc7aada3ee922cfb38eeb36ee696cc73dcbae0a4Chris Banes        }
1313cc7aada3ee922cfb38eeb36ee696cc73dcbae0a4Chris Banes    }
1314cc7aada3ee922cfb38eeb36ee696cc73dcbae0a4Chris Banes
1315ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes    /**
1316d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes     * Clears out internal reference when the action mode is destroyed.
1317d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes     */
1318d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes    private class ActionModeCallbackWrapper implements ActionMode.Callback {
1319d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        private ActionMode.Callback mWrapped;
1320d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes
1321d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        public ActionModeCallbackWrapper(ActionMode.Callback wrapped) {
1322d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes            mWrapped = wrapped;
1323d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        }
1324d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes
1325d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        public boolean onCreateActionMode(ActionMode mode, Menu menu) {
1326d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes            return mWrapped.onCreateActionMode(mode, menu);
1327d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        }
1328d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes
1329d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
13309addcff1698f71fb4145f39dacaf33a9c1fef24fChris Banes            return mWrapped.onPrepareActionMode(mode, menu);
1331d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        }
1332d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes
1333d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
1334d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes            return mWrapped.onActionItemClicked(mode, item);
1335d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        }
1336d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes
1337d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        public void onDestroyActionMode(ActionMode mode) {
1338d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes            mWrapped.onDestroyActionMode(mode);
13394c2a95906254748cb9a843b061288265d6e185a9Chris Banes            if (mActionModePopup != null) {
13404c2a95906254748cb9a843b061288265d6e185a9Chris Banes                mActivity.getWindow().getDecorView().removeCallbacks(mShowActionModePopup);
13414c2a95906254748cb9a843b061288265d6e185a9Chris Banes                mActionModePopup.dismiss();
13424c2a95906254748cb9a843b061288265d6e185a9Chris Banes            } else if (mActionModeView != null) {
13434c2a95906254748cb9a843b061288265d6e185a9Chris Banes                mActionModeView.setVisibility(View.GONE);
1344ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                if (mActionModeView.getParent() != null) {
1345ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                    ViewCompat.requestApplyInsets((View) mActionModeView.getParent());
1346ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes                }
13474c2a95906254748cb9a843b061288265d6e185a9Chris Banes            }
13484c2a95906254748cb9a843b061288265d6e185a9Chris Banes            if (mActionModeView != null) {
13494c2a95906254748cb9a843b061288265d6e185a9Chris Banes                mActionModeView.removeAllViews();
13504c2a95906254748cb9a843b061288265d6e185a9Chris Banes            }
13514c2a95906254748cb9a843b061288265d6e185a9Chris Banes            if (mActivity != null) {
13524c2a95906254748cb9a843b061288265d6e185a9Chris Banes                try {
13534c2a95906254748cb9a843b061288265d6e185a9Chris Banes                    mActivity.onSupportActionModeFinished(mActionMode);
13544c2a95906254748cb9a843b061288265d6e185a9Chris Banes                } catch (AbstractMethodError ame) {
13554c2a95906254748cb9a843b061288265d6e185a9Chris Banes                    // Older apps might not implement this callback method.
13564c2a95906254748cb9a843b061288265d6e185a9Chris Banes                }
13574c2a95906254748cb9a843b061288265d6e185a9Chris Banes            }
1358d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes            mActionMode = null;
1359d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes        }
1360d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes    }
1361d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes
136203fc11b659da1645507062bddda450136e13af35Chris Banes    private final class PanelMenuPresenterCallback implements MenuPresenter.Callback {
136303fc11b659da1645507062bddda450136e13af35Chris Banes        @Override
136400d183885b54de433e43118d3032340f40cac8c0Chris Banes        public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) {
136500d183885b54de433e43118d3032340f40cac8c0Chris Banes            final Menu parentMenu = menu.getRootMenu();
136600d183885b54de433e43118d3032340f40cac8c0Chris Banes            final boolean isSubMenu = parentMenu != menu;
136700d183885b54de433e43118d3032340f40cac8c0Chris Banes            final PanelFeatureState panel = findMenuPanel(isSubMenu ? parentMenu : menu);
136800d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (panel != null) {
136900d183885b54de433e43118d3032340f40cac8c0Chris Banes                if (isSubMenu) {
137000d183885b54de433e43118d3032340f40cac8c0Chris Banes                    callOnPanelClosed(panel.featureId, panel, parentMenu);
137100d183885b54de433e43118d3032340f40cac8c0Chris Banes                    closePanel(panel, true);
137200d183885b54de433e43118d3032340f40cac8c0Chris Banes                } else {
137300d183885b54de433e43118d3032340f40cac8c0Chris Banes                    // Close the panel and only do the callback if the menu is being
137400d183885b54de433e43118d3032340f40cac8c0Chris Banes                    // closed completely, not if opening a sub menu
137528cca4bf59e7f3fd35f9da05caa9418251b5227aChris Banes                    mActivity.closeOptionsMenu();
137600d183885b54de433e43118d3032340f40cac8c0Chris Banes                    closePanel(panel, allMenusAreClosing);
137700d183885b54de433e43118d3032340f40cac8c0Chris Banes                }
137800d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
137903fc11b659da1645507062bddda450136e13af35Chris Banes        }
138003fc11b659da1645507062bddda450136e13af35Chris Banes
138103fc11b659da1645507062bddda450136e13af35Chris Banes        @Override
138200d183885b54de433e43118d3032340f40cac8c0Chris Banes        public boolean onOpenSubMenu(MenuBuilder subMenu) {
138300d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (subMenu == null && mHasActionBar) {
138400d183885b54de433e43118d3032340f40cac8c0Chris Banes                WindowCallback cb = getWindowCallback();
13859b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes                if (cb != null && !isDestroyed()) {
138600d183885b54de433e43118d3032340f40cac8c0Chris Banes                    cb.onMenuOpened(FEATURE_ACTION_BAR, subMenu);
138700d183885b54de433e43118d3032340f40cac8c0Chris Banes                }
138800d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
138900d183885b54de433e43118d3032340f40cac8c0Chris Banes            return true;
139003fc11b659da1645507062bddda450136e13af35Chris Banes        }
139103fc11b659da1645507062bddda450136e13af35Chris Banes    }
139203fc11b659da1645507062bddda450136e13af35Chris Banes
139303fc11b659da1645507062bddda450136e13af35Chris Banes    private final class ActionMenuPresenterCallback implements MenuPresenter.Callback {
139403fc11b659da1645507062bddda450136e13af35Chris Banes        @Override
139503fc11b659da1645507062bddda450136e13af35Chris Banes        public boolean onOpenSubMenu(MenuBuilder subMenu) {
139600d183885b54de433e43118d3032340f40cac8c0Chris Banes            WindowCallback cb = getWindowCallback();
139700d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (cb != null) {
139800d183885b54de433e43118d3032340f40cac8c0Chris Banes                cb.onMenuOpened(FEATURE_ACTION_BAR, subMenu);
139900d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
140000d183885b54de433e43118d3032340f40cac8c0Chris Banes            return true;
140103fc11b659da1645507062bddda450136e13af35Chris Banes        }
140203fc11b659da1645507062bddda450136e13af35Chris Banes
140303fc11b659da1645507062bddda450136e13af35Chris Banes        @Override
140403fc11b659da1645507062bddda450136e13af35Chris Banes        public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) {
140500d183885b54de433e43118d3032340f40cac8c0Chris Banes            checkCloseActionMenu(menu);
140600d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
140700d183885b54de433e43118d3032340f40cac8c0Chris Banes    }
140800d183885b54de433e43118d3032340f40cac8c0Chris Banes
140900d183885b54de433e43118d3032340f40cac8c0Chris Banes    private static final class PanelFeatureState {
14109b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes
141100d183885b54de433e43118d3032340f40cac8c0Chris Banes        /** Feature ID for this panel. */
141200d183885b54de433e43118d3032340f40cac8c0Chris Banes        int featureId;
141300d183885b54de433e43118d3032340f40cac8c0Chris Banes
141400d183885b54de433e43118d3032340f40cac8c0Chris Banes        /** Dynamic state of the panel. */
141500d183885b54de433e43118d3032340f40cac8c0Chris Banes        ViewGroup decorView;
141600d183885b54de433e43118d3032340f40cac8c0Chris Banes
141700d183885b54de433e43118d3032340f40cac8c0Chris Banes        /** The panel that we are actually showing. */
141800d183885b54de433e43118d3032340f40cac8c0Chris Banes        View shownPanelView;
141900d183885b54de433e43118d3032340f40cac8c0Chris Banes
142000d183885b54de433e43118d3032340f40cac8c0Chris Banes        /** Use {@link #setMenu} to set this. */
142100d183885b54de433e43118d3032340f40cac8c0Chris Banes        MenuBuilder menu;
142200d183885b54de433e43118d3032340f40cac8c0Chris Banes
142300d183885b54de433e43118d3032340f40cac8c0Chris Banes        ListMenuPresenter listMenuPresenter;
142400d183885b54de433e43118d3032340f40cac8c0Chris Banes
142557c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes        Context listPresenterContext;
142600d183885b54de433e43118d3032340f40cac8c0Chris Banes
142700d183885b54de433e43118d3032340f40cac8c0Chris Banes        /**
142800d183885b54de433e43118d3032340f40cac8c0Chris Banes         * Whether the panel has been prepared (see
14299b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes         * {@link #preparePanel}).
143000d183885b54de433e43118d3032340f40cac8c0Chris Banes         */
143100d183885b54de433e43118d3032340f40cac8c0Chris Banes        boolean isPrepared;
143200d183885b54de433e43118d3032340f40cac8c0Chris Banes
143300d183885b54de433e43118d3032340f40cac8c0Chris Banes        /**
143400d183885b54de433e43118d3032340f40cac8c0Chris Banes         * Whether an item's action has been performed. This happens in obvious
143500d183885b54de433e43118d3032340f40cac8c0Chris Banes         * scenarios (user clicks on menu item), but can also happen with
143600d183885b54de433e43118d3032340f40cac8c0Chris Banes         * chording menu+(shortcut key).
143700d183885b54de433e43118d3032340f40cac8c0Chris Banes         */
143800d183885b54de433e43118d3032340f40cac8c0Chris Banes        boolean isHandled;
143900d183885b54de433e43118d3032340f40cac8c0Chris Banes
144000d183885b54de433e43118d3032340f40cac8c0Chris Banes        boolean isOpen;
144100d183885b54de433e43118d3032340f40cac8c0Chris Banes
144200d183885b54de433e43118d3032340f40cac8c0Chris Banes        public boolean qwertyMode;
144300d183885b54de433e43118d3032340f40cac8c0Chris Banes
144400d183885b54de433e43118d3032340f40cac8c0Chris Banes        boolean refreshDecorView;
144500d183885b54de433e43118d3032340f40cac8c0Chris Banes
144600d183885b54de433e43118d3032340f40cac8c0Chris Banes        boolean refreshMenuContent;
144700d183885b54de433e43118d3032340f40cac8c0Chris Banes
144800d183885b54de433e43118d3032340f40cac8c0Chris Banes        boolean wasLastOpen;
144900d183885b54de433e43118d3032340f40cac8c0Chris Banes
145000d183885b54de433e43118d3032340f40cac8c0Chris Banes        /**
145100d183885b54de433e43118d3032340f40cac8c0Chris Banes         * Contains the state of the menu when told to freeze.
145200d183885b54de433e43118d3032340f40cac8c0Chris Banes         */
145300d183885b54de433e43118d3032340f40cac8c0Chris Banes        Bundle frozenMenuState;
145400d183885b54de433e43118d3032340f40cac8c0Chris Banes
145500d183885b54de433e43118d3032340f40cac8c0Chris Banes        /**
145600d183885b54de433e43118d3032340f40cac8c0Chris Banes         * Contains the state of associated action views when told to freeze.
145700d183885b54de433e43118d3032340f40cac8c0Chris Banes         * These are saved across invalidations.
145800d183885b54de433e43118d3032340f40cac8c0Chris Banes         */
145900d183885b54de433e43118d3032340f40cac8c0Chris Banes        Bundle frozenActionViewState;
146000d183885b54de433e43118d3032340f40cac8c0Chris Banes
146100d183885b54de433e43118d3032340f40cac8c0Chris Banes        PanelFeatureState(int featureId) {
146200d183885b54de433e43118d3032340f40cac8c0Chris Banes            this.featureId = featureId;
146300d183885b54de433e43118d3032340f40cac8c0Chris Banes
146400d183885b54de433e43118d3032340f40cac8c0Chris Banes            refreshDecorView = false;
146500d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
146600d183885b54de433e43118d3032340f40cac8c0Chris Banes
146700d183885b54de433e43118d3032340f40cac8c0Chris Banes        public boolean hasPanelItems() {
146800d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (shownPanelView == null) return false;
146900d183885b54de433e43118d3032340f40cac8c0Chris Banes
147000d183885b54de433e43118d3032340f40cac8c0Chris Banes            return listMenuPresenter.getAdapter().getCount() > 0;
147100d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
147200d183885b54de433e43118d3032340f40cac8c0Chris Banes
147300d183885b54de433e43118d3032340f40cac8c0Chris Banes        /**
147400d183885b54de433e43118d3032340f40cac8c0Chris Banes         * Unregister and free attached MenuPresenters. They will be recreated as needed.
147500d183885b54de433e43118d3032340f40cac8c0Chris Banes         */
147600d183885b54de433e43118d3032340f40cac8c0Chris Banes        public void clearMenuPresenters() {
147700d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (menu != null) {
147800d183885b54de433e43118d3032340f40cac8c0Chris Banes                menu.removeMenuPresenter(listMenuPresenter);
147900d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
148000d183885b54de433e43118d3032340f40cac8c0Chris Banes            listMenuPresenter = null;
148100d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
148200d183885b54de433e43118d3032340f40cac8c0Chris Banes
148300d183885b54de433e43118d3032340f40cac8c0Chris Banes        void setStyle(Context context) {
148457c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes            final TypedValue outValue = new TypedValue();
148557c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes            final Resources.Theme widgetTheme = context.getResources().newTheme();
148657c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes            widgetTheme.setTo(context.getTheme());
148757c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes
148857c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes            // First apply the actionBarPopupTheme
148957c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes            widgetTheme.resolveAttribute(R.attr.actionBarPopupTheme, outValue, true);
149057c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes            if (outValue.resourceId != 0) {
149157c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes                widgetTheme.applyStyle(outValue.resourceId, true);
149257c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes            }
149357c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes
149457c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes            // Now apply the panelMenuListTheme
149557c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes            widgetTheme.resolveAttribute(R.attr.panelMenuListTheme, outValue, true);
149657c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes            if (outValue.resourceId != 0) {
149757c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes                widgetTheme.applyStyle(outValue.resourceId, true);
149857c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes            } else {
149957c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes                widgetTheme.applyStyle(R.style.Theme_AppCompat_CompactMenu, true);
150057c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes            }
150157c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes
150257c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes            context = new ContextThemeWrapper(context, 0);
150357c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes            context.getTheme().setTo(widgetTheme);
150457c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes
150557c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes            listPresenterContext = context;
150600d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
150700d183885b54de433e43118d3032340f40cac8c0Chris Banes
150800d183885b54de433e43118d3032340f40cac8c0Chris Banes        void setMenu(MenuBuilder menu) {
150900d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (menu == this.menu) return;
151000d183885b54de433e43118d3032340f40cac8c0Chris Banes
151100d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (this.menu != null) {
151200d183885b54de433e43118d3032340f40cac8c0Chris Banes                this.menu.removeMenuPresenter(listMenuPresenter);
151300d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
151400d183885b54de433e43118d3032340f40cac8c0Chris Banes            this.menu = menu;
151500d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (menu != null) {
151600d183885b54de433e43118d3032340f40cac8c0Chris Banes                if (listMenuPresenter != null) menu.addMenuPresenter(listMenuPresenter);
151700d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
151800d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
151900d183885b54de433e43118d3032340f40cac8c0Chris Banes
152057c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes        MenuView getListMenuView(MenuPresenter.Callback cb) {
152100d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (menu == null) return null;
152200d183885b54de433e43118d3032340f40cac8c0Chris Banes
152300d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (listMenuPresenter == null) {
152457c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes                listMenuPresenter = new ListMenuPresenter(listPresenterContext,
152557c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes                        R.layout.abc_list_menu_item_layout);
152600d183885b54de433e43118d3032340f40cac8c0Chris Banes                listMenuPresenter.setCallback(cb);
152700d183885b54de433e43118d3032340f40cac8c0Chris Banes                menu.addMenuPresenter(listMenuPresenter);
152800d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
152900d183885b54de433e43118d3032340f40cac8c0Chris Banes
153000d183885b54de433e43118d3032340f40cac8c0Chris Banes            MenuView result = listMenuPresenter.getMenuView(decorView);
153100d183885b54de433e43118d3032340f40cac8c0Chris Banes
153200d183885b54de433e43118d3032340f40cac8c0Chris Banes            return result;
153300d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
153400d183885b54de433e43118d3032340f40cac8c0Chris Banes
153500d183885b54de433e43118d3032340f40cac8c0Chris Banes        Parcelable onSaveInstanceState() {
153600d183885b54de433e43118d3032340f40cac8c0Chris Banes            SavedState savedState = new SavedState();
153700d183885b54de433e43118d3032340f40cac8c0Chris Banes            savedState.featureId = featureId;
153800d183885b54de433e43118d3032340f40cac8c0Chris Banes            savedState.isOpen = isOpen;
153900d183885b54de433e43118d3032340f40cac8c0Chris Banes
154000d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (menu != null) {
154100d183885b54de433e43118d3032340f40cac8c0Chris Banes                savedState.menuState = new Bundle();
154200d183885b54de433e43118d3032340f40cac8c0Chris Banes                menu.savePresenterStates(savedState.menuState);
154300d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
154400d183885b54de433e43118d3032340f40cac8c0Chris Banes
154500d183885b54de433e43118d3032340f40cac8c0Chris Banes            return savedState;
154600d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
154700d183885b54de433e43118d3032340f40cac8c0Chris Banes
154800d183885b54de433e43118d3032340f40cac8c0Chris Banes        void onRestoreInstanceState(Parcelable state) {
154900d183885b54de433e43118d3032340f40cac8c0Chris Banes            SavedState savedState = (SavedState) state;
155000d183885b54de433e43118d3032340f40cac8c0Chris Banes            featureId = savedState.featureId;
155100d183885b54de433e43118d3032340f40cac8c0Chris Banes            wasLastOpen = savedState.isOpen;
155200d183885b54de433e43118d3032340f40cac8c0Chris Banes            frozenMenuState = savedState.menuState;
155300d183885b54de433e43118d3032340f40cac8c0Chris Banes
155400d183885b54de433e43118d3032340f40cac8c0Chris Banes            shownPanelView = null;
155500d183885b54de433e43118d3032340f40cac8c0Chris Banes            decorView = null;
155600d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
155700d183885b54de433e43118d3032340f40cac8c0Chris Banes
155800d183885b54de433e43118d3032340f40cac8c0Chris Banes        void applyFrozenState() {
155900d183885b54de433e43118d3032340f40cac8c0Chris Banes            if (menu != null && frozenMenuState != null) {
156000d183885b54de433e43118d3032340f40cac8c0Chris Banes                menu.restorePresenterStates(frozenMenuState);
156100d183885b54de433e43118d3032340f40cac8c0Chris Banes                frozenMenuState = null;
156200d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
156300d183885b54de433e43118d3032340f40cac8c0Chris Banes        }
156400d183885b54de433e43118d3032340f40cac8c0Chris Banes
156500d183885b54de433e43118d3032340f40cac8c0Chris Banes        private static class SavedState implements Parcelable {
156600d183885b54de433e43118d3032340f40cac8c0Chris Banes            int featureId;
156700d183885b54de433e43118d3032340f40cac8c0Chris Banes            boolean isOpen;
156800d183885b54de433e43118d3032340f40cac8c0Chris Banes            Bundle menuState;
156900d183885b54de433e43118d3032340f40cac8c0Chris Banes
157000d183885b54de433e43118d3032340f40cac8c0Chris Banes            public int describeContents() {
157100d183885b54de433e43118d3032340f40cac8c0Chris Banes                return 0;
157200d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
157300d183885b54de433e43118d3032340f40cac8c0Chris Banes
157400d183885b54de433e43118d3032340f40cac8c0Chris Banes            public void writeToParcel(Parcel dest, int flags) {
157500d183885b54de433e43118d3032340f40cac8c0Chris Banes                dest.writeInt(featureId);
157600d183885b54de433e43118d3032340f40cac8c0Chris Banes                dest.writeInt(isOpen ? 1 : 0);
157700d183885b54de433e43118d3032340f40cac8c0Chris Banes
157800d183885b54de433e43118d3032340f40cac8c0Chris Banes                if (isOpen) {
157900d183885b54de433e43118d3032340f40cac8c0Chris Banes                    dest.writeBundle(menuState);
158000d183885b54de433e43118d3032340f40cac8c0Chris Banes                }
158100d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
158200d183885b54de433e43118d3032340f40cac8c0Chris Banes
158300d183885b54de433e43118d3032340f40cac8c0Chris Banes            private static SavedState readFromParcel(Parcel source) {
158400d183885b54de433e43118d3032340f40cac8c0Chris Banes                SavedState savedState = new SavedState();
158500d183885b54de433e43118d3032340f40cac8c0Chris Banes                savedState.featureId = source.readInt();
158600d183885b54de433e43118d3032340f40cac8c0Chris Banes                savedState.isOpen = source.readInt() == 1;
158700d183885b54de433e43118d3032340f40cac8c0Chris Banes
158800d183885b54de433e43118d3032340f40cac8c0Chris Banes                if (savedState.isOpen) {
158900d183885b54de433e43118d3032340f40cac8c0Chris Banes                    savedState.menuState = source.readBundle();
159000d183885b54de433e43118d3032340f40cac8c0Chris Banes                }
159100d183885b54de433e43118d3032340f40cac8c0Chris Banes
159200d183885b54de433e43118d3032340f40cac8c0Chris Banes                return savedState;
159300d183885b54de433e43118d3032340f40cac8c0Chris Banes            }
159400d183885b54de433e43118d3032340f40cac8c0Chris Banes
159500d183885b54de433e43118d3032340f40cac8c0Chris Banes            public static final Parcelable.Creator<SavedState> CREATOR
159600d183885b54de433e43118d3032340f40cac8c0Chris Banes                    = new Parcelable.Creator<SavedState>() {
159700d183885b54de433e43118d3032340f40cac8c0Chris Banes                public SavedState createFromParcel(Parcel in) {
159800d183885b54de433e43118d3032340f40cac8c0Chris Banes                    return readFromParcel(in);
159900d183885b54de433e43118d3032340f40cac8c0Chris Banes                }
160000d183885b54de433e43118d3032340f40cac8c0Chris Banes
160100d183885b54de433e43118d3032340f40cac8c0Chris Banes                public SavedState[] newArray(int size) {
160200d183885b54de433e43118d3032340f40cac8c0Chris Banes                    return new SavedState[size];
160300d183885b54de433e43118d3032340f40cac8c0Chris Banes                }
160400d183885b54de433e43118d3032340f40cac8c0Chris Banes            };
160503fc11b659da1645507062bddda450136e13af35Chris Banes        }
160603fc11b659da1645507062bddda450136e13af35Chris Banes    }
160703fc11b659da1645507062bddda450136e13af35Chris Banes
16086386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes}
1609